You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2020/04/06 18:31:10 UTC
[trafficserver] 08/25: Set END_STREAM flag when write_vio ntodo is 0
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 <ma...@apache.org>
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