HttpHeaderProcessorTest.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include "HttpHeaderProcessor.h"
  2. #include <iostream>
  3. #include <cppunit/extensions/HelperMacros.h>
  4. #include "HttpHeader.h"
  5. #include "DlRetryEx.h"
  6. #include "DlAbortEx.h"
  7. namespace aria2 {
  8. class HttpHeaderProcessorTest:public CppUnit::TestFixture {
  9. CPPUNIT_TEST_SUITE(HttpHeaderProcessorTest);
  10. CPPUNIT_TEST(testParse1);
  11. CPPUNIT_TEST(testParse2);
  12. CPPUNIT_TEST(testParse3);
  13. CPPUNIT_TEST(testGetLastBytesProcessed);
  14. CPPUNIT_TEST(testGetLastBytesProcessed_nullChar);
  15. CPPUNIT_TEST(testGetHttpResponseHeader);
  16. CPPUNIT_TEST(testGetHttpResponseHeader_statusOnly);
  17. CPPUNIT_TEST(testGetHttpResponseHeader_insufficientStatusLength);
  18. CPPUNIT_TEST(testGetHttpResponseHeader_nameStartsWs);
  19. CPPUNIT_TEST(testBeyondLimit);
  20. CPPUNIT_TEST(testGetHeaderString);
  21. CPPUNIT_TEST(testGetHttpRequestHeader);
  22. CPPUNIT_TEST_SUITE_END();
  23. public:
  24. void testParse1();
  25. void testParse2();
  26. void testParse3();
  27. void testGetLastBytesProcessed();
  28. void testGetLastBytesProcessed_nullChar();
  29. void testGetHttpResponseHeader();
  30. void testGetHttpResponseHeader_statusOnly();
  31. void testGetHttpResponseHeader_insufficientStatusLength();
  32. void testGetHttpResponseHeader_nameStartsWs();
  33. void testBeyondLimit();
  34. void testGetHeaderString();
  35. void testGetHttpRequestHeader();
  36. };
  37. CPPUNIT_TEST_SUITE_REGISTRATION( HttpHeaderProcessorTest );
  38. void HttpHeaderProcessorTest::testParse1()
  39. {
  40. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  41. std::string hd1 = "HTTP/1.1 200 OK\r\n";
  42. CPPUNIT_ASSERT(!proc.parse(hd1));
  43. CPPUNIT_ASSERT(proc.parse("\r\n"));
  44. }
  45. void HttpHeaderProcessorTest::testParse2()
  46. {
  47. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  48. std::string hd1 = "HTTP/1.1 200 OK\n";
  49. CPPUNIT_ASSERT(!proc.parse(hd1));
  50. CPPUNIT_ASSERT(proc.parse("\n"));
  51. }
  52. void HttpHeaderProcessorTest::testParse3()
  53. {
  54. HttpHeaderProcessor proc(HttpHeaderProcessor::SERVER_PARSER);
  55. std::string s =
  56. "GET / HTTP/1.1\r\n"
  57. "Host: aria2.sourceforge.net\r\n"
  58. "Connection: close \r\n" // trailing white space (BWS)
  59. "Multi-Line: text1\r\n" // Multi-line header
  60. " text2\r\n"
  61. " text3\r\n"
  62. "Duplicate: foo\r\n"
  63. "Duplicate: bar\r\n"
  64. "No-value:\r\n"
  65. "\r\n";
  66. CPPUNIT_ASSERT(proc.parse(s));
  67. SharedHandle<HttpHeader> h = proc.getResult();
  68. CPPUNIT_ASSERT_EQUAL(std::string("aria2.sourceforge.net"),
  69. h->find("host"));
  70. CPPUNIT_ASSERT_EQUAL(std::string("close"),
  71. h->find("connection"));
  72. CPPUNIT_ASSERT_EQUAL(std::string("text1 text2 text3"),
  73. h->find("multi-line"));
  74. CPPUNIT_ASSERT_EQUAL(std::string("foo"),
  75. h->findAll("duplicate")[0]);
  76. CPPUNIT_ASSERT_EQUAL(std::string("bar"),
  77. h->findAll("duplicate")[1]);
  78. CPPUNIT_ASSERT_EQUAL(std::string(""), h->find("no-value"));
  79. CPPUNIT_ASSERT(h->defined("no-value"));
  80. }
  81. void HttpHeaderProcessorTest::testGetLastBytesProcessed()
  82. {
  83. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  84. std::string hd1 =
  85. "HTTP/1.1 200 OK\r\n"
  86. "\r\nputbackme";
  87. CPPUNIT_ASSERT(proc.parse(hd1));
  88. CPPUNIT_ASSERT_EQUAL((size_t)19, proc.getLastBytesProcessed());
  89. proc.clear();
  90. std::string hd2 =
  91. "HTTP/1.1 200 OK\n"
  92. "\nputbackme";
  93. CPPUNIT_ASSERT(proc.parse(hd2));
  94. CPPUNIT_ASSERT_EQUAL((size_t)17, proc.getLastBytesProcessed());
  95. }
  96. void HttpHeaderProcessorTest::testGetLastBytesProcessed_nullChar()
  97. {
  98. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  99. const char x[] =
  100. "HTTP/1.1 200 OK\r\n"
  101. "foo: foo\0bar\r\n"
  102. "\r\nputbackme";
  103. std::string hd1(&x[0], &x[sizeof(x)-1]);
  104. CPPUNIT_ASSERT(proc.parse(hd1));
  105. CPPUNIT_ASSERT_EQUAL((size_t)33, proc.getLastBytesProcessed());
  106. }
  107. void HttpHeaderProcessorTest::testGetHttpResponseHeader()
  108. {
  109. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  110. std::string hd =
  111. "HTTP/1.1 404 Not Found\r\n"
  112. "Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n"
  113. "Server: Apache/2.2.3 (Debian)\r\n"
  114. "Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n"
  115. "ETag: \"594065-23e3-50825cc0\"\r\n"
  116. "Accept-Ranges: bytes\r\n"
  117. "Content-Length: 9187\r\n"
  118. "Connection: close\r\n"
  119. "Content-Type: text/html; charset=UTF-8\r\n"
  120. "\r\n"
  121. "Entity: body";
  122. CPPUNIT_ASSERT(proc.parse(hd));
  123. SharedHandle<HttpHeader> header = proc.getResult();
  124. CPPUNIT_ASSERT_EQUAL(404, header->getStatusCode());
  125. CPPUNIT_ASSERT_EQUAL(std::string("Not Found"), header->getReasonPhrase());
  126. CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), header->getVersion());
  127. CPPUNIT_ASSERT_EQUAL(std::string("Mon, 25 Jun 2007 16:04:59 GMT"),
  128. header->find("date"));
  129. CPPUNIT_ASSERT_EQUAL(std::string("Apache/2.2.3 (Debian)"),
  130. header->find("server"));
  131. CPPUNIT_ASSERT_EQUAL((int64_t)9187LL,
  132. header->findAsLLInt("content-length"));
  133. CPPUNIT_ASSERT_EQUAL(std::string("text/html; charset=UTF-8"),
  134. header->find("content-type"));
  135. CPPUNIT_ASSERT(!header->defined("entity"));
  136. }
  137. void HttpHeaderProcessorTest::testGetHttpResponseHeader_statusOnly()
  138. {
  139. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  140. std::string hd = "HTTP/1.1 200\r\n\r\n";
  141. CPPUNIT_ASSERT(proc.parse(hd));
  142. SharedHandle<HttpHeader> header = proc.getResult();
  143. CPPUNIT_ASSERT_EQUAL(200, header->getStatusCode());
  144. }
  145. void HttpHeaderProcessorTest::testGetHttpResponseHeader_insufficientStatusLength()
  146. {
  147. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  148. std::string hd = "HTTP/1.1 20\r\n\r\n";
  149. try {
  150. proc.parse(hd);
  151. CPPUNIT_FAIL("Exception must be thrown.");
  152. } catch(DlAbortEx& ex) {
  153. // Success
  154. }
  155. }
  156. void HttpHeaderProcessorTest::testGetHttpResponseHeader_nameStartsWs()
  157. {
  158. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  159. std::string hd =
  160. "HTTP/1.1 200\r\n"
  161. " foo:bar\r\n"
  162. "\r\n";
  163. try {
  164. proc.parse(hd);
  165. CPPUNIT_FAIL("Exception must be thrown.");
  166. } catch(DlAbortEx& ex) {
  167. // Success
  168. }
  169. proc.clear();
  170. hd =
  171. "HTTP/1.1 200\r\n"
  172. ":foo:bar\r\n"
  173. "\r\n";
  174. try {
  175. proc.parse(hd);
  176. CPPUNIT_FAIL("Exception must be thrown.");
  177. } catch(DlAbortEx& ex) {
  178. // Success
  179. }
  180. proc.clear();
  181. hd =
  182. "HTTP/1.1 200\r\n"
  183. ":foo\r\n"
  184. "\r\n";
  185. try {
  186. proc.parse(hd);
  187. CPPUNIT_FAIL("Exception must be thrown.");
  188. } catch(DlAbortEx& ex) {
  189. // Success
  190. }
  191. }
  192. void HttpHeaderProcessorTest::testBeyondLimit()
  193. {
  194. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  195. std::string hd1 = "HTTP/1.1 200 OK\r\n";
  196. std::string hd2 = std::string(1025, 'A');
  197. proc.parse(hd1);
  198. try {
  199. proc.parse(hd2);
  200. CPPUNIT_FAIL("Exception must be thrown.");
  201. } catch(DlAbortEx& ex) {
  202. // Success
  203. }
  204. }
  205. void HttpHeaderProcessorTest::testGetHeaderString()
  206. {
  207. HttpHeaderProcessor proc(HttpHeaderProcessor::CLIENT_PARSER);
  208. std::string hd =
  209. "HTTP/1.1 200 OK\r\n"
  210. "Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n"
  211. "Server: Apache/2.2.3 (Debian)\r\n"
  212. "Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n"
  213. "ETag: \"594065-23e3-50825cc0\"\r\n"
  214. "Accept-Ranges: bytes\r\n"
  215. "Content-Length: 9187\r\n"
  216. "Connection: close\r\n"
  217. "Content-Type: text/html; charset=UTF-8\r\n"
  218. "\r\nputbackme";
  219. CPPUNIT_ASSERT(proc.parse(hd));
  220. CPPUNIT_ASSERT_EQUAL
  221. (std::string("HTTP/1.1 200 OK\r\n"
  222. "Date: Mon, 25 Jun 2007 16:04:59 GMT\r\n"
  223. "Server: Apache/2.2.3 (Debian)\r\n"
  224. "Last-Modified: Tue, 12 Jun 2007 14:28:43 GMT\r\n"
  225. "ETag: \"594065-23e3-50825cc0\"\r\n"
  226. "Accept-Ranges: bytes\r\n"
  227. "Content-Length: 9187\r\n"
  228. "Connection: close\r\n"
  229. "Content-Type: text/html; charset=UTF-8\r\n"
  230. "\r\n"),
  231. proc.getHeaderString());
  232. }
  233. void HttpHeaderProcessorTest::testGetHttpRequestHeader()
  234. {
  235. HttpHeaderProcessor proc(HttpHeaderProcessor::SERVER_PARSER);
  236. std::string request =
  237. "GET /index.html HTTP/1.1\r\n"
  238. "Host: host\r\n"
  239. "Connection: close\r\n"
  240. "\r\n"
  241. "Entity: body";
  242. CPPUNIT_ASSERT(proc.parse(request));
  243. SharedHandle<HttpHeader> httpHeader = proc.getResult();
  244. CPPUNIT_ASSERT_EQUAL(std::string("GET"), httpHeader->getMethod());
  245. CPPUNIT_ASSERT_EQUAL(std::string("/index.html"),httpHeader->getRequestPath());
  246. CPPUNIT_ASSERT_EQUAL(std::string("HTTP/1.1"), httpHeader->getVersion());
  247. CPPUNIT_ASSERT_EQUAL(std::string("close"),httpHeader->find("connection"));
  248. CPPUNIT_ASSERT(!httpHeader->defined("entity"));
  249. }
  250. } // namespace aria2