This is an automated email from the ASF dual-hosted git repository. sorber pushed a commit to branch 6.2.x in repository https://git-dual.apache.org/repos/asf/trafficserver.git
commit 9b7189fbc0cf1f9bbd29f5510fd308a69016159e Author: Susan Hinrichs <[email protected]> AuthorDate: Tue Sep 27 16:24:11 2016 +0000 TS-4813: Fix lingering stream. (cherry picked from commit dc8be341578aa0fa900c84265d0a336414dfad9b) Conflicts: iocore/net/SSLNetVConnection.cc proxy/http2/Http2ConnectionState.cc --- iocore/net/SSLNetVConnection.cc | 13 ++++++++----- proxy/http/HttpTunnel.cc | 20 ++++++++++---------- proxy/http2/Http2ConnectionState.cc | 29 ++++++++++++++++++++--------- proxy/http2/Http2Stream.cc | 2 +- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc index 44ae638..450c577 100644 --- a/iocore/net/SSLNetVConnection.cc +++ b/iocore/net/SSLNetVConnection.cc @@ -364,13 +364,16 @@ SSLNetVConnection::read_raw_data() b = b->next; } - if (niov == 1) { - r = socketManager.read(this->con.fd, tiovec[0].iov_base, tiovec[0].iov_len); - } else { + // If there was no room to write into the buffer then skip the read + if (niov > 0) { r = socketManager.readv(this->con.fd, &tiovec[0], niov); + + NET_INCREMENT_DYN_STAT(net_calls_to_read_stat); + total_read += rattempted; + } else { // No more space to write, break out + r = 0; + break; } - NET_INCREMENT_DYN_STAT(net_calls_to_read_stat); - total_read += rattempted; } while (rattempted && r == rattempted && total_read < toread); // if we have already moved some bytes successfully, summarize in r diff --git a/proxy/http/HttpTunnel.cc b/proxy/http/HttpTunnel.cc index 32694c4..a58b251 100644 --- a/proxy/http/HttpTunnel.cc +++ b/proxy/http/HttpTunnel.cc @@ -1198,8 +1198,6 @@ HttpTunnel::producer_handler(int event, HttpTunnelProducer *p) Debug("http_redirect", "[HttpTunnel::producer_handler] enable_redirection: [%d %d %d] event: %d", p->alive == true, sm->enable_redirection, (p->self_consumer && p->self_consumer->alive == true), event); - ink_assert(p->alive == true || event == HTTP_TUNNEL_EVENT_PRECOMPLETE || event == VC_EVENT_EOS || sm->enable_redirection || - (p->self_consumer && p->self_consumer->alive == true)); switch (event) { case VC_EVENT_READ_READY: @@ -1255,14 +1253,16 @@ HttpTunnel::producer_handler(int event, HttpTunnelProducer *p) case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: case HTTP_TUNNEL_EVENT_CONSUMER_DETACH: - p->alive = false; - p->bytes_read = p->read_vio->ndone; - // Interesting tunnel event, call SM - 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); + if (p->alive) { + p->alive = false; + p->bytes_read = p->read_vio->ndone; + // Interesting tunnel event, call SM + 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: diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc index 8dcec8c..d1279c6 100644 --- a/proxy/http2/Http2ConnectionState.cc +++ b/proxy/http2/Http2ConnectionState.cc @@ -793,6 +793,7 @@ Http2ConnectionState::main_event_handler(int event, void *edata) // Finalize HTTP/2 Connection case HTTP2_SESSION_EVENT_FINI: { + ink_assert(this->fini_received == false); this->fini_received = true; cleanup_streams(); SET_HANDLER(&Http2ConnectionState::state_closed); @@ -937,8 +938,8 @@ Http2ConnectionState::cleanup_streams() this->delete_stream(s); s = next; } + ink_assert(stream_list.head == NULL); - client_streams_count = 0; if (!is_state_closed()) { ua_session->get_netvc()->add_to_keep_alive_queue(); } @@ -947,6 +948,13 @@ Http2ConnectionState::cleanup_streams() void Http2ConnectionState::delete_stream(Http2Stream *stream) { + // If stream has already been removed from the list, just go on + if (!stream_list.in(stream)) { + return; + } + + DebugHttp2Stream(ua_session, stream->get_id(), "Delete stream"); + if (Http2::stream_priority_enabled) { DependencyTree::Node *node = stream->priority_node; if (node != NULL && node->active) { @@ -956,25 +964,24 @@ Http2ConnectionState::delete_stream(Http2Stream *stream) stream_list.remove(stream); stream->initiating_close(); - - ink_assert(client_streams_count > 0); - --client_streams_count; - - if (client_streams_count == 0 && ua_session) { - ua_session->get_netvc()->add_to_keep_alive_queue(); - } } void Http2ConnectionState::release_stream(Http2Stream *stream) { + // Update stream counts if (stream) { --total_client_streams_count; + stream_list.remove(stream); } // If the number of clients is 0, then mark the connection as inactive if (total_client_streams_count == 0 && ua_session) { ua_session->clear_session_active(); + if (ua_session->get_netvc()) { + ua_session->get_netvc()->add_to_keep_alive_queue(); + ua_session->get_netvc()->cancel_active_timeout(); + } } if (ua_session && fini_received && total_client_streams_count == 0) { @@ -1125,7 +1132,11 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len void Http2ConnectionState::send_data_frames(Http2Stream *stream) { - if (stream->get_state() == HTTP2_STREAM_STATE_CLOSED) { + // To follow RFC 7540 must not send more frames other than priority on + // a closed stream. So we return without sending + if (stream->get_state() == HTTP2_STREAM_STATE_HALF_CLOSED_LOCAL || stream->get_state() == HTTP2_STREAM_STATE_CLOSED) { + DebugSsn(this->ua_session, "http2_cs", "Shutdown half closed local stream %d", stream->get_id()); + this->delete_stream(stream); return; } diff --git a/proxy/http2/Http2Stream.cc b/proxy/http2/Http2Stream.cc index b505941..cb42673 100644 --- a/proxy/http2/Http2Stream.cc +++ b/proxy/http2/Http2Stream.cc @@ -285,7 +285,7 @@ Http2Stream::do_io_close(int /* flags */) static_cast<Http2ClientSession *>(parent)->connection_state.send_data_frames(this); } // Check to see if the stream is in the closed state - ink_assert(get_state() == HTTP2_STREAM_STATE_CLOSED); + ink_assert(get_state() == HTTP2_STREAM_STATE_CLOSED || get_state() == HTTP2_STREAM_STATE_HALF_CLOSED_REMOTE); clear_timers(); clear_io_events(); -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
