#include "HttpHeaderProcessor.h" #include #include #include "HttpHeader.h" #include "DlRetryEx.h" #include "DlAbortEx.h" namespace aria2 { class HttpHeaderProcessorTest:public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(HttpHeaderProcessorTest); CPPUNIT_TEST(testParse1); CPPUNIT_TEST(testParse2); CPPUNIT_TEST(testParse3); CPPUNIT_TEST(testGetLastBytesProcessed); CPPUNIT_TEST(testGetLastBytesProcessed_nullChar); CPPUNIT_TEST(testGetHttpResponseHeader); CPPUNIT_TEST(testGetHttpResponseHeader_statusOnly); CPPUNIT_TEST(testGetHttpResponseHeader_insufficientStatusLength); CPPUNIT_TEST(testGetHttpResponseHeader_nameStartsWs); CPPUNIT_TEST(testBeyondLimit); CPPUNIT_TEST(testGetHeaderString); CPPUNIT_TEST(testGetHttpRequestHeader); CPPUNIT_TEST_SUITE_END(); public: void testParse1(); void testParse2(); void testParse3(); void testGetLastBytesProcessed(); void testGetLastBytesProcessed_nullChar(); void testGetHttpResponseHeader(); void testGetHttpResponseHeader_statusOnly(); void testGetHttpResponseHeader_insufficientStatusLength(); void testGetHttpResponseHeader_nameStartsWs(); void testBeyondLimit(); void testGetHeaderString(); void testGetHttpRequestHeader(); }; CPPUNIT_TEST_SUITE_REGISTRATION( HttpHeaderProcessorTest ); void HttpHeaderProcessorTest::testParse1() { HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER); std::string hd1 = "HTTP/1.1 200 OK\r\n"; CPPUNIT_ASSERT(!proc.parse(hd1)); CPPUNIT_ASSERT(proc.parse("\r\n")); } void HttpHeaderProcessorTest::testParse2() { HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER); std::string hd1 = "HTTP/1.1 200 OK\n"; CPPUNIT_ASSERT(!proc.parse(hd1)); CPPUNIT_ASSERT(proc.parse("\n")); } void HttpHeaderProcessorTest::testParse3() { HttpHeaderProcessor proc(HttpHeaderProcessor::SERVER_PARSER); std::string s = "GET / HTTP/1.1\r\n" "Host: aria2.sourceforge.net\r\n" "Connection: close \r\n" // trailing white space (BWS) "Accept-Encoding: text1\r\n" // Multi-line header " text2\r\n" " text3\r\n" "Authorization: foo\r\n" "Authorization: bar\r\n" "Content-Type:\r\n" "\r\n"; CPPUNIT_ASSERT(proc.parse(s)); auto h = proc.getResult(); CPPUNIT_ASSERT_EQUAL(std::string("close"), h->find(HttpHeader::CONNECTION)); CPPUNIT_ASSERT_EQUAL(std::string("text1 text2 text3"), h->find(HttpHeader::ACCEPT_ENCODING)); CPPUNIT_ASSERT_EQUAL(std::string("foo"), h->findAll(HttpHeader::AUTHORIZATION)[0]); CPPUNIT_ASSERT_EQUAL(std::string("bar"), h->findAll(HttpHeader::AUTHORIZATION)[1]); CPPUNIT_ASSERT_EQUAL(std::string(""), h->find(HttpHeader::CONTENT_TYPE)); CPPUNIT_ASSERT(h->defined(HttpHeader::CONTENT_TYPE)); } void HttpHeaderProcessorTest::testGetLastBytesProcessed() { HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER); std::string hd1 = "HTTP/1.1 200 OK\r\n" "\r\nputbackme"; CPPUNIT_ASSERT(proc.parse(hd1)); CPPUNIT_ASSERT_EQUAL((size_t)19, proc.getLastBytesProcessed()); proc.clear(); std::string hd2 = "HTTP/1.1 200 OK\n" "\nputbackme"; CPPUNIT_ASSERT(proc.parse(hd2)); CPPUNIT_ASSERT_EQUAL((size_t)17, proc.getLastBytesProcessed()); } void HttpHeaderProcessorTest::testGetLastBytesProcessed_nullChar() { HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER); const char x[] = "HTTP/1.1 200 OK\r\n" "foo: foo\0bar\r\n" "\r\nputbackme"; std::string hd1(&x[0], &x[sizeof(x)-1]); CPPUNIT_ASSERT(proc.parse(hd1)); CPPUNIT_ASSERT_EQUAL((size_t)33, proc.getLastBytesProcessed()); } void HttpHeaderProcessorTest::testGetHttpResponseHeader() { HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER); std::string hd = "HTTP/1.1 404 Not Found\r\n" "Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n" "Server: Apache/2.2.3 (Debian)\r\n" "Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n" "ETag: \"594065-23e3-50825cc0\"\r\n" "Accept-Ranges: bytes\r\n" "Content-Length: 9187\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "\r\n" "Content-Encoding: body"; CPPUNIT_ASSERT(proc.parse(hd)); auto header = proc.getResult(); CPPUNIT_ASSERT_EQUAL(404, header->getStatusCode()); CPPUNIT_ASSERT_EQUAL(std::string("Not Found"), header->getReasonPhrase()); CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), header->getVersion()); CPPUNIT_ASSERT_EQUAL(std::string("9187"), header->find(HttpHeader::CONTENT_LENGTH)); CPPUNIT_ASSERT_EQUAL(std::string("text/html; charset=UTF-8"), header->find(HttpHeader::CONTENT_TYPE)); CPPUNIT_ASSERT(!header->defined(HttpHeader::CONTENT_ENCODING)); } void HttpHeaderProcessorTest::testGetHttpResponseHeader_statusOnly() { HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER); std::string hd = "HTTP/1.1 200\r\n\r\n"; CPPUNIT_ASSERT(proc.parse(hd)); auto header = proc.getResult(); CPPUNIT_ASSERT_EQUAL(200, header->getStatusCode()); } void HttpHeaderProcessorTest::testGetHttpResponseHeader_insufficientStatusLength() { HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER); std::string hd = "HTTP/1.1 20\r\n\r\n"; try { proc.parse(hd); CPPUNIT_FAIL("Exception must be thrown."); } catch(DlAbortEx& ex) { // Success } } 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); std::string hd1 = "HTTP/1.1 200 OK\r\n"; std::string hd2 = std::string(1025, 'A'); proc.parse(hd1); try { proc.parse(hd2); CPPUNIT_FAIL("Exception must be thrown."); } catch(DlAbortEx& ex) { // Success } } void HttpHeaderProcessorTest::testGetHeaderString() { HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER); std::string hd = "HTTP/1.1 200 OK\r\n" "Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n" "Server: Apache/2.2.3 (Debian)\r\n" "Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n" "ETag: \"594065-23e3-50825cc0\"\r\n" "Accept-Ranges: bytes\r\n" "Content-Length: 9187\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "\r\nputbackme"; CPPUNIT_ASSERT(proc.parse(hd)); CPPUNIT_ASSERT_EQUAL (std::string("HTTP/1.1 200 OK\r\n" "Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n" "Server: Apache/2.2.3 (Debian)\r\n" "Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n" "ETag: \"594065-23e3-50825cc0\"\r\n" "Accept-Ranges: bytes\r\n" "Content-Length: 9187\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "\r\n"), proc.getHeaderString()); } void HttpHeaderProcessorTest::testGetHttpRequestHeader() { HttpHeaderProcessor proc(HttpHeaderProcessor::SERVER_PARSER); std::string request = "GET /index.html HTTP/1.1\r\n" "Host: host\r\n" "Connection: close\r\n" "\r\n" "Content-Encoding: body"; CPPUNIT_ASSERT(proc.parse(request)); auto httpHeader = proc.getResult(); CPPUNIT_ASSERT_EQUAL(std::string("GET"), httpHeader->getMethod()); CPPUNIT_ASSERT_EQUAL(std::string("/index.html"),httpHeader->getRequestPath()); CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), httpHeader->getVersion()); CPPUNIT_ASSERT_EQUAL(std::string("close"), httpHeader->find(HttpHeader::CONNECTION)); CPPUNIT_ASSERT(!httpHeader->defined(HttpHeader::CONTENT_ENCODING)); } } // namespace aria2