shrpx: Added error handling when error_reply() failed
This commit is contained in:
parent
e817995063
commit
0f5a37fa2a
|
@ -145,8 +145,11 @@ int htp_hdrs_completecb(http_parser *htp)
|
||||||
|
|
||||||
if(downstream->get_expect_100_continue()) {
|
if(downstream->get_expect_100_continue()) {
|
||||||
static const char reply_100[] = "HTTP/1.1 100 Continue\r\n\r\n";
|
static const char reply_100[] = "HTTP/1.1 100 Continue\r\n\r\n";
|
||||||
bufferevent_write(upstream->get_client_handler()->get_bev(),
|
if(bufferevent_write(upstream->get_client_handler()->get_bev(),
|
||||||
reply_100, sizeof(reply_100)-1);
|
reply_100, sizeof(reply_100)-1) != 0) {
|
||||||
|
LOG(FATAL) << "bufferevent_write() faild";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rv = dconn->attach_downstream(downstream);
|
int rv = dconn->attach_downstream(downstream);
|
||||||
|
@ -154,7 +157,7 @@ int htp_hdrs_completecb(http_parser *htp)
|
||||||
downstream->set_request_state(Downstream::CONNECT_FAIL);
|
downstream->set_request_state(Downstream::CONNECT_FAIL);
|
||||||
downstream->set_downstream_connection(0);
|
downstream->set_downstream_connection(0);
|
||||||
delete dconn;
|
delete dconn;
|
||||||
return 1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
downstream->push_request_headers();
|
downstream->push_request_headers();
|
||||||
downstream->set_request_state(Downstream::HEADER_COMPLETE);
|
downstream->set_request_state(Downstream::HEADER_COMPLETE);
|
||||||
|
@ -229,7 +232,9 @@ int HttpsUpstream::on_read()
|
||||||
if(htperr == HPE_PAUSED) {
|
if(htperr == HPE_PAUSED) {
|
||||||
if(downstream->get_request_state() == Downstream::CONNECT_FAIL) {
|
if(downstream->get_request_state() == Downstream::CONNECT_FAIL) {
|
||||||
get_client_handler()->set_should_close_after_write(true);
|
get_client_handler()->set_should_close_after_write(true);
|
||||||
error_reply(503);
|
if(error_reply(503) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// Downstream gets deleted after response body is read.
|
// Downstream gets deleted after response body is read.
|
||||||
} else {
|
} else {
|
||||||
assert(downstream->get_request_state() == Downstream::MSG_COMPLETE);
|
assert(downstream->get_request_state() == Downstream::MSG_COMPLETE);
|
||||||
|
@ -250,7 +255,9 @@ int HttpsUpstream::on_read()
|
||||||
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);
|
||||||
error_reply(400);
|
if(error_reply(400) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else if(downstream->get_output_buffer_full()) {
|
} else if(downstream->get_output_buffer_full()) {
|
||||||
if(ENABLE_LOG) {
|
if(ENABLE_LOG) {
|
||||||
LOG(INFO) << "Downstream output buffer is full";
|
LOG(INFO) << "Downstream output buffer is full";
|
||||||
|
@ -265,7 +272,9 @@ int HttpsUpstream::on_read()
|
||||||
<< http_errno_description(htperr);
|
<< http_errno_description(htperr);
|
||||||
}
|
}
|
||||||
get_client_handler()->set_should_close_after_write(true);
|
get_client_handler()->set_should_close_after_write(true);
|
||||||
error_reply(400);
|
if(error_reply(400) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -359,7 +368,10 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
|
||||||
} else {
|
} else {
|
||||||
// We did not sent any HTTP response, so sent error
|
// We did not sent any HTTP response, so sent error
|
||||||
// response. Cannot reuse downstream connection in this case.
|
// response. Cannot reuse downstream connection in this case.
|
||||||
upstream->error_reply(502);
|
if(upstream->error_reply(502) != 0) {
|
||||||
|
delete upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(downstream->get_request_state() == Downstream::MSG_COMPLETE) {
|
if(downstream->get_request_state() == Downstream::MSG_COMPLETE) {
|
||||||
upstream->pop_downstream();
|
upstream->pop_downstream();
|
||||||
delete downstream;
|
delete downstream;
|
||||||
|
@ -423,7 +435,10 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
|
||||||
if(ENABLE_LOG) {
|
if(ENABLE_LOG) {
|
||||||
LOG(INFO) << "Treated as downstream error";
|
LOG(INFO) << "Treated as downstream error";
|
||||||
}
|
}
|
||||||
upstream->error_reply(502);
|
if(upstream->error_reply(502) != 0) {
|
||||||
|
delete upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(downstream->get_request_state() == Downstream::MSG_COMPLETE) {
|
if(downstream->get_request_state() == Downstream::MSG_COMPLETE) {
|
||||||
upstream->pop_downstream();
|
upstream->pop_downstream();
|
||||||
|
@ -441,7 +456,10 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
|
||||||
} else {
|
} else {
|
||||||
status = 502;
|
status = 502;
|
||||||
}
|
}
|
||||||
upstream->error_reply(status);
|
if(upstream->error_reply(status) != 0) {
|
||||||
|
delete upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(downstream->get_request_state() == Downstream::MSG_COMPLETE) {
|
if(downstream->get_request_state() == Downstream::MSG_COMPLETE) {
|
||||||
upstream->pop_downstream();
|
upstream->pop_downstream();
|
||||||
|
@ -452,7 +470,7 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void HttpsUpstream::error_reply(int status_code)
|
int HttpsUpstream::error_reply(int status_code)
|
||||||
{
|
{
|
||||||
std::string html = http::create_error_html(status_code);
|
std::string html = http::create_error_html(status_code);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
@ -466,12 +484,16 @@ void HttpsUpstream::error_reply(int status_code)
|
||||||
ss << "\r\n";
|
ss << "\r\n";
|
||||||
std::string header = ss.str();
|
std::string header = ss.str();
|
||||||
evbuffer *output = bufferevent_get_output(handler_->get_bev());
|
evbuffer *output = bufferevent_get_output(handler_->get_bev());
|
||||||
evbuffer_add(output, header.c_str(), header.size());
|
if(evbuffer_add(output, header.c_str(), header.size()) != 0 ||
|
||||||
evbuffer_add(output, html.c_str(), html.size());
|
evbuffer_add(output, html.c_str(), html.size()) != 0) {
|
||||||
|
LOG(FATAL) << "evbuffer_add() failed";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
Downstream *downstream = get_top_downstream();
|
Downstream *downstream = get_top_downstream();
|
||||||
if(downstream) {
|
if(downstream) {
|
||||||
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufferevent_data_cb HttpsUpstream::get_downstream_readcb()
|
bufferevent_data_cb HttpsUpstream::get_downstream_readcb()
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
void pop_downstream();
|
void pop_downstream();
|
||||||
Downstream* get_top_downstream();
|
Downstream* get_top_downstream();
|
||||||
Downstream* get_last_downstream();
|
Downstream* get_last_downstream();
|
||||||
void error_reply(int status_code);
|
int error_reply(int status_code);
|
||||||
|
|
||||||
void pause_read(IOCtrlReason reason);
|
void pause_read(IOCtrlReason reason);
|
||||||
void resume_read(IOCtrlReason reason);
|
void resume_read(IOCtrlReason reason);
|
||||||
|
|
|
@ -374,7 +374,10 @@ void spdy_downstream_readcb(bufferevent *bev, void *ptr)
|
||||||
if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
|
if(downstream->get_response_state() == Downstream::HEADER_COMPLETE) {
|
||||||
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
upstream->rst_stream(downstream, SPDYLAY_INTERNAL_ERROR);
|
||||||
} else {
|
} else {
|
||||||
upstream->error_reply(downstream, 502);
|
if(upstream->error_reply(downstream, 502) != 0) {
|
||||||
|
delete upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
||||||
// Clearly, we have to close downstream connection on http parser
|
// Clearly, we have to close downstream connection on http parser
|
||||||
|
@ -383,7 +386,10 @@ void spdy_downstream_readcb(bufferevent *bev, void *ptr)
|
||||||
delete dconn;
|
delete dconn;
|
||||||
dconn = 0;
|
dconn = 0;
|
||||||
}
|
}
|
||||||
upstream->send();
|
if(upstream->send() != 0) {
|
||||||
|
delete upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// At this point, downstream may be deleted.
|
// At this point, downstream may be deleted.
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -450,10 +456,16 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
|
||||||
} else {
|
} else {
|
||||||
// If stream was not closed, then we set MSG_COMPLETE and let
|
// If stream was not closed, then we set MSG_COMPLETE and let
|
||||||
// on_stream_close_callback delete downstream.
|
// on_stream_close_callback delete downstream.
|
||||||
upstream->error_reply(downstream, 502);
|
if(upstream->error_reply(downstream, 502) != 0) {
|
||||||
|
upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
||||||
}
|
}
|
||||||
upstream->send();
|
if(upstream->send() != 0) {
|
||||||
|
delete upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// At this point, downstream may be deleted.
|
// At this point, downstream may be deleted.
|
||||||
}
|
}
|
||||||
} else if(events & (BEV_EVENT_ERROR | BEV_EVENT_TIMEOUT)) {
|
} else if(events & (BEV_EVENT_ERROR | BEV_EVENT_TIMEOUT)) {
|
||||||
|
@ -490,11 +502,17 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
|
||||||
} else {
|
} else {
|
||||||
status = 502;
|
status = 502;
|
||||||
}
|
}
|
||||||
upstream->error_reply(downstream, status);
|
if(upstream->error_reply(downstream, status) != 0) {
|
||||||
|
delete upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
||||||
}
|
}
|
||||||
upstream->send();
|
if(upstream->send() != 0) {
|
||||||
|
delete upstream->get_client_handler();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// At this point, downstream may be deleted.
|
// At this point, downstream may be deleted.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,7 +586,7 @@ int SpdyUpstream::error_reply(Downstream *downstream, int status_code)
|
||||||
rv = evbuffer_add(body, html.c_str(), html.size());
|
rv = evbuffer_add(body, html.c_str(), html.size());
|
||||||
if(rv == -1) {
|
if(rv == -1) {
|
||||||
LOG(FATAL) << "evbuffer_add() failed";
|
LOG(FATAL) << "evbuffer_add() failed";
|
||||||
DIE();
|
return -1;
|
||||||
}
|
}
|
||||||
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
downstream->set_response_state(Downstream::MSG_COMPLETE);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue