diff --git a/integration-tests/nghttpx_http2_test.go b/integration-tests/nghttpx_http2_test.go index 11f2b0f3..ef261ed3 100644 --- a/integration-tests/nghttpx_http2_test.go +++ b/integration-tests/nghttpx_http2_test.go @@ -1548,6 +1548,26 @@ func TestH2H1HTTPSRedirectPort(t *testing.T) { } } +// TestH2H1Code204 tests that 204 response without content-length, and +// transfer-encoding is valid. +func TestH2H1Code204(t *testing.T) { + st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNoContent) + }) + defer st.Close() + + res, err := st.http2(requestParam{ + name: "TestH2H1Code204", + }) + if err != nil { + t.Fatalf("Error st.http2() = %v", err) + } + + if got, want := res.status, 204; got != want { + t.Errorf("status = %v; want %v", got, want) + } +} + // TestH2H1GracefulShutdown tests graceful shutdown. func TestH2H1GracefulShutdown(t *testing.T) { st := newServerTester(nil, t, noopHandler) @@ -2159,6 +2179,26 @@ func TestH2H2DNS(t *testing.T) { } } +// TestH2H2Code204 tests that 204 response without content-length, and +// transfer-encoding is valid. +func TestH2H2Code204(t *testing.T) { + st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNoContent) + }) + defer st.Close() + + res, err := st.http2(requestParam{ + name: "TestH2H2Code204", + }) + if err != nil { + t.Fatalf("Error st.http2() = %v", err) + } + + if got, want := res.status, 204; got != want { + t.Errorf("status = %v; want %v", got, want) + } +} + // TestH2APIBackendconfig exercise backendconfig API endpoint routine // for successful case. func TestH2APIBackendconfig(t *testing.T) { diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index aec721be..8c82b3df 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -892,13 +892,12 @@ int htp_hdrs_completecb(http_parser *htp) { if (resp.fs.parse_content_length() != 0) { return -1; } - if (resp.fs.content_length != 0) { - return -1; - } if (resp.fs.content_length == 0) { auto cl = resp.fs.header(http2::HD_CONTENT_LENGTH); assert(cl); http2::erase_header(cl); + } else if (resp.fs.content_length != -1) { + return -1; } } else if (resp.http_status / 100 == 1 || (resp.http_status == 200 && req.method == HTTP_CONNECT)) {