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);

Reply via email to