summaryrefslogtreecommitdiffstats
path: root/tests/HTTP
diff options
context:
space:
mode:
Diffstat (limited to 'tests/HTTP')
-rw-r--r--tests/HTTP/CMakeLists.txt60
-rw-r--r--tests/HTTP/HTTPMessageParser_file.cpp153
-rw-r--r--tests/HTTP/HTTPRequest1.data5
-rw-r--r--tests/HTTP/HTTPRequest2.data3
-rw-r--r--tests/HTTP/HTTPRequestParser_file.cpp153
-rw-r--r--tests/HTTP/HTTPResponse1.data10
-rw-r--r--tests/HTTP/HTTPResponse2.data15
-rw-r--r--tests/HTTP/HTTPResponseParser_file.cpp153
8 files changed, 552 insertions, 0 deletions
diff --git a/tests/HTTP/CMakeLists.txt b/tests/HTTP/CMakeLists.txt
new file mode 100644
index 000000000..233e5c0cb
--- /dev/null
+++ b/tests/HTTP/CMakeLists.txt
@@ -0,0 +1,60 @@
+cmake_minimum_required (VERSION 2.6)
+
+enable_testing()
+
+include_directories(${CMAKE_SOURCE_DIR}/src/)
+include_directories(${CMAKE_SOURCE_DIR}/lib/libevent/include)
+
+add_definitions(-DTEST_GLOBALS=1)
+
+# Create a single HTTP library that contains all the HTTP code:
+set (HTTP_SRCS
+ ${CMAKE_SOURCE_DIR}/src/HTTP/EnvelopeParser.cpp
+ ${CMAKE_SOURCE_DIR}/src/HTTP/HTTPMessage.cpp
+ ${CMAKE_SOURCE_DIR}/src/HTTP/HTTPMessageParser.cpp
+ ${CMAKE_SOURCE_DIR}/src/HTTP/TransferEncodingParser.cpp
+ ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp
+)
+
+set (HTTP_HDRS
+ ${CMAKE_SOURCE_DIR}/src/HTTP/EnvelopeParser.h
+ ${CMAKE_SOURCE_DIR}/src/HTTP/HTTPMessage.h
+ ${CMAKE_SOURCE_DIR}/src/HTTP/HTTPMessageParser.h
+ ${CMAKE_SOURCE_DIR}/src/HTTP/TransferEncodingParser.h
+ ${CMAKE_SOURCE_DIR}/src/StringUtils.h
+)
+
+add_library(HTTP
+ ${HTTP_SRCS}
+ ${HTTP_HDRS}
+)
+
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ add_flags_cxx("-Wno-error=conversion -Wno-error=old-style-cast")
+endif()
+
+
+
+
+
+# Define individual tests:
+
+# HTTPMessageParser_file: Feed file contents into a cHTTPResponseParser and print the callbacks as they're called:
+add_executable(HTTPMessageParser_file-exe HTTPMessageParser_file.cpp)
+target_link_libraries(HTTPMessageParser_file-exe HTTP)
+
+# Test parsing the response file in 2-byte chunks (should go from response line parsing through headers parsing to body parsing, each within a different step):
+add_test(NAME HTTPMessageParser_file-test1-2 COMMAND HTTPMessageParser_file-exe HTTPResponse1.data 2)
+
+# Test parsing the response file in 128-byte chunks (should parse response line and part of headers in one step, the rest in another step):
+add_test(NAME HTTPMessageParser_file-test1-128 COMMAND HTTPMessageParser_file-exe HTTPResponse1.data 128)
+
+# Test parsing a chunked-encoding response:
+add_test(NAME HTTPMessageParser_file-test2 COMMAND HTTPMessageParser_file-exe HTTPResponse2.data)
+
+# Test parsing the request file in 2-byte chunks (should go from request line parsing through headers parsing to body parsing, each within a different step):
+add_test(NAME HTTPMessageParser_file-test3-2 COMMAND HTTPMessageParser_file-exe HTTPRequest1.data 2)
+
+# Test parsing the request file in 512-byte chunks (should process everything in a single call):
+add_test(NAME HTTPMessageParser_file-test4-512 COMMAND HTTPMessageParser_file-exe HTTPRequest1.data 512)
+
diff --git a/tests/HTTP/HTTPMessageParser_file.cpp b/tests/HTTP/HTTPMessageParser_file.cpp
new file mode 100644
index 000000000..cd6dfa605
--- /dev/null
+++ b/tests/HTTP/HTTPMessageParser_file.cpp
@@ -0,0 +1,153 @@
+
+// HTTPMessageParser_file.cpp
+
+// Implements a test that feeds file contents into a cHTTPMessageParser instance and prints all callbacks
+
+#include "Globals.h"
+#include "HTTP/HTTPMessageParser.h"
+
+
+
+
+
+/** Maximum size of the input buffer, through which the file is read */
+static const size_t MAX_BUF = 4096;
+
+
+
+
+
+class cCallbacks:
+ public cHTTPMessageParser::cCallbacks
+{
+ typedef cHTTPMessageParser::cCallbacks Super;
+public:
+ cCallbacks(void)
+ {
+ printf("cCallbacks created\n");
+ }
+
+ // cHTTPResponseParser::cCallbacks overrides:
+ virtual void OnError(const AString & a_ErrorDescription) override
+ {
+ printf("Error: \"%s\"\n", a_ErrorDescription.c_str());
+ }
+
+ /** Called when the first line (request / status) is fully parsed. */
+ virtual void OnFirstLine(const AString & a_FirstLine) override
+ {
+ printf("First line: \"%s\"\n", a_FirstLine.c_str());
+ }
+
+ /** Called when a single header line is parsed. */
+ virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override
+ {
+ printf("Header line: \"%s\": \"%s\"\n", a_Key.c_str(), a_Value.c_str());
+ }
+
+ /** Called when all the headers have been parsed. */
+ virtual void OnHeadersFinished(void) override
+ {
+ printf("Headers finished\n");
+ }
+
+ /** Called for each chunk of the incoming body data. */
+ virtual void OnBodyData(const void * a_Data, size_t a_Size) override
+ {
+ AString hexDump;
+ CreateHexDump(hexDump, a_Data, a_Size, 16);
+ printf("Body data: %u bytes\n%s", static_cast<unsigned>(a_Size), hexDump.c_str());
+ }
+
+ virtual void OnBodyFinished(void) override
+ {
+ printf("Body finished\n");
+ }
+};
+
+
+
+
+
+int main(int argc, char * argv[])
+{
+ printf("HTTPMessageParser_file beginning\n");
+
+ // Open the input file:
+ if (argc <= 1)
+ {
+ printf("Usage: %s <filename> [<buffersize>]\n", argv[0]);
+ return 1;
+ }
+ FILE * f;
+ if (strcmp(argv[1], "-") == 0)
+ {
+ f = stdin;
+ }
+ else
+ {
+ f = fopen(argv[1], "rb");
+ if (f == nullptr)
+ {
+ printf("Cannot open file \"%s\". Aborting.\n", argv[1]);
+ return 2;
+ }
+ }
+
+ // If a third param is present, use it as the buffer size
+ size_t bufSize = MAX_BUF;
+ if (argc >= 3)
+ {
+ if (!StringToInteger(argv[2], bufSize) || (bufSize == 0))
+ {
+ bufSize = MAX_BUF;
+ printf("\"%s\" is not a valid buffer size, using the default of %u instead.\n", argv[2], static_cast<unsigned>(bufSize));
+ }
+ if (bufSize > MAX_BUF)
+ {
+ bufSize = MAX_BUF;
+ printf("\"%s\" is too large, maximum buffer size is %u. Using the size %u instead.\n", argv[2], static_cast<unsigned>(bufSize), static_cast<unsigned>(bufSize));
+ }
+ }
+
+ // Feed the file contents into the parser:
+ cCallbacks callbacks;
+ cHTTPMessageParser parser(callbacks);
+ while (true)
+ {
+ char buf[MAX_BUF];
+ auto numBytes = fread(buf, 1, bufSize, f);
+ if (numBytes == 0)
+ {
+ printf("Read 0 bytes from file (EOF?), terminating\n");
+ break;
+ }
+ auto numConsumed = parser.Parse(buf, numBytes);
+ if (numConsumed == AString::npos)
+ {
+ printf("Parser indicates there was an error, terminating parsing.\n");
+ break;
+ }
+ ASSERT(numConsumed <= numBytes);
+ if (numConsumed < numBytes)
+ {
+ printf("Parser indicates stream end, but there's more data (at least %u bytes) in the file.\n", static_cast<unsigned>(numBytes - numConsumed));
+ }
+ }
+ if (!parser.IsFinished())
+ {
+ printf("Parser indicates an incomplete stream.\n");
+ }
+
+ // Close the input file:
+ if (f != stdin)
+ {
+ fclose(f);
+ }
+
+ return 0;
+}
+
+
+
+
diff --git a/tests/HTTP/HTTPRequest1.data b/tests/HTTP/HTTPRequest1.data
new file mode 100644
index 000000000..cac43c06c
--- /dev/null
+++ b/tests/HTTP/HTTPRequest1.data
@@ -0,0 +1,5 @@
+GET /some/url HTTP/1.1
+Note: This is a test of a regular request
+Content-Length: 3
+
+bla \ No newline at end of file
diff --git a/tests/HTTP/HTTPRequest2.data b/tests/HTTP/HTTPRequest2.data
new file mode 100644
index 000000000..f7dbede4f
--- /dev/null
+++ b/tests/HTTP/HTTPRequest2.data
@@ -0,0 +1,3 @@
+GET /some/url HTTP/1.1
+Note: This is a test of a regular body-less request
+
diff --git a/tests/HTTP/HTTPRequestParser_file.cpp b/tests/HTTP/HTTPRequestParser_file.cpp
new file mode 100644
index 000000000..98f11e8b1
--- /dev/null
+++ b/tests/HTTP/HTTPRequestParser_file.cpp
@@ -0,0 +1,153 @@
+
+// HTTPResponseParser_file.cpp
+
+// Implements a test that feeds file contents into a cHTTPResponseParser instance and prints all callbacks
+
+#include "Globals.h"
+#include "HTTP/HTTPRequestParser.h"
+
+
+
+
+
+/** Maximum size of the input buffer, through which the file is read */
+static const size_t MAX_BUF = 4096;
+
+
+
+
+
+class cCallbacks:
+ public cHTTPRequestParser::cCallbacks
+{
+ typedef cHTTPResponseParser::cCallbacks Super;
+public:
+ cCallbacks(void)
+ {
+ printf("cCallbacks created\n");
+ }
+
+ // cHTTPResponseParser::cCallbacks overrides:
+ virtual void OnError(const AString & a_ErrorDescription) override
+ {
+ printf("Error: \"%s\"\n", a_ErrorDescription.c_str());
+ }
+
+ /** Called when the status line is fully parsed. */
+ virtual void OnStatusLine(const AString & a_StatusLine) override
+ {
+ printf("Status line: \"%s\"\n", a_StatusLine.c_str());
+ }
+
+ /** Called when a single header line is parsed. */
+ virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override
+ {
+ printf("Header line: \"%s\": \"%s\"\n", a_Key.c_str(), a_Value.c_str());
+ }
+
+ /** Called when all the headers have been parsed. */
+ virtual void OnHeadersFinished(void) override
+ {
+ printf("Headers finished\n");
+ }
+
+ /** Called for each chunk of the incoming body data. */
+ virtual void OnBodyData(const void * a_Data, size_t a_Size) override
+ {
+ AString hexDump;
+ CreateHexDump(hexDump, a_Data, a_Size, 16);
+ printf("Body data: %u bytes\n%s", static_cast<unsigned>(a_Size), hexDump.c_str());
+ }
+
+ virtual void OnBodyFinished(void) override
+ {
+ printf("Body finished\n");
+ }
+};
+
+
+
+
+
+int main(int argc, char * argv[])
+{
+ printf("HTTPResponseParser_file beginning\n");
+
+ // Open the input file:
+ if (argc <= 1)
+ {
+ printf("Usage: %s <filename> [<buffersize>]\n", argv[0]);
+ return 1;
+ }
+ FILE * f;
+ if (strcmp(argv[1], "-") == 0)
+ {
+ f = stdin;
+ }
+ else
+ {
+ f = fopen(argv[1], "rb");
+ if (f == nullptr)
+ {
+ printf("Cannot open file \"%s\". Aborting.\n", argv[1]);
+ return 2;
+ }
+ }
+
+ // If a third param is present, use it as the buffer size
+ size_t bufSize = MAX_BUF;
+ if (argc >= 3)
+ {
+ if (!StringToInteger(argv[2], bufSize) || (bufSize == 0))
+ {
+ bufSize = MAX_BUF;
+ printf("\"%s\" is not a valid buffer size, using the default of %u instead.\n", argv[2], static_cast<unsigned>(bufSize));
+ }
+ if (bufSize > MAX_BUF)
+ {
+ bufSize = MAX_BUF;
+ printf("\"%s\" is too large, maximum buffer size is %u. Using the size %u instead.\n", argv[2], static_cast<unsigned>(bufSize), static_cast<unsigned>(bufSize));
+ }
+ }
+
+ // Feed the file contents into the parser:
+ cCallbacks callbacks;
+ cHTTPResponseParser parser(callbacks);
+ while (!feof(f))
+ {
+ char buf[MAX_BUF];
+ auto numBytes = fread(buf, 1, bufSize, f);
+ if (numBytes == 0)
+ {
+ printf("Read 0 bytes from file (EOF?), terminating\n");
+ break;
+ }
+ auto numConsumed = parser.Parse(buf, numBytes);
+ if (numConsumed == AString::npos)
+ {
+ printf("Parser indicates there was an error, terminating parsing.\n");
+ break;
+ }
+ ASSERT(numConsumed <= numBytes);
+ if (numConsumed < numBytes)
+ {
+ printf("Parser indicates stream end, but there's more data (at least %u bytes) in the file.\n", static_cast<unsigned>(numBytes - numConsumed));
+ }
+ }
+ if (!parser.IsFinished())
+ {
+ printf("Parser indicates an incomplete stream.\n");
+ }
+
+ // Close the input file:
+ if (f != stdin)
+ {
+ fclose(f);
+ }
+
+ return 0;
+}
+
+
+
+
diff --git a/tests/HTTP/HTTPResponse1.data b/tests/HTTP/HTTPResponse1.data
new file mode 100644
index 000000000..97e0b23c3
--- /dev/null
+++ b/tests/HTTP/HTTPResponse1.data
@@ -0,0 +1,10 @@
+HTTP/1.0 200 OK
+Note: This is a test of a regular response with Content-Length set
+ (identity transfer encoding)
+Note2: The above header also tests multi-line header lines
+Note3: The data is 2 bytes longer than the actual request, parser should indicate 2 extra bytes at the end
+Header1: Value1
+Header2: Value2
+Content-Length: 3
+
+bla
diff --git a/tests/HTTP/HTTPResponse2.data b/tests/HTTP/HTTPResponse2.data
new file mode 100644
index 000000000..d708c4758
--- /dev/null
+++ b/tests/HTTP/HTTPResponse2.data
@@ -0,0 +1,15 @@
+HTTP/1.0 200 OK
+Note: This is a Chunked transfer encoding test
+Header2: Value2
+Transfer-Encoding: chunked
+
+4
+Wiki
+5
+pedia
+e
+ in
+
+chunks.
+0
+
diff --git a/tests/HTTP/HTTPResponseParser_file.cpp b/tests/HTTP/HTTPResponseParser_file.cpp
new file mode 100644
index 000000000..7e8d127b7
--- /dev/null
+++ b/tests/HTTP/HTTPResponseParser_file.cpp
@@ -0,0 +1,153 @@
+
+// HTTPResponseParser_file.cpp
+
+// Implements a test that feeds file contents into a cHTTPResponseParser instance and prints all callbacks
+
+#include "Globals.h"
+#include "HTTP/HTTPResponseParser.h"
+
+
+
+
+
+/** Maximum size of the input buffer, through which the file is read */
+static const size_t MAX_BUF = 4096;
+
+
+
+
+
+class cCallbacks:
+ public cHTTPResponseParser::cCallbacks
+{
+ typedef cHTTPResponseParser::cCallbacks Super;
+public:
+ cCallbacks(void)
+ {
+ printf("cCallbacks created\n");
+ }
+
+ // cHTTPResponseParser::cCallbacks overrides:
+ virtual void OnError(const AString & a_ErrorDescription) override
+ {
+ printf("Error: \"%s\"\n", a_ErrorDescription.c_str());
+ }
+
+ /** Called when the status line is fully parsed. */
+ virtual void OnStatusLine(const AString & a_StatusLine) override
+ {
+ printf("Status line: \"%s\"\n", a_StatusLine.c_str());
+ }
+
+ /** Called when a single header line is parsed. */
+ virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override
+ {
+ printf("Header line: \"%s\": \"%s\"\n", a_Key.c_str(), a_Value.c_str());
+ }
+
+ /** Called when all the headers have been parsed. */
+ virtual void OnHeadersFinished(void) override
+ {
+ printf("Headers finished\n");
+ }
+
+ /** Called for each chunk of the incoming body data. */
+ virtual void OnBodyData(const void * a_Data, size_t a_Size) override
+ {
+ AString hexDump;
+ CreateHexDump(hexDump, a_Data, a_Size, 16);
+ printf("Body data: %u bytes\n%s", static_cast<unsigned>(a_Size), hexDump.c_str());
+ }
+
+ virtual void OnBodyFinished(void) override
+ {
+ printf("Body finished\n");
+ }
+};
+
+
+
+
+
+int main(int argc, char * argv[])
+{
+ printf("HTTPResponseParser_file beginning\n");
+
+ // Open the input file:
+ if (argc <= 1)
+ {
+ printf("Usage: %s <filename> [<buffersize>]\n", argv[0]);
+ return 1;
+ }
+ FILE * f;
+ if (strcmp(argv[1], "-") == 0)
+ {
+ f = stdin;
+ }
+ else
+ {
+ f = fopen(argv[1], "rb");
+ if (f == nullptr)
+ {
+ printf("Cannot open file \"%s\". Aborting.\n", argv[1]);
+ return 2;
+ }
+ }
+
+ // If a third param is present, use it as the buffer size
+ size_t bufSize = MAX_BUF;
+ if (argc >= 3)
+ {
+ if (!StringToInteger(argv[2], bufSize) || (bufSize == 0))
+ {
+ bufSize = MAX_BUF;
+ printf("\"%s\" is not a valid buffer size, using the default of %u instead.\n", argv[2], static_cast<unsigned>(bufSize));
+ }
+ if (bufSize > MAX_BUF)
+ {
+ bufSize = MAX_BUF;
+ printf("\"%s\" is too large, maximum buffer size is %u. Using the size %u instead.\n", argv[2], static_cast<unsigned>(bufSize), static_cast<unsigned>(bufSize));
+ }
+ }
+
+ // Feed the file contents into the parser:
+ cCallbacks callbacks;
+ cHTTPResponseParser parser(callbacks);
+ while (!feof(f))
+ {
+ char buf[MAX_BUF];
+ auto numBytes = fread(buf, 1, bufSize, f);
+ if (numBytes == 0)
+ {
+ printf("Read 0 bytes from file (EOF?), terminating\n");
+ break;
+ }
+ auto numConsumed = parser.Parse(buf, numBytes);
+ if (numConsumed == AString::npos)
+ {
+ printf("Parser indicates there was an error, terminating parsing.\n");
+ break;
+ }
+ ASSERT(numConsumed <= numBytes);
+ if (numConsumed < numBytes)
+ {
+ printf("Parser indicates stream end, but there's more data (at least %u bytes) in the file.\n", static_cast<unsigned>(numBytes - numConsumed));
+ }
+ }
+ if (!parser.IsFinished())
+ {
+ printf("Parser indicates an incomplete stream.\n");
+ }
+
+ // Close the input file:
+ if (f != stdin)
+ {
+ fclose(f);
+ }
+
+ return 0;
+}
+
+
+
+