trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zw...@apache.org
Subject svn commit: r1199523 - /trafficserver/plugins/trunk/regex_remap/regex_remap.cc
Date Tue, 08 Nov 2011 23:19:23 GMT
Author: zwoop
Date: Tue Nov  8 23:19:23 2011
New Revision: 1199523

URL: http://svn.apache.org/viewvc?rev=1199523&view=rev
Log:
Get it to compile at least, albeit, crippled.

Modified:
    trafficserver/plugins/trunk/regex_remap/regex_remap.cc

Modified: trafficserver/plugins/trunk/regex_remap/regex_remap.cc
URL: http://svn.apache.org/viewvc/trafficserver/plugins/trunk/regex_remap/regex_remap.cc?rev=1199523&r1=1199522&r2=1199523&view=diff
==============================================================================
--- trafficserver/plugins/trunk/regex_remap/regex_remap.cc (original)
+++ trafficserver/plugins/trunk/regex_remap/regex_remap.cc Tue Nov  8 23:19:23 2011
@@ -21,62 +21,6 @@
     limitations under the License.
 */
 
-//////////////////////////////////////////////////////////////////////////////////////////////
-//
-// To use this plugin, configure a remap.config rule like
-//
-//   map http://foo.com http://bar.com @plugin=.../libexec/regex_remap.so @pparam=maps.reg
-//
-// An optional argument (@@pparam) with the string "profile" will enable profiling
-// of this regex remap rule, e.g.
-//
-//   ... @pparam=maps.reg @pparam=profile
-//
-// Profiling is very low overhead, and the information is dumped to traffic.out, which
-// is typically in /usr/local/var/logs/trafficserver/traffic.out. In order to force a profile
-// dump, you can do
-//
-//     $ sudo touch /usr/local/etc/trafficserver/remap.config
-//     $ sudo traffic_line -x
-//
-// By default, only the path (and query arguments etc.) of the URL is provided for the
-// regular expressions to match. If you want the full (original) URL, use the parameter
-// @pparam=full-url. For example:
-//
-//    ... @pparam=maps.reg @pparam=full-url
-//
-// The string that you will need to match against looks like
-//
-//    http://server.com/path?query=bar
-//
-// If you also wish to match on the HTTP method used (e.g. "GET"), you must use the
-// option @pparam=method. For example:
-//
-//    ... @pparam=maps.reg @pparam=method
-//
-// With this enabled, the string that you will need to match will look like
-//
-//    GET/path?query=bar
-//
-// The "method" parameter can also be used in combination with "full-url", and the
-// string to match against will then look like
-//
-//    GEThttp://server.com/path?query=bar
-//
-// The methods are always all upper-case, and always followed by one single space. There
-// is no space between the method and the rest of the URL (or URI path).
-//
-//
-// Note that the path to the plugin itself must be absolute, and by default it is
-//
-//    /usr/local/libexec/trafficserver/regex_remap.so
-//
-// The config file (maps.reg above) can be placed anywhere, but unless you specify an
-// absolute path (as above), it will default to the directory
-//
-//   /usr/local/etc/regex_remap
-//
-
 #define UNUSED __attribute__ ((unused))
 static char UNUSED rcsId__regex_remap_cc[] = "@(#) $Id$ built on " __DATE__ " " __TIME__;
 
@@ -96,13 +40,13 @@ static char UNUSED rcsId__regex_remap_cc
 #include <string>
 
 
-// This is copied from libinktomi++/*.h, only works with gcc 4.x or later (and compatible).
+// This is copied from lib/ts/*.h, only works with gcc 4.x or later (and compatible).
 // TODO: We really ought to expose these data types and atomic functions to the plugin APIs.
 typedef int int32;
 typedef volatile int32 vint32;
 typedef vint32 *pvint32;
 
-static inline int ink_atomic_increment(pvint32 mem, int value)
+static inline int atomic_increment(pvint32 mem, int value)
 {
   return __sync_fetch_and_add(mem, value);
 }
@@ -124,12 +68,53 @@ enum ExtraSubstitutions {
   SUB_SCHEME = 15,
   SUB_PATH = 16,
   SUB_QUERY = 17,
-  SUB_COOKIE = 18,
-  SUB_CLIENT_IP = 19
+  SUB_MATRIX = 18,
+  SUB_CLIENT_IP = 19,
 };
 
 
 ///////////////////////////////////////////////////////////////////////////////
+// Class holding one request URL's component, to simplify the code and
+// length calculations (we need all of them).
+//
+struct UrlComponents
+{
+  UrlComponents()
+    : scheme(NULL), host(NULL), path(NULL), query(NULL), matrix(NULL), port(0),
+      scheme_len(0), host_len(0), path_len(0), query_len(0), matrix_len(0), url_len(0)
+  {}
+
+  void populate(TSRemapRequestInfo *rri)
+  {
+    scheme = TSUrlSchemeGet(rri->requestBufp, rri->requestUrl, &scheme_len);
+    host = TSUrlHostGet(rri->requestBufp, rri->requestUrl, &host_len);
+    path = TSUrlPathGet(rri->requestBufp, rri->requestUrl, &path_len);
+    query = TSUrlHttpQueryGet(rri->requestBufp, rri->requestUrl, &query_len);
+    matrix = TSUrlHttpParamsGet(rri->requestBufp, rri->requestUrl, &matrix_len);
+    port = TSUrlPortGet(rri->requestBufp, rri->requestUrl);
+
+    url_len = scheme_len + host_len + path_len + query_len + matrix_len + 32;
+  }
+
+  const char* scheme;
+  const char* host;
+  const char* path;
+  const char* query;
+  const char* matrix;
+  int port;
+
+  int scheme_len;
+  int host_len;
+  int path_len;
+  int query_len;
+  int matrix_len;
+
+  int url_len; // Full length, of all components
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////////
 // Class encapsulating one regular expression (and the linked list).
 //
 class RemapRegex
@@ -139,21 +124,21 @@ class RemapRegex
     _num_subs(-1), _rex(NULL), _extra(NULL), _order(-1), _simple(false),
     _active_timeout(-1), _no_activity_timeout(-1), _connect_timeout(-1), _dns_timeout(-1)
   {
-    INKDebug("regex_remap", "Calling constructor");
+    TSDebug("regex_remap", "Calling constructor");
 
-    _status = static_cast<INKHttpStatus>(0);
+    _status = static_cast<TSHttpStatus>(0);
 
     if (!reg.empty()) {
       if (reg == ".") {
-        INKDebug("regex_remap", "Rule is simple, and fast!");
+        TSDebug("regex_remap", "Rule is simple, and fast!");
         _simple = true;
       }
-      _rex_string = INKstrdup(reg.c_str());
+      _rex_string = TSstrdup(reg.c_str());
     } else
       _rex_string = NULL;
 
     if (!sub.empty()) {
-      _subst = INKstrdup(sub.c_str());
+      _subst = TSstrdup(sub.c_str());
       _subst_len = sub.length();
     } else {
       _subst = NULL;
@@ -176,7 +161,7 @@ class RemapRegex
       ++start;
       pos1 = opt.find_first_of("=", start);
       if (pos1 == std::string::npos) {
-        INKError("Malformed options: %s", opt.c_str());
+        TSError("Malformed options: %s", opt.c_str());
         break;
       }
       ++pos1;
@@ -186,7 +171,7 @@ class RemapRegex
       opt_val = opt.substr(pos1, pos2-pos1);
 
       if (opt.compare(start, 6, "status") == 0) {
-        _status = static_cast<INKHttpStatus>(atoi(opt_val.c_str()));
+        _status = static_cast<TSHttpStatus>(atoi(opt_val.c_str()));
       } else if (opt.compare(start, 14, "active_timeout") == 0) {
         _active_timeout = atoi(opt_val.c_str());
       } else if (opt.compare(start, 19, "no_activity_timeout") == 0) {
@@ -196,7 +181,7 @@ class RemapRegex
       } else if (opt.compare(start, 11, "dns_timeout") == 0) {
         _dns_timeout = atoi(opt_val.c_str());
       } else {
-        INKError("Unknown options: %s", opt.c_str());
+        TSError("Unknown options: %s", opt.c_str());
       }
       start = opt.find_first_of("@", pos2);
     }
@@ -204,11 +189,11 @@ class RemapRegex
 
   ~RemapRegex()
   {
-    INKDebug("regex_remap", "Calling destructor");
+    TSDebug("regex_remap", "Calling destructor");
     if (_rex_string)
-      INKfree(_rex_string);
+      TSfree(_rex_string);
     if (_subst)
-      INKfree(_subst);
+      TSfree(_subst);
 
     if (_rex)
       pcre_free(_rex);
@@ -226,7 +211,7 @@ class RemapRegex
   inline void
   increment()
   {
-    ink_atomic_increment(&(_hits), 1);
+    atomic_increment(&(_hits), 1);
   }
 
   // Compile and study the regular expression.
@@ -285,8 +270,8 @@ class RemapRegex
           case 'q':
             ix = SUB_QUERY;
             break;
-          case 'c':
-            ix = SUB_COOKIE;
+          case 'm':
+            ix = SUB_MATRIX;
             break;
           case 'i':
             ix = SUB_CLIENT_IP;
@@ -298,7 +283,7 @@ class RemapRegex
 
         if (ix > -1) {
           if ((ix < 10) && (ix > ccount)) {
-            INKDebug("regex_remap", "Trying to use unavailable substitution, check the regex!");
+            TSDebug("regex_remap", "Trying to use unavailable substitution, check the regex!");
             return -1; // No substitutions available other than $0
           }
 
@@ -334,7 +319,7 @@ class RemapRegex
   // We also calculate a total length for the new string, which is the max length the
   // substituted string can have (use it to allocate a buffer before calling substitute()
).
   int
-  get_lengths(const int ovector[], int lengths[], TSRemapRequestInfo *rri)
+  get_lengths(const int ovector[], int lengths[], TSRemapRequestInfo *rri, UrlComponents
*req_url)
   {
     int len = _subst_len + 1;   // Bigger then necessary
 
@@ -345,30 +330,34 @@ class RemapRegex
         lengths[ix] = ovector[2*ix+1] - ovector[2*ix]; // -1 - -1 == 0
         len += lengths[ix];
       } else {
+        int tmp_len;
+
         switch (ix) {
         case SUB_HOST:
-          len += rri->request_host_size;
+          len += req_url->host_len;
           break;
         case SUB_FROM_HOST:
-          len += rri->remap_from_host_size;
+          TSUrlHostGet(rri->requestBufp, rri->mapFromUrl, &tmp_len);
+          len += tmp_len;
           break;
         case SUB_TO_HOST:
-          len += rri->remap_to_host_size;
+          TSUrlHostGet(rri->requestBufp, rri->mapToUrl, &tmp_len);
+          len += tmp_len;
           break;
         case SUB_PORT:
           len += 6; // One extra for snprintf()
           break;
         case SUB_SCHEME:
-          len += rri->from_scheme_len;
+          len += req_url->scheme_len;
           break;
         case SUB_PATH:
-          len += rri->request_path_size;
+          len += req_url->path_len;
           break;
         case SUB_QUERY:
-          len += rri->request_query_size;
+          len += req_url->query_len;
           break;
-        case SUB_COOKIE:
-          len += rri->request_cookie_size;
+        case SUB_MATRIX:
+          len += req_url->matrix_len;
           break;
         case SUB_CLIENT_IP:
           len += 15; // Allow for 255.255.255.255
@@ -386,7 +375,8 @@ class RemapRegex
   // regex that was matches, while $1 - $9 are the corresponding groups. Return the final
   // length of the string as written to dest (not including the trailing '0').
   int
-  substitute(char dest[], const char *src, const int ovector[], const int lengths[], TSRemapRequestInfo
*rri)
+  substitute(char dest[], const char *src, const int ovector[], const int lengths[],
+             TSRemapRequestInfo *rri, UrlComponents *req_url, struct sockaddr const* addr)
   {
     if (_num_subs > 0) {
       char* p1 = dest;
@@ -402,48 +392,53 @@ class RemapRegex
           memcpy(p1, src + ovector[2*ix], lengths[ix]);
           p1 += lengths[ix];
         } else {
+          const char* str = NULL;
+          int len = 0;
+
           switch (ix) {
           case SUB_HOST:
-            memcpy(p1, rri->request_host, rri->request_host_size);
-            p1 += rri->request_host_size;
+            str = req_url->host;
+            len = req_url->host_len;
             break;
           case SUB_FROM_HOST:
-            memcpy(p1, rri->remap_from_host, rri->remap_from_host_size);
-            p1 += rri->remap_from_host_size;
+            str = TSUrlHostGet(rri->requestBufp, rri->mapFromUrl, &len);
             break;
           case SUB_TO_HOST:
-            memcpy(p1, rri->remap_to_host, rri->remap_to_host_size);
-            p1 += rri->remap_to_host_size;
+            str = TSUrlHostGet(rri->requestBufp, rri->mapToUrl, &len);
             break;
           case SUB_PORT:
-            p1 += snprintf(p1, 6, "%u", rri->remap_from_port);
+            p1 += snprintf(p1, 6, "%u", req_url->port);
             break;
           case SUB_SCHEME:
-            memcpy(p1, rri->from_scheme, rri->from_scheme_len);
-            p1 += rri->from_scheme_len;
+            str = req_url->scheme;
+            len = req_url->scheme_len;
             break;
           case SUB_PATH:
-            memcpy(p1, rri->request_path, rri->request_path_size);
-            p1 += rri->request_path_size;
+            str = req_url->path;
+            len = req_url->path_len;
             break;
           case SUB_QUERY:
-            memcpy(p1, rri->request_query, rri->request_query_size);
-            p1 += rri->request_query_size;
+            str = req_url->query;
+            len = req_url->query_len;
             break;
-          case SUB_COOKIE:
-            memcpy(p1, rri->request_cookie, rri->request_cookie_size);
-            p1 += rri->request_cookie_size;
+          case SUB_MATRIX:
+            str = req_url->matrix;
+            len = req_url->matrix_len;
             break;
           case SUB_CLIENT_IP:
             {
-              unsigned char *ip = (unsigned char*)&rri->client_ip;
-
-              p1 += snprintf(p1, 15, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+              // TODO: Finish implementing with the addr from above
+              // p1 += snprintf(p1, 15, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
             }
             break;
           default:
             break;
           }
+          // If one of the rules fetched a read-only string, copy it in.
+          if (str && len > 0) {
+            memcpy(p1, str, len);
+            p1 += len;
+          }
         }
         p2 += (_sub_pos[i] - prev + 2);
         prev = _sub_pos[i] + 2;
@@ -475,7 +470,7 @@ class RemapRegex
 
   inline bool is_simple() const { return _simple; }
 
-  inline INKHttpStatus status_option() const { return _status; };
+  inline TSHttpStatus status_option() const { return _status; };
   inline int active_timeout_option() const  { return _active_timeout; };
   inline int no_activity_timeout_option() const  { return _no_activity_timeout; };
   inline int connect_timeout_option() const  { return _connect_timeout; };
@@ -494,7 +489,7 @@ class RemapRegex
   int _sub_ix[MAX_SUBS];
   RemapRegex* _next;
   int _order;
-  INKHttpStatus _status;
+  TSHttpStatus _status;
   bool _simple;
   int _active_timeout;
   int _no_activity_timeout;
@@ -505,7 +500,7 @@ class RemapRegex
 struct RemapInstance
 {
   RemapInstance() :
-    first(NULL), last(NULL), profile(false), full_url(false), method(false), query_string(true),
+    first(NULL), last(NULL), profile(false), method(false), query_string(true),
     matrix_params(false), hits(0), misses(0),
     filename("unknown")
   { };
@@ -513,7 +508,6 @@ struct RemapInstance
   RemapRegex* first;
   RemapRegex* last;
   bool profile;
-  bool full_url;
   bool method;
   bool query_string;
   bool matrix_params;
@@ -523,62 +517,56 @@ struct RemapInstance
 };
 
 ///////////////////////////////////////////////////////////////////////////////
-// Helpers for memory management (to make sure pcre uses the INK APIs).
+// Helpers for memory management (to make sure pcre uses the TS APIs).
 //
 inline void*
-ink_malloc(size_t s)
+ts_malloc(size_t s)
 {
-  return INKmalloc(s);
+  return TSmalloc(s);
 }
 
 inline void
-ink_free(void *s)
+ts_free(void *s)
 {
-  return INKfree(s);
+  return TSfree(s);
 }
 
 void
 setup_memory_allocation()
 {
-  pcre_malloc = &ink_malloc;
-  pcre_free = &ink_free;
+  pcre_malloc = &ts_malloc;
+  pcre_free = &ts_free;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // Initialize the plugin.
 //
-int
-tsremap_init(TSREMAP_INTERFACE *api_info, char *errbuf, int errbuf_size)
+TSReturnCode
+TSRemapInit(TSRemapInterface* api_info, char *errbuf, int errbuf_size)
 {
   if (!api_info) {
-    strncpy(errbuf, "[tsremap_init] - Invalid TSREMAP_INTERFACE argument", errbuf_size -
1);
-    return -1;
-  }
-
-  if (api_info->size < sizeof(TSREMAP_INTERFACE)) {
-    strncpy(errbuf, "[tsremap_init] - Incorrect size of TSREMAP_INTERFACE structure", errbuf_size
- 1);
-    return -2;
+    strncpy(errbuf, "[tsremap_init] - Invalid TSRemapInterface argument", errbuf_size - 1);
+    return TS_ERROR;
   }
 
   if (api_info->tsremap_version < TSREMAP_VERSION) {
-    snprintf(errbuf, errbuf_size - 1, "[tsremap_init] - Incorrect API version %ld.%ld",
+    snprintf(errbuf, errbuf_size - 1, "[TSRemapInit] - Incorrect API version %ld.%ld",
              api_info->tsremap_version >> 16, (api_info->tsremap_version &
0xffff));
-    return -3;
+    return TS_ERROR;
   }
 
   setup_memory_allocation();
-
-  INKDebug("regex_remap", "plugin is succesfully initialized");
-  return 0;                     /* success */
+  TSDebug("regex_remap", "plugin is succesfully initialized");
+  return TS_SUCCESS;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // We don't have any specific "instances" here, at least not yet.
 //
-int
-tsremap_new_instance(int argc, char *argv[], ihandle *ih, char *errbuf, int errbuf_size)
+TSReturnCode
+TSRemapNewInstance(int argc, char* argv[], void** ih, char* errbuf, int errbuf_size)
 {
   const char* error;
   int erroffset;
@@ -588,10 +576,10 @@ tsremap_new_instance(int argc, char *arg
   int lineno = 0;
   int count = 0;
 
-  *ih = (ihandle)ri;
+  *ih = (void*)ri;
   if (ri == NULL) {
-    INKError("Unable to create remap instance");
-    return -5;
+    TSError("Unable to create remap instance");
+    return TS_ERROR;
   }
 
   // Really simple (e.g. basic) config parser
@@ -600,10 +588,6 @@ tsremap_new_instance(int argc, char *arg
       ri->profile = true;
     } else if (strncmp(argv[i], "no-profile", 10) == 0) {
       ri->profile = false;
-    } else if (strncmp(argv[i], "full-url", 8) == 0) {
-      ri->full_url = true;
-    } else if (strncmp(argv[i], "no-full-url", 11) == 0) {
-      ri->full_url = false;
     } else if (strncmp(argv[i], "method", 6) == 0) {
       ri->method = true;
     } else if (strncmp(argv[i], "no-method", 9) == 0) {
@@ -626,10 +610,10 @@ tsremap_new_instance(int argc, char *arg
 
       f.open((ri->filename).c_str(), std::ios::in);
       if (!f.is_open()) { // Try with the default path instead
-        INKError("unable to open %s", (ri->filename).c_str());
-        return -4;
+        TSError("unable to open %s", (ri->filename).c_str());
+        return TS_ERROR;
       }
-      INKDebug("regex_remap", "loading regular expression maps from %s", (ri->filename).c_str());
+      TSDebug("regex_remap", "loading regular expression maps from %s", (ri->filename).c_str());
 
       while (!f.eof()) {
         std::string line, regex, subst, options;
@@ -666,12 +650,12 @@ tsremap_new_instance(int argc, char *arg
 
         if (regex.empty()) {
           // No regex found on this line
-          INKError("no regexp found in %s: line %d", (ri->filename).c_str(), lineno);
+          TSError("no regexp found in %s: line %d", (ri->filename).c_str(), lineno);
           continue;
         }
         if (subst.empty() && options.empty()) {
           // No substitution found on this line (and no options)
-          INKError("no substitution string found in %s: line %d", (ri->filename).c_str(),
lineno);
+          TSError("no substitution string found in %s: line %d", (ri->filename).c_str(),
lineno);
           continue;
         }
 
@@ -679,15 +663,15 @@ tsremap_new_instance(int argc, char *arg
         RemapRegex* cur = new RemapRegex(regex, subst, options);
 
         if (cur == NULL) {
-          INKError("can't create a new regex remap rule");
+          TSError("can't create a new regex remap rule");
           continue;
         }
 
         if (cur->compile(&error, &erroffset) < 0) {
-          INKError("PCRE failed in %s (line %d) at offset %d: %s\n", (ri->filename).c_str(),
lineno, erroffset, error);
+          TSError("PCRE failed in %s (line %d) at offset %d: %s\n", (ri->filename).c_str(),
lineno, erroffset, error);
           delete(cur);
         } else {
-          INKDebug("regex_remap", "added regex=%s with substitution=%s and options `%s'",
+          TSDebug("regex_remap", "added regex=%s with substitution=%s and options `%s'",
                    regex.c_str(), subst.c_str(), options.c_str());
           cur->set_order(++count);
           if (ri->first == NULL)
@@ -702,25 +686,25 @@ tsremap_new_instance(int argc, char *arg
 
   // Make sure we got something...
   if (ri->first == NULL) {
-    INKError("Got no regular expressions from the maps");
-    return -1;
+    TSError("Got no regular expressions from the maps");
+    return TS_ERROR;
   }
 
-  return 0;
+  return TS_SUCCESS;
 }
 
 
 void
-tsremap_delete_instance(ihandle ih)
+TSRemapDeleteInstance(void* ih)
 {
   RemapInstance* ri = static_cast<RemapInstance*>(ih);
-  RemapRegex* re = ri->first;
+  RemapRegex* re;
   RemapRegex* tmp;
-  int ix = 1;
-  char now[64];
-  time_t tim = time(NULL);
 
   if (ri->profile) {
+    char now[64];
+    time_t tim = time(NULL);
+
     if (ctime_r(&tim, now))
       now[strlen(now) - 1] = '\0';
     else {
@@ -731,19 +715,26 @@ tsremap_delete_instance(ihandle ih)
     fprintf(stderr, "[%s]: Profiling information for regex_remap file `%s':\n", now, (ri->filename).c_str());
     fprintf(stderr, "[%s]:\tTotal hits (matches): %d\n", now, ri->hits);
     fprintf(stderr, "[%s]:\tTotal missed (no regex matches): %d\n", now, ri->misses);
-  }
 
-  if (ri->hits > 0) { // Avoid divide by zeros...
-    while (re) {
-      if (ri->profile)
+    if (ri->hits > 0) { // Avoid divide by zeros...
+      int ix = 1;
+
+      re = ri->first;
+      while (re) {
         re->print(ix, ri->hits, now);
-      tmp = re->next();
-      delete re;
-      re = tmp;
-      ++ix;
+        re = re->next();
+        ++ix;
+      }
     }
   }
 
+  re = ri->first;
+  while (re) {
+    tmp = re;
+    re = re->next();
+    delete tmp;
+  }
+
   delete ri;
 }
 
@@ -751,328 +742,169 @@ tsremap_delete_instance(ihandle ih)
 ///////////////////////////////////////////////////////////////////////////////
 // This is the main "entry" point for the plugin, called for every request.
 //
-int
-tsremap_remap(ihandle ih, rhandle rh, TSRemapRequestInfo *rri)
+TSRemapStatus
+TSRemapDoRemap(void* ih, TSHttpTxn txnp, TSRemapRequestInfo *rri, UrlComponents *req_url)
 {
   if (NULL == ih) {
-    INKDebug("regex_remap", "Falling back to default URL on regex remap without rules");
-    return 0;
+    TSDebug("regex_remap", "Falling back to default URL on regex remap without rules");
+    return TSREMAP_NO_REMAP;
   } else {
     RemapInstance* ri = (RemapInstance*)ih;
     int ovector[OVECCOUNT];
     int lengths[OVECCOUNT/2 + 1];
     int dest_len;
-    int retval = 1;
+    TSRemapStatus retval = TSREMAP_DID_REMAP;
     RemapRegex* re = ri->first;
-    char match_buf[rri->orig_url_size + 16 + 5]; // Worst case scenario and padded for
/,? and ;
+    char match_buf[req_url->url_len + 32]; // Worst case scenario and padded for /,? and
;
     int match_len = 0;
 
     if (ri->method) { // Prepend the URI path or URL with the HTTP method
-      INKMBuffer mBuf;
-      INKMLoc reqHttpHdrLoc;
+      TSMBuffer mBuf;
+      TSMLoc reqHttpHdrLoc;
       const char *method;
 
       // Note that Method can not be longer than 16 bytes, or we'll simply truncate it
-      if (INKHttpTxnClientReqGet(static_cast<INKHttpTxn>(rh), &mBuf, &reqHttpHdrLoc))
{
-        method = INKHttpHdrMethodGet(mBuf, reqHttpHdrLoc, &match_len);
+      if (TS_SUCCESS == TSHttpTxnClientReqGet(static_cast<TSHttpTxn>(txnp), &mBuf,
&reqHttpHdrLoc)) {
+        method = TSHttpHdrMethodGet(mBuf, reqHttpHdrLoc, &match_len);
         if (method && (match_len > 0)) {
           if (match_len > 16)
             match_len = 16;
           memcpy(match_buf, method, match_len);
-          INKHandleStringRelease(mBuf, reqHttpHdrLoc, method);
         }
       }
     }
 
-    if (ri->full_url) { // This ignores all the other match string options
-      memcpy(match_buf + match_len, rri->orig_url, rri->orig_url_size);
-      match_len += rri->orig_url_size;
-    } else {
-      *(match_buf + match_len) = '/';
-      memcpy(match_buf + match_len + 1, rri->request_path, rri->request_path_size);
-      match_len += rri->request_path_size + 1;
-
-      // Todo: This is crazy, but for now, we have to parse the URL to extract (possibly)
the
-      // matrix parameters from the original URL, and append them.
-      // XXX: This can now be fixed in Apache.
-      if (ri->matrix_params) {
-        INKMBuffer bufp = (INKMBuffer)INK_ERROR_PTR;
-        INKMLoc url_loc = (INKMLoc)INK_ERROR_PTR;
-        const char* start = rri->orig_url;
-        const char* params;
-        int params_len;
-
-        bufp = INKMBufferCreate();
-        if (bufp == INK_ERROR_PTR) {
-          INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, (INKHttpStatus)500);
-          INKError("can't create MBuffer");
-          goto param_error;
-        }
+    const char *str;
+    int len;
 
-        url_loc = INKUrlCreate(bufp);
-        if (url_loc == INK_ERROR_PTR) {
-          INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, (INKHttpStatus)500);
-          INKError("can't create URL buffer");
-          goto param_error;
-        }
-
-        if (INKUrlParse(bufp, url_loc, &start, start + rri->orig_url_size) == INK_PARSE_ERROR)
{
-          INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, (INKHttpStatus)500);
-          INKError("can't parse original URL string");
-          goto param_error;
-        }
-
-        params = INKUrlHttpParamsGet(bufp, url_loc, &params_len);
-        if (params && (params_len > 0)) {
-          *(match_buf + match_len) = ';';
-          memcpy(match_buf + match_len + 1 , params, params_len);
-          match_len += (params_len + 1);
-          INKHandleStringRelease(bufp, url_loc, params);
-        }
-
-      param_error:
-        if (url_loc != INK_ERROR_PTR) {
-          INKUrlDestroy(bufp, url_loc);
-          INKHandleMLocRelease(bufp, INK_NULL_MLOC, url_loc);
-        }
-        if (bufp != INK_ERROR_PTR)
-          INKMBufferDestroy(bufp);
-      }
+    *(match_buf + match_len) = '/';
+    str = TSUrlPathGet(rri->requestBufp, rri->requestUrl, &len);
+    if (str && len > 0) {
+      memcpy(match_buf + match_len + 1, str, len);
+      match_len += (len + 1);
+    }
 
-      if (ri->query_string && (rri->request_query_size > 0)) {
-        *(match_buf + match_len) = '?';
-        memcpy(match_buf + match_len + 1 , rri->request_query, rri->request_query_size);
-        match_len += (rri->request_query_size + 1);
-      }
+    str = TSUrlHttpParamsGet(rri->requestBufp, rri->requestUrl, &len);
+    if (str && len > 0) {
+      *(match_buf + match_len) = ';';
+      memcpy(match_buf + match_len + 1 , str, len);
+      match_len += (len + 1);
     }
+
     match_buf[match_len] = '\0'; // NULL terminate the match string
+    TSReleaseAssert(match_len < (req_url->url_len + 32)); // Just in case ...
 
-    INKDebug("regex_remap", "original match string is %s (length %d out of %d)", match_buf,
-             match_len, rri->orig_url_size + 16 + 5);
-    INKReleaseAssert(match_len < (rri->orig_url_size + 16 + 5)); // Just in case ...
+    // Populate the request url
+    UrlComponents req_url;
+    req_url.populate(rri);
 
     // Apply the regular expressions, in order. First one wins.
     while (re) {
       // Since we check substitutions on parse time, we don't need to reset ovector
-      if (re->is_simple() || (re->match(match_buf, match_len, ovector) != (-1))) {
-        int new_len = re->get_lengths(ovector, lengths, rri);
+      if (re->is_simple() || (re->match(match_buf, match_len, ovector) != -1)) {
+        int new_len = re->get_lengths(ovector, lengths, rri, &req_url);
 
         // Set timeouts
         if (re->active_timeout_option() > (-1)) {
-          INKDebug("regex_remap", "Setting active timeout to %d", re->active_timeout_option());
-          INKHttpTxnActiveTimeoutSet((INKHttpTxn)rh, re->active_timeout_option());
+          TSDebug("regex_remap", "Setting active timeout to %d", re->active_timeout_option());
+          TSHttpTxnActiveTimeoutSet(txnp, re->active_timeout_option());
         }
         if (re->no_activity_timeout_option() > (-1)) {
-          INKDebug("regex_remap", "Setting no activity timeout to %d", re->no_activity_timeout_option());
-          INKHttpTxnNoActivityTimeoutSet((INKHttpTxn)rh, re->no_activity_timeout_option());
+          TSDebug("regex_remap", "Setting no activity timeout to %d", re->no_activity_timeout_option());
+          TSHttpTxnNoActivityTimeoutSet(txnp, re->no_activity_timeout_option());
         }
         if (re->connect_timeout_option() > (-1)) {
-          INKDebug("regex_remap", "Setting connect timeout to %d", re->connect_timeout_option());
-          INKHttpTxnConnectTimeoutSet((INKHttpTxn)rh, re->connect_timeout_option());
+          TSDebug("regex_remap", "Setting connect timeout to %d", re->connect_timeout_option());
+          TSHttpTxnConnectTimeoutSet(txnp, re->connect_timeout_option());
         }
         if (re->dns_timeout_option() > (-1)) {
-          INKDebug("regex_remap", "Setting DNS timeout to %d", re->dns_timeout_option());
-          INKHttpTxnDNSTimeoutSet((INKHttpTxn)rh, re->dns_timeout_option());
+          TSDebug("regex_remap", "Setting DNS timeout to %d", re->dns_timeout_option());
+          TSHttpTxnDNSTimeoutSet(txnp, re->dns_timeout_option());
         }
 
         // Update profiling if requested
         if (ri->profile) {
           re->increment();
-          ink_atomic_increment(&(ri->hits), 1);
+          atomic_increment(&(ri->hits), 1);
         }
 
         if (new_len > 0) {
           char dest[new_len+8];
+          struct sockaddr const* addr = TSHttpTxnClientAddrGet(txnp);
 
-          dest_len = re->substitute(dest, match_buf, ovector, lengths, rri);
+          dest_len = re->substitute(dest, match_buf, ovector, lengths, rri, &req_url,
addr);
 
-          INKDebug("regex_remap", "New URL is estimated to be %d bytes long, or less\n",
new_len);
-          INKDebug("regex_remap", "New URL is %s (length %d)", dest, dest_len);
-          INKDebug("regex_remap", "    matched rule %d [%s]", re->order(), re->regex());
+          TSDebug("regex_remap", "New URL is estimated to be %d bytes long, or less\n", new_len);
+          TSDebug("regex_remap", "New URL is %s (length %d)", dest, dest_len);
+          TSDebug("regex_remap", "    matched rule %d [%s]", re->order(), re->regex());
 
           // Check for a quick response, if the status option is set
+// ToDo: Figure out how we make redirects now from a remap plugin ...
+#if 0
           if (re->status_option() > 0) {
-            INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, re->status_option());
-            if ((re->status_option() == (INKHttpStatus)301) || (re->status_option()
== (INKHttpStatus)302)) {
+            TSHttpTxnSetHttpRetStatus(txnp, re->status_option());
+            if ((re->status_option() == (TSHttpStatus)301) || (re->status_option()
== (TSHttpStatus)302)) {
               if (dest_len > TSREMAP_RRI_MAX_REDIRECT_URL) {
-                INKError("Redirect in target URL too long");
-                INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, INK_HTTP_STATUS_REQUEST_URI_TOO_LONG);
+                TSError("Redirect in target URL too long");
+                TSHttpTxnSetHttpRetStatus(txnp, TS_HTTP_STATUS_REQUEST_URI_TOO_LONG);
               } else {
                 memcpy(rri->redirect_url, dest, dest_len);
                 rri->redirect_url_size = dest_len;
               }
             }
-            return 1;
+            return TSREMAP_DID_REMAP;
           }
+#endif
 
           if (dest_len > 0) {
-            INKMBuffer bufp = (INKMBuffer)INK_ERROR_PTR;
-            INKMLoc url_loc = (INKMLoc)INK_ERROR_PTR;
-            const char *temp;
+            TSMBuffer bufp = NULL;
+            TSMLoc url_loc = NULL;
             const char *start = dest;
-            int len, port;
-
-            bufp = INKMBufferCreate();
-            if (bufp == INK_ERROR_PTR) {
-              INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, (INKHttpStatus)500);
-              INKError("can't create MBuffer");
-              goto error;
-            }
-
-            url_loc = INKUrlCreate(bufp);
-            if (url_loc == INK_ERROR_PTR) {
-              INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, (INKHttpStatus)500);
-              INKError("can't create URL buffer");
-              goto error;
-            }
 
-            if (INKUrlParse(bufp, url_loc, &start, start + dest_len) == INK_PARSE_ERROR)
{
-              INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, (INKHttpStatus)500);
-              INKError("can't parse substituted URL string");
+            if ((bufp = TSMBufferCreate())) {
+              TSHttpTxnSetHttpRetStatus(txnp, (TSHttpStatus)500);
+              TSError("can't create MBuffer");
               goto error;
             }
 
-            // Update the Host (if necessary)
-            temp = INKUrlHostGet(bufp, url_loc, &len);
-            if (len > TSREMAP_RRI_MAX_HOST_SIZE) {
-              INKError("Host in target URL too long");
-              INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, INK_HTTP_STATUS_REQUEST_URI_TOO_LONG);
-              INKHandleStringRelease(bufp, url_loc, temp);
+            if (TS_SUCCESS != TSUrlCreate(bufp, &url_loc)) {
+              TSHttpTxnSetHttpRetStatus(txnp, (TSHttpStatus)500);
+              TSError("can't create URL buffer");
               goto error;
-            } else {
-              if (temp && (len > 0) && ((len != rri->remap_to_host_size)
|| strncmp(temp, rri->remap_to_host, len))) {
-                INKDebug("regex_remap", "new host string: %s (len = %d)", temp, len);
-                memcpy(rri->new_host, temp, len);
-                rri->new_host_size = len;
-                INKHandleStringRelease(bufp, url_loc, temp);
-              }
             }
 
-            // Update the Path (if necessary)
-            // ToDo: Should we maybe compare with rri->remap_to_path + rri->request_path
?
-            temp = INKUrlPathGet(bufp, url_loc, &len);
-            if (len > TSREMAP_RRI_MAX_PATH_SIZE) {
-              INKError("Path in target URL too long");
-              INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, INK_HTTP_STATUS_REQUEST_URI_TOO_LONG);
-              INKHandleStringRelease(bufp, url_loc, temp);
+            if (TS_PARSE_ERROR == TSUrlParse(bufp, url_loc, &start, start + dest_len))
{
+              TSHttpTxnSetHttpRetStatus(txnp, (TSHttpStatus)500);
+              TSError("can't parse substituted URL string");
               goto error;
-            } else {
-              if (!temp || (len <= 0)) {
-                if (rri->request_path_size > 0) {
-                  rri->new_path_size = -1;
-                  INKDebug("regex_remap", "new path is empty");
-                }
-              } else {
-                if (*temp == '/') {
-                  ++temp;
-                  --len;
-                }
-                // ToDo: This is an ugly hack, since we must "modify" the path for the parameter
hack
-                // to function :/.
-                if ((len != rri->request_path_size) || strncmp(temp, rri->request_path,
len)) {
-                  INKDebug("regex_remap", "new path string: %s (len = %d)", temp, len);
-                }
-                memcpy(rri->new_path, temp, len);
-                rri->new_path_size = len;
-                INKHandleStringRelease(bufp, url_loc, temp);
-              }
-            }
-
-            // Update the matrix parameters (if necessary). TODO: This is very hacky right
now,
-            // instead of appending to the new_path, we really ought to set the matrix parameters
-            // using a proper API (which is not supported at this point). This only works
if
-            // there is a path as well.
-            if (rri->new_path_size != (-1)) {
-              temp = INKUrlHttpParamsGet(bufp, url_loc, &len);
-              if (len >= (TSREMAP_RRI_MAX_PATH_SIZE - rri->new_path_size - 3)) {
-                INKError("Matrix parameters in target URL too long");
-                INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, INK_HTTP_STATUS_REQUEST_URI_TOO_LONG);
-                INKHandleStringRelease(bufp, url_loc, temp);
-                goto error;
-              } else {
-                if (temp && (len > 0)) {
-                  *(rri->new_path + rri->new_path_size) = ';';
-                  memcpy(rri->new_path + rri->new_path_size + 1, temp, len);
-                  rri->new_path_size += (len + 1);
-                  INKHandleStringRelease(bufp, url_loc, temp);
-                  INKDebug("regex_remap", "appending matrix parameters: %.*s", len, temp);
-                  INKDebug("regex_remap", "new path string: %.*s", rri->new_path_size,
rri->new_path);
-                }
-              }
             }
 
-            // Update the Query string (if necessary)
-            temp = INKUrlHttpQueryGet(bufp, url_loc, &len);
-            if (len > TSREMAP_RRI_MAX_PATH_SIZE) {
-              INKError("Query in target URL too long");
-              INKHttpTxnSetHttpRetStatus((INKHttpTxn)rh, INK_HTTP_STATUS_REQUEST_URI_TOO_LONG);
-              INKHandleStringRelease(bufp, url_loc, temp);
-              goto error;
-            } else {
-              if (!temp || (len <= 0)) {
-                if (rri->request_query_size > 0) {
-                  *(rri->new_query) = 0;
-                  rri->new_query_size = -1; // Delete it
-                  INKDebug("regex_remap", "new query is empty");
-                }
-              } else {
-                if (*temp == '?') {
-                  ++temp;
-                  --len;
-                }
-                if ((len != rri->request_query_size) || strncmp(temp, rri->request_query,
len)) {
-                  INKDebug("regex_remap", "new query string: %s (len = %d)", temp, len);
-                  memcpy(rri->new_query, temp, len);
-                  rri->new_query_size = len;
-                }
-                INKHandleStringRelease(bufp, url_loc, temp);
-              }
-            }
-
-            // Update the port number (if necessary)
-            port = INKUrlPortGet(bufp, url_loc);
-            if (port != rri->remap_to_port) {
-              INKDebug("regex_remap", "new port: %d", port);
-              rri->new_port = port;
-            }
-
-            // Update the scheme (HTTP or HTTPS)
-            temp = INKUrlSchemeGet(bufp, url_loc, &len);
-            if (temp && (len > 0) && (len != rri->to_scheme_len)) {
-              if (!strncmp(temp, INK_URL_SCHEME_HTTPS, INK_URL_LEN_HTTPS)) {
-                rri->require_ssl = 1;
-                INKDebug("regex_remap", "changing scheme to HTTPS");
-              } else {
-                rri->require_ssl = 0;
-                INKDebug("regex_remap", "changing scheme to HTTP");
-              }
-              INKHandleStringRelease(bufp, url_loc, temp);
-            }
+            // TODO: Copy the new URL to request URL
 
             // Cleanup
           error:
-            if (url_loc != INK_ERROR_PTR) {
-              INKUrlDestroy(bufp, url_loc);
-              INKHandleMLocRelease(bufp, INK_NULL_MLOC, url_loc);
+            if (url_loc) {
+              TSUrlDestroy(bufp, url_loc);
+              TSHandleMLocRelease(bufp, TS_NULL_MLOC, url_loc);
             }
-            if (bufp != INK_ERROR_PTR)
-              INKMBufferDestroy(bufp);
+            if (bufp)
+              TSMBufferDestroy(bufp);
           }
           break; // We're done
         }
       }
       re = re->next();
       if (re == NULL) {
-        retval = 0; // No match
+        retval = TSREMAP_NO_REMAP; // No match
         if (ri->profile)
-          ink_atomic_increment(&(ri->misses), 1);
+          atomic_increment(&(ri->misses), 1);
       }
     }
     return retval;
   }
 
   // This shouldn't happen, but just in case
-  return 0;
+  return TSREMAP_NO_REMAP;
 }
 
 



Mime
View raw message