浏览代码

More http header parser tests

Tatsuhiro Tsujikawa 13 年之前
父节点
当前提交
b00ed1aa30
共有 2 个文件被更改,包括 50 次插入0 次删除
  1. 5 0
      src/HttpHeaderProcessor.cc
  2. 45 0
      test/HttpHeaderProcessorTest.cc

+ 5 - 0
src/HttpHeaderProcessor.cc

@@ -269,6 +269,9 @@ bool HttpHeaderProcessor::parse(const unsigned char* data, size_t length)
       break;
     case PREV_FIELD_NAME:
       if(util::isLws(c)) {
+        if(lastFieldName_.empty()) {
+          throw DL_ABORT_EX("Bad HTTP header: field name starts with LWS");
+        }
         // Evil Multi-line header field
         state_ = FIELD_VALUE;
       } else {
@@ -282,6 +285,8 @@ bool HttpHeaderProcessor::parse(const unsigned char* data, size_t length)
           state_ = HEADERS_COMPLETE;
         } else if(c == '\r') {
           state_ = PREV_EOH;
+        } else if(c == ':') {
+          throw DL_ABORT_EX("Bad HTTP header: field name starts with ':'");
         } else {
           state_ = FIELD_NAME;
           i = getFieldNameToken(lastFieldName_, data, length, i);

+ 45 - 0
test/HttpHeaderProcessorTest.cc

@@ -21,6 +21,7 @@ class HttpHeaderProcessorTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testGetHttpResponseHeader);
   CPPUNIT_TEST(testGetHttpResponseHeader_statusOnly);
   CPPUNIT_TEST(testGetHttpResponseHeader_insufficientStatusLength);
+  CPPUNIT_TEST(testGetHttpResponseHeader_nameStartsWs);
   CPPUNIT_TEST(testBeyondLimit);
   CPPUNIT_TEST(testGetHeaderString);
   CPPUNIT_TEST(testGetHttpRequestHeader);
@@ -35,6 +36,7 @@ public:
   void testGetHttpResponseHeader();
   void testGetHttpResponseHeader_statusOnly();
   void testGetHttpResponseHeader_insufficientStatusLength();
+  void testGetHttpResponseHeader_nameStartsWs();
   void testBeyondLimit();
   void testGetHeaderString();
   void testGetHttpRequestHeader();
@@ -71,6 +73,7 @@ void HttpHeaderProcessorTest::testParse3()
     "  text3\r\n"
     "Duplicate: foo\r\n"
     "Duplicate: bar\r\n"
+    "No-value:\r\n"
     "\r\n";
   CPPUNIT_ASSERT(proc.parse(s));
   SharedHandle<HttpHeader> h = proc.getResult();
@@ -84,6 +87,8 @@ void HttpHeaderProcessorTest::testParse3()
                        h->findAll("duplicate")[0]);
   CPPUNIT_ASSERT_EQUAL(std::string("bar"),
                        h->findAll("duplicate")[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string(""), h->find("no-value"));
+  CPPUNIT_ASSERT(h->defined("no-value"));
 }
 
 void HttpHeaderProcessorTest::testGetLastBytesProcessed()
@@ -172,6 +177,46 @@ void HttpHeaderProcessorTest::testGetHttpResponseHeader_insufficientStatusLength
   }
 }
 
+void HttpHeaderProcessorTest::testGetHttpResponseHeader_nameStartsWs()
+{
+  HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
+
+  std::string hd =
+    "HTTP/1.1 200\r\n"
+    " foo:bar\r\n"
+    "\r\n";
+  try {
+    proc.parse(hd);
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(DlAbortEx& ex) {
+    // Success
+  }
+
+  proc.clear();
+  hd =
+    "HTTP/1.1 200\r\n"
+    ":foo:bar\r\n"
+    "\r\n";
+  try {
+    proc.parse(hd);
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(DlAbortEx& ex) {
+    // Success
+  }
+
+  proc.clear();
+  hd =
+    "HTTP/1.1 200\r\n"
+    ":foo\r\n"
+    "\r\n";
+  try {
+    proc.parse(hd);
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(DlAbortEx& ex) {
+    // Success
+  }
+}
+
 void HttpHeaderProcessorTest::testBeyondLimit()
 {
   HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);