HttpResponseTest.cc 24 KB

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