@@ -44,7 +44,6 @@ const (
4444 hopTimeout time.Duration = 3 * time .Second
4545 flushTimeout time.Duration = 10 * time .Millisecond
4646 availProxyUpdateInterval time.Duration = 30 * time .Second
47- kbSize int64 = 1000
4847 rrIndexMax uint32 = 1_000_000
4948 maxBodySize int64 = 2 << 15
5049)
@@ -120,6 +119,7 @@ type proxyapp struct {
120119 nocolor bool
121120 body bool
122121 json bool
122+ closeConn chan bool
123123
124124 mu sync.RWMutex
125125 availProxyList []proxyEntry
@@ -459,6 +459,18 @@ func (p *proxyapp) colorizeTunnel(req, resp layers.Layer, sniffheader *[]string,
459459 return nil
460460}
461461
462+ // https://stackoverflow.com/a/1094933/1333724
463+ func prettifyBytes (b int64 ) string {
464+ bf := float64 (b )
465+ for _ , unit := range []string {"" , "K" , "M" , "G" , "T" , "P" , "E" , "Z" } {
466+ if bf < 1000.0 {
467+ return fmt .Sprintf ("%3.1f%sB" , bf , unit )
468+ }
469+ bf /= 1000.0
470+ }
471+ return fmt .Sprintf ("%.1fYB" , bf )
472+ }
473+
462474func copyHeader (dst , src http.Header ) {
463475 for k , vv := range src {
464476 for _ , v := range vv {
@@ -851,12 +863,7 @@ func (p *proxyapp) handleForward(w http.ResponseWriter, r *http.Request) {
851863 close (done )
852864 return
853865 }
854- var written string
855- if n < kbSize {
856- written = fmt .Sprintf ("%dB" , n )
857- } else {
858- written = fmt .Sprintf ("%dKB" , n / kbSize )
859- }
866+ written := prettifyBytes (n )
860867 if chunked {
861868 written = fmt .Sprintf ("%s - chunked" , written )
862869 }
@@ -1023,51 +1030,57 @@ func dispatch(data []byte) (layers.Layer, error) {
10231030
10241031func (p * proxyapp ) copyWithTimeout (dst net.Conn , src net.Conn , msgChan chan <- layers.Layer ) (written int64 , err error ) {
10251032 buf := make ([]byte , 32 * 1024 )
1033+ readLoop:
10261034 for {
1027- er := src .SetReadDeadline (time .Now ().Add (readTimeout ))
1028- if er != nil {
1029- err = er
1030- break
1031- }
1032- nr , er := src .Read (buf )
1033- if nr > 0 {
1034- er := dst .SetWriteDeadline (time .Now ().Add (writeTimeout ))
1035+ select {
1036+ case <- p .closeConn :
1037+ break readLoop
1038+ default :
1039+ er := src .SetReadDeadline (time .Now ().Add (readTimeout ))
10351040 if er != nil {
10361041 err = er
1037- break
1042+ break readLoop
10381043 }
1039- if p .sniff {
1040- l , err := dispatch (buf [0 :nr ])
1041- if err == nil {
1042- msgChan <- l
1044+ nr , er := src .Read (buf )
1045+ if nr > 0 {
1046+ er := dst .SetWriteDeadline (time .Now ().Add (writeTimeout ))
1047+ if er != nil {
1048+ err = er
1049+ break readLoop
10431050 }
1044- }
1045- nw , ew := dst .Write (buf [0 :nr ])
1046- if nw < 0 || nr < nw {
1047- nw = 0
1048- if ew == nil {
1049- ew = errInvalidWrite
1051+ if p .sniff {
1052+ l , err := dispatch (buf [0 :nr ])
1053+ if err == nil {
1054+ msgChan <- l
1055+ }
10501056 }
1051- }
1052- written += int64 (nw )
1053- if ew != nil {
1054- if ne , ok := ew .(net.Error ); ok && ne .Timeout () {
1055- err = ne
1056- break
1057+ nw , ew := dst .Write (buf [0 :nr ])
1058+ if nw < 0 || nr < nw {
1059+ nw = 0
1060+ if ew == nil {
1061+ ew = errInvalidWrite
1062+ }
1063+ }
1064+ written += int64 (nw )
1065+ if ew != nil {
1066+ if ne , ok := ew .(net.Error ); ok && ne .Timeout () {
1067+ err = ne
1068+ break readLoop
1069+ }
1070+ }
1071+ if nr != nw {
1072+ err = io .ErrShortWrite
1073+ break readLoop
10571074 }
10581075 }
1059- if nr != nw {
1060- err = io .ErrShortWrite
1061- break
1062- }
1063- }
1064- if er != nil {
1065- if ne , ok := err .(net.Error ); ok && ne .Timeout () {
1066- err = er
1067- break
1068- }
1069- if er == io .EOF {
1070- break
1076+ if er != nil {
1077+ if ne , ok := err .(net.Error ); ok && ne .Timeout () {
1078+ err = er
1079+ break readLoop
1080+ }
1081+ if er == io .EOF {
1082+ break readLoop
1083+ }
10711084 }
10721085 }
10731086 }
@@ -1083,13 +1096,7 @@ func (p *proxyapp) transfer(wg *sync.WaitGroup, dst net.Conn, src net.Conn, dest
10831096 if err != nil {
10841097 p .logger .Error ().Err (err ).Msgf ("Error during copy from %s to %s: %v" , srcName , destName , err )
10851098 }
1086- var written string
1087- if n < kbSize {
1088- written = fmt .Sprintf ("%dB" , n )
1089- } else {
1090- written = fmt .Sprintf ("%dKB" , n / kbSize )
1091- }
1092- p .logger .Debug ().Msgf ("copied %s from %s to %s" , written , srcName , destName )
1099+ p .logger .Debug ().Msgf ("copied %s from %s to %s" , prettifyBytes (n ), srcName , destName )
10931100}
10941101
10951102func parseProxyAuth (auth string ) (username , password string , ok bool ) {
@@ -1242,6 +1249,7 @@ func (p *proxyapp) clearRedirectRules(output string) error {
12421249func (p * proxyapp ) Run () {
12431250 done := make (chan bool )
12441251 quit := make (chan os.Signal , 1 )
1252+ p .closeConn = make (chan bool )
12451253 signal .Notify (quit , os .Interrupt )
12461254 var tproxyServer * tproxyServer
12471255 if p .tproxyAddr != "" {
@@ -1276,6 +1284,7 @@ func (p *proxyapp) Run() {
12761284 p .logger .Error ().Err (err ).Msg ("Failed clearing iptables rules" )
12771285 }
12781286 }
1287+ close (p .closeConn )
12791288 if tproxyServer != nil {
12801289 p .logger .Info ().Msg ("[tproxy] Server is shutting down..." )
12811290 tproxyServer .Shutdown ()
@@ -1317,6 +1326,7 @@ func (p *proxyapp) Run() {
13171326 p .logger .Error ().Err (err ).Msg ("Failed clearing iptables rules" )
13181327 }
13191328 }
1329+ close (p .closeConn )
13201330 p .logger .Info ().Msg ("[tproxy] Server is shutting down..." )
13211331 tproxyServer .Shutdown ()
13221332 close (done )
0 commit comments