From 71a3a70c026a49e5a62798cfe8b30b442f18a446 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 6 Jun 2012 02:23:07 +0900 Subject: [PATCH] Handle error when fd runs out The default log level is now WARNING. --- examples/shrpx.cc | 12 +++++++++++- examples/shrpx_downstream.cc | 8 ++++++-- examples/shrpx_downstream.h | 3 ++- examples/shrpx_downstream_queue.cc | 4 ++-- examples/shrpx_downstream_queue.h | 2 +- examples/shrpx_error.h | 3 ++- examples/shrpx_https_upstream.cc | 14 ++++++++++++-- examples/shrpx_log.cc | 17 +++++++++++++---- examples/shrpx_log.h | 4 +++- examples/shrpx_spdy_upstream.cc | 19 ++++++++++++++----- examples/shrpx_spdy_upstream.h | 2 +- 11 files changed, 67 insertions(+), 21 deletions(-) diff --git a/examples/shrpx.cc b/examples/shrpx.cc index f01a39fd..552d41af 100644 --- a/examples/shrpx.cc +++ b/examples/shrpx.cc @@ -83,6 +83,13 @@ int cache_downstream_host_address() } } // namespace +namespace { +void evlistener_errorcb(evconnlistener *listener, void *ptr) +{ + sleep(1); +} +} // namespace + namespace { evconnlistener* create_evlistener(ListenHandler *handler) { @@ -133,8 +140,9 @@ evconnlistener* create_evlistener(ListenHandler *handler) ssl_acceptcb, handler, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, - 256, + 1024, fd); + evconnlistener_set_error_cb(evlistener, evlistener_errorcb); return evlistener; } } // namespace @@ -172,6 +180,8 @@ int main(int argc, char **argv) SSL_load_error_strings(); SSL_library_init(); + Log::set_severity_level(WARNING); + create_config(); mod_config()->server_name = "shrpx spdylay/"SPDYLAY_VERSION; mod_config()->port = 3000; diff --git a/examples/shrpx_downstream.cc b/examples/shrpx_downstream.cc index 63e9872f..16e5fbd1 100644 --- a/examples/shrpx_downstream.cc +++ b/examples/shrpx_downstream.cc @@ -155,12 +155,16 @@ int Downstream::start_connection() bufferevent_set_timeouts(bev_, &get_config()->downstream_read_timeout, &get_config()->downstream_write_timeout); - bufferevent_socket_connect + int rv = bufferevent_socket_connect (bev_, // TODO maybe not thread-safe? const_cast(&get_config()->downstream_addr.sa), get_config()->downstream_addrlen); - return 0; + if(rv == 0) { + return 0; + } else { + return SHRPX_ERR_NETWORK; + } } void Downstream::set_request_state(int state) diff --git a/examples/shrpx_downstream.h b/examples/shrpx_downstream.h index 3bf67d9f..e7df104c 100644 --- a/examples/shrpx_downstream.h +++ b/examples/shrpx_downstream.h @@ -72,7 +72,8 @@ public: INITIAL, HEADER_COMPLETE, MSG_COMPLETE, - STREAM_CLOSED + STREAM_CLOSED, + CONNECT_FAIL }; void set_request_state(int state); int get_request_state() const; diff --git a/examples/shrpx_downstream_queue.cc b/examples/shrpx_downstream_queue.cc index 8c61d835..6d943eb8 100644 --- a/examples/shrpx_downstream_queue.cc +++ b/examples/shrpx_downstream_queue.cc @@ -44,9 +44,9 @@ void DownstreamQueue::add(Downstream *downstream) downstreams_[downstream->get_stream_id()] = downstream; } -void DownstreamQueue::start(Downstream *downstream) +int DownstreamQueue::start(Downstream *downstream) { - downstream->start_connection(); + return downstream->start_connection(); } void DownstreamQueue::remove(Downstream *downstream) diff --git a/examples/shrpx_downstream_queue.h b/examples/shrpx_downstream_queue.h index d8c76c85..b4e100aa 100644 --- a/examples/shrpx_downstream_queue.h +++ b/examples/shrpx_downstream_queue.h @@ -40,7 +40,7 @@ public: DownstreamQueue(); ~DownstreamQueue(); void add(Downstream *downstream); - void start(Downstream *downstream); + int start(Downstream *downstream); void remove(Downstream *downstream); Downstream* find(int32_t stream_id); private: diff --git a/examples/shrpx_error.h b/examples/shrpx_error.h index 40a68502..581b1d69 100644 --- a/examples/shrpx_error.h +++ b/examples/shrpx_error.h @@ -32,7 +32,8 @@ namespace shrpx { enum ErrorCode { SHRPX_ERR_SUCCESS = 0, SHRPX_ERR_UNKNOWN = -1, - SHRPX_ERR_HTTP_PARSE = -2 + SHRPX_ERR_HTTP_PARSE = -2, + SHRPX_ERR_NETWORK = -3 }; } // namespace shrpx diff --git a/examples/shrpx_https_upstream.cc b/examples/shrpx_https_upstream.cc index 276b81a6..8bf3623b 100644 --- a/examples/shrpx_https_upstream.cc +++ b/examples/shrpx_https_upstream.cc @@ -157,7 +157,12 @@ int htp_hdrs_completecb(htparser *htp) downstream->push_request_headers(); downstream->set_request_state(Downstream::HEADER_COMPLETE); - downstream->start_connection(); + int rv = downstream->start_connection(); + if(rv != 0) { + LOG(ERROR) << "Upstream connection failed"; + downstream->set_request_state(Downstream::CONNECT_FAIL); + return 1; + } return 0; } } // namespace @@ -227,7 +232,12 @@ int HttpsUpstream::on_read() current_header_length_ += nread; htpparse_error htperr = htparser_get_error(htp_); if(htperr == htparse_error_user) { - if(current_header_length_ > SHRPX_HTTPS_MAX_HEADER_LENGTH) { + Downstream *downstream = get_top_downstream(); + if(downstream && + downstream->get_request_state() == Downstream::CONNECT_FAIL) { + get_client_handler()->set_should_close_after_write(true); + error_reply(503); + } else if(current_header_length_ > SHRPX_HTTPS_MAX_HEADER_LENGTH) { LOG(WARNING) << "Request Header too long:" << current_header_length_ << " bytes"; get_client_handler()->set_should_close_after_write(true); diff --git a/examples/shrpx_log.cc b/examples/shrpx_log.cc index 5f7469eb..5869f6ca 100644 --- a/examples/shrpx_log.cc +++ b/examples/shrpx_log.cc @@ -32,6 +32,13 @@ const char *SEVERITY_STR[] = { "INFO", "WARN", "ERROR", "FATAL" }; +int Log::severity_thres_ = WARNING; + +void Log::set_severity_level(int severity) +{ + severity_thres_ = severity; +} + Log::Log(int severity, const char *filename, int linenum) : severity_(severity), filename_(filename), @@ -40,10 +47,12 @@ Log::Log(int severity, const char *filename, int linenum) Log::~Log() { - fprintf(stderr, "[%s] %s\n (%s, line %d)\n", - SEVERITY_STR[severity_], stream_.str().c_str(), - filename_, linenum_); - fflush(stderr); + if(severity_ >= severity_thres_) { + fprintf(stderr, "[%s] %s\n (%s, line %d)\n", + SEVERITY_STR[severity_], stream_.str().c_str(), + filename_, linenum_); + fflush(stderr); + } } } // namespace shrpx diff --git a/examples/shrpx_log.h b/examples/shrpx_log.h index 9a1515ab..bbda7ef0 100644 --- a/examples/shrpx_log.h +++ b/examples/shrpx_log.h @@ -41,18 +41,20 @@ enum SeverityLevel { class Log { public: - Log(int severiy, const char *filename, int linenum); + Log(int severity, const char *filename, int linenum); ~Log(); template Log& operator<<(Type s) { stream_ << s; return *this; } + static void set_severity_level(int severity); private: int severity_; const char *filename_; int linenum_; std::stringstream stream_; + static int severity_thres_; }; } // namespace shrpx diff --git a/examples/shrpx_spdy_upstream.cc b/examples/shrpx_spdy_upstream.cc index 8cc39d9a..a78356dd 100644 --- a/examples/shrpx_spdy_upstream.cc +++ b/examples/shrpx_spdy_upstream.cc @@ -95,10 +95,15 @@ void on_stream_close_callback SpdyUpstream *upstream = reinterpret_cast(user_data); Downstream *downstream = upstream->get_downstream_queue()->find(stream_id); if(downstream) { - downstream->set_request_state(Downstream::STREAM_CLOSED); - if(downstream->get_response_state() == Downstream::MSG_COMPLETE) { + if(downstream->get_request_state() == Downstream::CONNECT_FAIL) { upstream->get_downstream_queue()->remove(downstream); delete downstream; + } else { + downstream->set_request_state(Downstream::STREAM_CLOSED); + if(downstream->get_response_state() == Downstream::MSG_COMPLETE) { + upstream->get_downstream_queue()->remove(downstream); + delete downstream; + } } } } @@ -152,7 +157,11 @@ void on_ctrl_recv_callback downstream->set_request_state(Downstream::MSG_COMPLETE); } upstream->add_downstream(downstream); - upstream->start_downstream(downstream); + if(upstream->start_downstream(downstream) != 0) { + // If downstream connection fails, issue RST_STREAM. + upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR); + downstream->set_request_state(Downstream::CONNECT_FAIL); + } break; } default: @@ -455,9 +464,9 @@ void SpdyUpstream::add_downstream(Downstream *downstream) downstream_queue_.add(downstream); } -void SpdyUpstream::start_downstream(Downstream *downstream) +int SpdyUpstream::start_downstream(Downstream *downstream) { - downstream_queue_.start(downstream); + return downstream_queue_.start(downstream); } void SpdyUpstream::remove_downstream(Downstream *downstream) diff --git a/examples/shrpx_spdy_upstream.h b/examples/shrpx_spdy_upstream.h index fc878988..6a0c2bf2 100644 --- a/examples/shrpx_spdy_upstream.h +++ b/examples/shrpx_spdy_upstream.h @@ -50,7 +50,7 @@ public: virtual bufferevent_event_cb get_downstream_eventcb(); void add_downstream(Downstream *downstream); void remove_downstream(Downstream *downstream); - void start_downstream(Downstream *downstream); + int start_downstream(Downstream *downstream); spdylay_session* get_spdy_session(); DownstreamQueue* get_downstream_queue();