mirror of
https://github.com/golang/net.git
synced 2026-03-31 10:27:08 +09:00
internal/http3: add Server support for handling HEAD requests
When handling HEAD requests, Server will now always send an HTTP response with an empty body, even if the HTTP handler would normally write to the body. For golang/go#70914 Change-Id: Id656a8f9901b97357a343e204761f6a47f87f9fe Reviewed-on: https://go-review.googlesource.com/c/net/+/740160 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Nicholas Husin <husin@google.com>
This commit is contained in:
committed by
Nicholas Husin
parent
57ea86db08
commit
1973e8da2d
@@ -207,11 +207,21 @@ func (sc *serverConn) handleRequestStream(st *stream) error {
|
||||
}
|
||||
defer req.Body.Close()
|
||||
|
||||
responseWriter := sc.newResponseWriter(st)
|
||||
defer responseWriter.close()
|
||||
rw := &responseWriter{
|
||||
st: st,
|
||||
headers: make(http.Header),
|
||||
isHeadResp: req.Method == "HEAD",
|
||||
bw: &bodyWriter{
|
||||
st: st,
|
||||
remain: -1,
|
||||
flush: false,
|
||||
name: "response",
|
||||
},
|
||||
}
|
||||
defer rw.close()
|
||||
|
||||
// TODO: handle panic coming from the HTTP handler.
|
||||
sc.handler.ServeHTTP(responseWriter, req)
|
||||
sc.handler.ServeHTTP(rw, req)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -234,20 +244,7 @@ type responseWriter struct {
|
||||
headers http.Header
|
||||
// TODO: support 1xx status
|
||||
wroteHeader bool // Non-1xx header has been (logically) written.
|
||||
}
|
||||
|
||||
func (sc *serverConn) newResponseWriter(st *stream) *responseWriter {
|
||||
rw := &responseWriter{
|
||||
st: st,
|
||||
headers: make(http.Header),
|
||||
bw: &bodyWriter{
|
||||
st: st,
|
||||
remain: -1,
|
||||
flush: false,
|
||||
name: "response",
|
||||
},
|
||||
}
|
||||
return rw
|
||||
isHeadResp bool // response is for a HEAD request.
|
||||
}
|
||||
|
||||
func (rw *responseWriter) Header() http.Header {
|
||||
@@ -295,6 +292,9 @@ func (rw *responseWriter) Write(b []byte) (int, error) {
|
||||
if !rw.wroteHeader {
|
||||
rw.writeHeaderLocked(http.StatusOK)
|
||||
}
|
||||
if rw.isHeadResp {
|
||||
return 0, nil
|
||||
}
|
||||
return rw.bw.Write(b)
|
||||
}
|
||||
|
||||
|
||||
@@ -150,6 +150,30 @@ func TestServerBody(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestServerHeadResponseNoBody(t *testing.T) {
|
||||
bodyContent := []byte("response body that will not be sent for HEAD requests")
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
ts := newTestServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write(bodyContent)
|
||||
}))
|
||||
tc := ts.connect()
|
||||
tc.greet()
|
||||
|
||||
reqStream := tc.newStream(streamTypeRequest)
|
||||
reqStream.writeHeaders(http.Header{":method": {http.MethodGet}})
|
||||
synctest.Wait()
|
||||
reqStream.wantHeaders(http.Header{":status": {"200"}})
|
||||
reqStream.wantData(bodyContent)
|
||||
reqStream.wantClosed("request is complete")
|
||||
|
||||
reqStream = tc.newStream(streamTypeRequest)
|
||||
reqStream.writeHeaders(http.Header{":method": {http.MethodHead}})
|
||||
synctest.Wait()
|
||||
reqStream.wantHeaders(http.Header{":status": {"200"}})
|
||||
reqStream.wantClosed("request is complete")
|
||||
})
|
||||
}
|
||||
|
||||
type testServer struct {
|
||||
t testing.TB
|
||||
s *Server
|
||||
|
||||
Reference in New Issue
Block a user