You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by sh...@apache.org on 2015/01/22 15:29:27 UTC
trafficserver git commit: TS-3100: Extend tr-pass to allow malformed
HTTP GET requests to be blind tunneled.
Repository: trafficserver
Updated Branches:
refs/heads/master 9e2689b78 -> 497e4755d
TS-3100: Extend tr-pass to allow malformed HTTP GET requests to be blind
tunneled.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/497e4755
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/497e4755
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/497e4755
Branch: refs/heads/master
Commit: 497e4755d7773590204b89b6c262f6605a9c8e21
Parents: 9e2689b
Author: shinrich <sh...@yahoo-inc.com>
Authored: Thu Jan 22 08:28:52 2015 -0600
Committer: shinrich <sh...@yahoo-inc.com>
Committed: Thu Jan 22 08:28:52 2015 -0600
----------------------------------------------------------------------
CHANGES | 3 ++
proxy/hdrs/HTTP.h | 66 +++++++++++++++++++++++++++++++++++++--
proxy/hdrs/MIME.h | 9 ++++++
proxy/http/HttpSM.cc | 23 +++++++++++---
proxy/http/HttpTransact.cc | 68 ++---------------------------------------
5 files changed, 97 insertions(+), 72 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/497e4755/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index ddbd7e0..2d81063 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
-*- coding: utf-8 -*-
Changes with Apache Traffic Server 5.3.0
+ *) [TS-3100] Extend tr-pass to allow malformed HTTP GET requested to be blind
+ tunneled.
+
*) [TS-3140] Traffic Server asserts during response redirect.
*) [TS-3309] Document TLS session ticket rotation.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/497e4755/proxy/hdrs/HTTP.h
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h
index 00a9c78..fa0281d 100644
--- a/proxy/hdrs/HTTP.h
+++ b/proxy/hdrs/HTTP.h
@@ -549,7 +549,7 @@ public:
HTTPType type_get() const;
- HTTPVersion version_get();
+ HTTPVersion version_get() const;
void version_set(HTTPVersion version);
const char *method_get(int *length);
@@ -662,6 +662,9 @@ public:
// Utility routines
bool is_cache_control_set(const char *cc_directive_wks);
bool is_pragma_no_cache_set();
+ bool is_keep_alive_set() const;
+ HTTPKeepAlive keep_alive_get() const;
+
protected:
/** Load the target cache.
@@ -1006,7 +1009,7 @@ http_hdr_version_get(HTTPHdrImpl *hh)
-------------------------------------------------------------------------*/
inline HTTPVersion
-HTTPHdr::version_get()
+HTTPHdr::version_get() const
{
ink_assert(valid());
return HTTPVersion(http_hdr_version_get(m_http));
@@ -1015,6 +1018,65 @@ HTTPHdr::version_get()
/*-------------------------------------------------------------------------
-------------------------------------------------------------------------*/
+inline static HTTPKeepAlive
+is_header_keep_alive(const HTTPVersion & http_version, const MIMEField* con_hdr)
+{
+ enum {
+ CON_TOKEN_NONE = 0,
+ CON_TOKEN_KEEP_ALIVE,
+ CON_TOKEN_CLOSE
+ };
+
+ int con_token = CON_TOKEN_NONE;
+ HTTPKeepAlive keep_alive = HTTP_NO_KEEPALIVE;
+ // *unknown_tokens = false;
+
+ if (con_hdr) {
+ if (con_hdr->value_get_index("keep-alive", 10) >= 0)
+ con_token = CON_TOKEN_KEEP_ALIVE;
+ else if (con_hdr->value_get_index("close", 5) >= 0)
+ con_token = CON_TOKEN_CLOSE;
+ }
+
+ if (HTTPVersion(1, 0) == http_version) {
+ keep_alive = (con_token == CON_TOKEN_KEEP_ALIVE) ? (HTTP_KEEPALIVE) : (HTTP_NO_KEEPALIVE);
+ } else if (HTTPVersion(1, 1) == http_version) {
+ // We deviate from the spec here. If the we got a response where
+ // where there is no Connection header and the request 1.0 was
+ // 1.0 don't treat this as keep-alive since Netscape-Enterprise/3.6 SP1
+ // server doesn't
+ keep_alive = ((con_token == CON_TOKEN_KEEP_ALIVE) ||
+ (con_token == CON_TOKEN_NONE && HTTPVersion(1, 1) == http_version)) ? (HTTP_KEEPALIVE)
+ : (HTTP_NO_KEEPALIVE);
+ } else {
+ keep_alive = HTTP_NO_KEEPALIVE;
+ }
+ return (keep_alive);
+}
+
+inline HTTPKeepAlive
+HTTPHdr::keep_alive_get() const
+{
+ HTTPKeepAlive retval = HTTP_NO_KEEPALIVE;
+ const MIMEField *pc = this->field_find(MIME_FIELD_PROXY_CONNECTION, MIME_LEN_PROXY_CONNECTION);
+ if (pc != NULL) {
+ retval = is_header_keep_alive(this->version_get(), pc);
+ } else {
+ const MIMEField *c = this->field_find(MIME_FIELD_CONNECTION, MIME_LEN_CONNECTION);
+ retval = is_header_keep_alive(this->version_get(), c);
+ }
+ return retval;
+}
+
+inline bool
+HTTPHdr::is_keep_alive_set() const
+{
+ return this->keep_alive_get() == HTTP_KEEPALIVE;
+}
+
+/*-------------------------------------------------------------------------
+ -------------------------------------------------------------------------*/
+
inline void
HTTPHdr::version_set(HTTPVersion version)
{
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/497e4755/proxy/hdrs/MIME.h
----------------------------------------------------------------------
diff --git a/proxy/hdrs/MIME.h b/proxy/hdrs/MIME.h
index 127da61..860af82 100644
--- a/proxy/hdrs/MIME.h
+++ b/proxy/hdrs/MIME.h
@@ -905,6 +905,7 @@ public:
MIMEField *field_create(const char *name = NULL, int length = -1);
MIMEField *field_find(const char *name, int length);
+ const MIMEField *field_find(const char *name, int length) const;
void field_attach(MIMEField * field);
void field_detach(MIMEField * field, bool detach_all_dups = true);
void field_delete(MIMEField * field, bool delete_all_dups = true);
@@ -1101,6 +1102,14 @@ MIMEHdr::field_find(const char *name, int length)
return mime_hdr_field_find(m_mime, name, length);
}
+inline const MIMEField *
+MIMEHdr::field_find(const char *name, int length) const
+{
+// ink_assert(valid());
+ MIMEField *retval = mime_hdr_field_find(const_cast<MIMEHdr *>(this)->m_mime, name, length);
+ return retval;
+}
+
/*-------------------------------------------------------------------------
-------------------------------------------------------------------------*/
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/497e4755/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 3998771..8323929 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -680,11 +680,25 @@ HttpSM::state_read_client_request_header(int event, void *data)
// We need to handle EOS as well as READ_READY because the client
// may have sent all of the data already followed by a fIN and that
// should be OK.
- if ((event == VC_EVENT_READ_READY || event == VC_EVENT_EOS) &&
- state == PARSE_ERROR &&
- is_transparent_passthrough_allowed() &&
+ if (is_transparent_passthrough_allowed() &&
ua_raw_buffer_reader != NULL) {
-
+ bool do_blind_tunnel = false;
+ // If we had a parse error and we're done reading data
+ // blind tunnel
+ if ((event == VC_EVENT_READ_READY || event == VC_EVENT_EOS) &&
+ state == PARSE_ERROR) {
+ do_blind_tunnel = true;
+
+ // If we had a GET request that has data after the
+ // get request, do blind tunnel
+ } else if (state == PARSE_DONE &&
+ t_state.hdr_info.client_request.method_get_wksidx() ==
+ HTTP_WKSIDX_GET &&
+ ua_raw_buffer_reader->read_avail() > 0 &&
+ !t_state.hdr_info.client_request.is_keep_alive_set()) {
+ do_blind_tunnel = true;
+ }
+ if (do_blind_tunnel) {
DebugSM("http", "[%" PRId64 "] first request on connection failed parsing, switching to passthrough.", sm_id);
t_state.transparent_passthrough = true;
@@ -703,6 +717,7 @@ HttpSM::state_read_client_request_header(int event, void *data)
t_state.client_info.keep_alive = HTTP_NO_KEEPALIVE;
}
return 0;
+ }
}
// Check to see if we are done parsing the header
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/497e4755/proxy/http/HttpTransact.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
index 987a084..e3f06f0 100644
--- a/proxy/http/HttpTransact.cc
+++ b/proxy/http/HttpTransact.cc
@@ -69,47 +69,6 @@ extern HttpBodyFactory *body_factory;
static const char local_host_ip_str[] = "127.0.0.1";
-
-// someday, reduce the amount of duplicate code between this
-// function and _process_xxx_connection_field_in_outgoing_header
-inline static HTTPKeepAlive
-is_header_keep_alive(const HTTPVersion & http_version, const HTTPVersion & request_http_version, MIMEField* con_hdr /*, bool* unknown_tokens */)
-{
- enum
- {
- CON_TOKEN_NONE = 0,
- CON_TOKEN_KEEP_ALIVE,
- CON_TOKEN_CLOSE
- };
-
- int con_token = CON_TOKEN_NONE;
- HTTPKeepAlive keep_alive = HTTP_NO_KEEPALIVE;
- // *unknown_tokens = false;
-
- if (con_hdr) {
- if (con_hdr->value_get_index("keep-alive", 10) >= 0)
- con_token = CON_TOKEN_KEEP_ALIVE;
- else if (con_hdr->value_get_index("close", 5) >= 0)
- con_token = CON_TOKEN_CLOSE;
- }
-
- if (HTTPVersion(1, 0) == http_version) {
- keep_alive = (con_token == CON_TOKEN_KEEP_ALIVE) ? (HTTP_KEEPALIVE) : (HTTP_NO_KEEPALIVE);
- } else if (HTTPVersion(1, 1) == http_version) {
- // We deviate from the spec here. If the we got a response where
- // where there is no Connection header and the request 1.0 was
- // 1.0 don't treat this as keep-alive since Netscape-Enterprise/3.6 SP1
- // server doesn't
- keep_alive = ((con_token == CON_TOKEN_KEEP_ALIVE) ||
- (con_token == CON_TOKEN_NONE && HTTPVersion(1, 1) == request_http_version)) ? (HTTP_KEEPALIVE)
- : (HTTP_NO_KEEPALIVE);
- } else {
- keep_alive = HTTP_NO_KEEPALIVE;
- }
-
- return (keep_alive);
-}
-
inline static bool
is_request_conditional(HTTPHdr* header)
{
@@ -5468,14 +5427,7 @@ HttpTransact::initialize_state_variables_from_request(State* s, HTTPHdr* obsolet
if (!s->txn_conf->keep_alive_enabled_in) {
s->client_info.keep_alive = HTTP_NO_KEEPALIVE;
} else {
- // If there is a Proxy-Connection header use that, otherwise use the Connection header
- if (pc != NULL) {
- s->client_info.keep_alive = is_header_keep_alive(s->client_info.http_version, s->client_info.http_version, pc);
- } else {
- MIMEField *c = incoming_request->field_find(MIME_FIELD_CONNECTION, MIME_LEN_CONNECTION);
-
- s->client_info.keep_alive = is_header_keep_alive(s->client_info.http_version, s->client_info.http_version, c);
- }
+ s->client_info.keep_alive = incoming_request->keep_alive_get();
}
if (s->client_info.keep_alive == HTTP_KEEPALIVE && s->client_info.http_version == HTTPVersion(1, 1)) {
@@ -5582,23 +5534,7 @@ HttpTransact::initialize_state_variables_from_response(State* s, HTTPHdr* incomi
* if we sent "Connection: close" We need check the response
* header regardless of what we sent to the server
*/
- MIMEField *c_hdr;
- if ((s->current.request_to != ORIGIN_SERVER) &&
- (s->current.request_to == PARENT_PROXY ||
- s->current.request_to == ICP_SUGGESTED_HOST)) {
- c_hdr = s->hdr_info.server_response.field_find(MIME_FIELD_PROXY_CONNECTION, MIME_LEN_PROXY_CONNECTION);
-
- // If there is a Proxy-Connection header use that,
- // otherwise use the Connection header
- if (c_hdr == NULL) {
- c_hdr = s->hdr_info.server_response.field_find(MIME_FIELD_CONNECTION, MIME_LEN_CONNECTION);
- }
- } else {
- c_hdr = s->hdr_info.server_response.field_find(MIME_FIELD_CONNECTION, MIME_LEN_CONNECTION);
- }
-
- s->current.server->keep_alive = is_header_keep_alive(s->hdr_info.server_response.version_get(),
- s->hdr_info.server_request.version_get(), c_hdr);
+ s->current.server->keep_alive = s->hdr_info.server_response.keep_alive_get();
// Don't allow an upgrade request to Keep Alive
if (s->is_upgrade_request) {