Handle error when fd runs out
The default log level is now WARNING.
This commit is contained in:
parent
8f1c49e75c
commit
71a3a70c02
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue