Repository: trafficserver
Updated Branches:
  refs/heads/master 631763c42 -> 1e5d1732f


TS-1570: remap doesn't reject request with invalid characters after port


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/0c9fb914
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/0c9fb914
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/0c9fb914

Branch: refs/heads/master
Commit: 0c9fb914fd1893dbed7df55cb1782aeaca495be3
Parents: 631763c
Author: Cynthia Gu <czhen...@linkedin.com>
Authored: Mon Dec 8 13:47:37 2014 -0800
Committer: Brian Geffon <bri...@apache.org>
Committed: Mon Dec 8 13:47:37 2014 -0800

----------------------------------------------------------------------
 lib/ts/TsBuffer.h  |  2 +-
 lib/ts/ink_inet.cc | 44 ++++++++++++++++++++++++++------------------
 lib/ts/ink_inet.h  |  3 ++-
 proxy/hdrs/HTTP.cc | 38 +++++++++++++++++++++++++++++++++++++-
 proxy/hdrs/HTTP.h  |  1 +
 5 files changed, 67 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0c9fb914/lib/ts/TsBuffer.h
----------------------------------------------------------------------
diff --git a/lib/ts/TsBuffer.h b/lib/ts/TsBuffer.h
index d4fac87..006c821 100644
--- a/lib/ts/TsBuffer.h
+++ b/lib/ts/TsBuffer.h
@@ -246,7 +246,7 @@ namespace ts {
         This is convenient when tokenizing and @a p points at the token
         separator.
 
-        @note If @a *p is in the buffer then @a this is not changed
+        @note If @a *p is not in the buffer then @a this is not changed
         and an empty buffer is returned. This means the caller can
         simply pass the result of @c find and check for an empty
         buffer returned to detect no more separators.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0c9fb914/lib/ts/ink_inet.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_inet.cc b/lib/ts/ink_inet.cc
index a841a76..de874ff 100644
--- a/lib/ts/ink_inet.cc
+++ b/lib/ts/ink_inet.cc
@@ -193,17 +193,19 @@ char const* ats_ip_nptop(
 }
 
 int
-ats_ip_parse(ts::ConstBuffer src, ts::ConstBuffer* addr, ts::ConstBuffer* 
port) {
+ats_ip_parse(ts::ConstBuffer src, ts::ConstBuffer* addr, ts::ConstBuffer* 
port, ts::ConstBuffer* rest) {
   // In case the incoming arguments are null.
   ts::ConstBuffer localAddr, localPort;
   if (!addr) addr = &localAddr;
   if (!port) port = &localPort;
   addr->reset();
   port->reset();
+  if (rest) rest->reset();
 
   // Let's see if we can find out what's in the address string.
   if (src) {
-    while (src && isspace(*src)) ++src;
+    bool colon_p = false;
+    while (src && ParseRules::is_ws(*src)) ++src;
     // Check for brackets.
     if ('[' == *src) {
       /* Ugly. In a number of places we must use bracket notation
@@ -222,25 +224,31 @@ ats_ip_parse(ts::ConstBuffer src, ts::ConstBuffer* addr, 
ts::ConstBuffer* port)
       */
       ++src; // skip bracket.
       *addr = src.splitOn(']');
-      if (*addr && ':' == *src) { // found the closing bracket and port colon
-        ++src; // skip colon.
-        *port = src;
-      } // else it's a fail for unclosed brackets.
+      if (':' == *src) {
+        colon_p = true;
+        ++src;
+      }
     } else {
-      // See if there's exactly 1 colon
-      ts::ConstBuffer tmp = src.after(':');
-      if (tmp && ! tmp.find(':')) { // 1 colon and no others
-        src.clip(tmp.data() - 1); // drop port from address.
-        *port = tmp;
-      } // else 0 or > 1 colon and no brackets means no port.
-      *addr = src;
+      *addr = src.splitOn(':');
+      if (*addr) {
+        colon_p = true;
+      } else { // no colon found, use everything.
+        *addr = src;
+        src.reset();
+      }
     }
-    // clip port down to digits.
-    if (*port) {
-      char const* spot = port->data();
-      while (isdigit(*spot)) ++spot;
-      port->clip(spot);
+    if (colon_p) {
+      ts::ConstBuffer tmp(src);
+      while (ParseRules::is_digit(*src))
+        ++src;
+
+      if (tmp.data() == src.data()) { // no digits at all
+        src.set(tmp.data()-1, tmp.size()+1); // back up to include colon
+      } else {
+        *port = tmp.clip(src.data());
+      }
     }
+    if (rest) *rest = src;
   }
   return *addr ? 0 : -1; // true if we found an address.
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0c9fb914/lib/ts/ink_inet.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_inet.h b/lib/ts/ink_inet.h
index 9181f38..388ce3c 100644
--- a/lib/ts/ink_inet.h
+++ b/lib/ts/ink_inet.h
@@ -165,7 +165,8 @@ int
 ats_ip_parse(
              ts::ConstBuffer src, ///< [in] String to search.
              ts::ConstBuffer* addr, ///< [out] Range containing IP address.
-             ts::ConstBuffer* port ///< [out] Range containing port.
+             ts::ConstBuffer* port, ///< [out] Range containing port.
+            ts::ConstBuffer* rest = 0 ///< [out] Remnant past the addr/port if 
any.
 );
 
 /**  Check to see if a buffer contains only IP address characters.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0c9fb914/proxy/hdrs/HTTP.cc
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc
index ce28ba7..aab1228 100644
--- a/proxy/hdrs/HTTP.cc
+++ b/proxy/hdrs/HTTP.cc
@@ -952,7 +952,9 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, 
HTTPHdrImpl *hh, const
       if (version == HTTP_VERSION(0, 9))
         return PARSE_DONE;
 
-      return mime_parser_parse(&parser->m_mime_parser, heap, 
hh->m_fields_impl, start, end, must_copy_strings, eof);
+      MIMEParseResult ret =  mime_parser_parse(&parser->m_mime_parser, heap, 
hh->m_fields_impl, start, end, must_copy_strings, eof);
+      if (ret == PARSE_DONE) ret = validate_hdr_host(hh); // if we're done 
with the main parse, check HOST.
+      return ret;
     }
 #endif
 
@@ -972,6 +974,7 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap *heap, 
HTTPHdrImpl *hh, const
       goto start;
 
   parse_method1:
+
     if (ParseRules::is_ws(*cur)) {
       GETNEXT(done);
       goto parse_method1;
@@ -1089,11 +1092,44 @@ http_parser_parse_req(HTTPParser *parser, HdrHeap 
*heap, HTTPHdrImpl *hh, const
     parser->m_parsing_http = false;
     if (version == HTTP_VERSION(0, 9))
       return PARSE_DONE;
+
+       MIMEParseResult ret =  mime_parser_parse(&parser->m_mime_parser, heap, 
hh->m_fields_impl, start, end, must_copy_strings, eof);
+       if (ret == PARSE_DONE) ret = validate_hdr_host(hh); // if we're done 
with the main parse, check HOST.
+       return ret;
   }
 
   return mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, 
start, end, must_copy_strings, eof);
 }
 
+MIMEParseResult
+validate_hdr_host(HTTPHdrImpl* hh) {
+  MIMEParseResult ret = PARSE_DONE;
+  MIMEField* host_field = mime_hdr_field_find(hh->m_fields_impl, 
MIME_FIELD_HOST, MIME_LEN_HOST);
+  if (host_field) {
+    if (host_field->has_dups()) {
+      ret = PARSE_ERROR; // can't have more than 1 host field.
+    } else {
+      int host_len = 0;
+      char const* host_val = host_field->value_get(&host_len);
+      ts::ConstBuffer addr, port, rest, host(host_val, host_len);
+      if (0 == ats_ip_parse(host, &addr, &port, &rest)) {
+       if (port) {
+         if (port.size() > 5) return PARSE_ERROR;
+         int port_i = ink_atoi(port.data(), port.size());
+          if ( port.size() > 5 || port_i >= 65536 || port_i <= 0) return 
PARSE_ERROR;
+        } 
+        while (rest && PARSE_DONE == ret) {
+          if (!ParseRules::is_ws(*rest)) return PARSE_ERROR;
+          ++rest;
+        }
+      } else {
+        ret = PARSE_ERROR;
+      }
+    }
+  }
+  return ret;
+}
+
 /*-------------------------------------------------------------------------
   -------------------------------------------------------------------------*/
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/0c9fb914/proxy/hdrs/HTTP.h
----------------------------------------------------------------------
diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h
index f9175e5..00a9c78 100644
--- a/proxy/hdrs/HTTP.h
+++ b/proxy/hdrs/HTTP.h
@@ -467,6 +467,7 @@ void http_parser_clear(HTTPParser *parser);
 MIMEParseResult http_parser_parse_req(HTTPParser *parser, HdrHeap *heap,
                                       HTTPHdrImpl *hh, const char **start,
                                       const char *end, bool must_copy_strings, 
bool eof);
+MIMEParseResult validate_hdr_host(HTTPHdrImpl* hh);
 MIMEParseResult http_parser_parse_resp(HTTPParser *parser, HdrHeap *heap,
                                        HTTPHdrImpl *hh, const char **start,
                                        const char *end, bool 
must_copy_strings, bool eof);

Reply via email to