HttpResponseTest.cc 24 KB

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