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 2011/12/30 18:47:15 UTC

svn commit: r1225874 - in /trafficserver/traffic/trunk: ./ lib/ts/ proxy/ proxy/api/ts/ proxy/hdrs/ proxy/logging/

Author: zwoop
Date: Fri Dec 30 17:47:14 2011
New Revision: 1225874

URL: http://svn.apache.org/viewvc?rev=1225874&view=rev
Log:
TS-245 Add TSStringPercentEncode(), TSUrlPercentEncode(), and TSStringPercentDecode()

Modified:
    trafficserver/traffic/trunk/CHANGES
    trafficserver/traffic/trunk/lib/ts/ink_string++.cc
    trafficserver/traffic/trunk/lib/ts/ink_string.cc
    trafficserver/traffic/trunk/lib/ts/ink_string.h
    trafficserver/traffic/trunk/proxy/InkAPI.cc
    trafficserver/traffic/trunk/proxy/InkAPITest.cc
    trafficserver/traffic/trunk/proxy/api/ts/ts.h.in
    trafficserver/traffic/trunk/proxy/hdrs/URL.cc
    trafficserver/traffic/trunk/proxy/hdrs/URL.h
    trafficserver/traffic/trunk/proxy/logging/LogUtils.cc
    trafficserver/traffic/trunk/proxy/logging/LogUtils.h

Modified: trafficserver/traffic/trunk/CHANGES
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/CHANGES?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/CHANGES (original)
+++ trafficserver/traffic/trunk/CHANGES Fri Dec 30 17:47:14 2011
@@ -1,13 +1,15 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 3.1.2
+  *) [TS-245] Add TSStringPercentEncode(), TSUrlPercentEncode(), and
+   TSStringPercentDecode().
+
   *) [TS-1065] traffic_cop segment fault when enable TRACE_LOG_COP.
-     Author: Conan Wang.
+   Author: Conan Wang.
 
-  *) [TS-1029] DNS crash if we free the memory into system.
-    Author: weijin
+  *) [TS-1029] DNS crash if we free the memory into system. Author: weijin
 
   *) [TS-1055] Wrong implementation of TSHttpSsnArgGet().
-    Author: Yakov Kopel
+   Author: Yakov Kopel
 
   *) [TS-992] Portability fixes. Author: Piotr Sikora.
 

Modified: trafficserver/traffic/trunk/lib/ts/ink_string++.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/ink_string%2B%2B.cc?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_string++.cc (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_string++.cc Fri Dec 30 17:47:14 2011
@@ -33,18 +33,6 @@
 #include "libts.h"
 #include "ink_unused.h"      /* MAGIC_EDITING_TAG */
 
-/*-------------------------------------------------------------------------
-  -------------------------------------------------------------------------*/
-
-char *
-ink_memcpy_until_char(char *dst, char *src, unsigned int n, unsigned char c)
-{
-  unsigned int i = 0;
-  for (; ((i < n) && (((unsigned char) src[i]) != c)); i++)
-    dst[i] = src[i];
-  return &src[i];
-}
-
 /***********************************************************************
  *                                                                     *
  *       StrList (doubly-linked list of string/length list cells)      *

Modified: trafficserver/traffic/trunk/lib/ts/ink_string.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/ink_string.cc?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_string.cc (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_string.cc Fri Dec 30 17:47:14 2011
@@ -30,6 +30,17 @@
 
 #define INK_MAX_STRING_ARRAY_SIZE 128
 
+/*-------------------------------------------------------------------------
+  -------------------------------------------------------------------------*/
+char *
+ink_memcpy_until_char(char *dst, char *src, unsigned int n, unsigned char c)
+{
+  unsigned int i = 0;
+  for (; ((i < n) && (((unsigned char) src[i]) != c)); i++)
+    dst[i] = src[i];
+  return &src[i];
+}
+
 /*---------------------------------------------------------------------------*
 
   char *ink_strncpy(char *dest, char *src, int n)

Modified: trafficserver/traffic/trunk/lib/ts/ink_string.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/lib/ts/ink_string.h?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/lib/ts/ink_string.h (original)
+++ trafficserver/traffic/trunk/lib/ts/ink_string.h Fri Dec 30 17:47:14 2011
@@ -49,6 +49,7 @@
  *===========================================================================*/
 /* these are supposed to be fast */
 
+inkcoreapi char *ink_memcpy_until_char(char *dst, char *src, unsigned int n, unsigned char c);
 inkcoreapi char *ink_strncpy(char *dest, const char *src, int n);
 inkcoreapi char *ink_strncat(char *dest, const char *src, int n);
 inkcoreapi char *ink_string_concatenate_strings(char *dest, ...);

Modified: trafficserver/traffic/trunk/proxy/InkAPI.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/InkAPI.cc?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/InkAPI.cc (original)
+++ trafficserver/traffic/trunk/proxy/InkAPI.cc Fri Dec 30 17:47:14 2011
@@ -91,7 +91,7 @@ volatile int next_argv_index = 0;
 
 struct _STATE_ARG_TABLE {
   char* name;
-  int name_len;
+  size_t name_len;
   char* description;
 } state_arg_table[HTTP_SSN_TXN_MAX_USER_ARG];
 
@@ -2285,6 +2285,73 @@ TSUrlHttpFragmentSet(TSMBuffer bufp, TSM
   return URLPartSet(bufp, obj, value, length, &URL::fragment_set);
 }
 
+// URL percent encoding
+TSReturnCode
+TSStringPercentEncode(const char* str, int str_len, char *dst, size_t dst_size, size_t *length, const unsigned char *map)
+{
+  sdk_assert(sdk_sanity_check_null_ptr((void*)str) == TS_SUCCESS);
+  sdk_assert(sdk_sanity_check_null_ptr((void*)dst) == TS_SUCCESS);
+  sdk_assert(sdk_sanity_check_null_ptr((void*)length) == TS_SUCCESS);
+
+  int new_len; // Unfortunately, a lot of the core uses "int" for length's internally...
+
+  if (str_len < 0)
+    str_len = strlen(str);
+
+  sdk_assert(str_len < static_cast<int>(dst_size));
+
+  // TODO: Perhaps we should make escapify_url() deal with const properly...
+  if (NULL == LogUtils::escapify_url(NULL, const_cast<char*>(str), str_len, &new_len, dst, dst_size, map)) {
+    *length = 0;
+    return TS_ERROR;
+  }
+
+  *length = new_len;
+  return TS_SUCCESS;
+}
+
+size_t
+TSStringPercentDecode(const char *src, size_t src_len, char* dst, size_t dst_size)
+{
+  sdk_assert(sdk_sanity_check_null_ptr((void*)src) == TS_SUCCESS);
+  sdk_assert(sdk_sanity_check_null_ptr((void*)dst) == TS_SUCCESS);
+
+  if (src_len < 0)
+    src_len = strlen(src);
+
+  // return unescapifyStr(str);
+  char *buffer = dst;
+  const char *str =  src;
+  int s = 0; // State, which we don't really use
+
+  unescape_str(buffer, buffer+dst_size, str, str+src_len, s);
+  *buffer = '\0';
+
+  return buffer - dst;
+}
+
+
+
+TSReturnCode
+TSUrlPercentEncode(TSMBuffer bufp, TSMLoc obj, char *dst, size_t dst_size, size_t *length, const unsigned char *map)
+{
+  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
+  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);
+  sdk_assert(sdk_sanity_check_null_ptr((void*)length) == TS_SUCCESS);
+
+  char *url;
+  int url_len;
+  TSReturnCode ret;
+  URLImpl *url_impl = (URLImpl *)obj;
+
+  // TODO: at some point, it might be nice to allow this to write to a pre-allocated buffer
+  url = url_string_get(url_impl, NULL, &url_len, NULL);
+  ret = TSStringPercentEncode(url, url_len, dst, dst_size, length, map);
+  ats_free(url);
+
+  return ret;
+}
+
 
 ////////////////////////////////////////////////////////////////////
 //
@@ -5455,7 +5522,7 @@ TSHttpArgIndexNameLookup(const char* nam
 {
   sdk_assert(sdk_sanity_check_null_ptr(arg_idx) == TS_SUCCESS);
 
-  int len = strlen(name);
+  size_t len = strlen(name);
 
   for (int ix = 0; ix <  next_argv_index; ++ix) {
     if ((len == state_arg_table[ix].name_len) && (0 == strcmp(name, state_arg_table[ix].name))) {

Modified: trafficserver/traffic/trunk/proxy/InkAPITest.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/InkAPITest.cc?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/InkAPITest.cc (original)
+++ trafficserver/traffic/trunk/proxy/InkAPITest.cc Fri Dec 30 17:47:14 2011
@@ -7598,7 +7598,7 @@ const char *SDK_Overridable_Configs[] = 
 REGRESSION_TEST(SDK_API_OVERRIDABLE_CONFIGS) (RegressionTest * test, int atype, int *pstatus)
 {
   NOWARN_UNUSED(atype);
-  const char* conf;
+  const char *conf;
   TSOverridableConfigKey key;
   TSRecordDataType type;
   HttpSM* s = HttpSM::allocate();
@@ -7606,8 +7606,8 @@ REGRESSION_TEST(SDK_API_OVERRIDABLE_CONF
   TSHttpTxn txnp = reinterpret_cast<TSHttpTxn>(s);
   TSMgmtInt ival;
   TSMgmtFloat fval;
-  const char* sval;
-  const char* test_string = "The Apache Traffic Server";
+  const char *sval;
+  const char *test_string = "The Apache Traffic Server";
   int tmp_int;
 
   s->init();
@@ -7676,3 +7676,46 @@ REGRESSION_TEST(SDK_API_OVERRIDABLE_CONF
 
   return;
 }
+
+////////////////////////////////////////////////
+// SDK_API_PERCENT_ENCODING
+//
+// Unit Test for API: TSStringPercentEncode
+//                    TSUrlPercentEncode
+//                    TSStringPercentDecode
+////////////////////////////////////////////////
+
+REGRESSION_TEST(SDK_API_PERCENT_ENCODING) (RegressionTest * test, int atype, int *pstatus)
+{
+  const char *url = "http://www.example.com/foo?fie= \"#%<>[]\\^`{}~&bar={test}&fum=Apache Traffic Server";
+  const char *url_encoded =
+    "http://www.example.com/foo?fie=%20%22%23%25%3C%3E%5B%5D%5C%5E%60%7B%7D%7E&bar=%7Btest%7D&fum=Apache%20Traffic%20Server";
+  char buf[1024];
+  size_t length;
+  bool success = true;
+
+  if (TS_SUCCESS != TSStringPercentEncode(url, strlen(url), buf, sizeof(buf), &length, NULL)) {
+    SDK_RPRINT(test, "TSStringPercentEncode", "TestCase1", TC_FAIL, "Failed on %s", url);
+    success = false;
+  } else {
+    if (strcmp(buf, url_encoded)) {
+      SDK_RPRINT(test, "TSStringPercentEncode", "TestCase1", TC_FAIL, "Failed on %s != %s", buf, url_encoded);
+      success = false;
+    }
+  }
+
+  length = TSStringPercentDecode(url_encoded, strlen(url_encoded), buf, sizeof(buf));
+  if (length != strlen(url) || strcmp(buf, url)) {
+    SDK_RPRINT(test, "TSStringPercentDecode", "TestCase1", TC_FAIL, "Failed on %s != %s", buf, url);
+    success = false;
+  }
+
+  if (success) {
+    *pstatus = REGRESSION_TEST_PASSED;
+    SDK_RPRINT(test, "TSStringPercentEncode", "TestCase1", TC_PASS, "ok");
+  } else {
+    *pstatus = REGRESSION_TEST_FAILED;
+  }
+
+  return;
+}

Modified: trafficserver/traffic/trunk/proxy/api/ts/ts.h.in
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/api/ts/ts.h.in?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/api/ts/ts.h.in (original)
+++ trafficserver/traffic/trunk/proxy/api/ts/ts.h.in Fri Dec 30 17:47:14 2011
@@ -1572,6 +1572,50 @@ extern "C"
    */
   tsapi TSReturnCode TSUrlHttpFragmentSet(TSMBuffer bufp, TSMLoc offset, const char* value, int length);
 
+  /**
+     Perform percent-encoding of the string in the buffer, storing the
+     new string in the destination buffer. The length parameter will be
+     set to the new (encoded) string length, or 0 if the encoding failed.
+
+     @param str the string buffer to encode.
+     @param str_len length of the string buffer.
+     @param dst destination buffer.
+     @param dst_size size of the destination buffer.
+     @param length amount of data written to the destination buffer.
+     @param map optional (can be NULL) map of characters to encode.
+
+  */
+  tsapi TSReturnCode TSStringPercentEncode(const char* str, int str_len, char *dst, size_t dst_size, size_t *length, const unsigned char *map);
+
+  /**
+     Similar to TSStringPercentEncode(), but works on a URL object.
+
+     @param bufp marshal buffer containing the URL.
+     @param offset location of the URL within bufp.
+     @param dst destination buffer.
+     @param dst_size size of the destination buffer.
+     @param length amount of data written to the destination buffer.
+     @param map optional (can be NULL) map of characters to encode.
+
+  */
+  tsapi TSReturnCode TSUrlPercentEncode(TSMBuffer bufp, TSMLoc offset, char *dst, size_t dst_size, size_t *length, const unsigned char *map);
+
+  /**
+     Perform percent-decoding of the string in the buffer, writing
+     to the output buffer. The source and destination can be the same,
+     in which case they overwrite. The decoded string is always 
+     guaranteed to be no longer than the source string.
+
+     @param src the string to decode (and possibly write to).
+     @param src_len length of the input string (or -1).
+     @param dst output buffer (can be the same as src).
+     @param dst_len size of the output buffer.
+
+  */
+  tsapi size_t TSStringPercentDecode(const char *src, size_t src_len, char* dst, size_t dst_size);
+
+
+
   /* --------------------------------------------------------------------------
      MIME headers */
 

Modified: trafficserver/traffic/trunk/proxy/hdrs/URL.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/hdrs/URL.cc?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/hdrs/URL.cc (original)
+++ trafficserver/traffic/trunk/proxy/hdrs/URL.cc Fri Dec 30 17:47:14 2011
@@ -885,16 +885,15 @@ url_to_string(URLImpl * url, Arena * are
  *                                                                     *
  ***********************************************************************/
 
-static void
+void
 unescape_str(char *&buf, char *buf_e, const char *&str, const char *str_e, int &state)
 {
   int copy_len;
   char *first_pct;
-  extern char *ink_memcpy_until_char(char *dst, char *src, unsigned int n, unsigned char c);
-
   int buf_len = (int) (buf_e - buf);
   int str_len = (int) (str_e - str);
   int min_len = (int) (str_len < buf_len ? str_len : buf_len);
+
   first_pct = ink_memcpy_until_char(buf, (char *) str, min_len, '%');
   copy_len = (int) (first_pct - str);
   str += copy_len;
@@ -956,7 +955,7 @@ unescape_str(char *&buf, char *buf_e, co
 /*-------------------------------------------------------------------------
   -------------------------------------------------------------------------*/
 
-static void
+void
 unescape_str_tolower(char *&buf, char *end, const char *&str, const char *str_e, int &state)
 {
   while (str < str_e && (buf != end)) {

Modified: trafficserver/traffic/trunk/proxy/hdrs/URL.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/hdrs/URL.h?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/hdrs/URL.h (original)
+++ trafficserver/traffic/trunk/proxy/hdrs/URL.h Fri Dec 30 17:47:14 2011
@@ -208,6 +208,10 @@ MIMEParseResult url_parse_http_no_path_c
 
 char *url_unescapify(Arena *arena, const char *str, int length);
 
+void unescape_str(char *&buf, char *buf_e, const char *&str, const char *str_e, int &state);
+void unescape_str_tolower(char *&buf, char *end, const char *&str, const char *str_e, int &state);
+
+
 inline int
 url_canonicalize_port(int type, int port)
 {

Modified: trafficserver/traffic/trunk/proxy/logging/LogUtils.cc
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/logging/LogUtils.cc?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/logging/LogUtils.cc (original)
+++ trafficserver/traffic/trunk/proxy/logging/LogUtils.cc Fri Dec 30 17:47:14 2011
@@ -317,7 +317,7 @@ LogUtils::strip_trailing_newline(char *b
   -------------------------------------------------------------------------*/
 
 char *
-LogUtils::escapify_url(Arena * arena, char *url, int len_in, int *len_out)
+LogUtils::escapify_url(Arena *arena, char *url, size_t len_in, int *len_out, char *dst, size_t dst_size, const unsigned char *map)
 {
   // codes_to_escape is a bitmap encoding the codes that should be escaped.
   // These are all the codes defined in section 2.4.3 of RFC 2396
@@ -326,7 +326,7 @@ LogUtils::escapify_url(Arena * arena, ch
   // historically this is what the traffic_server has done.
   // Note that we leave codes beyond 127 unmodified.
   //
-  static unsigned char codes_to_escape[32] = {
+  static const unsigned char codes_to_escape[32] = {
     0xFF, 0xFF, 0xFF, 0xFF,     // control
     0xB4,                       // space " # %
     0x00, 0x00,                 //
@@ -346,29 +346,37 @@ LogUtils::escapify_url(Arena * arena, ch
     'D', 'E', 'F'
   };
 
-  if (!url) {
+  if (!url || (dst && dst_size < len_in)) {
     *len_out = 0;
-    return (NULL);
+    return NULL;
   }
+
+  if (!map)
+    map = codes_to_escape;
+
   // Count specials in the url, assuming that there won't be any.
   //
   int count = 0;
   char *p = url;
   char *in_url_end = url + len_in;
+
   while (p < in_url_end) {
     register unsigned char c = *p;
-    if (codes_to_escape[c / 8] & (1 << (7 - c % 8))) {
-      count++;
+    if (map[c / 8] & (1 << (7 - c % 8))) {
+      ++count;
     }
-    p++;
+    ++p;
   }
 
   if (!count) {
     // The common case, no escapes, so just return the source string.
     //
     *len_out = len_in;
+    if (dst)
+      ink_strlcpy(dst, url, len_in);
     return url;
   }
+
   // For each special char found, we'll need an escape string, which is
   // three characters long.  Count this and allocate the string required.
   //
@@ -376,19 +384,30 @@ LogUtils::escapify_url(Arena * arena, ch
   // for when we calculate out_len !!! in other words,
   // out_len = len_in + 3*count - count
   //
-  int out_len = len_in + 2 * count;
+  size_t out_len = len_in + 2 * count;
+
+  if (dst && out_len > dst_size) {
+    *len_out = 0;
+    return NULL;
+  }
 
   // To play it safe, we null terminate the string we return in case
   // a module that expects null-terminated strings calls escapify_url,
   // so we allocate an extra byte for the EOS
   //
-  char *new_url = (char *) arena->str_alloc(out_len + 1);
+  char *new_url;
+
+  if (dst)
+    new_url = dst;
+  else
+    new_url = (char *) arena->str_alloc(out_len + 1);
 
   char *from = url;
   char *to = new_url;
+
   while (from < in_url_end) {
     register unsigned char c = *from;
-    if (codes_to_escape[c / 8] & (1 << (7 - c % 8))) {
+    if (map[c / 8] & (1 << (7 - c % 8))) {
       *to++ = '%';
       *to++ = hex_digit[c / 16];
       *to++ = hex_digit[c % 16];

Modified: trafficserver/traffic/trunk/proxy/logging/LogUtils.h
URL: http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/logging/LogUtils.h?rev=1225874&r1=1225873&r2=1225874&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/logging/LogUtils.h (original)
+++ trafficserver/traffic/trunk/proxy/logging/LogUtils.h Fri Dec 30 17:47:14 2011
@@ -54,7 +54,7 @@ public:
   static unsigned ip_from_host(char *host);
   static void manager_alarm(AlarmType alarm_type, const char *msg, ...);
   static void strip_trailing_newline(char *buf);
-  static char *escapify_url(Arena * arena, char *url, int len_in, int *len_out);
+  static char *escapify_url(Arena * arena, char *url, size_t len_in, int *len_out, char *dst=NULL, size_t dst_size=0, const unsigned char *map=NULL);
   static char *int64_to_str(char *buf, unsigned int buf_size, int64_t val, unsigned int *total_chars, unsigned int req_width=0, char pad_char='0');
   static void remove_content_type_attributes(char *type_str, int *type_len);
   static int timestamp_to_hex_str(unsigned timestamp, char *str, size_t len, size_t * n_chars = 0);