trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bri...@apache.org
Subject [01/17] git commit: Hide query parameters access log
Date Wed, 18 Jun 2014 23:51:27 GMT
Repository: trafficserver
Updated Branches:
  refs/heads/4.2.x a0f821eb6 -> 940489d7a
  refs/heads/master eab97f120 -> 5207ad03f


Hide query parameters access log


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

Branch: refs/heads/4.2.x
Commit: 9fdb7f3437bdffa65ddddc4744917695cdb926d2
Parents: a0f821e
Author: Brian Geffon <briang@apache.org>
Authored: Tue Jun 10 11:13:23 2014 -0700
Committer: Brian Geffon <briang@apache.org>
Committed: Tue Jun 10 15:55:19 2014 -0700

----------------------------------------------------------------------
 mgmt/RecordsConfig.cc                    |   2 +
 proxy/config/records.config.default.in   |   9 ++
 proxy/logging/LogConfig.cc               |  18 ++++
 proxy/logging/LogConfig.h                |   8 ++
 proxy/logging/LogUtils.cc                |  82 ++++++++++-----
 proxy/logging/Makefile.am                |  11 +-
 proxy/logging/QueryParamsEscaper.cc      |  81 ++++++++++++++
 proxy/logging/QueryParamsEscaper.h       |  53 ++++++++++
 proxy/logging/test_QueryParamsEscaper.cc | 146 ++++++++++++++++++++++++++
 9 files changed, 383 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index db8c531..18095f0 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -1184,6 +1184,8 @@ RecordElement RecordsConfig[] = {
   ,
   {RECT_CONFIG, "proxy.config.log.search_log_filters", RECD_STRING, NULL, RECU_DYNAMIC, RR_NULL,
RECC_NULL, NULL, RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.log.hide_query_parameters", RECD_STRING, NULL, RECU_RESTART_TS,
RR_NULL, RECC_NULL, NULL, RECA_NULL}
+  ,
   // End    HCL Modifications.
 
   //##############################################################################

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/proxy/config/records.config.default.in
----------------------------------------------------------------------
diff --git a/proxy/config/records.config.default.in b/proxy/config/records.config.default.in
index 91b0969..ae69faa 100644
--- a/proxy/config/records.config.default.in
+++ b/proxy/config/records.config.default.in
@@ -467,6 +467,15 @@ CONFIG proxy.config.log.auto_delete_rolled_files INT 1
 CONFIG proxy.config.log.sampling_frequency INT 1
 ##############################################################################
 #
+# This config can be used to hide values of certain query parameters. This 
+# config is specified as a space-separated list of substrings. Any query 
+# containing a specified substring will have it's value filled with asterisks.
+# Example: "login password"
+#
+##############################################################################
+CONFIG proxy.config.log.hide_query_parameters STRING NULL
+##############################################################################
+#
 # Reverse Proxy
 #
 ##############################################################################

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/proxy/logging/LogConfig.cc
----------------------------------------------------------------------
diff --git a/proxy/logging/LogConfig.cc b/proxy/logging/LogConfig.cc
index 6b381ce..78a9e26 100644
--- a/proxy/logging/LogConfig.cc
+++ b/proxy/logging/LogConfig.cc
@@ -66,6 +66,9 @@
 
 #define PARTITION_HEADROOM_MB 	10
 
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+
 void
 LogConfig::setup_default_values()
 {
@@ -511,6 +514,18 @@ LogConfig::read_configuration_variables()
   if (val > 0) {
     search_rolling_interval_sec = val;
   }
+
+  ptr = REC_ConfigReadString("proxy.config.log.hide_query_parameters");
+  if (ptr != NULL) {
+    std::vector<std::string> raw_params;
+    std::string paramsStr(ptr);
+    boost::split(raw_params, paramsStr, boost::is_any_of(" "));
+    for (size_t i = 0; i < raw_params.size(); ++i) {
+      if (raw_params[i].size()) {
+        query_parameters_to_hide.push_back(raw_params[i]);
+      }
+    }
+  }
 }
 
 /*-------------------------------------------------------------------------
@@ -1273,6 +1288,9 @@ LogConfig::register_stat_callbacks()
   RecRegisterRawStat(log_rsb, RECT_PROCESS,
                      "proxy.process.log.log_files_space_used",
                      RECD_INT, RECP_NON_PERSISTENT, (int) log_stat_log_files_space_used_stat,
RecRawStatSyncSum);
+  RecRegisterRawStat(log_rsb, RECT_PROCESS,
+                     "proxy.process.log.params_masked_url_count",
+                     RECD_COUNTER, RECP_PERSISTENT, (int) log_stat_params_masked_url_count,
RecRawStatSyncCount);
 }
 
 /*-------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/proxy/logging/LogConfig.h
----------------------------------------------------------------------
diff --git a/proxy/logging/LogConfig.h b/proxy/logging/LogConfig.h
index ab1cb40..b452577 100644
--- a/proxy/logging/LogConfig.h
+++ b/proxy/logging/LogConfig.h
@@ -26,6 +26,9 @@
 #ifndef LOG_CONFIG_H
 #define LOG_CONFIG_H
 
+#include <string>
+#include <vector>
+
 #include "libts.h"
 #include "P_RecProcess.h"
 #include "ProxyConfig.h"
@@ -69,6 +72,7 @@ enum
   log_stat_log_files_open_stat,
   log_stat_log_files_space_used_stat,
 
+  log_stat_params_masked_url_count,
   log_stat_count
 };
 
@@ -250,6 +254,9 @@ public:
   char *xml_config_file;
   char *hosts_config_file;
 
+  const std::vector<std::string> &get_query_parameters_to_hide() const {
+    return query_parameters_to_hide;
+  }
 private:
 
   void read_xml_log_config(int from_memory);
@@ -286,6 +293,7 @@ private:
   // -- member functions not allowed --
   LogConfig(const LogConfig &);
   LogConfig & operator=(const LogConfig &);
+  std::vector<std::string> query_parameters_to_hide;
 };
 
 /*-------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/proxy/logging/LogUtils.cc
----------------------------------------------------------------------
diff --git a/proxy/logging/LogUtils.cc b/proxy/logging/LogUtils.cc
index 8d42258..ef356e9 100644
--- a/proxy/logging/LogUtils.cc
+++ b/proxy/logging/LogUtils.cc
@@ -49,6 +49,11 @@
 
 #include "LogUtils.h"
 #include "LogLimits.h"
+#include "LogFormat.h"
+#include "LogObject.h"
+#include "LogConfig.h"
+#include "Log.h"
+#include "QueryParamsEscaper.h"
 
 
 /*-------------------------------------------------------------------------
@@ -305,8 +310,9 @@ LogUtils::escapify_url(Arena *arena, char *url, size_t len_in, int *len_out,
cha
     return NULL;
   }
 
-  if (!map)
+  if (!map) {
     map = codes_to_escape;
+  }
 
   // Count specials in the url, assuming that there won't be any.
   //
@@ -322,25 +328,39 @@ LogUtils::escapify_url(Arena *arena, char *url, size_t len_in, int *len_out,
cha
     ++p;
   }
 
+  QueryParamsEscaper params_escaper(Log::config->get_query_parameters_to_hide());
+
   if (!count) {
     // The common case, no escapes, so just return the source string.
-    //
     *len_out = len_in;
-    if (dst)
-      ink_strlcpy(dst, url, dst_size);
+    bool params_escaping_required = params_escaper.is_escaping_required_for_url(url, len_in);
+    if (params_escaping_required && !dst) {
+      dst = (char *) arena->str_alloc(len_in);
+    }
+    if (dst) {
+      memcpy(dst, url, len_in);
+      if (params_escaping_required) {
+        params_escaper.escape_url(dst);
+        RecIncrRawStat(log_rsb, this_ethread(), (int) log_stat_params_masked_url_count, 1);
+        url = dst;
+      }
+    }
     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.
-  //
-  // make sure we take into account the characters we are substituting
-  // for when we calculate out_len !!! in other words,
-  // out_len = len_in + 3*count - count
-  //
-  size_t out_len = len_in + 2 * count;
+  size_t out_len = len_in; // default
+  if (count) {
+    // For each special char found, we'll need an escape string, which is
+    // three characters long.  Count this and allocate the string required.
+    //
+    // make sure we take into account the characters we are substituting
+    // for when we calculate out_len !!! in other words,
+    // out_len = len_in + 3*count - count
+    //
+    out_len = len_in + 2 * count;
+  }
 
-  if (dst && out_len > dst_size) {
+  if (dst && (dst_size < out_len + 1)) {
     *len_out = 0;
     return NULL;
   }
@@ -356,23 +376,33 @@ LogUtils::escapify_url(Arena *arena, char *url, size_t len_in, int *len_out,
cha
   else
     new_url = (char *) arena->str_alloc(out_len + 1);
 
-  char *from = url;
-  char *to = new_url;
-
-  while (from < in_url_end) {
-    unsigned char c = *from;
-    if (map[c / 8] & (1 << (7 - c % 8))) {
-      *to++ = '%';
-      *to++ = hex_digit[c / 16];
-      *to++ = hex_digit[c % 16];
-    } else {
-      *to++ = *from;
+  if (count) {
+    char *from = url;
+    char *to = new_url;
+    
+    while (from < in_url_end) {
+      register unsigned char c = *from;
+      if (map[c / 8] & (1 << (7 - c % 8))) {
+        *to++ = '%';
+        *to++ = hex_digit[c / 16];
+        *to++ = hex_digit[c % 16];
+      } else {
+        *to++ = *from;
+      }
+      from++;
     }
-    from++;
+  } else {
+    memcpy(new_url, url, len_in);
   }
-  *to = '\0';                      // null terminate string
 
+  new_url[out_len] = '\0';                      // null terminate string
   *len_out = out_len;
+
+  if (params_escaper.is_escaping_required_for_url(new_url, out_len)) {
+    params_escaper.escape_url(new_url);
+    RecIncrRawStat(log_rsb, this_ethread(), (int) log_stat_params_masked_url_count, 1);
+  }
+
   return new_url;
 }
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/proxy/logging/Makefile.am
----------------------------------------------------------------------
diff --git a/proxy/logging/Makefile.am b/proxy/logging/Makefile.am
index 6014bb4..e94a66a 100644
--- a/proxy/logging/Makefile.am
+++ b/proxy/logging/Makefile.am
@@ -16,6 +16,9 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
+check_PROGRAMS = test_QueryParamsEscaper
+TESTS = $(check_PROGRAMS)
+
 AM_CPPFLAGS = \
   $(iocore_include_dirs) \
   -I$(top_srcdir)/lib \
@@ -70,7 +73,9 @@ liblogging_a_SOURCES = \
   LogSock.cc \
   LogSock.h \
   LogUtils.cc \
-  LogUtils.h
+  LogUtils.h \
+  QueryParamsEscaper.h \
+  QueryParamsEscaper.cc
 
 liblogcollation_a_SOURCES = \
   LogCollationAccept.cc \
@@ -84,3 +89,7 @@ liblogcollation_a_SOURCES = \
 #test_UNUSED_SOURCES = \
 #  LogAccessTest.cc \
 #  LogAccessTest.h
+
+test_QueryParamsEscaper_SOURCES = test_QueryParamsEscaper.cc
+test_QueryParamsEscaper_LDADD = liblogging.a
+test_QueryParamsEscaper_LDFLAGS = @EXTRA_CXX_LDFLAGS@ @LIBTOOL_LINK_FLAGS@

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/proxy/logging/QueryParamsEscaper.cc
----------------------------------------------------------------------
diff --git a/proxy/logging/QueryParamsEscaper.cc b/proxy/logging/QueryParamsEscaper.cc
new file mode 100644
index 0000000..9aabe9b
--- /dev/null
+++ b/proxy/logging/QueryParamsEscaper.cc
@@ -0,0 +1,81 @@
+/** @file
+
+ This file contains a set of utility routines that are used throughout the
+ logging implementation.
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#include "QueryParamsEscaper.h"
+
+using std::list;
+using std::string;
+using std::vector;
+
+bool QueryParamsEscaper::is_escaping_required_for_url(const char *url, size_t url_len)
+{
+  if (!_num_targets) {
+    return false;
+  }
+  size_t start;
+  for (start = 0; (start < url_len) && (url[start] != '?'); ++start); // find
start of query
+  if (start == url_len) { // no query
+    return false;
+  }
+  ++start;
+  string param_name;
+  bool save_value_range = false;
+  for (size_t i = start; i < url_len; ++i) {
+    if (url[i] == '=') {
+      if (i - start) {
+        param_name.assign(url + start /* start */, i - start /* num bytes */);
+        for (size_t j = 0; j < _num_targets; ++j) {
+          if (param_name.find(_targets[j]) != string::npos) {
+            save_value_range = true;
+            break; // no need to check for other targets
+          }
+        }
+      }
+      start = i + 1;
+    }
+    else if ((url[i] == '&') || (i == url_len - 1) || (url[i] == '#')) { // end of query/value
+      if (save_value_range) {
+        size_t end = (url[i] == '&') || (url[i] == '#') ? i - 1 : i;
+        if (end >= start) {
+          _ranges_to_escape.push_back(IndexRange(start, end));
+        }
+        save_value_range = false;
+      }
+      start = i + 1;
+      if (url[i] == '#') {
+        break;
+      }
+    }
+  }
+  return !_ranges_to_escape.empty();
+}
+
+void QueryParamsEscaper::escape_url(char *mutable_url)
+{
+  for (list<IndexRange>::iterator iter = _ranges_to_escape.begin(); iter != _ranges_to_escape.end();
++iter) {
+    for (size_t i = iter->first; i <= iter->second; ++i) {
+      mutable_url[i] = '*';
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/proxy/logging/QueryParamsEscaper.h
----------------------------------------------------------------------
diff --git a/proxy/logging/QueryParamsEscaper.h b/proxy/logging/QueryParamsEscaper.h
new file mode 100644
index 0000000..d7fb602
--- /dev/null
+++ b/proxy/logging/QueryParamsEscaper.h
@@ -0,0 +1,53 @@
+/** @file
+
+ This file contains a set of utility routines that are used throughout the
+ logging implementation.
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+#ifndef TS_PROXY_LOGGING_QUERY_PARAMS_ESCAPER
+
+#define TS_PROXY_LOGGING_QUERY_PARAMS_ESCAPER
+
+#include <list>
+#include <string>
+#include <vector>
+
+class QueryParamsEscaper
+{
+public:
+  QueryParamsEscaper(const std::vector<std::string> &params_to_hide)
+    : _targets(params_to_hide), _num_targets(_targets.size()) { };
+  bool is_escaping_required_for_url(const char *immutable_url, size_t url_len);
+
+  // arg should point to mutable version of url tested previously via
+  // is_escaping_required_for_url()
+  void escape_url(char *mutable_url);
+
+  // resets state about URL currently being worked on
+  void reset() { _ranges_to_escape.clear(); }
+private:
+  const std::vector<std::string> &_targets;
+  const size_t _num_targets;
+  typedef std::pair<size_t, size_t> IndexRange;
+  std::list<IndexRange> _ranges_to_escape;
+};
+
+#endif

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9fdb7f34/proxy/logging/test_QueryParamsEscaper.cc
----------------------------------------------------------------------
diff --git a/proxy/logging/test_QueryParamsEscaper.cc b/proxy/logging/test_QueryParamsEscaper.cc
new file mode 100644
index 0000000..db38084
--- /dev/null
+++ b/proxy/logging/test_QueryParamsEscaper.cc
@@ -0,0 +1,146 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+/*
+  QueryParamsEscaper(const std::vector<std::string> &params_to_hide)
+    : _targets(params_to_hide), _num_targets(_targets.size()) { };
+  bool is_escaping_required_for_url(const char *immutable_url, size_t url_len);
+
+  // arg should point to mutable version of url tested previously via
+  // is_escaping_required_for_url()
+  void escape_url(char *mutable_url);
+*/
+
+#include "QueryParamsEscaper.h"
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+using std::list;
+using std::string;
+using std::vector;
+
+int
+main(int argc, const char *argv[])
+{
+  {
+    vector<string> params_to_hide;
+    QueryParamsEscaper escaper(params_to_hide); // no params
+    char url[] = { "http://server/path?login=blah&password=blah123" };
+    assert(!escaper.is_escaping_required_for_url(url, sizeof(url) - 1));
+    assert(!escaper.is_escaping_required_for_url(url, 0));
+    assert(!escaper.is_escaping_required_for_url(0, 0));
+  }
+
+  {
+    vector<string> params_to_hide;
+    params_to_hide.push_back("login");
+    QueryParamsEscaper escaper(params_to_hide);
+    char url1[] = { "http://server/path?login=blah&password=blah123" };
+    assert(escaper.is_escaping_required_for_url(url1, sizeof(url1) - 1));
+    escaper.escape_url(url1);
+    assert(strcmp(url1, "http://server/path?login=****&password=blah123") == 0);
+    assert(!escaper.is_escaping_required_for_url(url1, 0));
+    assert(!escaper.is_escaping_required_for_url(0, 0));
+    escaper.reset();
+    char url2[] = { "http://server/path?blah=login&password=blah123" }; // login is param
value, not name
+    assert(!escaper.is_escaping_required_for_url(url2, sizeof(url2) - 1));
+    escaper.reset();
+    char url3[] = { "http://server/login=blahpath?foo=bar" }; // login= is not a param, but
part of path
+    assert(!escaper.is_escaping_required_for_url(url3, sizeof(url3) - 1));
+    escaper.reset();
+    char url4[] = { "http://login=blahserver/path?foo=bar" }; // login= is not a param, but
part of server name
+    assert(!escaper.is_escaping_required_for_url(url4, sizeof(url4) - 1));
+    escaper.reset();
+    char url5[] = { "http://server/path?foo=bar&login=login1&login=login2&foo2=bar2"
}; // multiple occurences
+    assert(escaper.is_escaping_required_for_url(url5, sizeof(url5) - 1));
+    escaper.escape_url(url5);
+    assert(strcmp(url5, "http://server/path?foo=bar&login=******&login=******&foo2=bar2")
== 0);
+  }
+
+  {
+    vector<string> params_to_hide;
+    params_to_hide.push_back("login");
+    params_to_hide.push_back("password"); // multiple params to hide
+    QueryParamsEscaper escaper(params_to_hide);
+    char url1[] = { "http://server/path?login=blah&password=blah123" };
+    assert(escaper.is_escaping_required_for_url(url1, sizeof(url1) - 1));
+    escaper.escape_url(url1);
+    assert(strcmp(url1, "http://server/path?login=****&password=*******") == 0);
+    assert(!escaper.is_escaping_required_for_url(url1, 0));
+    assert(!escaper.is_escaping_required_for_url(0, 0));
+    escaper.reset();
+    char url2[] = { "http://server/path?login=blah&password=blah123&login=blah&password=blah123"
};
+    assert(escaper.is_escaping_required_for_url(url2, sizeof(url2) - 1));
+    escaper.escape_url(url2);
+    assert(strcmp(url2, "http://server/path?login=****&password=*******&login=****&password=*******")
== 0);
+    escaper.reset();
+    char url3[] = { "http://server/path?login=blah&password=&login=blah&password="
}; // empty values
+    assert(escaper.is_escaping_required_for_url(url3, sizeof(url3) - 1));
+    escaper.escape_url(url3);
+    assert(strcmp(url3, "http://server/path?login=****&password=&login=****&password=")
== 0);
+    escaper.reset();
+
+    // sub string test
+    char url4[] = { "http://server/path?user_login=blah&new_password=123&login=test&old_password=456"
};
+    assert(escaper.is_escaping_required_for_url(url4, sizeof(url4) - 1));
+    escaper.escape_url(url4);
+    assert(strcmp(url4, "http://server/path?user_login=****&new_password=***&login=****&old_password=***")
== 0);
+
+    escaper.reset();
+    char url5[] = { "http://127.0.0.1:12175/uas/js/userspace?v=0.0.2000-RC1.24082-1337&apiKey=consumer_key_7&"
};
+    assert(!escaper.is_escaping_required_for_url(url5, sizeof(url5) - 1));
+
+    escaper.reset();
+    char url6[] = { "http://127.0.0.1:12175/uas/js/userspace?v=0.0.2000-RC1.24082-1337&password=consumer_key_7&"
};
+    assert(escaper.is_escaping_required_for_url(url6, sizeof(url6) - 1));
+    escaper.escape_url(url6);
+    assert(
+      strcmp(url6,
+             "http://127.0.0.1:12175/uas/js/userspace?v=0.0.2000-RC1.24082-1337&password=**************&")
== 0);
+
+    escaper.reset();
+    char url7[] = { "http://127.0.0.1:12175/uas/js/userspace?v=0.0.2000-RC1.24082-1337&apiKey=consumer_key_7#"
};
+    assert(!escaper.is_escaping_required_for_url(url7, sizeof(url7) - 1));
+
+    escaper.reset();
+    char url8[] = { "http://127.0.0.1:12175/uas/js/userspace?v=0.0.2000-RC1.24082-1337&password="
};
+    assert(!escaper.is_escaping_required_for_url(url8, sizeof(url8) - 1));
+
+    escaper.reset();
+    char url9[] = { "http://127.0.0.1:12175/uas/js/js?login=0.0.2000-RC1.24082-1337&password="
};
+    assert(escaper.is_escaping_required_for_url(url9, sizeof(url9) - 1));
+    escaper.escape_url(url9);
+    assert(strcmp(url9, "http://127.0.0.1:12175/uas/js/js?login=***********************&password=")
== 0);
+
+    escaper.reset();
+    char url10[] = { "http://127.0.0.1/path?=b&=c&=d" };
+    assert(!escaper.is_escaping_required_for_url(url10, sizeof(url10) - 1));
+
+    escaper.reset();
+    char url11[] = { ".?a=b&c=d" };
+    url11[0] = '\0';
+    assert(!escaper.is_escaping_required_for_url(url11, sizeof(url11) - 1));
+  }
+  return 0;
+}


Mime
View raw message