Repository: trafficserver Updated Branches: refs/heads/master a13a52734 -> 36087159a
[TS-3060] - Enhance POST failure (timeout) scenarios by sending a HTTP status response where possible Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/36087159 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/36087159 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/36087159 Branch: refs/heads/master Commit: 36087159ad494e71c665a3d78f4f2e07edbe9e52 Parents: a13a527 Author: Sudheer Vinukonda <[email protected]> Authored: Fri Oct 10 16:09:41 2014 +0000 Committer: Sudheer Vinukonda <[email protected]> Committed: Fri Oct 10 16:09:41 2014 +0000 ---------------------------------------------------------------------- mgmt/RecordsConfig.cc | 2 ++ proxy/http/HttpConfig.cc | 2 ++ proxy/http/HttpConfig.h | 2 ++ proxy/http/HttpSM.cc | 50 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/36087159/mgmt/RecordsConfig.cc ---------------------------------------------------------------------- diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc index f042037..b75bc29 100644 --- a/mgmt/RecordsConfig.cc +++ b/mgmt/RecordsConfig.cc @@ -428,6 +428,8 @@ RecordElement RecordsConfig[] = { , {RECT_CONFIG, "proxy.config.http.send_100_continue_response", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL} , + {RECT_CONFIG, "proxy.config.http.send_408_post_timeout_response", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL} + , {RECT_CONFIG, "proxy.config.http.share_server_sessions", RECD_INT, "2", RECU_RESTART_TS, RR_NULL, RECC_NULL, NULL, RECA_NULL} , {RECT_CONFIG, "proxy.config.http.server_session_sharing.match", RECD_STRING, "both", RECU_RESTART_TS, RR_NULL, RECC_NULL, NULL, RECA_NULL} http://git-wip-us.apache.org/repos/asf/trafficserver/blob/36087159/proxy/http/HttpConfig.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc index db66e83..7cc8df2 100644 --- a/proxy/http/HttpConfig.cc +++ b/proxy/http/HttpConfig.cc @@ -1402,6 +1402,7 @@ HttpConfig::startup() HttpEstablishStaticConfigByte(c.ignore_accept_charset_mismatch, "proxy.config.http.cache.ignore_accept_charset_mismatch"); HttpEstablishStaticConfigByte(c.send_100_continue_response, "proxy.config.http.send_100_continue_response"); + HttpEstablishStaticConfigByte(c.send_408_post_timeout_response, "proxy.config.http.send_408_post_timeout_response"); HttpEstablishStaticConfigByte(c.oride.cache_when_to_revalidate, "proxy.config.http.cache.when_to_revalidate"); HttpEstablishStaticConfigByte(c.oride.cache_required_headers, "proxy.config.http.cache.required_headers"); @@ -1658,6 +1659,7 @@ HttpConfig::reconfigure() params->ignore_accept_charset_mismatch = m_master.ignore_accept_charset_mismatch; params->send_100_continue_response = INT_TO_BOOL(m_master.send_100_continue_response); + params->send_408_post_timeout_response = INT_TO_BOOL(m_master.send_408_post_timeout_response); params->oride.cache_when_to_revalidate = m_master.oride.cache_when_to_revalidate; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/36087159/proxy/http/HttpConfig.h ---------------------------------------------------------------------- diff --git a/proxy/http/HttpConfig.h b/proxy/http/HttpConfig.h index 9d3a60d..81ed6cd 100644 --- a/proxy/http/HttpConfig.h +++ b/proxy/http/HttpConfig.h @@ -784,6 +784,7 @@ public: MgmtByte ignore_accept_charset_mismatch; MgmtByte send_100_continue_response; + MgmtByte send_408_post_timeout_response; OverridableHttpConfigParams oride; @@ -938,6 +939,7 @@ HttpConfigParams::HttpConfigParams() ignore_accept_encoding_mismatch(0), ignore_accept_charset_mismatch(0), send_100_continue_response(0), + send_408_post_timeout_response(0), autoconf_port(0), autoconf_localhost_only(0) { http://git-wip-us.apache.org/repos/asf/trafficserver/blob/36087159/proxy/http/HttpSM.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index cdde36b..8a519a0 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -96,6 +96,9 @@ static const int boundary_size = 2 + sizeof("RANGE_SEPARATOR") - 1 + 2; static const char *str_100_continue_response = "HTTP/1.1 100 Continue\r\n\r\n"; static const int len_100_continue_response = strlen(str_100_continue_response); +static const char *str_408_request_timeout_response = "HTTP/1.1 408 Request Timeout\r\n\r\n"; +static const int len_408_request_timeout_response = strlen(str_408_request_timeout_response); + /** * Takes two milestones and returns the difference. * @param start The start time @@ -2646,6 +2649,20 @@ HttpSM::tunnel_handler_post(int event, void *data) { STATE_ENTER(&HttpSM::tunnel_handler_post, event); + if (event != HTTP_TUNNEL_EVENT_DONE) { + if (t_state.http_config_param->send_408_request_timeout_response) { + Debug("http_tunnel", "cleanup tunnel in tunnel_handler_post"); + ink_assert((event == VC_EVENT_WRITE_COMPLETE) || (event == VC_EVENT_EOS)); + free_MIOBuffer(ua_entry->write_buffer); + tunnel.chain_abort_all(p); + p->read_vio = NULL; + p->vc->do_io_close(EHTTP_ERROR); + set_ua_abort(HttpTransact::ABORTED, event); + hsm_release_assert(ua_entry->in_tunnel == true); + return 0; + } + } + ink_assert(event == HTTP_TUNNEL_EVENT_DONE); ink_assert(data == &tunnel); // The tunnel calls this when it is done @@ -3327,6 +3344,8 @@ HttpSM::tunnel_handler_post_ua(int event, HttpTunnelProducer * p) { STATE_ENTER(&HttpSM::tunnel_handler_post_ua, event); client_request_body_bytes = p->init_bytes_done + p->bytes_read; + int64_t alloc_index, nbytes; + IOBufferReader* buf_start; switch (event) { case VC_EVENT_EOS: @@ -3338,6 +3357,37 @@ HttpSM::tunnel_handler_post_ua(int event, HttpTunnelProducer * p) // Did not complete post tunnling. Abort the // server and close the ua p->handler_state = HTTP_SM_POST_UA_FAIL; + + if (t_state.http_config_param->send_408_request_timeout_response && client_response_hdr_bytes == 0) { + switch (event) { + case VC_EVENT_ERROR: + HttpTransact::build_error_response(&t_state, HTTP_STATUS_INTERNAL_SERVER_ERROR, "POST Error", "default", NULL); + break; + case VC_EVENT_INACTIVITY_TIMEOUT: + HttpTransact::build_error_response(&t_state, HTTP_STATUS_REQUEST_TIMEOUT, "POST Request timeout", "timeout#inactivity", NULL); + break; + case VC_EVENT_ACTIVE_TIMEOUT: + HttpTransact::build_error_response(&t_state, HTTP_STATUS_REQUEST_TIMEOUT, "POST Request timeout", "timeout#activity", NULL); + break; + } + + // send back 408 request timeout + alloc_index = buffer_size_to_index (len_408_request_timeout_response + t_state.internal_msg_buffer_size); + ua_entry->write_buffer = new_MIOBuffer(alloc_index); + buf_start = ua_entry->write_buffer->alloc_reader(); + + DebugSM("http_tunnel", "send 408 response to client to vc %p, tunnel vc %p", ua_session->get_netvc(), p->vc); + + nbytes = ua_entry->write_buffer->write(str_408_request_timeout_response, len_408_request_timeout_response); + nbytes += ua_entry->write_buffer->write(t_state.internal_msg_buffer, t_state.internal_msg_buffer_size); + + p->vc->do_io_write(this, nbytes, buf_start); + + set_ua_half_close_flag(); + p->vc->do_io_shutdown(IO_SHUTDOWN_READ); + return 0; + } + tunnel.chain_abort_all(p); p->read_vio = NULL; p->vc->do_io_close(EHTTP_ERROR);
