nghttpx: Set Connection: close after graceful shutdown in HTTP/1 upstream

This commit is contained in:
Tatsuhiro Tsujikawa 2015-01-22 23:46:35 +09:00
parent b685747643
commit 4a0dba08b9
3 changed files with 49 additions and 3 deletions

View File

@ -96,6 +96,44 @@ func TestH1H1ConnectFailure(t *testing.T) {
} }
} }
func TestH1H1GracefulShutdown(t *testing.T) {
st := newServerTester(nil, t, noopHandler)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1H1GracefulShutdown-1",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status: %v; want %v", got, want)
}
st.cmd.Process.Signal(syscall.SIGQUIT)
res, err = st.http1(requestParam{
name: "TestH1H1GracefulShutdown-2",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status: %v; want %v", got, want)
}
if got, want := res.connClose, true; got != want {
t.Errorf("res.connClose: %v; want %v", got, want)
}
want := io.EOF
if _, err := st.conn.Read(nil); err == nil || err != want {
t.Errorf("st.conn.Read(): %v; want %v", err, want)
}
}
func TestH1H2ConnectFailure(t *testing.T) { func TestH1H2ConnectFailure(t *testing.T) {
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler) st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
defer st.Close() defer st.Close()

View File

@ -275,9 +275,10 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
resp.Body.Close() resp.Body.Close()
res := &serverResponse{ res := &serverResponse{
status: resp.StatusCode, status: resp.StatusCode,
header: resp.Header, header: resp.Header,
body: respBody, body: respBody,
connClose: resp.Close,
} }
return res, nil return res, nil
@ -534,6 +535,7 @@ type serverResponse struct {
connErr bool // true if HTTP/2 connection error connErr bool // true if HTTP/2 connection error
spdyGoAwayErrCode spdy.GoAwayStatus // status code received in SPDY RST_STREAM spdyGoAwayErrCode spdy.GoAwayStatus // status code received in SPDY RST_STREAM
spdyRstErrCode spdy.RstStreamStatus // status code received in SPDY GOAWAY spdyRstErrCode spdy.RstStreamStatus // status code received in SPDY GOAWAY
connClose bool // Conection: close is included in response header in HTTP/1 test
} }
func cloneHeader(h http.Header) http.Header { func cloneHeader(h http.Header) http.Header {

View File

@ -664,6 +664,12 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
return 0; return 0;
} }
// after graceful shutdown commenced, add connection: close header
// field.
if (worker_config->graceful_shutdown) {
downstream->set_response_connection_close(true);
}
// We check downstream->get_response_connection_close() in case when // We check downstream->get_response_connection_close() in case when
// the Content-Length is not available. // the Content-Length is not available.
if (!downstream->get_request_connection_close() && if (!downstream->get_request_connection_close() &&