You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2016/11/10 03:46:55 UTC

[trafficserver] 01/02: TS-5040: Forward CONNECT without parent proxying.

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

jpeach pushed a commit to branch master
in repository https://git-dual.apache.org/repos/asf/trafficserver.git

commit cf58a91ccd3048f3f0a540463ad8609ae2ce1209
Author: James Peach <jp...@apache.org>
AuthorDate: Sun Nov 6 15:07:13 2016 -0800

    TS-5040: Forward CONNECT without parent proxying.
    
    Unless parent proxy is enabled, CONNECT methods always result in
    setting up a direct tunnel to the origin server. Parent proxy,
    however, has the option of forwarding the CONNECT to the next hop
    and allowing it to set up the tunnel.  This change adds the
    proxy.config.http.forward_connect_method configuration parameter
    that can be enabled to forward CONNECT methods even if we are not
    parent proxying.
---
 lib/ts/apidefs.h.in                              |  1 +
 mgmt/RecordsConfig.cc                            |  3 ++
 plugins/experimental/ts_lua/ts_lua_http_config.c |  4 +-
 proxy/InkAPI.cc                                  |  9 +++++
 proxy/InkAPITest.cc                              |  1 +
 proxy/http/HttpConfig.cc                         |  6 ++-
 proxy/http/HttpConfig.h                          |  3 ++
 proxy/http/HttpTransact.cc                       | 47 ++++++++++++------------
 8 files changed, 48 insertions(+), 26 deletions(-)

diff --git a/lib/ts/apidefs.h.in b/lib/ts/apidefs.h.in
index 1686415..ba62506 100644
--- a/lib/ts/apidefs.h.in
+++ b/lib/ts/apidefs.h.in
@@ -741,6 +741,7 @@ typedef enum {
   TS_CONFIG_HTTP_PARENT_PROXY_TOTAL_CONNECT_ATTEMPTS,
   TS_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_IN,
   TS_CONFIG_SRV_ENABLED,
+  TS_CONFIG_HTTP_FORWARD_CONNECT_METHOD,
   TS_CONFIG_LAST_ENTRY
 } TSOverridableConfigKey;
 
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index 7962d36..5a4f3ee 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -1402,6 +1402,9 @@ static const RecordElement RecordsConfig[] =
   {RECT_LOCAL, "proxy.local.http.parent_proxy.disable_connect_tunneling", RECD_INT, "0", RECU_NULL, RR_NULL, RECC_NULL, nullptr, RECA_NULL}
   ,
 
+  {RECT_CONFIG, "proxy.config.http.forward_connect_method", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-1]", RECA_NULL}
+  ,
+
   //############
   //#
   //# HTTP/2 global configuration.
diff --git a/plugins/experimental/ts_lua/ts_lua_http_config.c b/plugins/experimental/ts_lua/ts_lua_http_config.c
index 4b65b71..5de9081 100644
--- a/plugins/experimental/ts_lua/ts_lua_http_config.c
+++ b/plugins/experimental/ts_lua/ts_lua_http_config.c
@@ -120,6 +120,7 @@ typedef enum {
   TS_LUA_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_IN            = TS_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_IN,
   TS_LUA_CONFIG_LAST_ENTRY                                    = TS_CONFIG_LAST_ENTRY,
   TS_LUA_CONFIG_SRV_ENABLED                                   = TS_CONFIG_SRV_ENABLED,
+  TS_LUA_CONFIG_HTTP_FORWARD_CONNECT_METHOD                   = TS_CONFIG_HTTP_FORWARD_CONNECT_METHOD,
 } TSLuaOverridableConfigKey;
 
 typedef enum {
@@ -229,7 +230,8 @@ ts_lua_var_item ts_lua_http_config_vars[] = {
   TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_UNCACHEABLE_REQUESTS_BYPASS_PARENT),
   TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_PARENT_PROXY_TOTAL_CONNECT_ATTEMPTS),
   TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_IN),
-  TS_LUA_MAKE_VAR_ITEM(TS_CONFIG_SRV_ENABLED),
+  TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_SRV_ENABLED),
+  TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_FORWARD_CONNECT_METHOD),
   TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_LAST_ENTRY),
 };
 
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index b558add..6081bfa 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -8130,6 +8130,10 @@ _conf_to_memberp(TSOverridableConfigKey conf, OverridableHttpConfigParams *overr
     typ = OVERRIDABLE_TYPE_INT;
     ret = &overridableHttpConfig->srv_enabled;
     break;
+  case TS_CONFIG_HTTP_FORWARD_CONNECT_METHOD:
+    typ = OVERRIDABLE_TYPE_INT;
+    ret = &overridableHttpConfig->forward_connect_method;
+    break;
   // This helps avoiding compiler warnings, yet detect unhandled enum members.
   case TS_CONFIG_NULL:
   case TS_CONFIG_LAST_ENTRY:
@@ -8498,6 +8502,11 @@ TSHttpTxnConfigFind(const char *name, int length, TSOverridableConfigKey *conf,
 
   case 40:
     switch (name[length - 1]) {
+    case 'd':
+      if (!strncmp(name, "proxy.config.http.forward_connect_method", length)) {
+        cnf = TS_CONFIG_HTTP_FORWARD_CONNECT_METHOD;
+      }
+      break;
     case 'e':
       if (!strncmp(name, "proxy.config.http.down_server.cache_time", length)) {
         cnf = TS_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME;
diff --git a/proxy/InkAPITest.cc b/proxy/InkAPITest.cc
index 59f1801..f4defcb 100644
--- a/proxy/InkAPITest.cc
+++ b/proxy/InkAPITest.cc
@@ -7617,6 +7617,7 @@ const char *SDK_Overridable_Configs[TS_CONFIG_LAST_ENTRY] = {
   "proxy.config.http.parent_proxy.total_connect_attempts",
   "proxy.config.http.transaction_active_timeout_in",
   "proxy.config.srv_enabled",
+  "proxy.config.http.forward_connect_method",
 };
 
 REGRESSION_TEST(SDK_API_OVERRIDABLE_CONFIGS)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc
index 4b64fc7..13b3d84 100644
--- a/proxy/http/HttpConfig.cc
+++ b/proxy/http/HttpConfig.cc
@@ -887,8 +887,9 @@ HttpConfig::startup()
   HttpEstablishStaticConfigLongLong(c.origin_min_keep_alive_connections, "proxy.config.http.origin_min_keep_alive_connections");
   HttpEstablishStaticConfigByte(c.oride.attach_server_session_to_client, "proxy.config.http.attach_server_session_to_client");
 
-  // Wank me.
   HttpEstablishStaticConfigByte(c.disable_ssl_parenting, "proxy.local.http.parent_proxy.disable_connect_tunneling");
+  HttpEstablishStaticConfigByte(c.oride.forward_connect_method, "proxy.config.http.forward_connect_method");
+
   HttpEstablishStaticConfigByte(c.no_dns_forward_to_parent, "proxy.config.http.no_dns_just_forward_to_parent");
   HttpEstablishStaticConfigByte(c.oride.uncacheable_requests_bypass_parent, "proxy.config.http.uncacheable_requests_bypass_parent");
   HttpEstablishStaticConfigByte(c.oride.doc_in_cache_skip_dns, "proxy.config.http.doc_in_cache_skip_dns");
@@ -1150,7 +1151,8 @@ HttpConfig::reconfigure()
   params->use_client_source_port                   = INT_TO_BOOL(m_master.use_client_source_port);
   params->oride.maintain_pristine_host_hdr         = INT_TO_BOOL(m_master.oride.maintain_pristine_host_hdr);
 
-  params->disable_ssl_parenting = INT_TO_BOOL(m_master.disable_ssl_parenting);
+  params->disable_ssl_parenting        = INT_TO_BOOL(m_master.disable_ssl_parenting);
+  params->oride.forward_connect_method = INT_TO_BOOL(m_master.oride.forward_connect_method);
 
   params->server_max_connections             = m_master.server_max_connections;
   params->max_websocket_connections          = m_master.max_websocket_connections;
diff --git a/proxy/http/HttpConfig.h b/proxy/http/HttpConfig.h
index ac40c29..7d4bb27 100644
--- a/proxy/http/HttpConfig.h
+++ b/proxy/http/HttpConfig.h
@@ -375,6 +375,7 @@ struct OverridableHttpConfigParams {
       fwd_proxy_auth_to_parent(0),
       uncacheable_requests_bypass_parent(1),
       attach_server_session_to_client(0),
+      forward_connect_method(0),
       insert_age_in_response(1),
       anonymize_remove_from(0),
       anonymize_remove_referer(0),
@@ -492,6 +493,8 @@ struct OverridableHttpConfigParams {
   MgmtByte uncacheable_requests_bypass_parent;
   MgmtByte attach_server_session_to_client;
 
+  MgmtByte forward_connect_method;
+
   MgmtByte insert_age_in_response;
 
   ///////////////////////////////////////////////////////////////////
diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
index 54c8335..25e4026 100644
--- a/proxy/http/HttpTransact.cc
+++ b/proxy/http/HttpTransact.cc
@@ -464,10 +464,16 @@ how_to_open_connection(HttpTransact::State *s)
     break;
   }
 
-  if (s->method == HTTP_WKSIDX_CONNECT && s->parent_result.result != PARENT_SPECIFIED) {
-    s->cdn_saved_next_action = HttpTransact::SM_ACTION_ORIGIN_SERVER_RAW_OPEN;
-  } else {
-    s->cdn_saved_next_action = HttpTransact::SM_ACTION_ORIGIN_SERVER_OPEN;
+  s->cdn_saved_next_action = HttpTransact::SM_ACTION_ORIGIN_SERVER_OPEN;
+
+  // Setting up a direct CONNECT tunnel enters OriginServerRawOpen. We always do that if we
+  // are not forwarding CONNECT and are not going to a parent proxy.
+  if (s->method == HTTP_WKSIDX_CONNECT) {
+    if (s->txn_conf->forward_connect_method == 1 || s->parent_result.result != PARENT_SPECIFIED) {
+      s->cdn_saved_next_action = HttpTransact::SM_ACTION_ORIGIN_SERVER_OPEN;
+    } else {
+      s->cdn_saved_next_action = HttpTransact::SM_ACTION_ORIGIN_SERVER_RAW_OPEN;
+    }
   }
 
   // In the following, if url_remap_mode == 2 (URL_REMAP_FOR_OS)
@@ -550,7 +556,7 @@ how_to_open_connection(HttpTransact::State *s)
  ****                 HttpTransact State Machine Handlers                 ****
  ****                                                                     ****
  **** What follow from here on are the state machine handlers - the code  ****
- **** which is called from HttpSM::set_next_state to specify ****
+ **** which is called from HttpSM::set_next_state to specify              ****
  **** what action the state machine needs to execute next. These ftns     ****
  **** take as input just the state and set the next_action variable.      ****
  *****************************************************************************
@@ -7820,27 +7826,22 @@ HttpTransact::build_request(State *s, HTTPHdr *base_request, HTTPHdr *outgoing_r
     }
   }
 
-  if (s->current.server == &s->server_info && (s->next_hop_scheme == URL_WKSIDX_HTTP || s->next_hop_scheme == URL_WKSIDX_HTTPS ||
-                                               s->next_hop_scheme == URL_WKSIDX_WS || s->next_hop_scheme == URL_WKSIDX_WSS)) {
-    DebugTxn("http_trans", "[build_request] removing host name from url");
-    HttpTransactHeaders::remove_host_name_from_url(outgoing_request);
-  }
-
-  // If we're going to a parent proxy, make sure we pass host and port
-  // in the URL even if we didn't get them (e.g. transparent proxy)
-  if (s->current.request_to == PARENT_PROXY) {
-    if (!outgoing_request->is_target_in_url() && s->parent_result.parent_is_proxy()) {
+  // Figure out whether to force the outgoing request URL into absolute or relative styles.
+  if (outgoing_request->method_get_wksidx() == HTTP_WKSIDX_CONNECT) {
+    // CONNECT method requires a target in the URL, so always force it from the Host header.
+    outgoing_request->set_url_target_from_host_field();
+  } else if (s->current.request_to == PARENT_PROXY && s->parent_result.parent_is_proxy()) {
+    // If we have a parent proxy set the URL target field.
+    if (!outgoing_request->is_target_in_url()) {
       DebugTxn("http_trans", "[build_request] adding target to URL for parent proxy");
-
-      // No worry about HTTP/0.9 because we reject forward proxy requests that
-      // don't have a host anywhere.
       outgoing_request->set_url_target_from_host_field();
-    } else if (s->current.request_to == PARENT_PROXY && !s->parent_result.parent_is_proxy() &&
-               outgoing_request->is_target_in_url()) {
-      // If the parent is an origin server remove the hostname from the url.
-      DebugTxn("http_trans", "[build_request] removing target from URL for a parent origin.");
-      HttpTransactHeaders::remove_host_name_from_url(outgoing_request);
     }
+  } else if (s->next_hop_scheme == URL_WKSIDX_HTTP || s->next_hop_scheme == URL_WKSIDX_HTTPS ||
+             s->next_hop_scheme == URL_WKSIDX_WS || s->next_hop_scheme == URL_WKSIDX_WSS) {
+    // Otherwise, remove the URL target from HTTP and Websocket URLs since certain origins
+    // cannot deal with absolute URLs.
+    DebugTxn("http_trans", "[build_request] removing host name from url");
+    HttpTransactHeaders::remove_host_name_from_url(outgoing_request);
   }
 
   // If the response is most likely not cacheable, eg, request with Authorization,

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.