HttpResponseTest.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. #include "HttpResponse.h"
  2. #include "prefs.h"
  3. #include "PiecedSegment.h"
  4. #include "Piece.h"
  5. #include "Request.h"
  6. #include "HttpHeader.h"
  7. #include "HttpRequest.h"
  8. #include "Exception.h"
  9. #include "A2STR.h"
  10. #include "Decoder.h"
  11. #include "DlRetryEx.h"
  12. #include "CookieStorage.h"
  13. #include <iostream>
  14. #include <cppunit/extensions/HelperMacros.h>
  15. namespace aria2 {
  16. class HttpResponseTest : public CppUnit::TestFixture {
  17. CPPUNIT_TEST_SUITE(HttpResponseTest);
  18. CPPUNIT_TEST(testGetContentLength_null);
  19. CPPUNIT_TEST(testGetContentLength_contentLength);
  20. //CPPUNIT_TEST(testGetContentLength_range);
  21. CPPUNIT_TEST(testGetEntityLength);
  22. CPPUNIT_TEST(testGetContentType);
  23. CPPUNIT_TEST(testDeterminFilename_without_ContentDisposition);
  24. CPPUNIT_TEST(testDeterminFilename_with_ContentDisposition_zero_length);
  25. CPPUNIT_TEST(testDeterminFilename_with_ContentDisposition);
  26. CPPUNIT_TEST(testGetRedirectURI_without_Location);
  27. CPPUNIT_TEST(testGetRedirectURI_with_Location);
  28. CPPUNIT_TEST(testIsRedirect);
  29. CPPUNIT_TEST(testIsTransferEncodingSpecified);
  30. CPPUNIT_TEST(testGetTransferEncoding);
  31. CPPUNIT_TEST(testGetTransferEncodingDecoder);
  32. CPPUNIT_TEST(testIsContentEncodingSpecified);
  33. CPPUNIT_TEST(testGetContentEncoding);
  34. CPPUNIT_TEST(testGetContentEncodingDecoder);
  35. CPPUNIT_TEST(testValidateResponse);
  36. CPPUNIT_TEST(testValidateResponse_good_range);
  37. CPPUNIT_TEST(testValidateResponse_bad_range);
  38. CPPUNIT_TEST(testValidateResponse_chunked);
  39. CPPUNIT_TEST(testHasRetryAfter);
  40. CPPUNIT_TEST(testProcessRedirect);
  41. CPPUNIT_TEST(testRetrieveCookie);
  42. CPPUNIT_TEST_SUITE_END();
  43. private:
  44. public:
  45. void setUp() {
  46. }
  47. void testGetContentLength_null();
  48. void testGetContentLength_contentLength();
  49. void testGetEntityLength();
  50. void testGetContentType();
  51. void testDeterminFilename_without_ContentDisposition();
  52. void testDeterminFilename_with_ContentDisposition_zero_length();
  53. void testDeterminFilename_with_ContentDisposition();
  54. void testGetRedirectURI_without_Location();
  55. void testGetRedirectURI_with_Location();
  56. void testIsRedirect();
  57. void testIsTransferEncodingSpecified();
  58. void testGetTransferEncoding();
  59. void testGetTransferEncodingDecoder();
  60. void testIsContentEncodingSpecified();
  61. void testGetContentEncoding();
  62. void testGetContentEncodingDecoder();
  63. void testValidateResponse();
  64. void testValidateResponse_good_range();
  65. void testValidateResponse_bad_range();
  66. void testValidateResponse_chunked();
  67. void testHasRetryAfter();
  68. void testProcessRedirect();
  69. void testRetrieveCookie();
  70. };
  71. CPPUNIT_TEST_SUITE_REGISTRATION( HttpResponseTest );
  72. void HttpResponseTest::testGetContentLength_null()
  73. {
  74. HttpResponse httpResponse;
  75. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, httpResponse.getContentLength());
  76. }
  77. void HttpResponseTest::testGetContentLength_contentLength()
  78. {
  79. HttpResponse httpResponse;
  80. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  81. httpHeader->put("Content-Length", "4294967296");
  82. httpResponse.setHttpHeader(httpHeader);
  83. CPPUNIT_ASSERT_EQUAL((uint64_t)4294967296ULL, httpResponse.getContentLength());
  84. }
  85. void HttpResponseTest::testGetEntityLength()
  86. {
  87. HttpResponse httpResponse;
  88. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  89. httpHeader->put("Content-Length", "4294967296");
  90. httpResponse.setHttpHeader(httpHeader);
  91. CPPUNIT_ASSERT_EQUAL((uint64_t)4294967296ULL, httpResponse.getEntityLength());
  92. httpHeader->put("Content-Range", "bytes 1-4294967296/4294967297");
  93. CPPUNIT_ASSERT_EQUAL((uint64_t)4294967297ULL, httpResponse.getEntityLength());
  94. }
  95. void HttpResponseTest::testGetContentType()
  96. {
  97. HttpResponse httpResponse;
  98. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  99. httpHeader->put("content-type", "application/octet-stream");
  100. httpResponse.setHttpHeader(httpHeader);
  101. CPPUNIT_ASSERT_EQUAL(std::string("application/octet-stream"),
  102. httpResponse.getContentType());
  103. }
  104. void HttpResponseTest::testDeterminFilename_without_ContentDisposition()
  105. {
  106. HttpResponse httpResponse;
  107. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  108. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  109. SharedHandle<Request> request(new Request());
  110. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  111. httpRequest->setRequest(request);
  112. httpResponse.setHttpHeader(httpHeader);
  113. httpResponse.setHttpRequest(httpRequest);
  114. CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"),
  115. httpResponse.determinFilename());
  116. }
  117. void HttpResponseTest::testDeterminFilename_with_ContentDisposition_zero_length
  118. ()
  119. {
  120. HttpResponse httpResponse;
  121. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  122. httpHeader->put("Content-Disposition", "attachment; filename=\"\"");
  123. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  124. SharedHandle<Request> request(new Request());
  125. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  126. httpRequest->setRequest(request);
  127. httpResponse.setHttpHeader(httpHeader);
  128. httpResponse.setHttpRequest(httpRequest);
  129. CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"),
  130. httpResponse.determinFilename());
  131. }
  132. void HttpResponseTest::testDeterminFilename_with_ContentDisposition()
  133. {
  134. HttpResponse httpResponse;
  135. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  136. httpHeader->put("Content-Disposition",
  137. "attachment; filename=\"aria2-current.tar.bz2\"");
  138. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  139. SharedHandle<Request> request(new Request());
  140. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  141. httpRequest->setRequest(request);
  142. httpResponse.setHttpHeader(httpHeader);
  143. httpResponse.setHttpRequest(httpRequest);
  144. CPPUNIT_ASSERT_EQUAL(std::string("aria2-current.tar.bz2"),
  145. httpResponse.determinFilename());
  146. }
  147. void HttpResponseTest::testGetRedirectURI_without_Location()
  148. {
  149. HttpResponse httpResponse;
  150. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  151. httpResponse.setHttpHeader(httpHeader);
  152. CPPUNIT_ASSERT_EQUAL(std::string(""),
  153. httpResponse.getRedirectURI());
  154. }
  155. void HttpResponseTest::testGetRedirectURI_with_Location()
  156. {
  157. HttpResponse httpResponse;
  158. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  159. httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2");
  160. httpResponse.setHttpHeader(httpHeader);
  161. CPPUNIT_ASSERT_EQUAL
  162. (std::string("http://localhost/download/aria2-1.0.0.tar.bz2"),
  163. httpResponse.getRedirectURI());
  164. }
  165. void HttpResponseTest::testIsRedirect()
  166. {
  167. HttpResponse httpResponse;
  168. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  169. httpHeader->setResponseStatus("200");
  170. httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2");
  171. httpResponse.setHttpHeader(httpHeader);
  172. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  173. httpHeader->setResponseStatus("304");
  174. CPPUNIT_ASSERT(httpResponse.isRedirect());
  175. }
  176. void HttpResponseTest::testIsTransferEncodingSpecified()
  177. {
  178. HttpResponse httpResponse;
  179. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  180. httpResponse.setHttpHeader(httpHeader);
  181. CPPUNIT_ASSERT(!httpResponse.isTransferEncodingSpecified());
  182. httpHeader->put("Transfer-Encoding", "chunked");
  183. CPPUNIT_ASSERT(httpResponse.isTransferEncodingSpecified());
  184. }
  185. void HttpResponseTest::testGetTransferEncoding()
  186. {
  187. HttpResponse httpResponse;
  188. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  189. httpResponse.setHttpHeader(httpHeader);
  190. CPPUNIT_ASSERT_EQUAL(std::string(""), httpResponse.getTransferEncoding());
  191. httpHeader->put("Transfer-Encoding", "chunked");
  192. CPPUNIT_ASSERT_EQUAL(std::string("chunked"),
  193. httpResponse.getTransferEncoding());
  194. }
  195. void HttpResponseTest::testGetTransferEncodingDecoder()
  196. {
  197. HttpResponse httpResponse;
  198. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  199. httpResponse.setHttpHeader(httpHeader);
  200. CPPUNIT_ASSERT(httpResponse.getTransferEncodingDecoder().isNull());
  201. httpHeader->put("Transfer-Encoding", "chunked");
  202. CPPUNIT_ASSERT(!httpResponse.getTransferEncodingDecoder().isNull());
  203. }
  204. void HttpResponseTest::testIsContentEncodingSpecified()
  205. {
  206. HttpResponse httpResponse;
  207. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  208. httpResponse.setHttpHeader(httpHeader);
  209. CPPUNIT_ASSERT(!httpResponse.isContentEncodingSpecified());
  210. httpHeader->put("Content-Encoding", "gzip");
  211. CPPUNIT_ASSERT(httpResponse.isContentEncodingSpecified());
  212. }
  213. void HttpResponseTest::testGetContentEncoding()
  214. {
  215. HttpResponse httpResponse;
  216. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  217. httpResponse.setHttpHeader(httpHeader);
  218. CPPUNIT_ASSERT_EQUAL(A2STR::NIL, httpResponse.getContentEncoding());
  219. httpHeader->put("Content-Encoding", "gzip");
  220. CPPUNIT_ASSERT_EQUAL(std::string("gzip"), httpResponse.getContentEncoding());
  221. }
  222. void HttpResponseTest::testGetContentEncodingDecoder()
  223. {
  224. HttpResponse httpResponse;
  225. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  226. httpResponse.setHttpHeader(httpHeader);
  227. CPPUNIT_ASSERT(httpResponse.getContentEncodingDecoder().isNull());
  228. #ifdef HAVE_LIBZ
  229. httpHeader->put("Content-Encoding", "gzip");
  230. {
  231. SharedHandle<Decoder> decoder = httpResponse.getContentEncodingDecoder();
  232. CPPUNIT_ASSERT(!decoder.isNull());
  233. CPPUNIT_ASSERT_EQUAL(std::string("GZipDecoder"), decoder->getName());
  234. }
  235. httpHeader.reset(new HttpHeader());
  236. httpResponse.setHttpHeader(httpHeader);
  237. httpHeader->put("Content-Encoding", "deflate");
  238. {
  239. SharedHandle<Decoder> decoder = httpResponse.getContentEncodingDecoder();
  240. CPPUNIT_ASSERT(!decoder.isNull());
  241. CPPUNIT_ASSERT_EQUAL(std::string("GZipDecoder"), decoder->getName());
  242. }
  243. #endif // HAVE_LIBZ
  244. httpHeader.reset(new HttpHeader());
  245. httpResponse.setHttpHeader(httpHeader);
  246. httpHeader->put("Content-Encoding", "bzip2");
  247. {
  248. SharedHandle<Decoder> decoder = httpResponse.getContentEncodingDecoder();
  249. CPPUNIT_ASSERT(decoder.isNull());
  250. }
  251. }
  252. void HttpResponseTest::testValidateResponse()
  253. {
  254. HttpResponse httpResponse;
  255. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  256. httpResponse.setHttpHeader(httpHeader);
  257. httpHeader->setResponseStatus("304");
  258. try {
  259. httpResponse.validateResponse();
  260. CPPUNIT_FAIL("exception must be thrown.");
  261. } catch(Exception& e) {
  262. }
  263. httpHeader->put("Location", "http://localhost/archives/aria2-1.0.0.tar.bz2");
  264. try {
  265. httpResponse.validateResponse();
  266. } catch(Exception& e) {
  267. CPPUNIT_FAIL("exception must not be thrown.");
  268. }
  269. }
  270. void HttpResponseTest::testValidateResponse_good_range()
  271. {
  272. HttpResponse httpResponse;
  273. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  274. httpResponse.setHttpHeader(httpHeader);
  275. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  276. SharedHandle<Piece> p(new Piece(1, 1024*1024));
  277. SharedHandle<Segment> segment(new PiecedSegment(1024*1024, p));
  278. httpRequest->setSegment(segment);
  279. SharedHandle<Request> request(new Request());
  280. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  281. httpRequest->setRequest(request);
  282. httpResponse.setHttpRequest(httpRequest);
  283. httpHeader->setResponseStatus("206");
  284. httpHeader->put("Content-Range", "bytes 1048576-10485760/10485761");
  285. try {
  286. httpResponse.validateResponse();
  287. } catch(Exception& e) {
  288. std::cerr << e.stackTrace() << std::endl;
  289. CPPUNIT_FAIL("exception must not be thrown.");
  290. }
  291. }
  292. void HttpResponseTest::testValidateResponse_bad_range()
  293. {
  294. HttpResponse httpResponse;
  295. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  296. httpResponse.setHttpHeader(httpHeader);
  297. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  298. SharedHandle<Piece> p(new Piece(1, 1024*1024));
  299. SharedHandle<Segment> segment(new PiecedSegment(1024*1024, p));
  300. httpRequest->setSegment(segment);
  301. SharedHandle<Request> request(new Request());
  302. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  303. httpRequest->setRequest(request);
  304. httpResponse.setHttpRequest(httpRequest);
  305. httpHeader->setResponseStatus("206");
  306. httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
  307. try {
  308. httpResponse.validateResponse();
  309. CPPUNIT_FAIL("exception must be thrown.");
  310. } catch(Exception& e) {
  311. }
  312. }
  313. void HttpResponseTest::testValidateResponse_chunked()
  314. {
  315. HttpResponse httpResponse;
  316. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  317. httpResponse.setHttpHeader(httpHeader);
  318. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  319. SharedHandle<Piece> p(new Piece(1, 1024*1024));
  320. SharedHandle<Segment> segment(new PiecedSegment(1024*1024, p));
  321. httpRequest->setSegment(segment);
  322. SharedHandle<Request> request(new Request());
  323. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  324. httpRequest->setRequest(request);
  325. httpResponse.setHttpRequest(httpRequest);
  326. httpHeader->setResponseStatus("206");
  327. httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
  328. httpHeader->put("Transfer-Encoding", "chunked");
  329. // if transfer-encoding is specified, then range validation is skipped.
  330. try {
  331. httpResponse.validateResponse();
  332. } catch(Exception& e) {
  333. CPPUNIT_FAIL("exception must not be thrown.");
  334. }
  335. }
  336. void HttpResponseTest::testHasRetryAfter()
  337. {
  338. HttpResponse httpResponse;
  339. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  340. httpResponse.setHttpHeader(httpHeader);
  341. httpHeader->put("Retry-After", "60");
  342. CPPUNIT_ASSERT(httpResponse.hasRetryAfter());
  343. CPPUNIT_ASSERT_EQUAL((time_t)60, httpResponse.getRetryAfter());
  344. }
  345. void HttpResponseTest::testProcessRedirect()
  346. {
  347. HttpResponse httpResponse;
  348. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  349. httpResponse.setHttpHeader(httpHeader);
  350. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  351. SharedHandle<Request> request(new Request());
  352. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  353. httpRequest->setRequest(request);
  354. httpResponse.setHttpRequest(httpRequest);
  355. httpHeader->put("Location", "http://mirror/aria2-1.0.0.tar.bz2");
  356. httpResponse.processRedirect();
  357. httpHeader->clearField();
  358. // Give unsupported scheme
  359. httpHeader->put("Location", "unsupported://mirror/aria2-1.0.0.tar.bz2");
  360. try {
  361. httpResponse.processRedirect();
  362. CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
  363. } catch(DlRetryEx& e) {
  364. // Success
  365. } catch(...) {
  366. CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
  367. }
  368. }
  369. void HttpResponseTest::testRetrieveCookie()
  370. {
  371. HttpResponse httpResponse;
  372. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  373. httpResponse.setHttpHeader(httpHeader);
  374. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  375. SharedHandle<Request> request(new Request());
  376. request->setUrl("http://www.aria2.org/archives/aria2-1.0.0.tar.bz2");
  377. httpRequest->setRequest(request);
  378. SharedHandle<CookieStorage> st(new CookieStorage());
  379. httpRequest->setCookieStorage(st);
  380. httpResponse.setHttpRequest(httpRequest);
  381. httpHeader->put("Set-Cookie", "k1=v1; expires=Sun, 2007-06-10 11:00:00 GMT;"
  382. "path=/; domain=.aria2.org;");
  383. httpHeader->put("Set-Cookie", "k2=v2; expires=Sun, 2038-01-01 00:00:00 GMT;"
  384. "path=/; domain=.aria2.org;");
  385. httpHeader->put("Set-Cookie", "k3=v3;");
  386. httpResponse.retrieveCookie();
  387. CPPUNIT_ASSERT_EQUAL((size_t)2, st->size());
  388. std::deque<Cookie>::const_iterator citer = st->begin();
  389. CPPUNIT_ASSERT_EQUAL(std::string("k2=v2"), (*(st->begin())).toString());
  390. CPPUNIT_ASSERT_EQUAL(std::string("k3=v3"), (*(st->begin()+1)).toString());
  391. }
  392. } // namespace aria2