HttpResponseTest.cc 23 KB

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