This is an automated email from the ASF dual-hosted git repository. zwoop pushed a commit to branch 8.1.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 273aea8d9be782d25103cbda63ba86e753825991 Author: Masaori Koshiba <[email protected]> AuthorDate: Tue Nov 19 10:10:16 2019 +0900 Set END_STREAM flag when write_vio ntodo is 0 (cherry picked from commit 52538c4fe966b5a67f6701a919f7e07fade164a2) Conflicts: proxy/http2/Http2ConnectionState.cc --- proxy/http2/Http2ConnectionState.cc | 12 +++++++----- proxy/http2/Http2Stream.h | 4 ++-- tests/gold_tests/h2/gold/http2_9_stderr.gold | 10 ++++++++++ tests/gold_tests/h2/gold/http2_9_stdout.gold | 0 tests/gold_tests/h2/http2.test.py | 13 +++++++++++++ 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc index 7588b75..3e4056b 100644 --- a/proxy/http2/Http2ConnectionState.cc +++ b/proxy/http2/Http2ConnectionState.cc @@ -1415,7 +1415,7 @@ Http2ConnectionState::send_data_frames_depends_on_priority() switch (result) { case Http2SendDataFrameResult::NO_ERROR: { // No response body to send - if (len == 0 && !stream->is_body_done()) { + if (len == 0 && !stream->is_write_vio_done()) { dependency_tree->deactivate(node, len); } else { dependency_tree->update(node, len); @@ -1476,12 +1476,12 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len // Are we at the end? // If we return here, we never send the END_STREAM in the case of a early terminating OS. // OK if there is no body yet. Otherwise continue on to send a DATA frame and delete the stream - if (!stream->is_body_done() && payload_length == 0) { + if (!stream->is_write_vio_done() && payload_length == 0) { Http2StreamDebug(this->ua_session, stream->get_id(), "No payload"); return Http2SendDataFrameResult::NO_PAYLOAD; } - if (stream->is_body_done() && !current_reader->is_read_avail_more_than(0)) { + if (stream->is_write_vio_done() && !current_reader->is_read_avail_more_than(0)) { flags |= HTTP2_FLAGS_DATA_END_STREAM; } @@ -1505,7 +1505,7 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len this->ua_session->handleEvent(HTTP2_SESSION_EVENT_XMIT, &data); if (flags & HTTP2_FLAGS_DATA_END_STREAM) { - Http2StreamDebug(ua_session, stream->get_id(), "End of DATA frame"); + Http2StreamDebug(ua_session, stream->get_id(), "END_STREAM"); stream->send_end_stream = true; // Setting to the same state shouldn't be erroneous stream->change_state(data.header().type, data.header().flags); @@ -1583,7 +1583,9 @@ Http2ConnectionState::send_headers_frame(Http2Stream *stream) if (header_blocks_size <= static_cast<uint32_t>(BUFFER_SIZE_FOR_INDEX(buffer_size_index[HTTP2_FRAME_TYPE_HEADERS]))) { payload_length = header_blocks_size; flags |= HTTP2_FLAGS_HEADERS_END_HEADERS; - if (h2_hdr.presence(MIME_PRESENCE_CONTENT_LENGTH) && h2_hdr.get_content_length() == 0) { + if ((h2_hdr.presence(MIME_PRESENCE_CONTENT_LENGTH) && h2_hdr.get_content_length() == 0) || + (!resp_header->expect_final_response() && stream->is_write_vio_done())) { + Http2StreamDebug(ua_session, stream->get_id(), "END_STREAM"); flags |= HTTP2_FLAGS_HEADERS_END_STREAM; stream->send_end_stream = true; } diff --git a/proxy/http2/Http2Stream.h b/proxy/http2/Http2Stream.h index e93ae14..4630190 100644 --- a/proxy/http2/Http2Stream.h +++ b/proxy/http2/Http2Stream.h @@ -111,7 +111,7 @@ public: void increment_data_length(uint64_t length); bool payload_length_is_valid() const; - bool is_body_done() const; + bool is_write_vio_done() const; void update_sent_count(unsigned num_bytes); Http2StreamId get_id() const; Http2StreamState get_state() const; @@ -227,7 +227,7 @@ Http2Stream::mark_milestone(Http2StreamMilestone type) } inline bool -Http2Stream::is_body_done() const +Http2Stream::is_write_vio_done() const { return this->write_vio.ntodo() == 0; } diff --git a/tests/gold_tests/h2/gold/http2_9_stderr.gold b/tests/gold_tests/h2/gold/http2_9_stderr.gold new file mode 100644 index 0000000..ea2f129 --- /dev/null +++ b/tests/gold_tests/h2/gold/http2_9_stderr.gold @@ -0,0 +1,10 @@ +`` +> GET /status/204 HTTP/2 +> Host: `` +> User-Agent: curl/`` +> Accept: */* +`` +< HTTP/2 204`` +< server: ATS/`` +< date: `` +`` diff --git a/tests/gold_tests/h2/gold/http2_9_stdout.gold b/tests/gold_tests/h2/gold/http2_9_stdout.gold new file mode 100644 index 0000000..e69de29 diff --git a/tests/gold_tests/h2/http2.test.py b/tests/gold_tests/h2/http2.test.py index 4a4fc29..fd139a3 100644 --- a/tests/gold_tests/h2/http2.test.py +++ b/tests/gold_tests/h2/http2.test.py @@ -70,6 +70,11 @@ server.addResponse("sessionlog.json", {"headers": "GET /huge_resp_hdrs HTTP/1.1\r\nHost: www.example.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""}, {"headers": "HTTP/1.1 200 OK\r\nServer: microserver\r\nConnection: close\r\nContent-Length: 6\r\n\r\n", "timestamp": "1469733493.993", "body": "200 OK"}) +# For Test Case 9 - /status/204 +server.addResponse("sessionlog.json", + {"headers": "GET /status/204 HTTP/1.1\r\nHost: www.example.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""}, + {"headers": "HTTP/1.1 204 No Content\r\nServer: microserver\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""}) + # ---- # Setup ATS # ---- @@ -181,3 +186,11 @@ tr.Processes.Default.ReturnCode = 0 tr.Processes.Default.Streams.stdout = "gold/http2_8_stdout.gold" tr.Processes.Default.Streams.stderr = "gold/http2_8_stderr.gold" tr.StillRunningAfter = server + +# Test Case 9: Header Only Response - e.g. 204 +tr = Test.AddTestRun() +tr.Processes.Default.Command = 'curl -vs -k --http2 https://127.0.0.1:{0}/status/204'.format(ts.Variables.ssl_port) +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.Streams.stdout = "gold/http2_9_stdout.gold" +tr.Processes.Default.Streams.stderr = "gold/http2_9_stderr.gold" +tr.StillRunningAfter = server
