This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 9.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/9.1.x by this push:
     new 6730b86  Adjust so transfer-encoding header can be treated hop-by-hop 
(#7473)
6730b86 is described below

commit 6730b866e91270c355e601d2d8a03a81104cada4
Author: Susan Hinrichs <[email protected]>
AuthorDate: Thu Feb 4 16:57:57 2021 -0600

    Adjust so transfer-encoding header can be treated hop-by-hop (#7473)
    
    (cherry picked from commit 926dd71b32ade8615fbba6737816240d6df0c9ad)
---
 proxy/hdrs/HdrToken.cc                             |  3 +-
 proxy/http/HttpSM.cc                               | 17 ++++++--
 proxy/http/HttpTransact.cc                         | 50 ++++++++++++++--------
 proxy/http/HttpTransact.h                          |  2 +
 .../chunked_encoding/chunked_encoding.test.py      |  1 -
 tests/gold_tests/h2/http2.test.py                  |  4 +-
 6 files changed, 51 insertions(+), 26 deletions(-)

diff --git a/proxy/hdrs/HdrToken.cc b/proxy/hdrs/HdrToken.cc
index 5ea3b4f..5fe2280 100644
--- a/proxy/hdrs/HdrToken.cc
+++ b/proxy/hdrs/HdrToken.cc
@@ -228,7 +228,8 @@ static HdrTokenFieldInfo 
_hdrtoken_strs_field_initializers[] = {
   {"Subject", MIME_SLOTID_NONE, MIME_PRESENCE_SUBJECT, HTIF_NONE},
   {"Summary", MIME_SLOTID_NONE, MIME_PRESENCE_SUMMARY, HTIF_NONE},
   {"TE", MIME_SLOTID_TE, MIME_PRESENCE_TE, (HTIF_COMMAS | HTIF_MULTVALS | 
HTIF_HOPBYHOP)},
-  {"Transfer-Encoding", MIME_SLOTID_TRANSFER_ENCODING, 
MIME_PRESENCE_TRANSFER_ENCODING, (HTIF_COMMAS | HTIF_MULTVALS)},
+  {"Transfer-Encoding", MIME_SLOTID_TRANSFER_ENCODING, 
MIME_PRESENCE_TRANSFER_ENCODING,
+   (HTIF_COMMAS | HTIF_MULTVALS | HTIF_HOPBYHOP)},
   {"Upgrade", MIME_SLOTID_NONE, MIME_PRESENCE_UPGRADE, (HTIF_COMMAS | 
HTIF_MULTVALS | HTIF_HOPBYHOP)},
   {"User-Agent", MIME_SLOTID_USER_AGENT, MIME_PRESENCE_USER_AGENT, HTIF_NONE},
   {"Vary", MIME_SLOTID_VARY, MIME_PRESENCE_VARY, (HTIF_COMMAS | 
HTIF_MULTVALS)},
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 650107e..2648131 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -2073,8 +2073,7 @@ HttpSM::state_send_server_request_header(int event, void 
*data)
     free_MIOBuffer(server_entry->write_buffer);
     server_entry->write_buffer = nullptr;
     method                     = 
t_state.hdr_info.server_request.method_get_wksidx();
-    if (!t_state.api_server_request_body_set && method != HTTP_WKSIDX_TRACE &&
-        (t_state.hdr_info.request_content_length > 0 || 
t_state.client_info.transfer_encoding == HttpTransact::CHUNKED_ENCODING)) {
+    if (!t_state.api_server_request_body_set && method != HTTP_WKSIDX_TRACE && 
HttpTransact::has_request_body(&t_state, ua_txn)) {
       if (post_transform_info.vc) {
         setup_transform_to_server_transfer();
       } else {
@@ -5792,7 +5791,8 @@ close_connection:
 void
 HttpSM::do_setup_post_tunnel(HttpVC_t to_vc_type)
 {
-  bool chunked       = (t_state.client_info.transfer_encoding == 
HttpTransact::CHUNKED_ENCODING);
+  bool chunked = t_state.client_info.transfer_encoding == 
HttpTransact::CHUNKED_ENCODING ||
+                 t_state.hdr_info.request_content_length == HTTP_UNDEFINED_CL;
   bool post_redirect = false;
 
   HttpTunnelProducer *p = nullptr;
@@ -6129,6 +6129,17 @@ HttpSM::attach_server_session(PoolableSession *s)
   server_session->set_inactivity_timeout(get_server_connect_timeout());
   server_session->set_active_timeout(get_server_active_timeout());
 
+  // Do we need Transfer_Encoding?
+  if (HttpTransact::has_request_body(&t_state, ua_txn)) {
+    // See if we need to insert a chunked header
+    if 
(!t_state.hdr_info.server_request.presence(MIME_PRESENCE_CONTENT_LENGTH)) {
+      // Stuff in a TE setting so we treat this as chunked, sort of.
+      t_state.server_info.transfer_encoding = HttpTransact::CHUNKED_ENCODING;
+      
t_state.hdr_info.server_request.value_append(MIME_FIELD_TRANSFER_ENCODING, 
MIME_LEN_TRANSFER_ENCODING, HTTP_VALUE_CHUNKED,
+                                                   HTTP_LEN_CHUNKED, true);
+    }
+  }
+
   if (plugin_tunnel_type != HTTP_NO_PLUGIN_TUNNEL || will_be_private_ss) {
     SMDebug("http_ss", "Setting server session to private");
     server_session->set_private();
diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
index b89d7f4..279c532 100644
--- a/proxy/http/HttpTransact.cc
+++ b/proxy/http/HttpTransact.cc
@@ -1501,8 +1501,7 @@ HttpTransact::HandleRequest(State *s)
         }
       }
     }
-    if (s->txn_conf->request_buffer_enabled &&
-        (s->hdr_info.request_content_length > 0 || 
s->client_info.transfer_encoding == CHUNKED_ENCODING)) {
+    if (s->txn_conf->request_buffer_enabled && has_request_body(s, 
s->state_machine->ua_txn)) {
       TRANSACT_RETURN(SM_ACTION_WAIT_FOR_FULL_BODY, nullptr);
     }
   }
@@ -5351,8 +5350,11 @@ HttpTransact::check_request_validity(State *s, HTTPHdr 
*incoming_hdr)
   // than in initialize_state_variables_from_request //
   /////////////////////////////////////////////////////
   if (method != HTTP_WKSIDX_TRACE) {
-    int64_t length                     = incoming_hdr->get_content_length();
-    s->hdr_info.request_content_length = (length >= 0) ? length : 
HTTP_UNDEFINED_CL; // content length less than zero is invalid
+    if (incoming_hdr->presence(MIME_PRESENCE_CONTENT_LENGTH)) {
+      s->hdr_info.request_content_length = incoming_hdr->get_content_length();
+    } else {
+      s->hdr_info.request_content_length = HTTP_UNDEFINED_CL; // content 
length less than zero is invalid
+    }
 
     TxnDebug("http_trans", "[init_stat_vars_from_req] set req cont length to 
%" PRId64, s->hdr_info.request_content_length);
 
@@ -5382,22 +5384,23 @@ HttpTransact::check_request_validity(State *s, HTTPHdr 
*incoming_hdr)
     if ((scheme == URL_WKSIDX_HTTP || scheme == URL_WKSIDX_HTTPS) &&
         (method == HTTP_WKSIDX_POST || method == HTTP_WKSIDX_PUSH || method == 
HTTP_WKSIDX_PUT) &&
         s->client_info.transfer_encoding != CHUNKED_ENCODING) {
-      if (!incoming_hdr->presence(MIME_PRESENCE_CONTENT_LENGTH)) {
-        // In normal operation there will always be a ua_txn at this point, 
but in one of the -R1  regression tests a request is
-        // created
-        // independent of a transaction and this method is called, so we must 
null check
-        if (s->txn_conf->post_check_content_length_enabled &&
-            (!s->state_machine->ua_txn || 
s->state_machine->ua_txn->is_chunked_encoding_supported())) {
-          return NO_POST_CONTENT_LENGTH;
-        } else {
-          // Stuff in a TE setting so we treat this as chunked, sort of.
-          s->client_info.transfer_encoding = HttpTransact::CHUNKED_ENCODING;
-          incoming_hdr->value_append(MIME_FIELD_TRANSFER_ENCODING, 
MIME_LEN_TRANSFER_ENCODING, HTTP_VALUE_CHUNKED, HTTP_LEN_CHUNKED,
-                                     true);
+      // In normal operation there will always be a ua_txn at this point, but 
in one of the -R1  regression tests a request is
+      // createdindependent of a transaction and this method is called, so we 
must null check
+      if (!s->state_machine->ua_txn || 
s->state_machine->ua_txn->is_chunked_encoding_supported()) {
+        // See if we need to insert a chunked header
+        if (!incoming_hdr->presence(MIME_PRESENCE_CONTENT_LENGTH)) {
+          if (s->txn_conf->post_check_content_length_enabled) {
+            return NO_POST_CONTENT_LENGTH;
+          } else {
+            // Stuff in a TE setting so we treat this as chunked, sort of.
+            s->client_info.transfer_encoding = HttpTransact::CHUNKED_ENCODING;
+            incoming_hdr->value_append(MIME_FIELD_TRANSFER_ENCODING, 
MIME_LEN_TRANSFER_ENCODING, HTTP_VALUE_CHUNKED,
+                                       HTTP_LEN_CHUNKED, true);
+          }
+        }
+        if (HTTP_UNDEFINED_CL == s->hdr_info.request_content_length) {
+          return INVALID_POST_CONTENT_LENGTH;
         }
-      }
-      if (HTTP_UNDEFINED_CL == s->hdr_info.request_content_length) {
-        return INVALID_POST_CONTENT_LENGTH;
       }
     }
   }
@@ -8846,6 +8849,15 @@ 
HttpTransact::change_response_header_because_of_range_request(State *s, HTTPHdr
   }
 }
 
+bool
+HttpTransact::has_request_body(State *s, ProxyTransaction *txn)
+{
+  int method = s->hdr_info.client_request.method_get_wksidx();
+  return (method == HTTP_WKSIDX_POST || method == HTTP_WKSIDX_PUSH || method 
== HTTP_WKSIDX_PUT) &&
+         (s->hdr_info.request_content_length > 0 || 
s->client_info.transfer_encoding == CHUNKED_ENCODING ||
+          !txn->is_chunked_encoding_supported());
+}
+
 #if TS_HAS_TESTS
 void forceLinkRegressionHttpTransact();
 void
diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h
index 686d8b4..8cc53ba 100644
--- a/proxy/http/HttpTransact.h
+++ b/proxy/http/HttpTransact.h
@@ -1018,6 +1018,8 @@ public:
   static bool is_cache_hit(CacheLookupResult_t r);
   static bool is_fresh_cache_hit(CacheLookupResult_t r);
 
+  static bool has_request_body(State *s, ProxyTransaction *txn);
+
   static void build_request(State *s, HTTPHdr *base_request, HTTPHdr 
*outgoing_request, HTTPVersion outgoing_version);
   static void build_response(State *s, HTTPHdr *base_response, HTTPHdr 
*outgoing_response, HTTPVersion outgoing_version,
                              HTTPStatus status_code, const char *reason_phrase 
= nullptr);
diff --git a/tests/gold_tests/chunked_encoding/chunked_encoding.test.py 
b/tests/gold_tests/chunked_encoding/chunked_encoding.test.py
index 1905406..fc4b189 100644
--- a/tests/gold_tests/chunked_encoding/chunked_encoding.test.py
+++ b/tests/gold_tests/chunked_encoding/chunked_encoding.test.py
@@ -141,7 +141,6 @@ tr.StillRunningAfter = server
 
 server4_out = Test.Disk.File("outserver4")
 server4_out.Content = Testers.ExcludesExpression("sneaky", "Extra body bytes 
should not be delivered")
-server4_out.Content += Testers.ContainsExpression("Transfer-Encoding: 
chunked", "Request should be chunked encoded")
 
 # HTTP/1.1 Try to smuggle another request to the origin
 tr = Test.AddTestRun()
diff --git a/tests/gold_tests/h2/http2.test.py 
b/tests/gold_tests/h2/http2.test.py
index cd38bfe..9834730 100644
--- a/tests/gold_tests/h2/http2.test.py
+++ b/tests/gold_tests/h2/http2.test.py
@@ -61,7 +61,7 @@ server.addResponse("sessionlog.json",
 
 # For Test Case 6 - /postchunked
 post_body = 
"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
-server.addResponse("sessionlog.jason",
+server.addResponse("sessionlog.json",
                    {"headers": "POST /postchunked HTTP/1.1\r\nHost: 
www.example.com\r\n\r\n",
                     "timestamp": "1469733493.993",
                     "body": post_body},
@@ -72,7 +72,7 @@ server.addResponse("sessionlog.jason",
 # For Test Case 7 - /bigpostchunked
 # Make a post body that will be split across at least two frames
 big_post_body = "0123456789" * 131070
-server.addResponse("sessionlog.jason",
+server.addResponse("sessionlog.json",
                    {"headers": "POST /bigpostchunked HTTP/1.1\r\nHost: 
www.example.com\r\n\r\n",
                     "timestamp": "1469733493.993",
                     "body": big_post_body},

Reply via email to