HttpResponseTest.cc 23 KB

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