Skip to content

Commit 29ed7e2

Browse files
authored
Merge pull request #123 from SenseUnit/optimism
handler: postpone conn acknowledgement if client uses fast start
2 parents 2ada7f0 + 67146b7 commit 29ed7e2

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

handler/handler.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,6 @@ func (s *ProxyHandler) HandleTunnel(wr http.ResponseWriter, req *http.Request, u
103103
}
104104
defer localconn.Close()
105105

106-
// Inform client connection is built
107-
fmt.Fprintf(localconn, "HTTP/%d.%d 200 OK\r\n\r\n", req.ProtoMajor, req.ProtoMinor)
108-
109106
if buffered := rw.Reader.Buffered(); buffered > 0 {
110107
s.logger.Debug("saving %d bytes buffered in bufio.ReadWriter", buffered)
111108
s.forward(
@@ -114,11 +111,20 @@ func (s *ProxyHandler) HandleTunnel(wr http.ResponseWriter, req *http.Request, u
114111
wrapH1ReqBody(io.NopCloser(io.LimitReader(rw.Reader, int64(buffered)))),
115112
wrapH1RespWriter(conn),
116113
)
114+
s.forward(
115+
req.Context(),
116+
username,
117+
wrapPendingWrite(
118+
[]byte(fmt.Sprintf("HTTP/%d.%d 200 OK\r\n\r\n", req.ProtoMajor, req.ProtoMinor)),
119+
localconn,
120+
),
121+
conn,
122+
)
117123
} else {
118124
s.logger.Debug("not rescuing remaining data in bufio.ReadWriter")
125+
fmt.Fprintf(localconn, "HTTP/%d.%d 200 OK\r\n\r\n", req.ProtoMajor, req.ProtoMinor)
126+
s.forward(req.Context(), username, localconn, conn)
119127
}
120-
121-
s.forward(req.Context(), username, localconn, conn)
122128
} else if req.ProtoMajor == 2 {
123129
wr.Header()["Date"] = nil
124130
wr.WriteHeader(http.StatusOK)

handler/proxy.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,28 @@ func flush(flusher interface{}) bool {
6262
f.Flush()
6363
return true
6464
}
65+
66+
func wrapPendingWrite(data []byte, c net.Conn) *pendingWriteConn {
67+
return &pendingWriteConn{
68+
data: data,
69+
Conn: c,
70+
}
71+
}
72+
73+
type pendingWriteConn struct {
74+
net.Conn
75+
data []byte
76+
done bool
77+
}
78+
79+
func (p *pendingWriteConn) Write(b []byte) (n int, err error) {
80+
if !p.done {
81+
buf := append(append(make([]byte, 0, len(p.data)+len(b)), p.data...), b...)
82+
n, err := p.Conn.Write(buf)
83+
n = max(0, n - len(p.data))
84+
p.done = true
85+
p.data = nil
86+
return n, err
87+
}
88+
return p.Conn.Write(b)
89+
}

0 commit comments

Comments
 (0)