Handle error when fd runs out

The default log level is now WARNING.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-06-06 02:23:07 +09:00
parent 8f1c49e75c
commit 71a3a70c02
11 changed files with 67 additions and 21 deletions

View File

@ -83,6 +83,13 @@ int cache_downstream_host_address()
} }
} // namespace } // namespace
namespace {
void evlistener_errorcb(evconnlistener *listener, void *ptr)
{
sleep(1);
}
} // namespace
namespace { namespace {
evconnlistener* create_evlistener(ListenHandler *handler) evconnlistener* create_evlistener(ListenHandler *handler)
{ {
@ -133,8 +140,9 @@ evconnlistener* create_evlistener(ListenHandler *handler)
ssl_acceptcb, ssl_acceptcb,
handler, handler,
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
256, 1024,
fd); fd);
evconnlistener_set_error_cb(evlistener, evlistener_errorcb);
return evlistener; return evlistener;
} }
} // namespace } // namespace
@ -172,6 +180,8 @@ int main(int argc, char **argv)
SSL_load_error_strings(); SSL_load_error_strings();
SSL_library_init(); SSL_library_init();
Log::set_severity_level(WARNING);
create_config(); create_config();
mod_config()->server_name = "shrpx spdylay/"SPDYLAY_VERSION; mod_config()->server_name = "shrpx spdylay/"SPDYLAY_VERSION;
mod_config()->port = 3000; mod_config()->port = 3000;

View File

@ -155,12 +155,16 @@ int Downstream::start_connection()
bufferevent_set_timeouts(bev_, bufferevent_set_timeouts(bev_,
&get_config()->downstream_read_timeout, &get_config()->downstream_read_timeout,
&get_config()->downstream_write_timeout); &get_config()->downstream_write_timeout);
bufferevent_socket_connect int rv = bufferevent_socket_connect
(bev_, (bev_,
// TODO maybe not thread-safe? // TODO maybe not thread-safe?
const_cast<sockaddr*>(&get_config()->downstream_addr.sa), const_cast<sockaddr*>(&get_config()->downstream_addr.sa),
get_config()->downstream_addrlen); get_config()->downstream_addrlen);
if(rv == 0) {
return 0; return 0;
} else {
return SHRPX_ERR_NETWORK;
}
} }
void Downstream::set_request_state(int state) void Downstream::set_request_state(int state)

View File

@ -72,7 +72,8 @@ public:
INITIAL, INITIAL,
HEADER_COMPLETE, HEADER_COMPLETE,
MSG_COMPLETE, MSG_COMPLETE,
STREAM_CLOSED STREAM_CLOSED,
CONNECT_FAIL
}; };
void set_request_state(int state); void set_request_state(int state);
int get_request_state() const; int get_request_state() const;

View File

@ -44,9 +44,9 @@ void DownstreamQueue::add(Downstream *downstream)
downstreams_[downstream->get_stream_id()] = 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) void DownstreamQueue::remove(Downstream *downstream)

View File

@ -40,7 +40,7 @@ public:
DownstreamQueue(); DownstreamQueue();
~DownstreamQueue(); ~DownstreamQueue();
void add(Downstream *downstream); void add(Downstream *downstream);
void start(Downstream *downstream); int start(Downstream *downstream);
void remove(Downstream *downstream); void remove(Downstream *downstream);
Downstream* find(int32_t stream_id); Downstream* find(int32_t stream_id);
private: private:

View File

@ -32,7 +32,8 @@ namespace shrpx {
enum ErrorCode { enum ErrorCode {
SHRPX_ERR_SUCCESS = 0, SHRPX_ERR_SUCCESS = 0,
SHRPX_ERR_UNKNOWN = -1, SHRPX_ERR_UNKNOWN = -1,
SHRPX_ERR_HTTP_PARSE = -2 SHRPX_ERR_HTTP_PARSE = -2,
SHRPX_ERR_NETWORK = -3
}; };
} // namespace shrpx } // namespace shrpx

View File

@ -157,7 +157,12 @@ int htp_hdrs_completecb(htparser *htp)
downstream->push_request_headers(); downstream->push_request_headers();
downstream->set_request_state(Downstream::HEADER_COMPLETE); 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; return 0;
} }
} // namespace } // namespace
@ -227,7 +232,12 @@ int HttpsUpstream::on_read()
current_header_length_ += nread; current_header_length_ += nread;
htpparse_error htperr = htparser_get_error(htp_); htpparse_error htperr = htparser_get_error(htp_);
if(htperr == htparse_error_user) { 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_ LOG(WARNING) << "Request Header too long:" << current_header_length_
<< " bytes"; << " bytes";
get_client_handler()->set_should_close_after_write(true); get_client_handler()->set_should_close_after_write(true);

View File

@ -32,6 +32,13 @@ const char *SEVERITY_STR[] = {
"INFO", "WARN", "ERROR", "FATAL" "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) Log::Log(int severity, const char *filename, int linenum)
: severity_(severity), : severity_(severity),
filename_(filename), filename_(filename),
@ -40,10 +47,12 @@ Log::Log(int severity, const char *filename, int linenum)
Log::~Log() Log::~Log()
{ {
if(severity_ >= severity_thres_) {
fprintf(stderr, "[%s] %s\n (%s, line %d)\n", fprintf(stderr, "[%s] %s\n (%s, line %d)\n",
SEVERITY_STR[severity_], stream_.str().c_str(), SEVERITY_STR[severity_], stream_.str().c_str(),
filename_, linenum_); filename_, linenum_);
fflush(stderr); fflush(stderr);
} }
}
} // namespace shrpx } // namespace shrpx

View File

@ -41,18 +41,20 @@ enum SeverityLevel {
class Log { class Log {
public: public:
Log(int severiy, const char *filename, int linenum); Log(int severity, const char *filename, int linenum);
~Log(); ~Log();
template<typename Type> Log& operator<<(Type s) template<typename Type> Log& operator<<(Type s)
{ {
stream_ << s; stream_ << s;
return *this; return *this;
} }
static void set_severity_level(int severity);
private: private:
int severity_; int severity_;
const char *filename_; const char *filename_;
int linenum_; int linenum_;
std::stringstream stream_; std::stringstream stream_;
static int severity_thres_;
}; };
} // namespace shrpx } // namespace shrpx

View File

@ -95,6 +95,10 @@ void on_stream_close_callback
SpdyUpstream *upstream = reinterpret_cast<SpdyUpstream*>(user_data); SpdyUpstream *upstream = reinterpret_cast<SpdyUpstream*>(user_data);
Downstream *downstream = upstream->get_downstream_queue()->find(stream_id); Downstream *downstream = upstream->get_downstream_queue()->find(stream_id);
if(downstream) { if(downstream) {
if(downstream->get_request_state() == Downstream::CONNECT_FAIL) {
upstream->get_downstream_queue()->remove(downstream);
delete downstream;
} else {
downstream->set_request_state(Downstream::STREAM_CLOSED); downstream->set_request_state(Downstream::STREAM_CLOSED);
if(downstream->get_response_state() == Downstream::MSG_COMPLETE) { if(downstream->get_response_state() == Downstream::MSG_COMPLETE) {
upstream->get_downstream_queue()->remove(downstream); upstream->get_downstream_queue()->remove(downstream);
@ -102,6 +106,7 @@ void on_stream_close_callback
} }
} }
} }
}
} // namespace } // namespace
namespace { namespace {
@ -152,7 +157,11 @@ void on_ctrl_recv_callback
downstream->set_request_state(Downstream::MSG_COMPLETE); downstream->set_request_state(Downstream::MSG_COMPLETE);
} }
upstream->add_downstream(downstream); 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; break;
} }
default: default:
@ -455,9 +464,9 @@ void SpdyUpstream::add_downstream(Downstream *downstream)
downstream_queue_.add(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) void SpdyUpstream::remove_downstream(Downstream *downstream)

View File

@ -50,7 +50,7 @@ public:
virtual bufferevent_event_cb get_downstream_eventcb(); virtual bufferevent_event_cb get_downstream_eventcb();
void add_downstream(Downstream *downstream); void add_downstream(Downstream *downstream);
void remove_downstream(Downstream *downstream); void remove_downstream(Downstream *downstream);
void start_downstream(Downstream *downstream); int start_downstream(Downstream *downstream);
spdylay_session* get_spdy_session(); spdylay_session* get_spdy_session();
DownstreamQueue* get_downstream_queue(); DownstreamQueue* get_downstream_queue();