Repository: trafficserver Updated Branches: refs/heads/master 5f7f7cd2d -> deb77cf15
TS-3188: Do not set half_close for keep alive POST. This closes #142. Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/deb77cf1 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/deb77cf1 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/deb77cf1 Branch: refs/heads/master Commit: deb77cf15fa1bbab8232d9d907680451fb84545f Parents: 5f7f7cd Author: shinrich <[email protected]> Authored: Tue Nov 11 10:46:14 2014 -0600 Committer: Alan M. Carroll <[email protected]> Committed: Wed Nov 19 11:35:58 2014 -0600 ---------------------------------------------------------------------- CHANGES | 2 ++ proxy/http/HttpClientSession.cc | 4 ++++ proxy/http/HttpSM.cc | 1 + proxy/http/HttpTunnel.cc | 24 ++++++++++++++++++------ proxy/http/HttpTunnel.h | 11 +++++++++++ 5 files changed, 36 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/deb77cf1/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 4ad9303..a56c126 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ -*- coding: utf-8 -*- Changes with Apache Traffic Server 5.2.0 + *) [TS-3188] Do not set half_close_flag on keep_alive connections. + *) [TS-2417] Add forward secrecy support with DHE. Author: John Eaglesham <[email protected]> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/deb77cf1/proxy/http/HttpClientSession.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpClientSession.cc b/proxy/http/HttpClientSession.cc index e9cb6de..68a9a93 100644 --- a/proxy/http/HttpClientSession.cc +++ b/proxy/http/HttpClientSession.cc @@ -124,6 +124,10 @@ HttpClientSession::new_transaction() ink_assert(current_reader == NULL); PluginIdentity* pi = dynamic_cast<PluginIdentity*>(client_vc); + // Defensive programming, make sure nothing persists across + // connection re-use + half_close = false; + read_state = HCS_ACTIVE_READER; current_reader = HttpSM::allocate(); current_reader->init(); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/deb77cf1/proxy/http/HttpSM.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 7cb11b0..413e3df 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -534,6 +534,7 @@ HttpSM::attach_client_session(HttpClientSession * client_vc, IOBufferReader * bu ink_assert(client_vc != NULL); ua_session = client_vc; + ink_release_assert(ua_session->get_half_close_flag() == false); mutex = client_vc->mutex; if (ua_session->debug()) debug_on = true; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/deb77cf1/proxy/http/HttpTunnel.cc ---------------------------------------------------------------------- diff --git a/proxy/http/HttpTunnel.cc b/proxy/http/HttpTunnel.cc index 492ea8e..1c8ffa7 100644 --- a/proxy/http/HttpTunnel.cc +++ b/proxy/http/HttpTunnel.cc @@ -897,13 +897,10 @@ HttpTunnel::producer_run(HttpTunnelProducer * p) // to the server on VC_EVENT_WRITE_COMPLETE. if (p->vc_type == HT_HTTP_CLIENT) { HttpClientSession* ua_vc = static_cast<HttpClientSession*>(p->vc); - if (ua_vc->get_half_close_flag() || producer_n == 0) { - // Force the half close to make sure we send the FIN immediately after we finish writing. - ua_vc->set_half_close_flag(); + if (ua_vc->get_half_close_flag()) { c_write = c->buffer_reader->read_avail(); - if (producer_n != 0) { - p->alive = false; - } + p->alive = false; + p->handler_state = HTTP_SM_POST_SUCCESS; } } c->write_vio = c->vc->do_io_write(this, c_write, c->buffer_reader); @@ -978,6 +975,7 @@ HttpTunnel::producer_run(HttpTunnelProducer * p) // done but we didn't do anything p->alive = false; p->read_success = true; + p->handler_state = HTTP_SM_POST_SUCCESS; Debug("http_tunnel", "[%" PRId64 "] [tunnel_run] producer already done", sm->sm_id); producer_handler(HTTP_TUNNEL_EVENT_PRECOMPLETE, p); } else { @@ -1161,6 +1159,7 @@ bool HttpTunnel::producer_handler(int event, HttpTunnelProducer * p) jump_point = p->vc_handler; (sm->*jump_point) (event, p); sm_callback = true; + p->update_state_if_not_set(HTTP_SM_POST_SUCCESS); break; case VC_EVENT_READ_COMPLETE: @@ -1188,6 +1187,7 @@ bool HttpTunnel::producer_handler(int event, HttpTunnelProducer * p) jump_point = p->vc_handler; (sm->*jump_point) (event, p); sm_callback = true; + p->update_state_if_not_set(HTTP_SM_POST_SUCCESS); // Data read from producer, reenable consumers for (c = p->consumer_list.head; c; c = c->link.next) { @@ -1207,6 +1207,8 @@ bool HttpTunnel::producer_handler(int event, HttpTunnelProducer * p) jump_point = p->vc_handler; (sm->*jump_point) (event, p); sm_callback = true; + // Failure case anyway + p->update_state_if_not_set(HTTP_SM_POST_UA_FAIL); break; case VC_EVENT_WRITE_READY: @@ -1315,6 +1317,16 @@ bool HttpTunnel::consumer_handler(int event, HttpTunnelConsumer * c) // Interesting tunnel event, call SM jump_point = c->vc_handler; (sm->*jump_point) (event, c); + // Make sure the handler_state is set + // Necessary for post tunnel end processing + if (c->producer && c->producer->handler_state == 0) { + if (event == VC_EVENT_WRITE_COMPLETE) + c->producer->handler_state = HTTP_SM_POST_SUCCESS; + else if (c->vc_type == HT_HTTP_SERVER) + c->producer->handler_state = HTTP_SM_POST_UA_FAIL; + else if (c->vc_type == HT_HTTP_CLIENT) + c->producer->handler_state = HTTP_SM_POST_SERVER_FAIL; + } sm_callback = true; // Deallocate the reader after calling back the sm http://git-wip-us.apache.org/repos/asf/trafficserver/blob/deb77cf1/proxy/http/HttpTunnel.h ---------------------------------------------------------------------- diff --git a/proxy/http/HttpTunnel.h b/proxy/http/HttpTunnel.h index 4b44642..6c1e21f 100644 --- a/proxy/http/HttpTunnel.h +++ b/proxy/http/HttpTunnel.h @@ -250,6 +250,9 @@ struct HttpTunnelProducer /// Check throttled state. bool is_throttled() const; + /// Update the handler_state member if it is still 0 + void update_state_if_not_set(int new_handler_state); + /** Set the flow control source producer for the flow. This sets the value for this producer and all downstream producers. @note This is the implementation for @c throttle and @c unthrottle. @@ -547,6 +550,14 @@ HttpTunnelProducer::is_source() const return HT_HTTP_SERVER == vc_type || HT_CACHE_READ == vc_type || HT_HTTP_CLIENT == vc_type; } +inline void +HttpTunnelProducer::update_state_if_not_set(int new_handler_state) +{ + if (this->handler_state == 0) { + this->handler_state = new_handler_state; + } +} + inline bool HttpTunnelProducer::is_throttled() const {
