]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #47 in SNORT/snort3 from nhttp17 to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Fri, 25 Sep 2015 11:55:05 +0000 (07:55 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Fri, 25 Sep 2015 11:55:05 +0000 (07:55 -0400)
Squashed commit of the following:

commit fd3a359b9351d82994151148e9d801983f1e0177
Author: Tom Peters <thopeter@cisco.com>
Date:   Wed Sep 23 17:48:32 2015 -0400

    updates

src/service_inspectors/nhttp_inspect/dev_notes.txt
src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc
src/service_inspectors/nhttp_inspect/nhttp_flow_data.h
src/service_inspectors/nhttp_inspect/nhttp_inspect.cc
src/service_inspectors/nhttp_inspect/nhttp_module.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_section.cc
src/service_inspectors/nhttp_inspect/nhttp_stream_splitter.cc
src/service_inspectors/nhttp_inspect/nhttp_test_input.cc
src/service_inspectors/nhttp_inspect/nhttp_test_input.h
src/service_inspectors/nhttp_inspect/nhttp_test_manager.h
src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt [deleted file]

index 5ad2d5b00e4f601171a3b2ef42248cfdc14f4a3e..f8af3f6d608ed7d99467115c2285b417999fcbba 100644 (file)
@@ -77,7 +77,65 @@ for enumerated values in NHI.
 The NHI internal test tool is the NHttpTestInput class. It allows the developer
 to write tests that simulate HTTP messages split into TCP segments at specified
 points. The tests cover all of splitter and inspector and the impact on
-downstream customers such as detection and file processing. A growing set of
-tests is maintained in nhttp_test_msgs.txt. Read the header of that file for
-documentation of how to write tests.
+downstream customers such as detection and file processing.
+
+Test tool usage instructions:
+
+The test input comes from the file nhttp_test_msgs.txt in the current directory. Enter HTTP test
+message text as you want it to be presented to the StreamSplitter.
+
+The easiest way to format is to put a blank line between message sections so that each message
+section is its own "paragraph". Within a paragraph the placement of single new lines does not have
+any effect. Format a paragraph any way you are comfortable. Extra blank lines between paragraphs
+also do not have any effect.
+
+Each paragraph represents a TCP segment. The splitter can be tested by putting multiple sections in
+the same paragraph (splitter must split) or continuing a section in the next paragraph (splitter
+must search and reassemble).
+
+Lines beginning with # are comments. Lines beginning with @ are commands. This does not apply to
+lines in the middle of a paragraph.
+
+Command lines are left justified, lower case, with no whitespace:
+  @break resets HTTP Inspect data structures and begins a new test. Use it liberally to prevent
+     unrelated tests from interfering with each other.
+  @tcpclose simulates a half-duplex TCP close following the next paragraph of data.
+  @request and @response set the message direction. Applies to subsequent paragraphs until changed.
+     The initial direction is always request and the break command resets the direction to request.
+  @fill<decimal number> create a paragraph consisting of <number> octets of auto-fill data
+     ABCDEFGHIJABC ... Primarily useful for chunk testing.
+  @<decimal number> sets the test number and hence the test output file name. Applies to subsequent
+     sections until changed. Don't reuse numbers.
+
+Escape sequences begin with '\'. They may be used within a paragraph or to begin a paragraph.
+  \r - carriage return
+  \n - linefeed
+  \t - tab
+  \\ - backslash
+  \# - #
+  \@ - @
+  \xnn or \Xnn - where nn is a two-digit hexadecimal number. Insert an arbitrary 8-bit number as
+     the next character. a-f and A-F are both acceptable.
+
+Data is separated into segments for presentation to the splitter whenever a paragraph ends (blank
+line).
+
+Whenever a segment contains insufficient data to make up a body, fill data will be generated to
+make up the difference based on the Content-Length field. Specifically, flushing more data than in
+the current segment will trigger filling. The user should include at least one character of body
+data either as part of the previous header segment or at the beginning of a new segment following
+the headers. All data bytes included in the file will be used followed by required fill data in the
+pattern ABC...XYZABC...
+
+The current chunk reassembly algorithm does not flush data beyond the current segment. The fill
+feature does not work with chunked bodies but the fill command can be used.
+
+Fill data will not be provided for a paragraph that is preceded by tcpclose. The body will
+terminate at the end of the paragraph.
+
+This test tool does not implement the feature of being hardened against bad input. If you write a
+badly formatted or improper test case the program may assert or crash. The responsibility is on the
+developer to get it right. Currently that is the best use of resources.
+
+Test input is currently designed for single-threaded operation only.
 
index 1122c1c3872a17ec3361b295bc3493bb097e840f..6d524f8a69f95a553b70ce2a61f3b737aab57b1f 100644 (file)
 using namespace NHttpEnums;
 
 unsigned NHttpFlowData::nhttp_flow_id = 0;
+
+#ifdef REG_TEST
 uint64_t NHttpFlowData::instance_count = 0;
+#endif
 
 NHttpFlowData::NHttpFlowData() : FlowData(nhttp_flow_id)
 {
-    if (!NHttpTestManager::use_test_input() && NHttpTestManager::use_test_output())
+#ifdef REG_TEST
+    if (NHttpTestManager::use_test_output())
     {
         seq_num = ++instance_count;
-        printf("Flow Data construct %" PRIu64 "\n", seq_num);
-        fflush(nullptr);
+        if (!NHttpTestManager::use_test_input())
+        {
+            printf("Flow Data construct %" PRIu64 "\n", seq_num);
+            fflush(nullptr);
+        }
     }
+#endif
 }
 
 NHttpFlowData::~NHttpFlowData()
 {
+#ifdef REG_TEST
     if (!NHttpTestManager::use_test_input() && NHttpTestManager::use_test_output())
     {
         printf("Flow Data destruct %" PRIu64 "\n", seq_num);
         fflush(nullptr);
     }
+#endif
     for (int k=0; k <= 1; k++)
     {
         delete[] section_buffer[k];
index 0aaa8661392828975f0e69b985aba51329feb6c4..a46299254f0f8cff45fa9b0125a8c394f15c169c 100644 (file)
@@ -53,9 +53,6 @@ public:
     friend class NHttpTransaction;
 
 private:
-    static uint64_t instance_count;
-    uint64_t seq_num;
-
     void half_reset(NHttpEnums::SourceId source_id);
 
     // 0 element refers to client request, 1 element refers to server response
@@ -116,6 +113,11 @@ private:
     bool add_to_pipeline(NHttpTransaction* latest);
     NHttpTransaction* take_from_pipeline();
     void delete_pipeline();
+
+#ifdef REG_TEST
+    static uint64_t instance_count;
+    uint64_t seq_num;
+#endif
 };
 
 #endif
index c0b1bbd1695eebd795acf32c8ddd8916e946ca30..44641c8f19a2634c32aa92f5b24c3512ef2f1fc1 100644 (file)
@@ -39,6 +39,7 @@ using namespace NHttpEnums;
 
 NHttpInspect::NHttpInspect(NHttpParaList params_) : params(params_)
 {
+#ifdef REG_TEST
     if (params.test_input)
     {
         NHttpTestManager::activate_test_input();
@@ -47,6 +48,7 @@ NHttpInspect::NHttpInspect(NHttpParaList params_) : params(params_)
     {
         NHttpTestManager::activate_test_output();
     }
+#endif
 }
 
 THREAD_LOCAL uint8_t NHttpInspect::body_buffer[MAX_OCTETS];
@@ -120,7 +122,7 @@ bool NHttpInspect::process(const uint8_t* data, const uint16_t dsize, Flow* cons
             flow, &params);
         break;
     default:
-        assert(0);
+        assert(false);
         if (buf_owner)
         {
             delete[] data;
@@ -132,6 +134,7 @@ bool NHttpInspect::process(const uint8_t* data, const uint16_t dsize, Flow* cons
     latest_section->update_flow();
     latest_section->gen_events();
 
+#ifdef REG_TEST
     if (NHttpTestManager::use_test_output())
     {
         latest_section->print_section(NHttpTestManager::get_output_file());
@@ -143,6 +146,7 @@ bool NHttpInspect::process(const uint8_t* data, const uint16_t dsize, Flow* cons
         }
         fflush(stdout);
     }
+#endif
 
     return latest_section->worth_detection();
 }
index 13ba40d60acf94dc194aced478c228552ba4d00c..0e784464c16fc792d6ebbb5919328b69453519bf 100644 (file)
 
 const Parameter NHttpModule::nhttp_params[] =
 {
-    { "test_input", Parameter::PT_BOOL, nullptr, "false", "read HTTP messages from text file" },
-    { "test_output", Parameter::PT_BOOL, nullptr, "false", "print out HTTP section data" },
     { "request_depth", Parameter::PT_INT, "-1:", "-1",
           "maximum request message body bytes to examine (-1 no limit)" },
     { "response_depth", Parameter::PT_INT, "-1:", "-1",
           "maximum response message body bytes to examine (-1 no limit)" },
+#ifdef REG_TEST
+    { "test_input", Parameter::PT_BOOL, nullptr, "false", "read HTTP messages from text file" },
+    { "test_output", Parameter::PT_BOOL, nullptr, "false", "print out HTTP section data" },
+#endif
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
@@ -40,22 +42,24 @@ bool NHttpModule::begin(const char*, int, SnortConfig*)
 
 bool NHttpModule::set(const char*, Value& val, SnortConfig*)
 {
-    if (val.is("test_input"))
+    if (val.is("request_depth"))
     {
-        params.test_input = val.get_bool();
+        params.request_depth = val.get_long();
     }
-    else if (val.is("test_output"))
+    else if (val.is("response_depth"))
     {
-        params.test_output = val.get_bool();
+        params.response_depth = val.get_long();
     }
-    else if (val.is("request_depth"))
+#ifdef REG_TEST
+    else if (val.is("test_input"))
     {
-        params.request_depth = val.get_long();
+        params.test_input = val.get_bool();
     }
-    else if (val.is("response_depth"))
+    else if (val.is("test_output"))
     {
-        params.response_depth = val.get_long();
+        params.test_output = val.get_bool();
     }
+#endif
     else
     {
         return false;
index ef4e7ea1fcf53b223cb37bfc30a276c1fd40105b..7d294250d6f5915e79e4b0b976712ba1822e65ef 100644 (file)
@@ -145,7 +145,7 @@ const Field& NHttpMsgSection::get_legacy(unsigned buffer_id)
         return (request != nullptr) ? request->get_uri_norm_legacy() : Field::FIELD_NULL;
       }
     default:
-        assert(0);
+        assert(false);
         return Field::FIELD_NULL;
     }
 }
index 668c95c075ade816019ded381f3f241135947785..3dc2a3aa381243b49dbd4c7757babe6975391b83 100644 (file)
@@ -42,14 +42,15 @@ void NHttpStreamSplitter::prepare_flush(NHttpFlowData* session_data, uint32_t* f
     session_data->num_good_chunks[source_id] = num_good_chunks;
     session_data->flush_size[source_id] = num_flushed + octets_seen;
 
-    if (!NHttpTestManager::use_test_input())
-    {
-        *flush_offset = num_flushed;
-    }
-    else
+#ifdef REG_TEST
+    if (NHttpTestManager::use_test_input())
     {
         NHttpTestManager::get_test_input_source()->flush(num_flushed);
     }
+    else
+#endif
+
+    *flush_offset = num_flushed;
 }
 
 NHttpCutter* NHttpStreamSplitter::get_cutter(SectionType type,
@@ -64,7 +65,7 @@ NHttpCutter* NHttpStreamSplitter::get_cutter(SectionType type,
     case SEC_BODY: return (NHttpCutter*)new NHttpBodyCutter(
         session_data->data_length[source_id]);
     case SEC_CHUNK: return (NHttpCutter*)new NHttpChunkCutter;
-    default: assert(0); return nullptr;
+    default: assert(false); return nullptr;
     }
 }
 
@@ -142,7 +143,7 @@ void NHttpStreamSplitter::chunk_spray(NHttpFlowData* session_data, uint8_t* buff
           }
         case CHUNK_ZEROS:
             // Not a possible state in reassemble(). Here to avoid compiler warning.
-            assert(0);
+            assert(false);
             break;
         }
     }
@@ -165,29 +166,23 @@ StreamSplitter::Status NHttpStreamSplitter::scan(Flow* flow, const uint8_t* data
     }
     assert(session_data != nullptr);
 
+    const SectionType type = session_data->type_expected[source_id];
+
+    if (type == SEC_ABORT)
+        return StreamSplitter::ABORT;
+
+#ifdef REG_TEST
     if (NHttpTestManager::use_test_input())
     {
         // This block substitutes a completely new data buffer supplied by the test tool in place
-        // of the "real" data. It also rewrites the buffer length and TCP close indicator.
+        // of the "real" data. It also rewrites the buffer length.
         *flush_offset = length;
-        bool need_break;
         uint8_t* test_data = nullptr;
-        NHttpTestManager::get_test_input_source()->scan(test_data, length, source_id, need_break);
-        if (need_break)
-        {
-            session_data = new NHttpFlowData;
-            flow->set_application_data(session_data);
-        }
+        NHttpTestManager::get_test_input_source()->scan(test_data, length, source_id,
+            session_data->seq_num);
         if (length == 0)
-        {
             return StreamSplitter::FLUSH;
-        }
         data = test_data;
-        if (session_data->type_expected[source_id] == SEC_ABORT)
-        {
-            session_data = new NHttpFlowData;
-            flow->set_application_data(session_data);
-        }
     }
     else if (NHttpTestManager::use_test_output())
     {
@@ -195,10 +190,9 @@ StreamSplitter::Status NHttpStreamSplitter::scan(Flow* flow, const uint8_t* data
             source_id, length);
         fflush(stdout);
     }
+#endif
 
-    const SectionType type = session_data->type_expected[source_id];
-
-    if ((type == SEC_ABORT) || (session_data->tcp_close[source_id]))
+    if (session_data->tcp_close[source_id])
         return StreamSplitter::ABORT;
 
     NHttpCutter*& cutter = session_data->cutter[source_id];
@@ -222,31 +216,20 @@ StreamSplitter::Status NHttpStreamSplitter::scan(Flow* flow, const uint8_t* data
             session_data->type_expected[source_id] = SEC_ABORT;
             delete cutter;
             cutter = nullptr;
-            if (!NHttpTestManager::use_test_input())
-            {
-                return StreamSplitter::ABORT;
-            }
-            else
-            {
-                NHttpTestManager::get_test_input_source()->discard(length);
-                return StreamSplitter::FLUSH;
-            }
+            return StreamSplitter::ABORT;
         }
         // Incomplete headers wait patiently for more data
-        return NHttpTestManager::use_test_input() ? StreamSplitter::FLUSH : StreamSplitter::SEARCH;
+#ifdef REG_TEST
+        if (NHttpTestManager::use_test_input())
+            return StreamSplitter::FLUSH;
+        else
+#endif
+        return StreamSplitter::SEARCH;
     case SCAN_ABORT:
         session_data->type_expected[source_id] = SEC_ABORT;
         delete cutter;
         cutter = nullptr;
-        if (!NHttpTestManager::use_test_input())
-        {
-            return StreamSplitter::ABORT;
-        }
-        else
-        {
-            NHttpTestManager::get_test_input_source()->discard(length);
-            return StreamSplitter::FLUSH;
-        }
+        return StreamSplitter::ABORT;
     case SCAN_DISCARD:
     case SCAN_DISCARD_PIECE:
         prepare_flush(session_data, flush_offset, SEC_DISCARD, cutter->get_num_flush(),
@@ -272,7 +255,7 @@ StreamSplitter::Status NHttpStreamSplitter::scan(Flow* flow, const uint8_t* data
         return StreamSplitter::FLUSH;
       }
     default:
-        assert(0);
+        assert(false);
         return StreamSplitter::ABORT;
     }
 }
@@ -291,6 +274,7 @@ const StreamBuffer* NHttpStreamSplitter::reassemble(Flow* flow, unsigned total,
         NHttpFlowData::nhttp_flow_id);
     assert(session_data != nullptr);
 
+#ifdef REG_TEST
     if (NHttpTestManager::use_test_output())
     {
         if (NHttpTestManager::use_test_input())
@@ -325,6 +309,7 @@ const StreamBuffer* NHttpStreamSplitter::reassemble(Flow* flow, unsigned total,
             fflush(stdout);
         }
     }
+#endif
 
     if (session_data->section_type[source_id] == SEC__NOTCOMPUTE)
     {   // FIXIT-M In theory this check should not be necessary
@@ -335,11 +320,13 @@ const StreamBuffer* NHttpStreamSplitter::reassemble(Flow* flow, unsigned total,
     // is how scan() handles things we don't need to examine.
     if (session_data->section_type[source_id] == SEC_DISCARD)
     {
+#ifdef REG_TEST
         if (NHttpTestManager::use_test_output())
         {
             fprintf(NHttpTestManager::get_output_file(), "Discarded %u octets\n\n", len);
             fflush(NHttpTestManager::get_output_file());
         }
+#endif
         if (flags & PKT_PDU_TAIL)
         {
             session_data->section_type[source_id] = SEC__NOTCOMPUTE;
@@ -421,12 +408,14 @@ const StreamBuffer* NHttpStreamSplitter::reassemble(Flow* flow, unsigned total,
             nhttp_buf.length = section_length;
             assert((nhttp_buf.length <= MAX_OCTETS) && (nhttp_buf.length != 0));
             buffer = nullptr;
+#ifdef REG_TEST
             if (NHttpTestManager::use_test_output())
             {
                 fprintf(NHttpTestManager::get_output_file(), "Sent to detection %u octets\n\n",
                     nhttp_buf.length);
                 fflush(NHttpTestManager::get_output_file());
             }
+#endif
             return &nhttp_buf;
         }
         my_inspector->clear(session_data, source_id);
@@ -440,12 +429,14 @@ bool NHttpStreamSplitter::finish(Flow* flow)
     NHttpFlowData* session_data = (NHttpFlowData*)flow->get_application_data(
         NHttpFlowData::nhttp_flow_id);
 
+#ifdef REG_TEST
     if (NHttpTestManager::use_test_output() && !NHttpTestManager::use_test_input())
     {
         printf("Finish from flow data %" PRIu64 " direction %d\n",
             session_data ? session_data->seq_num : 0, source_id);
         fflush(stdout);
     }
+#endif
 
     if (session_data == nullptr) // FIXIT-H this should not be necessary
     {
index 63475f625e3e73d716670c6fdcacebc129ed72fb..160fb661a3db09b4abbffa0fae918e07e6bf2a96 100644 (file)
@@ -31,20 +31,40 @@ NHttpTestInput::NHttpTestInput(const char* file_name)
         throw std::runtime_error("Cannot open test input file");
 }
 
-NHttpTestInput::~NHttpTestInput()
+void NHttpTestInput::reset()
 {
-    fclose(test_data_file);
+    flushed = false;
+    last_source_id = SRC_CLIENT;
+    just_flushed = true;
+    tcp_closed = false;
+    flush_octets = 0;
+    previous_offset = 0;
+    end_offset = 0;
+    close_pending = false;
+    close_notified = false;
+    need_break = false;
 }
 
 // Read from the test data file and present to StreamSplitter. In the process we may need to skip
 // comments, execute simple commands, and handle escape sequences. The best way to understand this
 // function is to read the comments at the top of the file of test cases.
-void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id, bool& need_break)
+void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id, uint64_t seq_num)
 {
-    need_break = false;
+    bool skip_to_break = false;
+    if (seq_num != curr_seq_num)
+    {
+        assert(source_id == SRC_CLIENT);
+        curr_seq_num = seq_num;
+        // If we have not yet found the break command we need to skim past everything and not
+        // return any data until we find it.
+        skip_to_break = !need_break;
+        reset();
+    }
+
     // Don't proceed if we have previously flushed data not reassembled yet.
     // Piggyback on traffic moving in the correct direction.
-    if (flushed || (source_id != last_source_id))
+    // Once a break is read we must wait for a new flow.
+    else if (flushed || (source_id != last_source_id) || need_break)
     {
         length = 0;
         return;
@@ -52,21 +72,22 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
 
     if (just_flushed)
     {
-        // StreamSplitter just flushed and it has all been sent by reassemble. There may or may not
-        // be leftover data from the last paragraph that was not flushed.
+        // Beginning of a new test or StreamSplitter just flushed and it has all been sent by
+        // reassemble(). There may or may not be leftover data from the last paragraph that was not
+        // flushed.
         just_flushed = false;
         data = msg_buf;
         // compute the leftover data
-        length = (flush_octets <= end_offset) ? (end_offset - flush_octets) : 0;
+        end_offset = (flush_octets <= end_offset) ? (end_offset - flush_octets) : 0;
         previous_offset = 0;
-        end_offset = length;
-        if (length > 0)
+        if (end_offset > 0)
         {
             // Must present unflushed leftovers to StreamSplitter again. If we don't take this
             // opportunity to left justify our data in the buffer we may "walk" to the right until
             // we run out of buffer space.
-            memmove(msg_buf, msg_buf+flush_octets, length);
+            memmove(msg_buf, msg_buf+flush_octets, end_offset);
             flush_octets = 0;
+            length = end_offset - previous_offset;
             return;
         }
         // If we reach here then StreamSplitter has already flushed all data read so far
@@ -75,7 +96,6 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
     else
     {
         // The data we gave StreamSplitter last time was not flushed
-        length = 0;
         previous_offset = end_offset;
         data = msg_buf + previous_offset;
     }
@@ -114,7 +134,7 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
             {
                 state = PARAGRAPH;
                 ending = false;
-                data[length++] = (uint8_t)new_char;
+                msg_buf[end_offset++] = (uint8_t)new_char;
             }
             break;
         case COMMENT:
@@ -127,13 +147,12 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
             if (new_char == '\n')
             {
                 state = WAITING;
-                // FIXIT-L should not change direction with unflushed data remaining from previous
-                // paragraph. At the minimum need to test for this and assert.
                 if ((command_length == strlen("request")) && !memcmp(command_value, "request",
                     strlen("request")))
                 {
+                    assert(end_offset == 0);
                     last_source_id = SRC_CLIENT;
-                    if (source_id != last_source_id)
+                    if (!skip_to_break)
                     {
                         length = 0;
                         return;
@@ -142,8 +161,9 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
                 else if ((command_length == strlen("response")) && !memcmp(command_value,
                     "response", strlen("response")))
                 {
+                    assert(end_offset == 0);
                     last_source_id = SRC_SERVER;
-                    if (source_id != last_source_id)
+                    if (!skip_to_break)
                     {
                         length = 0;
                         return;
@@ -152,10 +172,11 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
                 else if ((command_length == strlen("break")) && !memcmp(command_value, "break",
                     strlen("break")))
                 {
-                    // Data leftover from previous test? Trash it.
-                    previous_offset = 0;
-                    data = msg_buf;
-                    need_break = true;
+                    reset();
+                    if (!skip_to_break)
+                        need_break = true;
+                    length = 0;
+                    return;
                 }
                 else if ((command_length == strlen("tcpclose")) && !memcmp(command_value,
                     "tcpclose", strlen("tcpclose")))
@@ -177,10 +198,15 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
                     for (int k = 0; k < amount; k++)
                     {
                         // auto-fill ABCDEFGHIJABCD ...
-                        data[length++] = 'A' + k%10;
+                        msg_buf[end_offset++] = 'A' + k%10;
+                    }
+                    if (skip_to_break)
+                        end_offset = 0;
+                    else
+                    {
+                        length = end_offset - previous_offset;
+                        return;
                     }
-                    end_offset = previous_offset + length;
-                    return;
                 }
                 else if (command_length > 0)
                 {
@@ -202,7 +228,7 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
                     else
                     {
                         // Bad command in test file
-                        assert(0);
+                        assert(false);
                     }
                 }
             }
@@ -214,7 +240,7 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
                 }
                 else
                 {
-                    assert(0);
+                    assert(false);
                 }
             }
             break;
@@ -226,32 +252,41 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
             }
             else if (new_char == '\n')
             {
-                if (ending)
+                if (!ending)
+                {
+                    ending = true;
+                }
+                // Found the second consecutive blank line that ends the paragraph.
+                else if (skip_to_break)
+                {
+                    end_offset = 0;
+                    ending = false;
+                    state = WAITING;
+                }
+                else
                 {
-                    // Found the second consecutive blank line that ends the paragraph.
-                    end_offset = previous_offset + length;
+                    length = end_offset - previous_offset;
                     return;
                 }
-                ending = true;
             }
             else
             {
                 ending = false;
-                data[length++] = (uint8_t)new_char;
+                msg_buf[end_offset++] = (uint8_t)new_char;
             }
             break;
         case ESCAPE:
             switch (new_char)
             {
-            case 'n':  state = PARAGRAPH; data[length++] = '\n'; break;
-            case 'r':  state = PARAGRAPH; data[length++] = '\r'; break;
-            case 't':  state = PARAGRAPH; data[length++] = '\t'; break;
-            case '#':  state = PARAGRAPH; data[length++] = '#';  break;
-            case '@':  state = PARAGRAPH; data[length++] = '@';  break;
-            case '\\': state = PARAGRAPH; data[length++] = '\\'; break;
+            case 'n':  state = PARAGRAPH; msg_buf[end_offset++] = '\n'; break;
+            case 'r':  state = PARAGRAPH; msg_buf[end_offset++] = '\r'; break;
+            case 't':  state = PARAGRAPH; msg_buf[end_offset++] = '\t'; break;
+            case '#':  state = PARAGRAPH; msg_buf[end_offset++] = '#';  break;
+            case '@':  state = PARAGRAPH; msg_buf[end_offset++] = '@';  break;
+            case '\\': state = PARAGRAPH; msg_buf[end_offset++] = '\\'; break;
             case 'x':
             case 'X':  state = HEXVAL; hex_val = 0; num_digits = 0; break;
-            default:   assert(0); state = PARAGRAPH; break;
+            default:   assert(false); state = PARAGRAPH; break;
             }
             break;
         case HEXVAL:
@@ -262,19 +297,22 @@ void NHttpTestInput::scan(uint8_t*& data, uint32_t& length, SourceId source_id,
             else if ((new_char >= 'A') && (new_char <= 'F'))
                 hex_val = hex_val * 16 + 10 + (new_char - 'A');
             else
-                assert(0);
+                assert(false);
             if (++num_digits == 2)
             {
-                data[length++] = hex_val;
+                msg_buf[end_offset++] = hex_val;
                 state = PARAGRAPH;
             }
             break;
         }
         // Don't allow a buffer overrun.
-        assert(previous_offset + length < sizeof(msg_buf));
+        assert(end_offset < sizeof(msg_buf));
     }
     // End-of-file. Return everything we have so far.
-    end_offset = previous_offset + length;
+    if (skip_to_break)
+        end_offset = 0;
+    length = end_offset - previous_offset;
+    return;
 }
 
 void NHttpTestInput::flush(uint32_t num_octets)
@@ -284,12 +322,6 @@ void NHttpTestInput::flush(uint32_t num_octets)
     flushed = true;
 }
 
-void NHttpTestInput::discard(uint32_t num_octets)
-{
-    flush_octets = previous_offset + num_octets;
-    just_flushed = true;
-}
-
 void NHttpTestInput::reassemble(uint8_t** buffer, unsigned& length, SourceId source_id,
     bool& tcp_close)
 {
@@ -309,7 +341,7 @@ void NHttpTestInput::reassemble(uint8_t** buffer, unsigned& length, SourceId sou
     // 2. exactly equal - process data now and signal the close next time around
     // 3. more than whole buffer - signal the close now and truncate and send next time around
     // 4. there was no flush - signal the close now and send the leftovers next time around
-    if ((tcp_closed) && (flush_octets >= end_offset))
+    if (tcp_closed && (!flushed || (flush_octets >= end_offset)))
     {
         if (close_pending)
         {
@@ -323,8 +355,8 @@ void NHttpTestInput::reassemble(uint8_t** buffer, unsigned& length, SourceId sou
         else if (!flushed)
         {
             // Failure to flush means scan() reached end of paragraph and returned PAF_SEARCH.
-            // Convert remaining data to flush and notify caller about close.
-            flush(end_offset - previous_offset);
+            // Notify caller about close and they will do a zero-length flush().
+            previous_offset = end_offset;
             tcp_close = true;
             close_notified = true;
         }
index be6cbe0878cb8a69b91957f3f556e8dd8880dca3..ce9ff4d1a259a6643cc297821ddecb0b5a76005e 100644 (file)
@@ -29,10 +29,8 @@ class NHttpTestInput
 {
 public:
     NHttpTestInput(const char* fileName);
-    ~NHttpTestInput();
-    void scan(uint8_t*& data, uint32_t& length, NHttpEnums::SourceId source_id, bool& need_break);
+    void scan(uint8_t*& data, uint32_t& length, NHttpEnums::SourceId source_id, uint64_t seq_num);
     void flush(uint32_t num_octets);
-    void discard(uint32_t num_octets);
     void reassemble(uint8_t** buffer, unsigned& length, NHttpEnums::SourceId source_id,
         bool& tcp_close);
 
@@ -40,6 +38,12 @@ private:
     FILE* test_data_file;
     uint8_t msg_buf[2 * NHttpEnums::MAX_OCTETS];
 
+    // break command has been read and we are waiting for a new flow to start
+    bool need_break = false;
+
+    // Sequence number of the flow we are currently piggybacking on
+    uint64_t curr_seq_num = 0;
+
     // data has been flushed and must be sent by reassemble() before more data may be given to
     // scan()
     bool flushed = false;
@@ -56,10 +60,10 @@ private:
     // number of octets that have been flushed and must be sent by reassemble
     uint32_t flush_octets = 0;
 
-    // last character in the buffer previously shown to PAF but not flushed yet
+    // number of characters in the buffer previously shown to PAF but not flushed yet
     uint32_t previous_offset = 0;
 
-    // last read character in the buffer
+    // number of characters in the buffer
     uint32_t end_offset = 0;
 
     // Need to send close with next pass through reassemble()
@@ -67,6 +71,8 @@ private:
 
     // Close notification already provided
     bool close_notified = false;
+
+    void reset();
 };
 
 #endif
index 5e4fd775f4ea998169cc900866ac3b9553aae51c..d7649eaf72fc21e3bdfc06ccc785fc2fa5050e98 100644 (file)
@@ -43,7 +43,6 @@ public:
 
 private:
     NHttpTestManager() = delete;
-    // Test input read from file
 
     static bool test_input;
     static NHttpTestInput* test_input_source;
diff --git a/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt b/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt
deleted file mode 100644 (file)
index d6bbf12..0000000
+++ /dev/null
@@ -1,1491 +0,0 @@
-#
-# Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License Version 2 as
-# published by the Free Software Foundation.  You may not use, modify or
-# distribute this program under any other version of the GNU General
-# Public License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-#
-# nhttp_test_msgs.txt author Tom Peters <thopeter@cisco.com>
-
-# Enter HTTP test message text as you want it to be presented to the StreamSplitter.
-#
-# The easiest way to format is to put a blank line between message sections so that each message section is its own "paragraph". Within a paragraph
-# the placement of single new lines does not have any effect. Format a paragraph any way you are comfortable. Extra blank lines between paragraphs
-# also do not have any effect.
-#
-# Each paragraph represents a TCP segment. The splitter can be tested by putting multiple sections in the same paragraph (splitter must split)
-# or continuing a section in the next paragraph (splitter must search and reassemble).
-#
-# It is not necessary to specify complete body and chunk body sections. Specify at least one octet that will begin the section and the
-# remainder will be autofilled in 16384-octet sections up to the length flushed.
-#
-# Lines beginning with # are comments. Lines beginning with @ are commands. This does not apply to lines in the middle of a paragraph.
-#
-# Command lines are left justified, lower case, with no whitespace:
-#   @break resets HTTP Inspect data structures and begins a new test. Use it liberally to prevent unrelated tests from interfering with each other.
-#   @tcpclose simulates a half-duplex TCP close following the next paragraph of data.
-#   @request and @response set the message direction. Applies to subsequent sections until changed.
-#   @<decimal number> sets the test number and hence the test output file name. Applies to subsequent sections until changed. Don't reuse numbers.
-#
-# Escape sequences begin with '\'. They may be used within a paragraph or to begin a paragraph.
-#   \r - carriage return
-#   \n - linefeed
-#   \t - tab
-#   \\ - backslash
-#   \# - #
-#   \@ - @
-#   \xnn or \Xnn - where nn is a two-digit hexadecimal number. Insert an arbitrary 8-bit number as the next character. a-f and A-F are both acceptable.
-
-# Data is separated into segments for presentation to PAF whenever a paragraph ends (blank line).
-#
-# Whenever a segment contains insufficient data to make up a body or chunk, fill data will be generated to make up the difference based on the
-# Content-Length field or chunk header. Specifically, flushing more data than in the current segment will trigger filling. The user should include at
-# least one character of body/chunk data either as part of the previous header segment or at the beginning of a new segment following the headers.
-# All data bytes included in the file will be used followed by required fill data in the pattern ABC...XYZABC...
-#
-# Fill data will not be provided for a paragraph that is preceded by tcpclose. The body or chunk will terminate at the end of the paragraph.
-#
-# This test tool does not implement the feature of being hardened against bad input. If you write a badly formatted or improper test case the
-# program may assert or crash. The responsibility is on the developer to get it right. Currently that is the best use of resources.
-#
-# Test input is currently designed for single-threaded operation only.
-
-# ***********************************************************************************************
-# Valid response start lines
-@1001
-@break
-@response
-HTTP/1.1 200 OK\r\n\r\n
-
-@1002
-@break
-@response
-HTTP/1.0 315 An example reason phrase with spaces\r\n\r\n
-
-@1003
-@break
-@response
-HTTP/2.0 100 minimum valid status code\r\n\r\n
-
-@1004
-@break
-@response
-HTTP/1.1 599 MAX\r\n\r\n
-
-@1005
-@break
-@response
-HTTP/1.1 502 I'm very long and contain punctuationabcdefghijklmnopqrstuvwxyz!@#$%^&*()-_=+`~![]{}1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghij
-|\\;:'",<.>/?klmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstu vwxyz123 4567890abcdefghijklmnopqrstuvwxyz1234567890abcd
-efghijklmnopqrstuvwxyz1234567890\r\n\r\n
-
-@1006
-@break
-@response
-HTTP/1.0 200 1\r\n\r\n
-
-@1007
-@break
-@response
-HTTP/1.1 301 \r\n\r\n
-
-@1008
-@break
-@response
-HTTP/1.1 560  \r\n\r\n
-
-@1009
-@break
-@response
-HTTP/1.1 111     \r\n\r\n
-
-@1010
-@break
-@response
-HTTP/1.1 234 qwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZ qwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDE{}[]
-FGHIJKLMNOPQRSTUVWXYZ   qwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZ qwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZ qwertyuiopasdfghjklzxcv
-bnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklz
-xcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghj
-klzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdf
-ghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZ,.;'<>:"qwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwe
-rtyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklzxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZ
-\r\n\r\n
-
-@1011
-@break
-@response
- HTTP/1.1 200 OK\r\n\r\n
-
-@1012
-@break
-@response
-   HTTP/1.1 200 OK\r\n\r\n
-
-@1013
-@break
-@response
-\tHTTP/1.1 200 OK\r\n\r\n
-
-# ***********************************************************************************************
-# Invalid response start lines
-
-@2001
-@break
-@response
-HTTP/2.0 099 status-code too small\r\n\r\n
-
-@2002
-@break
-@response
-HTTP/1.1 600 status-code too large\r\n\r\n
-
-@2003
-@break
-@response
-HTTP/1.1 879 x\r\n\r\n
-
-@2004
-@break
-@response
-HTTP/1.1 000 x----------------------------------------------------------s\r\n\r\n
-
-@2005
-@break
-@response
-HTTP/1.1 999 \r\n\r\n
-
-@2006
-@break
-@response
-HTTP/0.9 401  aaa\r\n\r\n
-
-@2007
-@break
-@response
-HTTP/1.2 344 \r\n\r\n
-
-@2008
-@break
-@response
-HTTP/2.1 200 400\r\n\r\n
-
-@2009
-@break
-@response
-HTTP/8.0 500 HTTP/1.1\r\n\r\n
-
-@2010
-@break
-@response
-HTOP/1.1 378 :"<>;'m,.\r\n\r\n
-
-@2011
-@break
-@response
-hTTP/1.1 400 OK\r\n\r\n
-
-@2012
-@break
-@response
-HTT5/1.1 200 OK\r\n\r\n
-
-@2013
-@break
-@response
-H TP/1.1 588 OK\r\n\r\n
-
-@2014
-@break
-@response
-HTTP\\1.1 101 OK\r\n\r\n
-
-@2015
-@break
-@response
-HTTP/1.A 700 OK\r\n\r\n
-
-@2016
-@break
-@response
-HTTP/1.a 303 OK   \r\n\r\n
-
-@2017
-@break
-@response
-HTTP/k.1 400 OK\tok\r\n\r\n
-
-@2018
-@break
-@response
-HTTP/1;0 400 O K\r\n\r\n
-
-@2019
-@break
-@response
-HTTP/1.0 444 O\rK\r\n\r\n
-
-@2020
-@break
-@response
-HTTP/1.1 444 O\n K1234567890\r\n\r\n
-
-@2021
-@break
-@response
-HTTP/1.1 46 status code too short\r\n
-
-@2022
-@break
-@response
-HTTP/1.1 2001 status code too \x31 long\r\n
-
-@2023
-@break
-@response
-HTTP/1.1 +88 bad character in status code I\r\n\r\n
-
-@2024
-@break
-@response
-HTTP/1.1 5E8 bad character in status code\x20II\r\n\r\n
-
-@2025
-@break
-@response
-HTTP/1.1 56a bad character in status code III\r\n\r\n
-
-@2026
-@break
-@response
-HTTP/1.0 401 illegal nontext char\x00acter in reason phrase null\r\n\r\n
-
-@2027
-@break
-@response
-HTTP/1.0 401 illegal nontext character in reason\xFFphrase delete\r\n\r\n
-
-@2028
-@break
-@response
-HTTP/1.0 401 \x08illegal nontext character in reason phrase backspace\r\n\r\n
-
-@2029
-@break
-@response
-HTTP/1.0  310 Excessive white space\r\n\r\n
-
-@2030
-@break
-@response
-HTTP/1.0     310 Excessive white space\r\n\r\n
-
-@2031
-@break
-@response
-HTTP/1.1\t310 Tab instead of space\r\n\r\n
-
-@2032
-@break
-@response
-HTTP/1.0 310\tTab instead of space\r\n\r\n
-
-@2033
-@break
-@response
-HTTP/1.0    \t310 Excessive white space and tab\r\n\r\n
-
-@2034
-@break
-@response
-HTTP/1.0 700 \tTab is in reason phrase\r\n\r\n
-
-@2035
-@break
-@response
-HTTP/1.0\t\t\t310 Excessive white space consisting of tabs\r\n\r\n
-
-# ***********************************************************************************************
-# Valid request start lines
-@3001
-@break
-@request
-MKREDIRECTREF / HTTP/2.0\r\n\r\n
-
-@3002
-@break
-@request
-BIND /1234567890?abcdef HTTP/1.1\r\n\r\n
-
-@3003
-@break
-@request
-GET /test/hi-there.txt HTTP/1.0\r\n\r\n
-
-@3004
-@break
-@request
-GET /URI/Absolute/Path/Example HTTP/1.1\r\n\r\n
-
-@3005
-@break
-@request
-GET /uri/aBSOLUTE/pATH/eXAMPLE?with-query HTTP/1.1\r\n\r\n
-
-@3006
-@break
-@request
-MKWORKSPACE /URI/Absolute/Path/Example#with-fragment HTTP/1.1\r\n\r\n
-
-@3007
-@break
-@request
-BPROPFIND /URI/Absolute/Path/Example?with_QUERY#AndAFragmentToo HTTP/1.1\r\n\r\n
-
-@3008
-@break
-@request
-GET /?with-query HTTP/1.1\r\n\r\n
-
-@3009
-@break
-@request
-ORDERPATCH /#with-fragment HTTP/1.1\r\n\r\n
-
-@3010
-@break
-@request
-UPDATEREDIRECTREF /?with_QUERY#AndAFragmentToo HTTP/1.1\r\n\r\n
-
-@3011
-@break
-@request
-VERYLONGUNKNOWNMETHODTEST /?# HTTP/1.1\r\n\r\n
-
-@3012
-@break
-@request
-LABEL /stuff?# HTTP/1.1\r\n\r\n
-
-@3013
-@break
-@request
-MKCALENDAR /*stufflotsandlotslotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsofstuff?1# HTTP/1.1\r\n\r\n
-
-@3014
-@break
-@request
-VERSION-CONTROL /*stufflotsandlotslotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsofstuff?#A HTTP/1.1\r\n\r\n
-
-@3015
-@break
-@request
-OPTIONS * HTTP/1.1\r\n\r\n
-
-@3016
-@break
-@request
-OPTIONS /*options/may/have?a*resource HTTP/1.1\r\n\r\n
-
-@3017
-@break
-@request
-CONNECT this.is.an.authority.com HTTP/1.1\r\n\r\n
-
-@3018
-@break
-@request
-CONNECT this.is.an.authority.with.a.port.com:8739 HTTP/1.1\r\n\r\n
-
-@3019
-@break
-@request
-GET http://iamahost.com/simple/example/of/a/path/ HTTP/1.1\r\n\r\n
-
-@3020
-@break
-@request
-GET HtTpS://1.2.3.4.5.a:6/abcdef/ghijklmnop/qrstuvwxyz/?thequery?fieldcontinues?until#afragme#arrives#1234 HTTP/1.1\r\n\r\n
-
-@3021
-@break
-@request
- MKREDIRECTREF / HTTP/2.0\r\n\r\n
-
-@3022
-@break
-@request
-\t\t\t\tBIND /1234567890?abcdef HTTP/1.1\r\n\r\n
-
-@3023
-@break
-@request
-GET12345678901234567890123456789012345678901234567890123456789012345678901234567 http://hostname.com/?# HTTP/1.1\r\n\r\n
-
-# ***********************************************************************************************
-# Invalid request start lines
-@4001
-@break
-@request
-GET http://sam\xC6plehost.%3d.com:65535/abcdef//ghijkl\x7F?%21%23%24%25%26%27%28%29%2a%2b%2c%2f%3a%3b%3d%3f%40%5b%5dallgoodescapeshere#1234567890%abaaa HTTP/1.1\r\n\r\n
-
-@4002
-@break
-@request
-GET http://hostname.com:0/abcde/fghijklmn/opqrstuvwxyz?%5D%5d%5B%5b%40%3F%3f%3D%3d%3B%3b%3A%3a%2F%2f%2C%2c%2B%2b%2A%2a%29%28%27%26%25%24%23%21#
-1%5D2%5d3%5B4%5b5%406%3F7%3f8%3D9%3da%3Bb%3bc%3Ad%3ae%2Ff%2fg%2CA%2cB%2BC%2bD%2AE%2aF%29%28%27%26%25%24%23%21 HTTP/1.1\r\n\r\n
-
-@4003
-@break
-@request
-GET HTTP://longLONGlonglonglonglonglonglonglonglonglonglong.host.name.com:1/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/0123456789/
--_.~.._./?# HTTP/1.1\r\n\r\n
-
-@4004
-@break
-@request
-GET HTTPS://host%6Eamewith\xD3impr oper%25.characters.com:123/..?# HTTP/1.1\r\n\r\n
-
-@4005
-@break
-@request
-GET Ftp://%48%6F%53%74%4E%61%4d%2e%63%6F%6D:45678/./123/./456/./7890././.abcdef/ghijklmn///.//./.?# HTTP/1.1\r\n\r\n
-
-@4006
-@break
-@request
-GET a://\xe8hostname.com%25%22\x08:65535/./././././//././/?# HTTP/1.1\r\n\r\n
-
-@4007
-@break
-@request
-GET http\x00://hostname.com:65536/%2e%2f/%2E%2F%2E%2F%2E%2F%2f%2f%2fUVWXYZ__~_/%2E?# HTTP/1.1\r\n\r\n
-
-@4008
-@break
-@request
-GET \xFF://hostname.com:1000000000/..?# HTTP/1.1\r\n\r\n
-
-@4009
-@break
-@request
-GET ht tp://hostname.com/../?# HTTP/1.1\r\n\r\n
-
-@4010
-@break
-@request
-GET http://hostname.com/../../../../%2e%2e/.%2e%2f%2e./../bogus_directory///bogus-subdirectory%2F../../real_directory//
-%54%61%72%67%03%65%74/./?# HTTP/1.1\r\n\r\n
-
-@4011
-@break
-@request
-GET http://hostname.com/1/2/../3//4/..///5/6/..//////////7/8abcdefghijklmnopqrstuvwxyz%25abcdefghijklmnopqrstuvwxyz%3D/
-fa%6be/..?# HTTP/1.1\r\n\r\n
-
-@4012
-@break
-@request
-GET http://hostname.com/1\\2/../3/\\4/..\\//5/6/..///\\\\\\////7/8abcdefghijklmnopqrstuvwxyz%25abcdefghijklmnopqrstuvwxyz%3D\\
-fa%6be\\..?# HTTP/1.1\r\n\r\n
-
-@4013
-@break
-@request
-GET123456789012345678901234567890123456789012345678901234567890123456789012345678 http://hostname.com/?# HTTP/1.1\r\n\r\n
-
-@4014
-@break
-@request
-GE;T http://hostname.com/?# HTTP/1.1\r\n\r\n
-
-@4015
-@break
-@request
-GET\xAA http://hostname.com/?# HTTP/1.1\r\n\r\n
-
-@4016
-@break
-@request
-GET   /white/space/abuse HTTP/1.1\r\n\r\n
-
-@4017
-@break
-@request
-GET /white/space/abuse  HTTP/1.1\r\n\r\n
-
-@4018
-@break
-@request
-GET\t/white/space/abuse HTTP/1.1\r\n\r\n
-
-@4019
-@break
-@request
-GET /white/space/abuse\tHTTP/1.1\r\n\r\n
-
-@4020
-@break
-@request
-GET \t /white/space/abuse HTTP/1.1\r\n\r\n
-
-@4021
-@break
-@request
-GET /white/space/abuse       \tHTTP/1.1\r\n\r\n
-
-# ***********************************************************************************************
-# Valid headers without body
-@5001
-@break
-@request
-GET /test/hi-there.htm HTTP/1.1\r\nAccept: text/*\r\nAccept-Language: en,fr\r\n\r\n
-
-# Base example followed by whitespace variations before and after header field values.
-# Varying whitespace in comma-separated fields.
-@5002
-@break
-@request
-GET / HTTP/1.1\r\nAccept: */*\r\nAccept-Language: en,en-us,de,is\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0\r\n\t(compatible: MSIE 5.5;
- Windows NT 5.0)\r\nHost: www.ft.com\r\nConnection: Keep-Alive\r\n\r\n
-
-@5003
-# Whitespace variations before header values
-@break
-@request
-GET / HTTP/1.1\r\nAccept:*/*\r\nAccept-Language: en, en-us,\tde,    is\r\nAccept-Encoding:\tgzip,deflate\r\nUser-Agent:\t\t\t\t\tMozilla/4.0\r\n (compatible: MSIE 5.5;
- Windows NT 5.0)\r\nHost:\t \t \t   \t\twww.ft.com\r\nConnection:               \t         Keep-Alive\r\n\r\n
-
-@5004
-# Whitespace variations after header values
-@break
-@request
-GET / HTTP/1.1\r\nAccept: */* \r\nAccept-Language: en,\t\ten-us,\t de,\r\n is\t\r\nAccept-Encoding: gzip,\tdeflate         \r\nUser-Agent: Mozilla/4.0\r\n\t \r\n\t(compatible: MSIE 5.5;
- Windows NT 5.0)\t\t\t \t\t\r\nHost: www.ft.com   \t\r\n\t\t\r\nConnection: Keep-Alive \t \t \t\r\n\r\n
-
-@5005
-@break
-@response
-HTTP/2.0 200 OK\r\nContent-type: text/plain\r\nTransfer-Encoding: gzip,identity,compress,deflate,foo,chunked\r\n\r\n
-
-@5006
-@break
-@response
-HTTP/2.0 200 OK\r\nContent-type: text/plain\r\nTransfer-Encoding: gzip, identity, compress, deflate, foo, chunked\r\n\r\n
-
-@5007
-@break
-@response
-HTTP/2.0 200 OK\r\nContent-type: text/plain\r\nTransfer-Encoding: gzip\r\nTransfer-Encoding: identity\r\nTransfer-Encoding: compress\r\nTransfer-Encoding: deflate
-\r\nTransfer-Encoding: foo\r\nTransfer-Encoding: chunked\r\n\r\n
-
-@5008
-@break
-@request
-GET /max/header/request/200/is/ok HTTP/1.1\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-\r\n
-
-# ***********************************************************************************************
-# Invalid headers without body
-@6001
-@break
-@request
-GET /max/header/request/201/is/too/much HTTP/1.1\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\nh1:val\r\nh2:val\r\nh3:val\r\nh4:val\r\nh5:val\r\nh6:val\r\nh7:val\r\nh8:val\r\nh9:val\r\n
-h0:val\r\n\r\n
-
-# ***********************************************************************************************
-# Valid Content-Length and body
-@7001
-@break
-@response
-HTTP/1.1 200 OK\r\nContent-type: \ttext/plain\t\r\nContent-LENGTH: 19\r\n\r\n
-I'm a message body.
-
-@7002
-@break
-@response
-HTTP/1.1 200 OK\r\nContent-type: \ttext/plain\t\r\nContent-LENGTH: 19\r\n\r\n
-12345
-
-@7003
-@break
-@response
-HTTP/1.1 200 OK\r\nContent-type: \ttext/plain\t\r\nContent-LENGTH: 19\r\n\r\n
-
-12345678
-
-@7004
-@break
-@response
-HTTP/1.1 200 OK\r\nContent-type: \ttext/plain\t\r\nContent-LENGTH: 19\r\n\r\n
-
-I'm a message body.
-
-@7005
-@break
-@response
-HTTP/1.1 200 OK\r\n
-Transfer-Encoding: identity\r\n
-CoNtEnT-lEnGtH:16382\r\n
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@7006
-@break
-@request
-POST /body/in/a/request/ HTTP/1.1\r\n
-Content-Length:16383\r\n
-\r\n
-
-*
-
-@7007
-@break
-@request
-POST /body/in/a/request/ HTTP/1.1\r\n
-Content-Length:16384\r\n
-\r\n
-*
-
-@7008
-@break
-@response
-HTTP/1.0 408 barely too big for one section\r\n
-Content-Length:16385\r\n
-\r\n
-
-*
-
-@7009
-@break
-@response
-HTTP/1.1 408 barely too big for two sections\r\n
-Content-Length:32772\r\n
-\r\n
-body-1
-
-body-2
-
-@7010
-@break
-@response
-HTTP/1.1 408 more than eight sections\r\n
-Content-Length:133072\r\n
-\r\n
-
-body-1
-
-body-2
-
-body-3
-
-body-4
-
-body-5
-
-body-6
-
-body-7
-
-body-8
-
-# ***********************************************************************************************
-# Invalid Content-Length
-@8001
-@break
-@response
-HTTP/2.0 200 Illegal zero length\r\nContent-type: \ttext/plain\t\r\nContent-LENGTH: 0\r\n\r\n
-
-@8002
-@break
-@response
-HTTP/1.1 200 Silly gigantic length\r\nContent-type: \ttext/plain\t\r\nContent-LENGTH: 12345678901
-23456789\r\n\r\n
-
-
-# ***********************************************************************************************
-# Valid chunks
-# Remember chunk lengths are required to be specified in hex
-@9001
-@break
-@response
-HTTP/1.1 208 Example with chunks\r\nTransfer-Encoding: chunked\r\n\r\n
-
-64\r\n
-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\r\n
-
-8A\r\n
-
-chunkoflength138
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901\r
-
-\ne6\r\nchunkoflength230
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-01234567890123
-
-\r\n0\r\n
-
-\r\n
-
-@9002
-@break
-@request
-POST /request/with/chunks HTTP/1.1\r\n
-Content-Type:    text/plain\r\n
-Transfer-Encoding: compress\r\n
-Via: 1.1 proxy3.company.com\r\n
-tRaNsFeR-eNcO
-
-dInG: cHuNkEd   \r\n
-Accept: *\r\n
-\r\n
-
-6A\r\n
-chunk1
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-\r\nCE; testing-the-extension-feature\r\n
-chunk2
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-\r\n132;  \r\n
-
-chunk3
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-\r\n196 ;\r\n
-chunk4
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-\r\n1FA  ;\r\n
-
-chunk5
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-\r\n25E\t;sdfgh jk\tl\r\n
-chunk6
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-\r\n2C2;\r\n
-chunk7
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-\r\n00000;chunkextension=3\r\n
-
-date: Sun, 01 Oct 2000 23:25:17 GMT\r\n
-X-madeupdate: Mon, 02 Oct 2000 23:25:17 GMT\r\n
-Accept-Language: en,  de\r\n
-Accept-Language: is\r\n
-\r\n
-
-@9003
-@break
-@response
-HTTP/1.1 200 Example with exactly 16384 octets\r\nTransfer-Encoding: chunked\r\n\r\n
-
-400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n400\r\n
-
-@fill 1024
-\r\n0\r\n\r\n
-
-@9004
-@break
-@response
-HTTP/1.1 200 Example with various features including this illegal character\xAB!?\r\nTransfer-Encoding: identity,chunked\r\n\r\n
-20\r\n1234567890abcdef
-
-fedcba0987654321\r
-
-\n012 ;messy chunk header\r\nxy
-
-1234567890ABCDEF
-
-\r\n10000\r\n
-
-@fill 65536
-
-\r\n00000000000000000; lots: ofzeros\r\nx-madeupheader: 1234\r\n\r\n
-
-# ***********************************************************************************************
-# Invalid chunks
-# @10001
-@break
-@request
-
-
-
-# ***********************************************************************************************
-# Valid trailers
-# @11001
-@break
-@request
-
-
-
-# ***********************************************************************************************
-# Invalid trailers
-# @12001
-@break
-@request
-
-
-
-# ***********************************************************************************************
-# Valid request-response pairs
-@13001
-@break
-@request
-
-GET /basic/request/response/pair/with/large/body/returned HTTP/1.1\r\n
-Host: www.testcase.com\r\n
-\r\n
-
-@response
-
-HTTP/1.1 200 OK\r\n
-Content-Length: 60000\r\n
-\r\n
-body-start
-
-body-start2
-
-body-start3
-
-body-start4
-
-@13002
-@break
-@request
-
-POST /basic/request/response/pair/with/large/bodies/both/ways HTTP/1.1\r\n
-Host: www.testcase.com\r\n
-Content-Length: 50000\r\n
-\r\n
-
-body1-1
-
-body1-2
-
-body1-3
-
-@response
-
-HTTP/1.1 200 OK\r\n
-Content-Length: 60000\r\n
-\r\n
-body2-1
-
-body2-2
-
-body2-3
-
-body2-4
-
-@13003
-@break
-@request
-
-HEAD /basic/request/response/pair/using/HEAD HTTP/1.1\r\n
-Host: www.testcase.com\r\n
-\r\n
-
-@response
-
-HTTP/1.1 200 OK\r\n
-Content-Length: 60000\r\n
-\r\n
-
-HTTP/1.1 400 If we see this HEAD worked\r\n\r\n
-
-@13004
-@break
-@request
-
-GET /basic/request/response/pair/with/chunked/returned HTTP/1.1\r\n
-Host: www.testcase.com\r\n
-\r\n
-
-@response
-
-HTTP/1.1 200 OK\r\n
-Transfer-Encoding: chunked\r\n
-\r\n
-C\r\n
-chunk1-start
-
-\r\n70\r\n
-chunk2-start
-0123456789012345678901234567890123456789012345
-
-678901234567890123456789012345678901234567890123456789
-
-\r\n2C8\r\n
-
-chunk3-start
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-\r
-
-\n
-
-0\r
-
-\n
-date: Mon, 02 Oct 2000 20:25:00 GMT\r\n
-fakeheader: 1234\r\n
-\r\n
-
-
-@13005
-@break
-@request
-
-GET / HTTP/1.0\r\n
-\r\n
-
-@response
-
-HTTP/1.1 200 OK\r\n
-Content-Type: text/plain; charset=iso-8859-1\r\n
-Transfer-Encoding: chunked\r\n
-\r\n
-
-0A\r\nABCDEFGHIJ\r\n
-
-0A\r\n1234567890\r\n
-
-0A\r\nabcdefghij\r\n
-
-0A\r\n9876543210\r\n
-
-0\r\n\r\n
-
-@13006
-@break
-@request
-
-GET /wall/fruitwall_file.txt HTTP/1.1
-
-\r\nHost: www.hektik.org\r\n\r\n
-
-@response
-
-HTTP/1.1 200 OK\r\n
-Date: Fri, 01 Aug 2003 21:22:16 GMT\r\n
-Server: Apache/1.3.27 (Unix) mod_ssl/2.8.12 OpenSSL/0.9.7-beta3 PHP/4.3.0\r\n
-Last-Modified: Fri, 01 Aug 2003 18:08:10 GMT\r\n
-ETag: "295682-9-3f2aac8a"\r\n
-Accept-Ranges: bytes\r\n
-Content-Length: 9\r\n
-Content-Type: text/plain\r\n\r\n
-596254978
-
-# ***********************************************************************************************
-# Alerts
-@14001
-@break
-@request
-
-GET /trigger/basic/normalized/URI/content/match/alert HTTP/1.1\r\n\r\n
-
-@14002
-@break
-@request
-
-GET /%74%72%69%67%67%65%72/encoded/normalized/URI/content/match/alert HTTP/1.1\r\n\r\n
-
-
-# ***********************************************************************************************
-# Pipelining
-@15001
-@break
-@request
-
-GET /pipeline/test/1 HTTP/1.1\r\n
-Host: www.pipeline1.com\r\n
-\r\n
-GET /pipeline/test/2 HTTP/1.1\r\n
-Host: www.pipeline2.com\r\n
-\r\n
-GET /pipeline/test/3 HTTP/1.1\r\n
-Host: www.pipeline3.com\r\n
-\r\n
-GET /pipeline/test/4 HTTP/1.1\r\n
-Host: www.pipeline4.com\r\n
-\r\n
-
-GET /pipeline/test/5 HTTP/1.1\r\n
-Host: www.pipeline5.com\r\n
-\r\n
-GET /pipeline/test/6 HTTP/1.1\r\n
-Host: www.pipeline6.com\r\n
-\r\n
-
-@response
-
-HTTP/1.1 400 Response to pipeline 1\r\n
-Content-Length: 10000\r\n
-\r\n
-Data 1 from pipeline\r\n
-
-HTTP/1.1 400 Response to pipeline 2\r\n
-Content-Length: 20000\r\n
-\r\n
-Data 2 from pipeline\r\n
-
-HTTP/1.1 400 Response to pipeline 3\r\n
-Content-Length: 30000\r\n
-\r\n
-
-Data 3 from pipeline\r\n
-
-Data 3 from pipeline part 2\r\n
-
-HTTP/1.1 400 Response to pipeline 4\r\n
-Content-Length: 40000\r\n
-\r\n
-Data 4 from pipeline\r\n
-
-Data 4 from pipeline part 2\r\n
-
-HTTP/1.1 400 Response to pipeline 5\r\n
-Content-Length: 50000\r\n
-\r\n
-
-Data 5 from pipeline\r\n
-
-Data 5 from pipeline part 2\r\n
-
-Data 5 from pipeline part 3\r\n
-
-HTTP/1.1 400 Response to pipeline 6\r\n
-Content-Length: 60000\r\n
-\r\n
-Data 6 from pipeline\r\n
-
-Data 6 from pipeline part 2\r\n
-
-Data 6 from pipeline part 3\r\n
-
-Data 6 from pipeline part 4\r\n
-
-# ***********************************************************************************************
-# Section aggregation test cases
-@16001
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16002
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16003
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456
-
-789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16004
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16005
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r
-
-\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16006
-@break
-@response
-
-HTTP/1.1 200 OK
-
- Let's pad this out 1234567890123456789012345678
-
-9012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16007
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16008
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16009
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16010
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r
-
-\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16011
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain
-
-\r
-
-\n
-
-\r
-
-\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-
-@16012
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain
-
-\r
-
-\n
-
-\r
-
-\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxy
-
-@16013
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 
-
-12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16014
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 
-
-12345678901234567890123456789012345678901234567890\r\n
-
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-
-@16101
-@break
-@response
-
-HTTP/1.1 200 OK Let's pad this out 12345678901234567890123456789012345678901234567890\r\n
-Content-length:208\r\n
-Content-type: text/plain\r\n
-\r\n
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-abcdefghijklmnopqrstuvwxyz
-