From b9f41e34ef064ef81ad077707bccf9922306dfa0 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 20 Jan 2015 23:26:09 +0900 Subject: [PATCH] nghttpx: Return error when downstream HTTP/1 connection attempt failed --- integration-tests/nghttpx_test.go | 38 +++++++++++++++++++++++++ src/shrpx_http_downstream_connection.cc | 7 ++++- src/shrpx_https_upstream.cc | 2 ++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/integration-tests/nghttpx_test.go b/integration-tests/nghttpx_test.go index 3b8c9206..f3d90ce6 100644 --- a/integration-tests/nghttpx_test.go +++ b/integration-tests/nghttpx_test.go @@ -69,6 +69,25 @@ func TestH1H1MultipleRequestCL(t *testing.T) { } } +func TestH1H1ConnectFailure(t *testing.T) { + st := newServerTester(nil, t, noopHandler) + defer st.Close() + + // shutdown backend server to simulate backend connect failure + st.ts.Close() + + res, err := st.http1(requestParam{ + name: "TestH1H1ConnectFailure", + }) + if err != nil { + t.Fatalf("Error st.http2() = %v", err) + } + want := 502 + if got := res.status; got != want { + t.Errorf("status: %v; want %v", got, want) + } +} + func TestH2H1PlainGET(t *testing.T) { st := newServerTester(nil, t, noopHandler) defer st.Close() @@ -305,6 +324,25 @@ func TestH2H1InvalidRequestCL(t *testing.T) { } } +func TestH2H1ConnectFailure(t *testing.T) { + st := newServerTester(nil, t, noopHandler) + defer st.Close() + + // shutdown backend server to simulate backend connect failure + st.ts.Close() + + res, err := st.http2(requestParam{ + name: "TestH2H1ConnectFailure", + }) + if err != nil { + t.Fatalf("Error st.http2() = %v", err) + } + want := 502 + if got := res.status; got != want { + t.Errorf("status: %v; want %v", got, want) + } +} + func TestH2H2MultipleResponseCL(t *testing.T) { st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) { w.Header().Add("content-length", "1") diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index dbdb8fad..92d098a6 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -95,7 +95,9 @@ void connectcb(struct ev_loop *loop, ev_io *w, int revents) { auto upstream = downstream->get_upstream(); auto handler = upstream->get_client_handler(); if (dconn->on_connect() != 0) { - delete handler; + if (upstream->downstream_error(dconn, Downstream::EVENT_ERROR) != 0) { + delete handler; + } return; } writecb(loop, w, revents); @@ -747,6 +749,9 @@ end: int HttpDownstreamConnection::on_connect() { if (!util::check_socket_connected(fd_)) { + if (LOG_ENABLED(INFO)) { + DLOG(INFO, this) << "downstream connect failed"; + } return -1; } diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index a04e83c8..15a7f075 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -560,6 +560,8 @@ int HttpsUpstream::downstream_error(DownstreamConnection *dconn, int events) { return -1; } + handler_->set_should_close_after_write(true); + unsigned int status; if (events & Downstream::EVENT_TIMEOUT) { status = 504;