Skip to content

Commit 039b87f

Browse files
committed
internal/http3: return error when Write is used after status 304 is set
In our HTTP/1 and HTTP/2 implementations, calling Write in a server handler after WriteHeader has been called with status 304 will return an http.ErrBodyNotAllowed error. This change adds the same behavior for the HTTP/3 server. For golang/go#70914 Change-Id: I6be926412d51217a8b88b2ad4ce79935dd3e7af7 Reviewed-on: https://go-review.googlesource.com/c/net/+/751140 Reviewed-by: Nicholas Husin <husin@google.com> Reviewed-by: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent 6267c6c commit 039b87f

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

internal/http3/server.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,10 @@ func (rw *responseWriter) Write(b []byte) (n int, err error) {
463463
rw.mu.Lock()
464464
defer rw.mu.Unlock()
465465

466+
if rw.statusCode == http.StatusNotModified {
467+
return 0, http.ErrBodyNotAllowed
468+
}
469+
466470
b, trimmed := rw.trimWriteLocked(b)
467471
if trimmed {
468472
defer func() {

internal/http3/server_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package http3
66

77
import (
8+
"errors"
89
"io"
910
"maps"
1011
"net/http"
@@ -912,6 +913,25 @@ func TestServer103EarlyHints(t *testing.T) {
912913
})
913914
}
914915

916+
func TestServer304NotModified(t *testing.T) {
917+
synctest.Test(t, func(t *testing.T) {
918+
ts := newTestServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
919+
w.WriteHeader(http.StatusNotModified)
920+
if _, err := w.Write([]byte("body should not be allowed")); !errors.Is(err, http.ErrBodyNotAllowed) {
921+
t.Errorf("got %v error when calling Write after WriteHeader(304), want %v error", err, http.ErrBodyNotAllowed)
922+
}
923+
}))
924+
tc := ts.connect()
925+
tc.greet()
926+
927+
reqStream := tc.newStream(streamTypeRequest)
928+
reqStream.writeHeaders(requestHeader(nil))
929+
synctest.Wait()
930+
reqStream.wantSomeHeaders(http.Header{":status": {"304"}})
931+
reqStream.wantClosed("request is complete")
932+
})
933+
}
934+
915935
type testServer struct {
916936
t testing.TB
917937
s *Server

0 commit comments

Comments
 (0)