http: fix http/1.0 connection close

This commit is contained in:
ginuerzh
2024-11-01 18:17:50 +08:00
parent f4d9a5f79b
commit edb9a992e2
2 changed files with 18 additions and 12 deletions
+1 -1
View File
@@ -122,7 +122,7 @@ func (h *fileHandler) handleFunc(w http.ResponseWriter, r *http.Request) {
log.WithFields(map[string]any{ log.WithFields(map[string]any{
"duration": time.Since(start), "duration": time.Since(start),
}).Infof("%s %s %d %d", r.Method, r.RequestURI, rw.statusCode, rw.contentLength) }).Infof("%s %s %s %d %d", r.Method, r.RequestURI, r.Proto, rw.statusCode, rw.contentLength)
}() }()
if auther := h.options.Auther; auther != nil { if auther := h.options.Auther; auther != nil {
+17 -11
View File
@@ -424,7 +424,7 @@ func (h *httpHandler) handleProxy(ctx context.Context, conn net.Conn, req *http.
ro.Time = time.Time{} ro.Time = time.Time{}
if err := h.proxyRoundTrip(ctx, conn, req, ro, &pStats, log); err != nil { if close, err := h.proxyRoundTrip(ctx, conn, req, ro, &pStats, log); err != nil || close {
return err return err
} }
@@ -445,13 +445,15 @@ func (h *httpHandler) handleProxy(ctx context.Context, conn net.Conn, req *http.
log.Trace(string(dump)) log.Trace(string(dump))
} }
if err := h.proxyRoundTrip(ctx, xio.NewReadWriter(br, conn), req, ro, &pStats, log); err != nil { if close, err := h.proxyRoundTrip(ctx, xio.NewReadWriter(br, conn), req, ro, &pStats, log); err != nil || close {
return err return err
} }
} }
} }
func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats *stats.Stats, log logger.Logger) (err error) { func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriter, req *http.Request, ro *xrecorder.HandlerRecorderObject, pStats *stats.Stats, log logger.Logger) (close bool, err error) {
close = true
ro2 := &xrecorder.HandlerRecorderObject{} ro2 := &xrecorder.HandlerRecorderObject{}
*ro2 = *ro *ro2 = *ro
ro = ro2 ro = ro2
@@ -509,7 +511,8 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriter, req
} }
// HTTP/1.0 // HTTP/1.0
if req.ProtoMajor == 1 && req.ProtoMinor == 0 { http10 := req.ProtoMajor == 1 && req.ProtoMinor == 0
if http10 {
if strings.ToLower(req.Header.Get("Connection")) == "keep-alive" { if strings.ToLower(req.Header.Get("Connection")) == "keep-alive" {
req.Header.Del("Connection") req.Header.Del("Connection")
} else { } else {
@@ -540,7 +543,8 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriter, req
} }
log.Debug("bypass: ", host) log.Debug("bypass: ", host)
res.Write(rw) res.Write(rw)
return xbypass.ErrBypass err = xbypass.ErrBypass
return
} }
var reqBody *xhttp.Body var reqBody *xhttp.Body
@@ -585,16 +589,17 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriter, req
} }
// HTTP/1.0 // HTTP/1.0
if req.ProtoMajor == 1 && req.ProtoMinor == 0 { if http10 {
if !resp.Close { if !resp.Close {
resp.Header.Set("Connection", "keep-alive") resp.Header.Set("Connection", "keep-alive")
} }
resp.ProtoMajor = req.ProtoMajor resp.ProtoMajor = 1
resp.ProtoMinor = req.ProtoMinor resp.ProtoMinor = 0
} }
if resp.StatusCode == http.StatusSwitchingProtocols { if resp.StatusCode == http.StatusSwitchingProtocols {
return h.handleUpgradeResponse(ctx, rw, req, resp, ro, log) err = h.handleUpgradeResponse(ctx, rw, req, resp, ro, log)
return
} }
var respBody *xhttp.Body var respBody *xhttp.Body
@@ -618,10 +623,11 @@ func (h *httpHandler) proxyRoundTrip(ctx context.Context, rw io.ReadWriter, req
} }
if err != nil { if err != nil {
return fmt.Errorf("write response: %v", err) err = fmt.Errorf("write response: %v", err)
return
} }
return return resp.Close, nil
} }
func (h *httpHandler) dial(ctx context.Context, network, addr string) (conn net.Conn, err error) { func (h *httpHandler) dial(ctx context.Context, network, addr string) (conn net.Conn, err error) {