HttpResponseTest.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. #include "HttpResponse.h"
  2. #include "prefs.h"
  3. #include "PiecedSegment.h"
  4. #include "Piece.h"
  5. #include "Request.h"
  6. #include "HttpHeader.h"
  7. #include "HttpRequest.h"
  8. #include "Exception.h"
  9. #include "A2STR.h"
  10. #include "Decoder.h"
  11. #include "DlRetryEx.h"
  12. #include <iostream>
  13. #include <cppunit/extensions/HelperMacros.h>
  14. namespace aria2 {
  15. class HttpResponseTest : public CppUnit::TestFixture {
  16. CPPUNIT_TEST_SUITE(HttpResponseTest);
  17. CPPUNIT_TEST(testGetContentLength_null);
  18. CPPUNIT_TEST(testGetContentLength_contentLength);
  19. //CPPUNIT_TEST(testGetContentLength_range);
  20. CPPUNIT_TEST(testGetEntityLength);
  21. CPPUNIT_TEST(testGetContentType);
  22. CPPUNIT_TEST(testDeterminFilename_without_ContentDisposition);
  23. CPPUNIT_TEST(testDeterminFilename_with_ContentDisposition_zero_length);
  24. CPPUNIT_TEST(testDeterminFilename_with_ContentDisposition);
  25. CPPUNIT_TEST(testGetRedirectURI_without_Location);
  26. CPPUNIT_TEST(testGetRedirectURI_with_Location);
  27. CPPUNIT_TEST(testIsRedirect);
  28. CPPUNIT_TEST(testIsTransferEncodingSpecified);
  29. CPPUNIT_TEST(testGetTransferEncoding);
  30. CPPUNIT_TEST(testGetTransferEncodingDecoder);
  31. CPPUNIT_TEST(testIsContentEncodingSpecified);
  32. CPPUNIT_TEST(testGetContentEncoding);
  33. CPPUNIT_TEST(testGetContentEncodingDecoder);
  34. CPPUNIT_TEST(testValidateResponse);
  35. CPPUNIT_TEST(testValidateResponse_good_range);
  36. CPPUNIT_TEST(testValidateResponse_bad_range);
  37. CPPUNIT_TEST(testValidateResponse_chunked);
  38. CPPUNIT_TEST(testHasRetryAfter);
  39. CPPUNIT_TEST(testProcessRedirect);
  40. CPPUNIT_TEST_SUITE_END();
  41. private:
  42. public:
  43. void setUp() {
  44. }
  45. void testGetContentLength_null();
  46. void testGetContentLength_contentLength();
  47. void testGetEntityLength();
  48. void testGetContentType();
  49. void testDeterminFilename_without_ContentDisposition();
  50. void testDeterminFilename_with_ContentDisposition_zero_length();
  51. void testDeterminFilename_with_ContentDisposition();
  52. void testGetRedirectURI_without_Location();
  53. void testGetRedirectURI_with_Location();
  54. void testIsRedirect();
  55. void testIsTransferEncodingSpecified();
  56. void testGetTransferEncoding();
  57. void testGetTransferEncodingDecoder();
  58. void testIsContentEncodingSpecified();
  59. void testGetContentEncoding();
  60. void testGetContentEncodingDecoder();
  61. void testValidateResponse();
  62. void testValidateResponse_good_range();
  63. void testValidateResponse_bad_range();
  64. void testValidateResponse_chunked();
  65. void testHasRetryAfter();
  66. void testProcessRedirect();
  67. };
  68. CPPUNIT_TEST_SUITE_REGISTRATION( HttpResponseTest );
  69. void HttpResponseTest::testGetContentLength_null()
  70. {
  71. HttpResponse httpResponse;
  72. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, httpResponse.getContentLength());
  73. }
  74. void HttpResponseTest::testGetContentLength_contentLength()
  75. {
  76. HttpResponse httpResponse;
  77. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  78. httpHeader->put("Content-Length", "4294967296");
  79. httpResponse.setHttpHeader(httpHeader);
  80. CPPUNIT_ASSERT_EQUAL((uint64_t)4294967296ULL, httpResponse.getContentLength());
  81. }
  82. void HttpResponseTest::testGetEntityLength()
  83. {
  84. HttpResponse httpResponse;
  85. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  86. httpHeader->put("Content-Length", "4294967296");
  87. httpResponse.setHttpHeader(httpHeader);
  88. CPPUNIT_ASSERT_EQUAL((uint64_t)4294967296ULL, httpResponse.getEntityLength());
  89. httpHeader->put("Content-Range", "bytes 1-4294967296/4294967297");
  90. CPPUNIT_ASSERT_EQUAL((uint64_t)4294967297ULL, httpResponse.getEntityLength());
  91. }
  92. void HttpResponseTest::testGetContentType()
  93. {
  94. HttpResponse httpResponse;
  95. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  96. httpHeader->put("content-type", "application/octet-stream");
  97. httpResponse.setHttpHeader(httpHeader);
  98. CPPUNIT_ASSERT_EQUAL(std::string("application/octet-stream"),
  99. httpResponse.getContentType());
  100. }
  101. void HttpResponseTest::testDeterminFilename_without_ContentDisposition()
  102. {
  103. HttpResponse httpResponse;
  104. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  105. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  106. SharedHandle<Request> request(new Request());
  107. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  108. httpRequest->setRequest(request);
  109. httpResponse.setHttpHeader(httpHeader);
  110. httpResponse.setHttpRequest(httpRequest);
  111. CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"),
  112. httpResponse.determinFilename());
  113. }
  114. void HttpResponseTest::testDeterminFilename_with_ContentDisposition_zero_length
  115. ()
  116. {
  117. HttpResponse httpResponse;
  118. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  119. httpHeader->put("Content-Disposition", "attachment; filename=\"\"");
  120. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  121. SharedHandle<Request> request(new Request());
  122. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  123. httpRequest->setRequest(request);
  124. httpResponse.setHttpHeader(httpHeader);
  125. httpResponse.setHttpRequest(httpRequest);
  126. CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.0.tar.bz2"),
  127. httpResponse.determinFilename());
  128. }
  129. void HttpResponseTest::testDeterminFilename_with_ContentDisposition()
  130. {
  131. HttpResponse httpResponse;
  132. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  133. httpHeader->put("Content-Disposition",
  134. "attachment; filename=\"aria2-current.tar.bz2\"");
  135. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  136. SharedHandle<Request> request(new Request());
  137. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  138. httpRequest->setRequest(request);
  139. httpResponse.setHttpHeader(httpHeader);
  140. httpResponse.setHttpRequest(httpRequest);
  141. CPPUNIT_ASSERT_EQUAL(std::string("aria2-current.tar.bz2"),
  142. httpResponse.determinFilename());
  143. }
  144. void HttpResponseTest::testGetRedirectURI_without_Location()
  145. {
  146. HttpResponse httpResponse;
  147. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  148. httpResponse.setHttpHeader(httpHeader);
  149. CPPUNIT_ASSERT_EQUAL(std::string(""),
  150. httpResponse.getRedirectURI());
  151. }
  152. void HttpResponseTest::testGetRedirectURI_with_Location()
  153. {
  154. HttpResponse httpResponse;
  155. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  156. httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2");
  157. httpResponse.setHttpHeader(httpHeader);
  158. CPPUNIT_ASSERT_EQUAL
  159. (std::string("http://localhost/download/aria2-1.0.0.tar.bz2"),
  160. httpResponse.getRedirectURI());
  161. }
  162. void HttpResponseTest::testIsRedirect()
  163. {
  164. HttpResponse httpResponse;
  165. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  166. httpHeader->setResponseStatus("200");
  167. httpHeader->put("Location", "http://localhost/download/aria2-1.0.0.tar.bz2");
  168. httpResponse.setHttpHeader(httpHeader);
  169. CPPUNIT_ASSERT(!httpResponse.isRedirect());
  170. httpHeader->setResponseStatus("304");
  171. CPPUNIT_ASSERT(httpResponse.isRedirect());
  172. }
  173. void HttpResponseTest::testIsTransferEncodingSpecified()
  174. {
  175. HttpResponse httpResponse;
  176. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  177. httpResponse.setHttpHeader(httpHeader);
  178. CPPUNIT_ASSERT(!httpResponse.isTransferEncodingSpecified());
  179. httpHeader->put("Transfer-Encoding", "chunked");
  180. CPPUNIT_ASSERT(httpResponse.isTransferEncodingSpecified());
  181. }
  182. void HttpResponseTest::testGetTransferEncoding()
  183. {
  184. HttpResponse httpResponse;
  185. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  186. httpResponse.setHttpHeader(httpHeader);
  187. CPPUNIT_ASSERT_EQUAL(std::string(""), httpResponse.getTransferEncoding());
  188. httpHeader->put("Transfer-Encoding", "chunked");
  189. CPPUNIT_ASSERT_EQUAL(std::string("chunked"),
  190. httpResponse.getTransferEncoding());
  191. }
  192. void HttpResponseTest::testGetTransferEncodingDecoder()
  193. {
  194. HttpResponse httpResponse;
  195. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  196. httpResponse.setHttpHeader(httpHeader);
  197. CPPUNIT_ASSERT(httpResponse.getTransferEncodingDecoder().isNull());
  198. httpHeader->put("Transfer-Encoding", "chunked");
  199. CPPUNIT_ASSERT(!httpResponse.getTransferEncodingDecoder().isNull());
  200. }
  201. void HttpResponseTest::testIsContentEncodingSpecified()
  202. {
  203. HttpResponse httpResponse;
  204. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  205. httpResponse.setHttpHeader(httpHeader);
  206. CPPUNIT_ASSERT(!httpResponse.isContentEncodingSpecified());
  207. httpHeader->put("Content-Encoding", "gzip");
  208. CPPUNIT_ASSERT(httpResponse.isContentEncodingSpecified());
  209. }
  210. void HttpResponseTest::testGetContentEncoding()
  211. {
  212. HttpResponse httpResponse;
  213. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  214. httpResponse.setHttpHeader(httpHeader);
  215. CPPUNIT_ASSERT_EQUAL(A2STR::NIL, httpResponse.getContentEncoding());
  216. httpHeader->put("Content-Encoding", "gzip");
  217. CPPUNIT_ASSERT_EQUAL(std::string("gzip"), httpResponse.getContentEncoding());
  218. }
  219. void HttpResponseTest::testGetContentEncodingDecoder()
  220. {
  221. HttpResponse httpResponse;
  222. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  223. httpResponse.setHttpHeader(httpHeader);
  224. CPPUNIT_ASSERT(httpResponse.getContentEncodingDecoder().isNull());
  225. #ifdef HAVE_LIBZ
  226. httpHeader->put("Content-Encoding", "gzip");
  227. {
  228. SharedHandle<Decoder> decoder = httpResponse.getContentEncodingDecoder();
  229. CPPUNIT_ASSERT(!decoder.isNull());
  230. CPPUNIT_ASSERT_EQUAL(std::string("GZipDecoder"), decoder->getName());
  231. }
  232. httpHeader.reset(new HttpHeader());
  233. httpResponse.setHttpHeader(httpHeader);
  234. httpHeader->put("Content-Encoding", "deflate");
  235. {
  236. SharedHandle<Decoder> decoder = httpResponse.getContentEncodingDecoder();
  237. CPPUNIT_ASSERT(!decoder.isNull());
  238. CPPUNIT_ASSERT_EQUAL(std::string("GZipDecoder"), decoder->getName());
  239. }
  240. #endif // HAVE_LIBZ
  241. httpHeader.reset(new HttpHeader());
  242. httpResponse.setHttpHeader(httpHeader);
  243. httpHeader->put("Content-Encoding", "bzip2");
  244. {
  245. SharedHandle<Decoder> decoder = httpResponse.getContentEncodingDecoder();
  246. CPPUNIT_ASSERT(decoder.isNull());
  247. }
  248. }
  249. void HttpResponseTest::testValidateResponse()
  250. {
  251. HttpResponse httpResponse;
  252. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  253. httpResponse.setHttpHeader(httpHeader);
  254. httpHeader->setResponseStatus("304");
  255. try {
  256. httpResponse.validateResponse();
  257. CPPUNIT_FAIL("exception must be thrown.");
  258. } catch(Exception& e) {
  259. }
  260. httpHeader->put("Location", "http://localhost/archives/aria2-1.0.0.tar.bz2");
  261. try {
  262. httpResponse.validateResponse();
  263. } catch(Exception& e) {
  264. CPPUNIT_FAIL("exception must not be thrown.");
  265. }
  266. }
  267. void HttpResponseTest::testValidateResponse_good_range()
  268. {
  269. HttpResponse httpResponse;
  270. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  271. httpResponse.setHttpHeader(httpHeader);
  272. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  273. SharedHandle<Piece> p(new Piece(1, 1024*1024));
  274. SharedHandle<Segment> segment(new PiecedSegment(1024*1024, p));
  275. httpRequest->setSegment(segment);
  276. SharedHandle<Request> request(new Request());
  277. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  278. httpRequest->setRequest(request);
  279. httpResponse.setHttpRequest(httpRequest);
  280. httpHeader->setResponseStatus("206");
  281. httpHeader->put("Content-Range", "bytes 1048576-10485760/10485761");
  282. try {
  283. httpResponse.validateResponse();
  284. } catch(Exception& e) {
  285. std::cerr << e.stackTrace() << std::endl;
  286. CPPUNIT_FAIL("exception must not be thrown.");
  287. }
  288. }
  289. void HttpResponseTest::testValidateResponse_bad_range()
  290. {
  291. HttpResponse httpResponse;
  292. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  293. httpResponse.setHttpHeader(httpHeader);
  294. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  295. SharedHandle<Piece> p(new Piece(1, 1024*1024));
  296. SharedHandle<Segment> segment(new PiecedSegment(1024*1024, p));
  297. httpRequest->setSegment(segment);
  298. SharedHandle<Request> request(new Request());
  299. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  300. httpRequest->setRequest(request);
  301. httpResponse.setHttpRequest(httpRequest);
  302. httpHeader->setResponseStatus("206");
  303. httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
  304. try {
  305. httpResponse.validateResponse();
  306. CPPUNIT_FAIL("exception must be thrown.");
  307. } catch(Exception& e) {
  308. }
  309. }
  310. void HttpResponseTest::testValidateResponse_chunked()
  311. {
  312. HttpResponse httpResponse;
  313. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  314. httpResponse.setHttpHeader(httpHeader);
  315. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  316. SharedHandle<Piece> p(new Piece(1, 1024*1024));
  317. SharedHandle<Segment> segment(new PiecedSegment(1024*1024, p));
  318. httpRequest->setSegment(segment);
  319. SharedHandle<Request> request(new Request());
  320. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  321. httpRequest->setRequest(request);
  322. httpResponse.setHttpRequest(httpRequest);
  323. httpHeader->setResponseStatus("206");
  324. httpHeader->put("Content-Range", "bytes 0-10485760/10485761");
  325. httpHeader->put("Transfer-Encoding", "chunked");
  326. // if transfer-encoding is specified, then range validation is skipped.
  327. try {
  328. httpResponse.validateResponse();
  329. } catch(Exception& e) {
  330. CPPUNIT_FAIL("exception must not be thrown.");
  331. }
  332. }
  333. void HttpResponseTest::testHasRetryAfter()
  334. {
  335. HttpResponse httpResponse;
  336. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  337. httpResponse.setHttpHeader(httpHeader);
  338. httpHeader->put("Retry-After", "60");
  339. CPPUNIT_ASSERT(httpResponse.hasRetryAfter());
  340. CPPUNIT_ASSERT_EQUAL((time_t)60, httpResponse.getRetryAfter());
  341. }
  342. void HttpResponseTest::testProcessRedirect()
  343. {
  344. HttpResponse httpResponse;
  345. SharedHandle<HttpHeader> httpHeader(new HttpHeader());
  346. httpResponse.setHttpHeader(httpHeader);
  347. SharedHandle<HttpRequest> httpRequest(new HttpRequest());
  348. SharedHandle<Request> request(new Request());
  349. request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
  350. httpRequest->setRequest(request);
  351. httpResponse.setHttpRequest(httpRequest);
  352. httpHeader->put("Location", "http://mirror/aria2-1.0.0.tar.bz2");
  353. httpResponse.processRedirect();
  354. httpHeader->clearField();
  355. // Give unsupported scheme
  356. httpHeader->put("Location", "unsupported://mirror/aria2-1.0.0.tar.bz2");
  357. try {
  358. httpResponse.processRedirect();
  359. CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
  360. } catch(DlRetryEx& e) {
  361. // Success
  362. } catch(...) {
  363. CPPUNIT_FAIL("DlRetryEx exception must be thrown.");
  364. }
  365. }
  366. } // namespace aria2