HttpResponseTest.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. #include "HttpResponse.h"
  2. #include <iostream>
  3. #include <cppunit/extensions/HelperMacros.h>
  4. #include "TestUtil.h"
  5. #include "prefs.h"
  6. #include "PiecedSegment.h"
  7. #include "Piece.h"
  8. #include "Request.h"
  9. #include "HttpHeader.h"
  10. #include "HttpRequest.h"
  11. #include "Exception.h"
  12. #include "A2STR.h"
  13. #include "DlRetryEx.h"
  14. #include "CookieStorage.h"
  15. #include "AuthConfigFactory.h"
  16. #include "AuthConfig.h"
  17. #include "StreamFilter.h"
  18. #include "MetalinkHttpEntry.h"
  19. #include "Option.h"
  20. #include "Checksum.h"
  21. namespace aria2 {
  22. class HttpResponseTest : public CppUnit::TestFixture {
  23. CPPUNIT_TEST_SUITE(HttpResponseTest);
  24. CPPUNIT_TEST(testGetContentLength_null);
  25. CPPUNIT_TEST(testGetContentLength_contentLength);
  26. //CPPUNIT_TEST(testGetContentLength_range);
  27. CPPUNIT_TEST(testGetEntityLength);
  28. CPPUNIT_TEST(testGetContentType);
  29. CPPUNIT_TEST(testDetermineFilename_without_ContentDisposition);
  30. CPPUNIT_TEST(testDetermineFilename_with_ContentDisposition_zero_length);
  31. CPPUNIT_TEST(testDetermineFilename_with_ContentDisposition);
  32. CPPUNIT_TEST(testGetRedirectURI_without_Location);
  33. CPPUNIT_TEST(testGetRedirectURI_with_Location);
  34. CPPUNIT_TEST(testIsRedirect);
  35. CPPUNIT_TEST(testIsTransferEncodingSpecified);
  36. CPPUNIT_TEST(testGetTransferEncoding);
  37. CPPUNIT_TEST(testGetTransferEncodingStreamFilter);
  38. CPPUNIT_TEST(testIsContentEncodingSpecified);
  39. CPPUNIT_TEST(testGetContentEncoding);
  40. CPPUNIT_TEST(testGetContentEncodingStreamFilter);
  41. CPPUNIT_TEST(testValidateResponse);
  42. CPPUNIT_TEST(testValidateResponse_good_range);
  43. CPPUNIT_TEST(testValidateResponse_bad_range);
  44. CPPUNIT_TEST(testValidateResponse_chunked);
  45. CPPUNIT_TEST(testValidateResponse_withIfModifiedSince);
  46. CPPUNIT_TEST(testProcessRedirect);
  47. CPPUNIT_TEST(testRetrieveCookie);
  48. CPPUNIT_TEST(testSupportsPersistentConnection);
  49. CPPUNIT_TEST(testGetMetalinKHttpEntries);
  50. #ifdef ENABLE_MESSAGE_DIGEST
  51. CPPUNIT_TEST(testGetDigest);
  52. #endif // ENABLE_MESSAGE_DIGEST
  53. CPPUNIT_TEST_SUITE_END();
  54. private:
  55. public:
  56. void setUp() {
  57. }
  58. void testGetContentLength_null();
  59. void testGetContentLength_contentLength();
  60. void testGetEntityLength();
  61. void testGetContentType();
  62. void testDetermineFilename_without_ContentDisposition();
  63. void testDetermineFilename_with_ContentDisposition_zero_length();
  64. void testDetermineFilename_with_ContentDisposition();
  65. void testGetRedirectURI_without_Location();
  66. void testGetRedirectURI_with_Location();
  67. void testIsRedirect();
  68. void testIsTransferEncodingSpecified();
  69. void testGetTransferEncoding();
  70. void testGetTransferEncodingStreamFilter();
  71. void testIsContentEncodingSpecified();
  72. void testGetContentEncoding();
  73. void testGetContentEncodingStreamFilter();
  74. void testValidateResponse();
  75. void testValidateResponse_good_range();
  76. void testValidateResponse_bad_range();
  77. void testValidateResponse_chunked();
  78. void testValidateResponse_withIfModifiedSince();
  79. void testProcessRedirect();
  80. void testRetrieveCookie();
  81. void testSupportsPersistentConnection();
  82. void testGetMetalinKHttpEntries();
  83. #ifdef ENABLE_MESSAGE_DIGEST
  84. void testGetDigest();
  85. #endif // ENABLE_MESSAGE_DIGEST
  86. };
  87. CPPUNIT_TEST_SUITE_REGISTRATION( HttpResponseTest );
  88. void HttpResponseTest::testGetContentLength_null()
  89. {
  90. HttpResponse httpResponse;
  91. CPPUNIT_ASSERT_EQUAL((int64_t)0LL, httpResponse.getContentLength());
  92. }
  93. void HttpResponseTest::testGetContentLength_contentLength()
  94. {
  95. HttpResponse httpResponse;
  96. auto httpHeader = make_unique<HttpHeader>();
  97. httpHeader->put(HttpHeader::CONTENT_LENGTH, "4294967296");
  98. httpResponse.setHttpHeader(std::move(httpHeader));
  99. CPPUNIT_ASSERT_EQUAL((int64_t)4294967296LL, httpResponse.getContentLength());
  100. }
  101. void HttpResponseTest::testGetEntityLength()
  102. {
  103. HttpResponse httpResponse;
  104. auto httpHeader = make_unique<HttpHeader>();
  105. httpHeader->put(HttpHeader::CONTENT_LENGTH, "4294967296");
  106. httpResponse.setHttpHeader(std::move(httpHeader));
  107. CPPUNIT_ASSERT_EQUAL((int64_t)4294967296LL, httpResponse.getEntityLength());
  108. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_RANGE,
  109. "bytes 1-4294967296/4294967297");
  110. CPPUNIT_ASSERT_EQUAL((int64_t)4294967297LL, httpResponse.getEntityLength());
  111. }
  112. void HttpResponseTest::testGetContentType()
  113. {
  114. HttpResponse httpResponse;
  115. auto httpHeader = make_unique<HttpHeader>();
  116. httpHeader->put(HttpHeader::CONTENT_TYPE,
  117. "application/metalink+xml; charset=UTF-8");
  118. httpResponse.setHttpHeader(std::move(httpHeader));
  119. // See paramter is ignored.
  120. CPPUNIT_ASSERT_EQUAL(std::string("application/metalink+xml"),
  121. httpResponse.getContentType());
  122. }
  123. void HttpResponseTest::testDetermineFilename_without_ContentDisposition()
  124. {
  125. HttpResponse httpResponse;
  126. auto httpRequest = make_unique<HttpRequest>();
  127. auto request = std::make_shared<Request>();
  128. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  129. httpRequest->setRequest(request);
  130. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  131. httpResponse.setHttpRequest(std::move(httpRequest));
  132. CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"),
  133. httpResponse.determineFilename());
  134. }
  135. void HttpResponseTest::testDetermineFilename_with_ContentDisposition_zero_length
  136. ()
  137. {
  138. HttpResponse httpResponse;
  139. auto httpHeader = make_unique<HttpHeader>();
  140. httpHeader->put(HttpHeader::CONTENT_DISPOSITION, "attachment; filename=\"\"");
  141. auto httpRequest = make_unique<HttpRequest>();
  142. auto request = std::make_shared<Request>();
  143. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  144. httpRequest->setRequest(request);
  145. httpResponse.setHttpHeader(std::move(httpHeader));
  146. httpResponse.setHttpRequest(std::move(httpRequest));
  147. CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"),
  148. httpResponse.determineFilename());
  149. }
  150. void HttpResponseTest::testDetermineFilename_with_ContentDisposition()
  151. {
  152. HttpResponse httpResponse;
  153. auto httpHeader = make_unique<HttpHeader>();
  154. httpHeader->put(HttpHeader::CONTENT_DISPOSITION,
  155. "attachment; filename=\"aria2-current.tar.bz2\"");
  156. auto httpRequest = make_unique<HttpRequest>();
  157. auto request = std::make_shared<Request>();
  158. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  159. httpRequest->setRequest(request);
  160. httpResponse.setHttpHeader(std::move(httpHeader));
  161. httpResponse.setHttpRequest(std::move(httpRequest));
  162. CPPUNIT_ASSERT_EQUAL(std::string("aria2-current.tar.bz2"),
  163. httpResponse.determineFilename());
  164. }
  165. void HttpResponseTest::testGetRedirectURI_without_Location()
  166. {
  167. HttpResponse httpResponse;
  168. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  169. CPPUNIT_ASSERT_EQUAL(std::string(""),
  170. httpResponse.getRedirectURI());
  171. }
  172. void HttpResponseTest::testGetRedirectURI_with_Location()
  173. {
  174. HttpResponse httpResponse;
  175. auto httpHeader = make_unique<HttpHeader>();
  176. httpHeader->put(HttpHeader::LOCATION,
  177. "http://localhost/download/aria2-1.0.0.tar.bz2");
  178. httpResponse.setHttpHeader(std::move(httpHeader));
  179. CPPUNIT_ASSERT_EQUAL
  180. (std::string("http://localhost/download/aria2-1.0.0.tar.bz2"),
  181. httpResponse.getRedirectURI());
  182. }
  183. void HttpResponseTest::testIsRedirect()
  184. {
  185. HttpResponse httpResponse;
  186. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  187. httpResponse.getHttpHeader()->setStatusCode(301);
  188. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  189. httpResponse.getHttpHeader()->setStatusCode(200);
  190. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  191. httpResponse.getHttpHeader()->put
  192. (HttpHeader::LOCATION,
  193. "http://localhost/download/aria2-1.0.0.tar.bz2");
  194. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  195. httpResponse.getHttpHeader()->setStatusCode(300);
  196. CPPUNIT_ASSERT(httpResponse.isRedirect());
  197. httpResponse.getHttpHeader()->setStatusCode(301);
  198. CPPUNIT_ASSERT(httpResponse.isRedirect());
  199. httpResponse.getHttpHeader()->setStatusCode(302);
  200. CPPUNIT_ASSERT(httpResponse.isRedirect());
  201. httpResponse.getHttpHeader()->setStatusCode(303);
  202. CPPUNIT_ASSERT(httpResponse.isRedirect());
  203. httpResponse.getHttpHeader()->setStatusCode(304);
  204. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  205. httpResponse.getHttpHeader()->setStatusCode(305);
  206. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  207. httpResponse.getHttpHeader()->setStatusCode(306);
  208. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  209. httpResponse.getHttpHeader()->setStatusCode(307);
  210. CPPUNIT_ASSERT(httpResponse.isRedirect());
  211. httpResponse.getHttpHeader()->setStatusCode(308);
  212. CPPUNIT_ASSERT(httpResponse.isRedirect());
  213. httpResponse.getHttpHeader()->setStatusCode(309);
  214. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  215. }
  216. void HttpResponseTest::testIsTransferEncodingSpecified()
  217. {
  218. HttpResponse httpResponse;
  219. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  220. CPPUNIT_ASSERT(!httpResponse.isTransferEncodingSpecified());
  221. httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
  222. CPPUNIT_ASSERT(httpResponse.isTransferEncodingSpecified());
  223. }
  224. void HttpResponseTest::testGetTransferEncoding()
  225. {
  226. HttpResponse httpResponse;
  227. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  228. CPPUNIT_ASSERT_EQUAL(std::string(""), httpResponse.getTransferEncoding());
  229. httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
  230. CPPUNIT_ASSERT_EQUAL(std::string("chunked"),
  231. httpResponse.getTransferEncoding());
  232. }
  233. void HttpResponseTest::testGetTransferEncodingStreamFilter()
  234. {
  235. HttpResponse httpResponse;
  236. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  237. CPPUNIT_ASSERT(!httpResponse.getTransferEncodingStreamFilter());
  238. httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
  239. CPPUNIT_ASSERT(httpResponse.getTransferEncodingStreamFilter());
  240. }
  241. void HttpResponseTest::testIsContentEncodingSpecified()
  242. {
  243. HttpResponse httpResponse;
  244. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  245. CPPUNIT_ASSERT(!httpResponse.isContentEncodingSpecified());
  246. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "gzip");
  247. CPPUNIT_ASSERT(httpResponse.isContentEncodingSpecified());
  248. }
  249. void HttpResponseTest::testGetContentEncoding()
  250. {
  251. HttpResponse httpResponse;
  252. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  253. CPPUNIT_ASSERT_EQUAL(A2STR::NIL, httpResponse.getContentEncoding());
  254. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "gzip");
  255. CPPUNIT_ASSERT_EQUAL(std::string("gzip"), httpResponse.getContentEncoding());
  256. }
  257. void HttpResponseTest::testGetContentEncodingStreamFilter()
  258. {
  259. HttpResponse httpResponse;
  260. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  261. CPPUNIT_ASSERT(!httpResponse.getContentEncodingStreamFilter());
  262. #ifdef HAVE_ZLIB
  263. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "gzip");
  264. {
  265. std::shared_ptr<StreamFilter> filter =
  266. httpResponse.getContentEncodingStreamFilter();
  267. CPPUNIT_ASSERT(filter);
  268. CPPUNIT_ASSERT_EQUAL(std::string("GZipDecodingStreamFilter"),
  269. filter->getName());
  270. }
  271. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  272. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "deflate");
  273. {
  274. std::shared_ptr<StreamFilter> filter =
  275. httpResponse.getContentEncodingStreamFilter();
  276. CPPUNIT_ASSERT(filter);
  277. CPPUNIT_ASSERT_EQUAL(std::string("GZipDecodingStreamFilter"),
  278. filter->getName());
  279. }
  280. #endif // HAVE_ZLIB
  281. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  282. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_ENCODING, "bzip2");
  283. {
  284. std::shared_ptr<StreamFilter> filter =
  285. httpResponse.getContentEncodingStreamFilter();
  286. CPPUNIT_ASSERT(!filter);
  287. }
  288. }
  289. void HttpResponseTest::testValidateResponse()
  290. {
  291. HttpResponse httpResponse;
  292. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  293. httpResponse.getHttpHeader()->setStatusCode(301);
  294. try {
  295. httpResponse.validateResponse();
  296. CPPUNIT_FAIL("exception must be thrown.");
  297. } catch(Exception& e) {
  298. // success
  299. }
  300. httpResponse.getHttpHeader()->put(HttpHeader::LOCATION, "http://a/b");
  301. httpResponse.validateResponse();
  302. httpResponse.getHttpHeader()->setStatusCode(201);
  303. try{
  304. httpResponse.validateResponse();
  305. CPPUNIT_FAIL("exception must be thrown.");
  306. } catch(Exception& e) {
  307. // success
  308. }
  309. }
  310. void HttpResponseTest::testValidateResponse_good_range()
  311. {
  312. HttpResponse httpResponse;
  313. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  314. auto httpRequest = make_unique<HttpRequest>();
  315. auto p = std::make_shared<Piece>(1, 1024*1024);
  316. auto segment = std::make_shared<PiecedSegment>(1024*1024, p);
  317. httpRequest->setSegment(segment);
  318. auto fileEntry = std::make_shared<FileEntry>("file", 1024*1024*10, 0);
  319. httpRequest->setFileEntry(fileEntry);
  320. auto request = std::make_shared<Request>();
  321. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  322. httpRequest->setRequest(request);
  323. httpResponse.setHttpRequest(std::move(httpRequest));
  324. httpResponse.getHttpHeader()->setStatusCode(206);
  325. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_RANGE,
  326. "bytes 1048576-10485760/10485760");
  327. try {
  328. httpResponse.validateResponse();
  329. } catch(Exception& e) {
  330. std::cerr << e.stackTrace() << std::endl;
  331. CPPUNIT_FAIL("exception must not be thrown.");
  332. }
  333. }
  334. void HttpResponseTest::testValidateResponse_bad_range()
  335. {
  336. HttpResponse httpResponse;
  337. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  338. auto httpRequest = make_unique<HttpRequest>();
  339. auto p = std::make_shared<Piece>(1, 1024*1024);
  340. auto segment = std::make_shared<PiecedSegment>(1024*1024, p);
  341. httpRequest->setSegment(segment);
  342. auto fileEntry = std::make_shared<FileEntry>("file", 1024*1024*10, 0);
  343. httpRequest->setFileEntry(fileEntry);
  344. auto request = std::make_shared<Request>();
  345. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  346. httpRequest->setRequest(request);
  347. httpResponse.setHttpRequest(std::move(httpRequest));
  348. httpResponse.getHttpHeader()->setStatusCode(206);
  349. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_RANGE,
  350. "bytes 0-10485760/10485761");
  351. try {
  352. httpResponse.validateResponse();
  353. CPPUNIT_FAIL("exception must be thrown.");
  354. } catch(Exception& e) {
  355. }
  356. }
  357. void HttpResponseTest::testValidateResponse_chunked()
  358. {
  359. HttpResponse httpResponse;
  360. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  361. auto httpRequest = make_unique<HttpRequest>();
  362. auto p = std::make_shared<Piece>(1, 1024*1024);
  363. auto segment = std::make_shared<PiecedSegment>(1024*1024, p);
  364. httpRequest->setSegment(segment);
  365. auto fileEntry = std::make_shared<FileEntry>("file", 1024*1024*10, 0);
  366. httpRequest->setFileEntry(fileEntry);
  367. auto request = std::make_shared<Request>();
  368. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  369. httpRequest->setRequest(request);
  370. httpResponse.setHttpRequest(std::move(httpRequest));
  371. httpResponse.getHttpHeader()->setStatusCode(206);
  372. httpResponse.getHttpHeader()->put(HttpHeader::CONTENT_RANGE,
  373. "bytes 0-10485760/10485761");
  374. httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
  375. // if transfer-encoding is specified, then range validation is skipped.
  376. try {
  377. httpResponse.validateResponse();
  378. } catch(Exception& e) {
  379. CPPUNIT_FAIL("exception must not be thrown.");
  380. }
  381. }
  382. void HttpResponseTest::testValidateResponse_withIfModifiedSince()
  383. {
  384. HttpResponse httpResponse;
  385. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  386. httpResponse.getHttpHeader()->setStatusCode(304);
  387. auto httpRequest = make_unique<HttpRequest>();
  388. httpResponse.setHttpRequest(std::move(httpRequest));
  389. try {
  390. httpResponse.validateResponse();
  391. CPPUNIT_FAIL("exception must be thrown.");
  392. } catch(Exception& e) {
  393. }
  394. httpRequest = make_unique<HttpRequest>();
  395. httpRequest->setIfModifiedSinceHeader("Fri, 16 Jul 2010 12:56:59 GMT");
  396. httpResponse.setHttpRequest(std::move(httpRequest));
  397. httpResponse.validateResponse();
  398. }
  399. void HttpResponseTest::testProcessRedirect()
  400. {
  401. HttpResponse httpResponse;
  402. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  403. auto httpRequest = make_unique<HttpRequest>();
  404. auto request = std::make_shared<Request>();
  405. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  406. httpRequest->setRequest(request);
  407. httpResponse.setHttpRequest(std::move(httpRequest));
  408. httpResponse.getHttpHeader()->put(HttpHeader::LOCATION,
  409. "http://mirror/aria2-1.0.0.tar.bz2");
  410. httpResponse.processRedirect();
  411. httpResponse.getHttpHeader()->clearField();
  412. // Test for percent-encode
  413. httpResponse.getHttpHeader()->put(HttpHeader::LOCATION,
  414. "http://example.org/white space#aria2");
  415. httpResponse.processRedirect();
  416. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/white%20space"),
  417. request->getCurrentUri());
  418. httpResponse.getHttpHeader()->clearField();
  419. // Give unsupported scheme
  420. httpResponse.getHttpHeader()->put
  421. (HttpHeader::LOCATION, "unsupported://mirror/aria2-1.0.0.tar.bz2");
  422. try {
  423. httpResponse.processRedirect();
  424. CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
  425. } catch(DlRetryEx& e) {
  426. // Success
  427. } catch(...) {
  428. CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
  429. }
  430. }
  431. void HttpResponseTest::testRetrieveCookie()
  432. {
  433. HttpResponse httpResponse;
  434. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  435. auto httpRequest = make_unique<HttpRequest>();
  436. auto request = std::make_shared<Request>();
  437. request->setUri("http://www.aria2.org/archives/aria2-1.0.0.tar.bz2");
  438. httpRequest->setRequest(request);
  439. CookieStorage st;
  440. httpRequest->setCookieStorage(&st);
  441. httpResponse.setHttpRequest(std::move(httpRequest));
  442. httpResponse.getHttpHeader()->put
  443. (HttpHeader::SET_COOKIE,
  444. "k1=v1; expires=Sun, 10-Jun-2007 11:00:00 GMT;"
  445. "path=/; domain=.aria2.org;");
  446. httpResponse.getHttpHeader()->put
  447. (HttpHeader::SET_COOKIE,
  448. "k2=v2; expires=Sun, 01-Jan-38 00:00:00 GMT;"
  449. "path=/; domain=.aria2.org;");
  450. httpResponse.getHttpHeader()->put(HttpHeader::SET_COOKIE, "k3=v3;");
  451. httpResponse.retrieveCookie();
  452. CPPUNIT_ASSERT_EQUAL((size_t)2, st.size());
  453. auto cookies = std::vector<const Cookie*>{};
  454. st.dumpCookie(std::back_inserter(cookies));
  455. std::sort(std::begin(cookies), std::end(cookies), CookieSorter());
  456. CPPUNIT_ASSERT_EQUAL(std::string("k2=v2"), cookies[0]->toString());
  457. CPPUNIT_ASSERT_EQUAL(std::string("k3=v3"), cookies[1]->toString());
  458. }
  459. void HttpResponseTest::testSupportsPersistentConnection()
  460. {
  461. HttpResponse httpResponse;
  462. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  463. httpResponse.setHttpRequest(make_unique<HttpRequest>());
  464. httpResponse.getHttpHeader()->setVersion("HTTP/1.1");
  465. CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
  466. httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "close");
  467. CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
  468. httpResponse.getHttpHeader()->clearField();
  469. httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "keep-alive");
  470. CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
  471. httpResponse.getHttpHeader()->clearField();
  472. httpResponse.getHttpHeader()->setVersion("HTTP/1.0");
  473. CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
  474. httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "close");
  475. CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
  476. httpResponse.getHttpHeader()->clearField();
  477. httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "keep-alive");
  478. CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
  479. httpResponse.getHttpHeader()->clearField();
  480. // test proxy connection
  481. auto httpRequest = make_unique<HttpRequest>();
  482. httpRequest->setProxyRequest(std::make_shared<Request>());
  483. httpResponse.setHttpRequest(std::move(httpRequest));
  484. httpResponse.getHttpHeader()->setVersion("HTTP/1.1");
  485. CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
  486. httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "close");
  487. CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
  488. httpResponse.getHttpHeader()->clearField();
  489. httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "keep-alive");
  490. CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
  491. httpResponse.getHttpHeader()->clearField();
  492. httpResponse.getHttpHeader()->setVersion("HTTP/1.0");
  493. CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
  494. httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "close");
  495. CPPUNIT_ASSERT(!httpResponse.supportsPersistentConnection());
  496. httpResponse.getHttpHeader()->clearField();
  497. httpResponse.getHttpHeader()->put(HttpHeader::CONNECTION, "keep-alive");
  498. CPPUNIT_ASSERT(httpResponse.supportsPersistentConnection());
  499. httpResponse.getHttpHeader()->clearField();
  500. }
  501. void HttpResponseTest::testGetMetalinKHttpEntries()
  502. {
  503. HttpResponse httpResponse;
  504. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  505. std::shared_ptr<Option> option(new Option());
  506. httpResponse.getHttpHeader()->put
  507. (HttpHeader::LINK,
  508. "<http://uri1/>; rel=duplicate; pri=1; pref; geo=JP");
  509. httpResponse.getHttpHeader()->put
  510. (HttpHeader::LINK,
  511. "<http://uri2/>; rel=duplicate");
  512. httpResponse.getHttpHeader()->put
  513. (HttpHeader::LINK,
  514. "<http://uri3/>;;;;;;;;rel=duplicate;;;;;pri=2;;;;;");
  515. httpResponse.getHttpHeader()->put
  516. (HttpHeader::LINK,
  517. "<http://uri4/>;rel=duplicate;=pri=1;pref");
  518. httpResponse.getHttpHeader()->put
  519. (HttpHeader::LINK,
  520. "<http://describedby>; rel=describedby");
  521. httpResponse.getHttpHeader()->put
  522. (HttpHeader::LINK,
  523. "<http://norel/>");
  524. httpResponse.getHttpHeader()->put
  525. (HttpHeader::LINK,
  526. "<baduri>; rel=duplicate; pri=-1;");
  527. std::vector<MetalinkHttpEntry> result;
  528. httpResponse.getMetalinKHttpEntries(result, option);
  529. CPPUNIT_ASSERT_EQUAL((size_t)5, result.size());
  530. MetalinkHttpEntry e = result[0];
  531. CPPUNIT_ASSERT_EQUAL(std::string("http://uri1/"), e.uri);
  532. CPPUNIT_ASSERT_EQUAL(1, e.pri);
  533. CPPUNIT_ASSERT(e.pref);
  534. CPPUNIT_ASSERT_EQUAL(std::string("jp"), e.geo);
  535. e = result[1];
  536. CPPUNIT_ASSERT_EQUAL(std::string("http://uri4/"), e.uri);
  537. CPPUNIT_ASSERT_EQUAL(999999, e.pri);
  538. CPPUNIT_ASSERT(e.pref);
  539. CPPUNIT_ASSERT(e.geo.empty());
  540. e = result[2];
  541. CPPUNIT_ASSERT_EQUAL(std::string("http://uri3/"), e.uri);
  542. CPPUNIT_ASSERT_EQUAL(2, e.pri);
  543. CPPUNIT_ASSERT(!e.pref);
  544. CPPUNIT_ASSERT(e.geo.empty());
  545. e = result[3];
  546. CPPUNIT_ASSERT_EQUAL(std::string("http://uri2/"), e.uri);
  547. CPPUNIT_ASSERT_EQUAL(999999, e.pri);
  548. CPPUNIT_ASSERT(!e.pref);
  549. CPPUNIT_ASSERT(e.geo.empty());
  550. e = result[4];
  551. CPPUNIT_ASSERT_EQUAL(std::string("baduri"), e.uri);
  552. CPPUNIT_ASSERT_EQUAL(999999, e.pri);
  553. CPPUNIT_ASSERT(!e.pref);
  554. CPPUNIT_ASSERT(e.geo.empty());
  555. }
  556. #ifdef ENABLE_MESSAGE_DIGEST
  557. void HttpResponseTest::testGetDigest()
  558. {
  559. HttpResponse httpResponse;
  560. httpResponse.setHttpHeader(make_unique<HttpHeader>());
  561. std::shared_ptr<Option> option(new Option());
  562. // Python binascii.hexlify(base64.b64decode(B64ED_HASH)) is handy to
  563. // retrieve ascii hex hash string.
  564. httpResponse.getHttpHeader()->put(HttpHeader::DIGEST,
  565. "SHA-1=82AD8itGL/oYQ5BTPFANiYnp9oE=");
  566. httpResponse.getHttpHeader()->put(HttpHeader::DIGEST, "NOT_SUPPORTED");
  567. httpResponse.getHttpHeader()->put
  568. (HttpHeader::DIGEST,
  569. "SHA-224=rQdowoLHQJTMVZ3rF7vmYOIzUXlu7F+FcMbPnA==");
  570. httpResponse.getHttpHeader()->put
  571. (HttpHeader::DIGEST,
  572. "SHA-224=6Ik6LNZ1iPy6cbmlKO4NHfvxzaiurmHilMyhGA==");
  573. httpResponse.getHttpHeader()->put
  574. (HttpHeader::DIGEST,
  575. "SHA-256=+D8nGudz3G/kpkVKQeDrI3xD57v0UeQmzGCZOk03nsU=,"
  576. "MD5=LJDK2+9ClF8Nz/K5WZd/+A==");
  577. std::vector<Checksum> result;
  578. httpResponse.getDigest(result);
  579. #ifdef USE_INTERNAL_MD
  580. CPPUNIT_ASSERT_EQUAL((size_t)2, result.size());
  581. #else
  582. CPPUNIT_ASSERT_EQUAL((size_t)3, result.size());
  583. #endif
  584. Checksum c = result[0];
  585. #ifndef USE_INTERNAL_MD
  586. CPPUNIT_ASSERT_EQUAL(std::string("sha-256"), c.getHashType());
  587. CPPUNIT_ASSERT_EQUAL(std::string("f83f271ae773dc6fe4a6454a41e0eb237c43e7bbf451e426cc60993a4d379ec5"),
  588. util::toHex(c.getDigest()));
  589. c = result[1];
  590. #endif
  591. CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c.getHashType());
  592. CPPUNIT_ASSERT_EQUAL(std::string("f36003f22b462ffa184390533c500d8989e9f681"),
  593. util::toHex(c.getDigest()));
  594. }
  595. #endif // ENABLE_MESSAGE_DIGEST
  596. } // namespace aria2