Skip to content

Commit ddb7e9f

Browse files
committed
Merge branch 'pull_129'
elazarl#129
2 parents 5e29539 + c4627dc commit ddb7e9f

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

ctx.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ type ProxyCtx struct {
1919
// call of RespHandler
2020
UserData interface{}
2121
// Will connect a request to a response
22-
Session int64
23-
proxy *ProxyHttpServer
22+
Session int64
23+
proxy *ProxyHttpServer
24+
BytesUpstream int64
25+
BytesDownstream int64
2426
}
2527

2628
type RoundTripper interface {

https.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"strconv"
1515
"strings"
1616
"sync/atomic"
17+
"time"
1718
)
1819

1920
type ConnectActionLiteral int
@@ -98,8 +99,9 @@ func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request
9899
}
99100
ctx.Logf("Accepting CONNECT to %s", host)
100101
proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
101-
go copyAndClose(ctx, targetSiteCon, proxyClient)
102-
go copyAndClose(ctx, proxyClient, targetSiteCon)
102+
103+
pipeAndClose(ctx, targetSiteCon, proxyClient)
104+
103105
case ConnectHijack:
104106
ctx.Logf("Hijacking CONNECT to %s", host)
105107
proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
@@ -254,15 +256,46 @@ func httpError(w io.WriteCloser, ctx *ProxyCtx, err error) {
254256
}
255257
}
256258

257-
func copyAndClose(ctx *ProxyCtx, w, r net.Conn) {
259+
func pipeAndClose(ctx *ProxyCtx, targetSiteCon, proxyClient net.Conn) {
260+
upCh := make(chan int64)
261+
downCh := make(chan int64)
262+
closedConns := 0
263+
264+
go func() {
265+
upCh <- copyAndClose(ctx, targetSiteCon, proxyClient)
266+
}()
267+
268+
go func() {
269+
downCh <- copyAndClose(ctx, proxyClient, targetSiteCon)
270+
}()
271+
272+
for closedConns < 2 {
273+
select {
274+
case bytes := <-upCh:
275+
ctx.BytesUpstream += bytes
276+
closedConns++
277+
targetSiteCon.SetReadDeadline(time.Now())
278+
279+
case bytes := <-downCh:
280+
ctx.BytesDownstream += bytes
281+
closedConns++
282+
proxyClient.SetReadDeadline(time.Now())
283+
}
284+
}
285+
}
286+
287+
func copyAndClose(ctx *ProxyCtx, w, r net.Conn) (bytes int64) {
258288
connOk := true
259-
if _, err := io.Copy(w, r); err != nil {
289+
var err error
290+
291+
if bytes, err = io.Copy(w, r); err != nil && bytes <= 0 {
260292
connOk = false
261293
ctx.Warnf("Error copying to client: %s", err)
262294
}
263295
if err := r.Close(); err != nil && connOk {
264296
ctx.Warnf("Error closing: %s", err)
265297
}
298+
return bytes
266299
}
267300

268301
func dialerFromEnv(proxy *ProxyHttpServer) func(network, addr string) (net.Conn, error) {

proxy.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ func (proxy *ProxyHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
110110
if resp == nil {
111111
removeProxyHeaders(ctx, r)
112112
resp, err = ctx.RoundTrip(r)
113+
ctx.BytesUpstream += r.ContentLength
113114
if err != nil {
114115
ctx.Error = err
115116
resp = proxy.filterResponse(nil, ctx)
@@ -120,6 +121,7 @@ func (proxy *ProxyHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
120121
}
121122
}
122123
ctx.Logf("Received response %v", resp.Status)
124+
123125
}
124126
origBody := resp.Body
125127
resp = proxy.filterResponse(resp, ctx)
@@ -140,6 +142,7 @@ func (proxy *ProxyHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
140142
if err := resp.Body.Close(); err != nil {
141143
ctx.Warnf("Can't close response body %v", err)
142144
}
145+
ctx.BytesDownstream += nr
143146
ctx.Logf("Copied %v bytes to client error=%v", nr, err)
144147
}
145148
}

0 commit comments

Comments
 (0)