trafficserver git commit: TS-3701 - Crash in trampoline cleanup

2015-10-06 Thread shinrich
Repository: trafficserver
Updated Branches:
  refs/heads/master b3fab3619 -> 185956208


TS-3701 - Crash in trampoline cleanup


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

Branch: refs/heads/master
Commit: 1859562086b330eed6eda637f5f98a3431db5915
Parents: b3fab36
Author: shinrich 
Authored: Tue Oct 6 14:28:25 2015 -0500
Committer: shinrich 
Committed: Tue Oct 6 14:28:25 2015 -0500

--
 iocore/net/SSLNextProtocolAccept.cc | 4 
 1 file changed, 4 insertions(+)
--


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/18595620/iocore/net/SSLNextProtocolAccept.cc
--
diff --git a/iocore/net/SSLNextProtocolAccept.cc 
b/iocore/net/SSLNextProtocolAccept.cc
index c4748c3..df467f4 100644
--- a/iocore/net/SSLNextProtocolAccept.cc
+++ b/iocore/net/SSLNextProtocolAccept.cc
@@ -85,6 +85,8 @@ struct SSLNextProtocolTrampoline : public Continuation {
 case VC_EVENT_ERROR:
 case VC_EVENT_ACTIVE_TIMEOUT:
 case VC_EVENT_INACTIVITY_TIMEOUT:
+  // Cancel the read before we have a chance to delete the continuation
+  netvc->do_io_read(NULL, 0, NULL);
   netvc->do_io(VIO::CLOSE);
   delete this;
   return EVENT_ERROR;
@@ -94,6 +96,8 @@ struct SSLNextProtocolTrampoline : public Continuation {
   return EVENT_ERROR;
 }
 
+// Cancel the read before we have a chance to delete the continuation
+netvc->do_io_read(NULL, 0, NULL);
 plugin = netvc->endpoint();
 if (plugin) {
   send_plugin_event(plugin, NET_EVENT_ACCEPT, netvc);



trafficserver git commit: TS-3984 - Missing NULL checks in HttpSM::handler_server_setup_error.

2015-10-06 Thread shinrich
Repository: trafficserver
Updated Branches:
  refs/heads/master b975cb24b -> b3fab3619


TS-3984 - Missing NULL checks in HttpSM::handler_server_setup_error.


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

Branch: refs/heads/master
Commit: b3fab36196dc143283364b56b0db802e4dd81bad
Parents: b975cb2
Author: shinrich 
Authored: Tue Oct 6 14:00:44 2015 -0500
Committer: shinrich 
Committed: Tue Oct 6 14:00:44 2015 -0500

--
 proxy/http/HttpSM.cc | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b3fab361/proxy/http/HttpSM.cc
--
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 2889ef3..02b4ff3 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -5217,18 +5217,24 @@ HttpSM::handle_server_setup_error(int event, void *data)
   c = tunnel.get_consumer(post_transform_info.vc);
   // c->handler_state = HTTP_SM_TRANSFORM_FAIL;
 
-  HttpTunnelProducer *ua_producer = c->producer;
-  ink_assert(ua_entry->vc == ua_producer->vc);
+  // No point in proceeding if there is no consumer
+  // Do we need to do additional clean up in the c == NULL case?
+  if (c != NULL) {
+HttpTunnelProducer *ua_producer = c->producer;
+ink_assert(ua_entry->vc == ua_producer->vc);
 
-  ua_entry->vc_handler = &HttpSM::state_watch_for_client_abort;
-  ua_entry->read_vio = ua_producer->vc->do_io_read(this, INT64_MAX, 
c->producer->read_buffer);
-  ua_producer->vc->do_io_shutdown(IO_SHUTDOWN_READ);
+ua_entry->vc_handler = &HttpSM::state_watch_for_client_abort;
+ua_entry->read_vio = ua_producer->vc->do_io_read(this, INT64_MAX, 
c->producer->read_buffer);
+ua_producer->vc->do_io_shutdown(IO_SHUTDOWN_READ);
 
-  ua_producer->alive = false;
-  ua_producer->handler_state = HTTP_SM_POST_SERVER_FAIL;
-  tunnel.handleEvent(VC_EVENT_ERROR, c->write_vio);
+ua_producer->alive = false;
+ua_producer->handler_state = HTTP_SM_POST_SERVER_FAIL;
+tunnel.handleEvent(VC_EVENT_ERROR, c->write_vio);
+  }
 } else {
-  tunnel.handleEvent(event, c->write_vio);
+  // c could be null here as well
+  if (c != NULL)
+tunnel.handleEvent(event, c->write_vio);
 }
 return;
   } else {



trafficserver git commit: TS-3957 - Core dump for SpdyClientSession::state_session_start

2015-10-06 Thread shinrich
Repository: trafficserver
Updated Branches:
  refs/heads/master e71350b4b -> b975cb24b


TS-3957 - Core dump for SpdyClientSession::state_session_start


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

Branch: refs/heads/master
Commit: b975cb24b818102429c1849da04d31f8cb1cc9dc
Parents: e71350b
Author: shinrich 
Authored: Tue Oct 6 13:36:06 2015 -0500
Committer: shinrich 
Committed: Tue Oct 6 13:36:06 2015 -0500

--
 proxy/spdy/SpdyClientSession.cc | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)
--


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b975cb24/proxy/spdy/SpdyClientSession.cc
--
diff --git a/proxy/spdy/SpdyClientSession.cc b/proxy/spdy/SpdyClientSession.cc
index 91070ae..a54da43 100644
--- a/proxy/spdy/SpdyClientSession.cc
+++ b/proxy/spdy/SpdyClientSession.cc
@@ -198,7 +198,14 @@ SpdyClientSession::new_connection(NetVConnection *new_vc, 
MIOBuffer *iobuf, IOBu
   sm->resp_buffer = reinterpret_cast(new_empty_MIOBuffer());
   sm->resp_reader = TSIOBufferReaderAlloc(sm->resp_buffer);
 
-  eventProcessor.schedule_imm(sm, ET_NET);
+  // Block on the mutex.  We just allocated the object, so the lock should be 
available.
+  EThread *thread(this_ethread());
+  MUTEX_TAKE_LOCK(sm->mutex, thread);
+  // Call state_session_start directly rather than scheduling the event
+  // and leaving a half-setup session around.  It seems like there are some
+  // degenerate cases when event re-ordering causes problems (TS-3957)
+  sm->state_session_start(ET_NET, NULL);
+  MUTEX_UNTAKE_LOCK(sm->mutex, thread);
 }
 
 int



trafficserver git commit: Resolve coverity #1325735, #1325734, #1325736

2015-10-06 Thread briang
Repository: trafficserver
Updated Branches:
  refs/heads/master 61cbc5b95 -> e71350b4b


Resolve coverity #1325735, #1325734, #1325736


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

Branch: refs/heads/master
Commit: e71350b4b9c8abc3a81432c203accca03ed172e1
Parents: 61cbc5b
Author: Brian Geffon 
Authored: Tue Oct 6 06:43:58 2015 -0700
Committer: Brian Geffon 
Committed: Tue Oct 6 06:49:31 2015 -0700

--
 plugins/header_rewrite/header_rewrite_test.cc | 2 ++
 plugins/header_rewrite/parser.cc  | 3 ---
 2 files changed, 2 insertions(+), 3 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/e71350b4/plugins/header_rewrite/header_rewrite_test.cc
--
diff --git a/plugins/header_rewrite/header_rewrite_test.cc 
b/plugins/header_rewrite/header_rewrite_test.cc
index 4c836e4..ff78beb 100644
--- a/plugins/header_rewrite/header_rewrite_test.cc
+++ b/plugins/header_rewrite/header_rewrite_test.cc
@@ -37,6 +37,7 @@ TSError(const char *fmt, ...)
   if ((bytes = vsnprintf(buf, sizeof(buf), fmt, args)) > 0) {
 fprintf(stderr, "TSError: %s: %.*s\n", PLUGIN_NAME, bytes, buf);
   }
+  va_end(args);
 }
 
 extern "C" void
@@ -49,6 +50,7 @@ TSDebug(const char *tag, const char *fmt, ...)
   if ((bytes = vsnprintf(buf, sizeof(buf), fmt, args)) > 0) {
 fprintf(stdout, "TSDebug: %s: %.*s\n", PLUGIN_NAME, bytes, buf);
   }
+  va_end(args);
 }
 
 #define CHECK_EQ(x, y)   \

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/e71350b4/plugins/header_rewrite/parser.cc
--
diff --git a/plugins/header_rewrite/parser.cc b/plugins/header_rewrite/parser.cc
index 43ead4a..609b5be 100644
--- a/plugins/header_rewrite/parser.cc
+++ b/plugins/header_rewrite/parser.cc
@@ -69,9 +69,6 @@ Parser::Parser(const std::string &line) : _cond(false), 
_empty(false)
 return;
   }
 } else if (!extracting_token) {
-  if (inquote)
-continue; /* just keep eating until we hit the closing quote */
-
   if (_tokens.empty() && line[i] == '#') {
 // this is a comment line (it may have had leading whitespace before 
the #)
 _empty = true;



trafficserver git commit: TS-3956: clang format (sorry zwoop ;/)

2015-10-06 Thread briang
Repository: trafficserver
Updated Branches:
  refs/heads/master 147b9668e -> 61cbc5b95


TS-3956: clang format (sorry zwoop ;/)


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

Branch: refs/heads/master
Commit: 61cbc5b95a2d0ebbb1247d10628115112eac8827
Parents: 147b966
Author: Brian Geffon 
Authored: Tue Oct 6 00:24:52 2015 -0700
Committer: Brian Geffon 
Committed: Tue Oct 6 00:24:52 2015 -0700

--
 plugins/header_rewrite/header_rewrite_test.cc | 59 +-
 plugins/header_rewrite/parser.cc  |  9 ++--
 2 files changed, 38 insertions(+), 30 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/61cbc5b9/plugins/header_rewrite/header_rewrite_test.cc
--
diff --git a/plugins/header_rewrite/header_rewrite_test.cc 
b/plugins/header_rewrite/header_rewrite_test.cc
index f4fdabd..4c836e4 100644
--- a/plugins/header_rewrite/header_rewrite_test.cc
+++ b/plugins/header_rewrite/header_rewrite_test.cc
@@ -27,45 +27,53 @@
 const char PLUGIN_NAME[] = "TEST_header_rewrite";
 const char PLUGIN_NAME_DBG[] = "TEST_dbg_header_rewrite";
 
-extern "C" void TSError(const char* fmt, ...) {
+extern "C" void
+TSError(const char *fmt, ...)
+{
   char buf[2048];
   int bytes = 0;
   va_list args;
-  va_start (args, fmt);
-  if((bytes = vsnprintf (buf, sizeof(buf), fmt, args)) > 0) {
+  va_start(args, fmt);
+  if ((bytes = vsnprintf(buf, sizeof(buf), fmt, args)) > 0) {
 fprintf(stderr, "TSError: %s: %.*s\n", PLUGIN_NAME, bytes, buf);
   }
 }
 
-extern "C" void TSDebug(const char *tag, const char* fmt, ...) {
+extern "C" void
+TSDebug(const char *tag, const char *fmt, ...)
+{
   char buf[2048];
   int bytes = 0;
   va_list args;
-  va_start (args, fmt);
-  if((bytes = vsnprintf (buf, sizeof(buf), fmt, args)) > 0) {
+  va_start(args, fmt);
+  if ((bytes = vsnprintf(buf, sizeof(buf), fmt, args)) > 0) {
 fprintf(stdout, "TSDebug: %s: %.*s\n", PLUGIN_NAME, bytes, buf);
   }
 }
 
-#define CHECK_EQ(x, y) \
-  do { \
-   if ( (x) != (y) ) { \
-fprintf(stderr, "CHECK FAILED\n"); \
-return 1; \
-   } \
+#define CHECK_EQ(x, y)   \
+  do {   \
+if ((x) != (y)) {\
+  fprintf(stderr, "CHECK FAILED\n"); \
+  return 1;  \
+}\
   } while (false);
 
-class ParserTest : public Parser {
+class ParserTest : public Parser
+{
 public:
-  ParserTest(std::string line) : Parser(line) { }
+  ParserTest(std::string line) : Parser(line) {}
 
-  std::vector getTokens() {
+  std::vector
+  getTokens()
+  {
 return _tokens;
   }
 };
 
-int test_parsing() {
-
+int
+test_parsing()
+{
   {
 ParserTest p("cond  %{READ_REQUEST_HDR_HOOK}");
 CHECK_EQ(p.getTokens().size(), 2);
@@ -177,8 +185,9 @@ int test_parsing() {
   return 0;
 }
 
-int test_processing() {
-
+int
+test_processing()
+{
   /*
* These tests are designed to verify that the processing of the parsed 
input is correct.
*/
@@ -210,16 +219,18 @@ int test_processing() {
   return 0;
 }
 
-int tests() {
-  if (test_parsing() ||
-  test_processing()) {
+int
+tests()
+{
+  if (test_parsing() || test_processing()) {
 return 1;
   }
 
   return 0;
 }
 
-int main () {
+int
+main()
+{
   return tests();
 }
-

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/61cbc5b9/plugins/header_rewrite/parser.cc
--
diff --git a/plugins/header_rewrite/parser.cc b/plugins/header_rewrite/parser.cc
index e7e32c3..43ead4a 100644
--- a/plugins/header_rewrite/parser.cc
+++ b/plugins/header_rewrite/parser.cc
@@ -36,9 +36,7 @@ Parser::Parser(const std::string &line) : _cond(false), 
_empty(false)
   off_t cur_token_start = 0;
   size_t cur_token_length = 0;
   for (size_t i = 0; i < line.size(); ++i) {
-
-if (!inquote &&
-(std::isspace(line[i]) || (line[i] == '=' || line[i] == '>' || line[i] 
== '<'))) {
+if (!inquote && (std::isspace(line[i]) || (line[i] == '=' || line[i] == 
'>' || line[i] == '<'))) {
   if (extracting_token) {
 cur_token_length = i - cur_token_start;
 
@@ -129,9 +127,8 @@ Parser::preprocess(std::vector tokens)
   std::string s = tokens[0].substr(2, tokens[0].size() - 3);
 
   _op = s;
-  if (tokens.size() > 2
-  && (tokens[1][0] == '=' || tokens[1][0] == '>' || tokens[1][0] == 
'<')) { // cond + (=/) + argument
- _arg = tokens[1] + tokens[2];
+  if (tokens.size() > 2 && (tokens[1][0] == '=' || tokens[1][0] == '>' ||

trafficserver git commit: TS-3956: Header_rewrite applies strange logic with = operator, remove %{} which breaks printf

2015-10-06 Thread briang
Repository: trafficserver
Updated Branches:
  refs/heads/master 8c148c9e8 -> 147b9668e


TS-3956: Header_rewrite applies strange logic with = operator, remove %{} which 
breaks printf


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

Branch: refs/heads/master
Commit: 147b9668eea55354b063ba6f77b48b34b65247c9
Parents: 8c148c9
Author: Brian Geffon 
Authored: Tue Oct 6 00:20:26 2015 -0700
Committer: Brian Geffon 
Committed: Tue Oct 6 00:20:26 2015 -0700

--
 plugins/header_rewrite/header_rewrite_test.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
--


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/147b9668/plugins/header_rewrite/header_rewrite_test.cc
--
diff --git a/plugins/header_rewrite/header_rewrite_test.cc 
b/plugins/header_rewrite/header_rewrite_test.cc
index ebc9e2b..f4fdabd 100644
--- a/plugins/header_rewrite/header_rewrite_test.cc
+++ b/plugins/header_rewrite/header_rewrite_test.cc
@@ -50,7 +50,7 @@ extern "C" void TSDebug(const char *tag, const char* fmt, 
...) {
 #define CHECK_EQ(x, y) \
   do { \
if ( (x) != (y) ) { \
-fprintf(stderr, "CHECK FAILED " #x " != " #y "\n"); \
+fprintf(stderr, "CHECK FAILED\n"); \
 return 1; \
} \
   } while (false);



trafficserver git commit: TS-3956: Header_rewrite applies strange logic with = operator, this closes #300

2015-10-06 Thread briang
Repository: trafficserver
Updated Branches:
  refs/heads/master 370ad860d -> 8c148c9e8


TS-3956: Header_rewrite applies strange logic with = operator, this
closes #300


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

Branch: refs/heads/master
Commit: 8c148c9e885ea28ead4d46f49350256602b84d82
Parents: 370ad86
Author: Brian Geffon 
Authored: Tue Oct 6 00:06:49 2015 -0700
Committer: Brian Geffon 
Committed: Tue Oct 6 00:15:20 2015 -0700

--
 plugins/header_rewrite/Makefile.am|   6 +-
 plugins/header_rewrite/header_rewrite_test.cc | 225 +
 plugins/header_rewrite/parser.cc  | 141 -
 plugins/header_rewrite/parser.h   |   5 +-
 4 files changed, 323 insertions(+), 54 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8c148c9e/plugins/header_rewrite/Makefile.am
--
diff --git a/plugins/header_rewrite/Makefile.am 
b/plugins/header_rewrite/Makefile.am
index 8a1abf6..5a7acd3 100644
--- a/plugins/header_rewrite/Makefile.am
+++ b/plugins/header_rewrite/Makefile.am
@@ -31,5 +31,9 @@ header_rewrite_la_SOURCES = \
   resources.cc \
   ruleset.cc \
   statement.cc
-
+  
 header_rewrite_la_LDFLAGS = $(TS_PLUGIN_LDFLAGS)
+
+bin_PROGRAMS = header_rewrite_test
+header_rewrite_test_SOURCES = parser.cc header_rewrite_test.cc
+header_rewrite_test_CXXFLAGS = $(AM_CXXFLAGS)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/8c148c9e/plugins/header_rewrite/header_rewrite_test.cc
--
diff --git a/plugins/header_rewrite/header_rewrite_test.cc 
b/plugins/header_rewrite/header_rewrite_test.cc
new file mode 100644
index 000..ebc9e2b
--- /dev/null
+++ b/plugins/header_rewrite/header_rewrite_test.cc
@@ -0,0 +1,225 @@
+/*
+  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.
+*/
+
+/*
+ * These are misc unit tests for header rewrite
+ */
+
+#include 
+#include 
+#include 
+
+const char PLUGIN_NAME[] = "TEST_header_rewrite";
+const char PLUGIN_NAME_DBG[] = "TEST_dbg_header_rewrite";
+
+extern "C" void TSError(const char* fmt, ...) {
+  char buf[2048];
+  int bytes = 0;
+  va_list args;
+  va_start (args, fmt);
+  if((bytes = vsnprintf (buf, sizeof(buf), fmt, args)) > 0) {
+fprintf(stderr, "TSError: %s: %.*s\n", PLUGIN_NAME, bytes, buf);
+  }
+}
+
+extern "C" void TSDebug(const char *tag, const char* fmt, ...) {
+  char buf[2048];
+  int bytes = 0;
+  va_list args;
+  va_start (args, fmt);
+  if((bytes = vsnprintf (buf, sizeof(buf), fmt, args)) > 0) {
+fprintf(stdout, "TSDebug: %s: %.*s\n", PLUGIN_NAME, bytes, buf);
+  }
+}
+
+#define CHECK_EQ(x, y) \
+  do { \
+   if ( (x) != (y) ) { \
+fprintf(stderr, "CHECK FAILED " #x " != " #y "\n"); \
+return 1; \
+   } \
+  } while (false);
+
+class ParserTest : public Parser {
+public:
+  ParserTest(std::string line) : Parser(line) { }
+
+  std::vector getTokens() {
+return _tokens;
+  }
+};
+
+int test_parsing() {
+
+  {
+ParserTest p("cond  %{READ_REQUEST_HDR_HOOK}");
+CHECK_EQ(p.getTokens().size(), 2);
+CHECK_EQ(p.getTokens()[0], "cond");
+CHECK_EQ(p.getTokens()[1], "%{READ_REQUEST_HDR_HOOK}");
+  }
+
+  {
+ParserTest p("cond %{CLIENT-HEADER:Host}=a");
+CHECK_EQ(p.getTokens().size(), 4);
+CHECK_EQ(p.getTokens()[0], "cond");
+CHECK_EQ(p.getTokens()[1], "%{CLIENT-HEADER:Host}");
+CHECK_EQ(p.getTokens()[2], "=");
+CHECK_EQ(p.getTokens()[3], "a");
+  }
+
+  {
+ParserTest p(" # COMMENT!");
+CHECK_EQ(p.getTokens().size(), 0);
+CHECK_EQ(p.empty(), true);
+  }
+
+  {
+ParserTest p("# COMMENT");
+CHECK_EQ(p.getTokens().size(), 0);
+CHECK_EQ(p.empty(), true);
+  }
+
+  {
+ParserTest p("cond %{Client-HEADER:Foo} =b");
+CHECK_EQ(p.getTokens().size(), 4);
+CHECK_EQ(p.getTokens()