HttpRequestTest.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  1. #include "HttpRequest.h"
  2. #include <sstream>
  3. #include <cppunit/extensions/HelperMacros.h>
  4. #include "prefs.h"
  5. #include "AuthConfigFactory.h"
  6. #include "PiecedSegment.h"
  7. #include "Piece.h"
  8. #include "Range.h"
  9. #include "Request.h"
  10. #include "Option.h"
  11. #include "array_fun.h"
  12. #include "CookieStorage.h"
  13. #include "util.h"
  14. #include "AuthConfig.h"
  15. #include "TestUtil.h"
  16. #include "MessageDigest.h"
  17. namespace aria2 {
  18. class HttpRequestTest : public CppUnit::TestFixture {
  19. CPPUNIT_TEST_SUITE(HttpRequestTest);
  20. CPPUNIT_TEST(testGetStartByte);
  21. CPPUNIT_TEST(testGetEndByte);
  22. CPPUNIT_TEST(testCreateRequest);
  23. CPPUNIT_TEST(testCreateRequest_ftp);
  24. CPPUNIT_TEST(testCreateRequest_with_cookie);
  25. CPPUNIT_TEST(testCreateRequest_query);
  26. CPPUNIT_TEST(testCreateRequest_head);
  27. CPPUNIT_TEST(testCreateRequest_ipv6LiteralAddr);
  28. CPPUNIT_TEST(testCreateRequest_endOffsetOverride);
  29. CPPUNIT_TEST(testCreateRequest_wantDigest);
  30. CPPUNIT_TEST(testCreateProxyRequest);
  31. CPPUNIT_TEST(testIsRangeSatisfied);
  32. CPPUNIT_TEST(testUserAgent);
  33. CPPUNIT_TEST(testAddHeader);
  34. CPPUNIT_TEST(testAcceptMetalink);
  35. CPPUNIT_TEST(testEnableAcceptEncoding);
  36. CPPUNIT_TEST(testConditionalRequest);
  37. CPPUNIT_TEST_SUITE_END();
  38. private:
  39. std::unique_ptr<Option> option_;
  40. std::unique_ptr<AuthConfigFactory> authConfigFactory_;
  41. public:
  42. void setUp()
  43. {
  44. option_.reset(new Option());
  45. option_->put(PREF_HTTP_AUTH_CHALLENGE, A2_V_TRUE);
  46. authConfigFactory_.reset(new AuthConfigFactory());
  47. }
  48. void testGetStartByte();
  49. void testGetEndByte();
  50. void testCreateRequest();
  51. void testCreateRequest_ftp();
  52. void testCreateRequest_with_cookie();
  53. void testCreateRequest_query();
  54. void testCreateRequest_head();
  55. void testCreateRequest_ipv6LiteralAddr();
  56. void testCreateRequest_endOffsetOverride();
  57. void testCreateRequest_wantDigest();
  58. void testCreateProxyRequest();
  59. void testIsRangeSatisfied();
  60. void testUserAgent();
  61. void testAddHeader();
  62. void testAcceptMetalink();
  63. void testEnableAcceptEncoding();
  64. void testConditionalRequest();
  65. };
  66. CPPUNIT_TEST_SUITE_REGISTRATION(HttpRequestTest);
  67. void HttpRequestTest::testGetStartByte()
  68. {
  69. HttpRequest httpRequest;
  70. auto p = std::make_shared<Piece>(1, 1_k);
  71. auto segment = std::make_shared<PiecedSegment>(1_k, p);
  72. auto fileEntry = std::make_shared<FileEntry>("file", 10_k, 0);
  73. CPPUNIT_ASSERT_EQUAL((int64_t)0LL, httpRequest.getStartByte());
  74. httpRequest.setSegment(segment);
  75. httpRequest.setFileEntry(fileEntry);
  76. CPPUNIT_ASSERT_EQUAL((int64_t)1_k, httpRequest.getStartByte());
  77. }
  78. void HttpRequestTest::testGetEndByte()
  79. {
  80. size_t index = 1;
  81. size_t length = 1_m - 1_k;
  82. size_t segmentLength = 1_m;
  83. HttpRequest httpRequest;
  84. auto piece = std::make_shared<Piece>(index, length);
  85. auto segment = std::make_shared<PiecedSegment>(segmentLength, piece);
  86. auto fileEntry = std::make_shared<FileEntry>("file", segmentLength * 10, 0);
  87. CPPUNIT_ASSERT_EQUAL((int64_t)0LL, httpRequest.getEndByte());
  88. httpRequest.setSegment(segment);
  89. CPPUNIT_ASSERT_EQUAL((int64_t)0LL, httpRequest.getEndByte());
  90. auto request = std::make_shared<Request>();
  91. request->supportsPersistentConnection(true);
  92. request->setPipeliningHint(true);
  93. httpRequest.setRequest(request);
  94. httpRequest.setFileEntry(fileEntry);
  95. CPPUNIT_ASSERT_EQUAL((int64_t)(segmentLength * index + length - 1),
  96. httpRequest.getEndByte());
  97. // The end byte of FileEntry are placed inside segment
  98. fileEntry->setLength(segmentLength + 100);
  99. CPPUNIT_ASSERT_EQUAL((int64_t)(segmentLength * index + 100 - 1),
  100. httpRequest.getEndByte());
  101. request->setPipeliningHint(false);
  102. CPPUNIT_ASSERT_EQUAL((int64_t)0LL, httpRequest.getEndByte());
  103. }
  104. void HttpRequestTest::testCreateRequest()
  105. {
  106. auto request = std::make_shared<Request>();
  107. request->supportsPersistentConnection(true);
  108. request->setUri("http://localhost:8080/archives/aria2-1.0.0.tar.bz2");
  109. auto p = std::make_shared<Piece>(0, 1_k);
  110. auto segment = std::make_shared<PiecedSegment>(1_k, p);
  111. auto fileEntry = std::make_shared<FileEntry>("file", 10_m, 0);
  112. HttpRequest httpRequest;
  113. httpRequest.disableContentEncoding();
  114. httpRequest.setRequest(request);
  115. httpRequest.setSegment(segment);
  116. httpRequest.setFileEntry(fileEntry);
  117. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  118. httpRequest.setOption(option_.get());
  119. httpRequest.setNoWantDigest(true);
  120. // remove "Connection: close" and add end byte range
  121. request->setPipeliningHint(true);
  122. std::string expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  123. "User-Agent: aria2\r\n"
  124. "Accept: */*\r\n"
  125. "Host: localhost:8080\r\n"
  126. "Pragma: no-cache\r\n"
  127. "Cache-Control: no-cache\r\n"
  128. "Range: bytes=0-1023\r\n"
  129. "\r\n";
  130. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  131. request->setPipeliningHint(false);
  132. expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  133. "User-Agent: aria2\r\n"
  134. "Accept: */*\r\n"
  135. "Host: localhost:8080\r\n"
  136. "Pragma: no-cache\r\n"
  137. "Cache-Control: no-cache\r\n"
  138. "Connection: close\r\n"
  139. "\r\n";
  140. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  141. p.reset(new Piece(1, 1_m));
  142. segment.reset(new PiecedSegment(1_m, p));
  143. httpRequest.setSegment(segment);
  144. expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  145. "User-Agent: aria2\r\n"
  146. "Accept: */*\r\n"
  147. "Host: localhost:8080\r\n"
  148. "Pragma: no-cache\r\n"
  149. "Cache-Control: no-cache\r\n"
  150. "Connection: close\r\n"
  151. "Range: bytes=1048576-\r\n"
  152. "\r\n";
  153. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  154. request->setPipeliningHint(true);
  155. expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  156. "User-Agent: aria2\r\n"
  157. "Accept: */*\r\n"
  158. "Host: localhost:8080\r\n"
  159. "Pragma: no-cache\r\n"
  160. "Cache-Control: no-cache\r\n"
  161. "Range: bytes=1048576-2097151\r\n"
  162. "\r\n";
  163. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  164. // redirection set persistent connection flag to true
  165. request->redirectUri(
  166. "http://localhost:8080/archives/download/aria2-1.0.0.tar.bz2");
  167. expectedText = "GET /archives/download/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  168. "User-Agent: aria2\r\n"
  169. "Accept: */*\r\n"
  170. "Host: localhost:8080\r\n"
  171. "Pragma: no-cache\r\n"
  172. "Cache-Control: no-cache\r\n"
  173. "Range: bytes=1048576-2097151\r\n"
  174. "\r\n";
  175. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  176. request->supportsPersistentConnection(true);
  177. request->setPipeliningHint(false);
  178. // this only removes "Connection: close".
  179. request->setKeepAliveHint(true);
  180. expectedText = "GET /archives/download/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  181. "User-Agent: aria2\r\n"
  182. "Accept: */*\r\n"
  183. "Host: localhost:8080\r\n"
  184. "Pragma: no-cache\r\n"
  185. "Cache-Control: no-cache\r\n"
  186. "Range: bytes=1048576-\r\n"
  187. "\r\n";
  188. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  189. request->setKeepAliveHint(false);
  190. request->resetUri();
  191. p.reset(new Piece(0, 1_m));
  192. segment.reset(new PiecedSegment(1_m, p));
  193. httpRequest.setSegment(segment);
  194. // enable http auth
  195. option_->put(PREF_HTTP_USER, "aria2user");
  196. option_->put(PREF_HTTP_PASSWD, "aria2passwd");
  197. CPPUNIT_ASSERT(authConfigFactory_->activateBasicCred("localhost", 8080, "/",
  198. option_.get()));
  199. expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  200. "User-Agent: aria2\r\n"
  201. "Accept: */*\r\n"
  202. "Host: localhost:8080\r\n"
  203. "Pragma: no-cache\r\n"
  204. "Cache-Control: no-cache\r\n"
  205. "Connection: close\r\n"
  206. "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n"
  207. "\r\n";
  208. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  209. // enable http proxy auth
  210. auto proxyRequest = std::make_shared<Request>();
  211. CPPUNIT_ASSERT(proxyRequest->setUri(
  212. "http://aria2proxyuser:aria2proxypasswd@localhost:9000"));
  213. httpRequest.setProxyRequest(proxyRequest);
  214. expectedText =
  215. "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  216. "User-Agent: aria2\r\n"
  217. "Accept: */*\r\n"
  218. "Host: localhost:8080\r\n"
  219. "Pragma: no-cache\r\n"
  220. "Cache-Control: no-cache\r\n"
  221. "Connection: close\r\n"
  222. "Proxy-Authorization: Basic "
  223. "YXJpYTJwcm94eXVzZXI6YXJpYTJwcm94eXBhc3N3ZA==\r\n"
  224. "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n"
  225. "\r\n";
  226. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  227. request->setPipeliningHint(true);
  228. expectedText =
  229. "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  230. "User-Agent: aria2\r\n"
  231. "Accept: */*\r\n"
  232. "Host: localhost:8080\r\n"
  233. "Pragma: no-cache\r\n"
  234. "Cache-Control: no-cache\r\n"
  235. "Range: bytes=0-1048575\r\n"
  236. "Connection: Keep-Alive\r\n"
  237. "Proxy-Authorization: Basic "
  238. "YXJpYTJwcm94eXVzZXI6YXJpYTJwcm94eXBhc3N3ZA==\r\n"
  239. "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n"
  240. "\r\n";
  241. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  242. request->setPipeliningHint(false);
  243. // turn off proxy auth
  244. CPPUNIT_ASSERT(proxyRequest->setUri("http://localhost:9000"));
  245. expectedText =
  246. "GET http://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  247. "User-Agent: aria2\r\n"
  248. "Accept: */*\r\n"
  249. "Host: localhost:8080\r\n"
  250. "Pragma: no-cache\r\n"
  251. "Cache-Control: no-cache\r\n"
  252. "Connection: close\r\n"
  253. "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n"
  254. "\r\n";
  255. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  256. }
  257. void HttpRequestTest::testCreateRequest_ftp()
  258. {
  259. option_->put(PREF_FTP_USER, "aria2user");
  260. option_->put(PREF_FTP_PASSWD, "aria2passwd");
  261. auto request = std::make_shared<Request>();
  262. request->setUri("ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2");
  263. auto proxyRequest = std::make_shared<Request>();
  264. CPPUNIT_ASSERT(proxyRequest->setUri("http://localhost:9000"));
  265. HttpRequest httpRequest;
  266. auto p = std::make_shared<Piece>(0, 1_m);
  267. auto segment = std::make_shared<PiecedSegment>(1_m, p);
  268. auto fileEntry = std::make_shared<FileEntry>("file", 10_m, 0);
  269. httpRequest.disableContentEncoding();
  270. httpRequest.setRequest(request);
  271. httpRequest.setSegment(segment);
  272. httpRequest.setFileEntry(fileEntry);
  273. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  274. httpRequest.setOption(option_.get());
  275. httpRequest.setProxyRequest(proxyRequest);
  276. httpRequest.setNoWantDigest(true);
  277. std::string expectedText =
  278. "GET ftp://aria2user@localhost:8080/archives/aria2-1.0.0.tar.bz2"
  279. " HTTP/1.1\r\n"
  280. "User-Agent: aria2\r\n"
  281. "Accept: */*\r\n"
  282. "Host: localhost:8080\r\n"
  283. "Pragma: no-cache\r\n"
  284. "Cache-Control: no-cache\r\n"
  285. "Connection: close\r\n"
  286. "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n"
  287. "\r\n";
  288. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  289. // test proxy authorization
  290. CPPUNIT_ASSERT(proxyRequest->setUri(
  291. "http://aria2proxyuser:aria2proxypasswd@localhost:9000"));
  292. expectedText =
  293. "GET ftp://aria2user@localhost:8080/archives/aria2-1.0.0.tar.bz2"
  294. " HTTP/1.1\r\n"
  295. "User-Agent: aria2\r\n"
  296. "Accept: */*\r\n"
  297. "Host: localhost:8080\r\n"
  298. "Pragma: no-cache\r\n"
  299. "Cache-Control: no-cache\r\n"
  300. "Connection: close\r\n"
  301. "Proxy-Authorization: Basic "
  302. "YXJpYTJwcm94eXVzZXI6YXJpYTJwcm94eXBhc3N3ZA==\r\n"
  303. "Authorization: Basic YXJpYTJ1c2VyOmFyaWEycGFzc3dk\r\n"
  304. "\r\n";
  305. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  306. }
  307. template <typename InputIterator>
  308. void foo(CookieStorage& st, InputIterator first, InputIterator last, time_t t)
  309. {
  310. for (; first != last; ++first) {
  311. st.store(*first, t);
  312. }
  313. }
  314. void HttpRequestTest::testCreateRequest_with_cookie()
  315. {
  316. auto request = std::make_shared<Request>();
  317. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  318. auto p = std::make_shared<Piece>(0, 1_m);
  319. auto segment = std::make_shared<PiecedSegment>(1_m, p);
  320. auto fileEntry = std::make_shared<FileEntry>("file", 10_m, 0);
  321. auto st = CookieStorage{};
  322. CPPUNIT_ASSERT(st.store(
  323. createCookie("name1", "value1", "localhost", true, "/archives", false),
  324. 0));
  325. CPPUNIT_ASSERT(st.store(createCookie("name2", "value2", "localhost", true,
  326. "/archives/download", false),
  327. 0));
  328. CPPUNIT_ASSERT(st.store(createCookie("name3", "value3", "aria2.org", false,
  329. "/archives/download", false),
  330. 0));
  331. CPPUNIT_ASSERT(st.store(
  332. createCookie("name4", "value4", "aria2.org", false, "/archives/", true),
  333. 0));
  334. CPPUNIT_ASSERT(st.store(
  335. createCookie("name5", "value5", "example.org", false, "/", false), 0));
  336. HttpRequest httpRequest;
  337. httpRequest.disableContentEncoding();
  338. httpRequest.setRequest(request);
  339. httpRequest.setSegment(segment);
  340. httpRequest.setFileEntry(fileEntry);
  341. httpRequest.setCookieStorage(&st);
  342. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  343. httpRequest.setOption(option_.get());
  344. httpRequest.setNoWantDigest(true);
  345. std::string expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  346. "User-Agent: aria2\r\n"
  347. "Accept: */*\r\n"
  348. "Host: localhost\r\n"
  349. "Pragma: no-cache\r\n"
  350. "Cache-Control: no-cache\r\n"
  351. "Connection: close\r\n"
  352. "Cookie: name1=value1;\r\n"
  353. "\r\n";
  354. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  355. request->setUri("http://localhost/archives/download/aria2-1.0.0.tar.bz2");
  356. expectedText = "GET /archives/download/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  357. "User-Agent: aria2\r\n"
  358. "Accept: */*\r\n"
  359. "Host: localhost\r\n"
  360. "Pragma: no-cache\r\n"
  361. "Cache-Control: no-cache\r\n"
  362. "Connection: close\r\n"
  363. "Cookie: name2=value2;name1=value1;\r\n"
  364. "\r\n";
  365. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  366. request->setUri("http://www.aria2.org/archives/download/aria2-1.0.0.tar.bz2");
  367. expectedText = "GET /archives/download/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  368. "User-Agent: aria2\r\n"
  369. "Accept: */*\r\n"
  370. "Host: www.aria2.org\r\n"
  371. "Pragma: no-cache\r\n"
  372. "Cache-Control: no-cache\r\n"
  373. "Connection: close\r\n"
  374. "Cookie: name3=value3;\r\n"
  375. "\r\n";
  376. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  377. request->setUri("https://www.aria2.org/archives/download/"
  378. "aria2-1.0.0.tar.bz2");
  379. expectedText = "GET /archives/download/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  380. "User-Agent: aria2\r\n"
  381. "Accept: */*\r\n"
  382. "Host: www.aria2.org\r\n"
  383. "Pragma: no-cache\r\n"
  384. "Cache-Control: no-cache\r\n"
  385. "Connection: close\r\n"
  386. "Cookie: name3=value3;name4=value4;\r\n"
  387. "\r\n";
  388. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  389. // The path of cookie4 ends with '/'
  390. request->setUri("https://www.aria2.org/archives/aria2-1.0.0.tar.bz2");
  391. expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  392. "User-Agent: aria2\r\n"
  393. "Accept: */*\r\n"
  394. "Host: www.aria2.org\r\n"
  395. "Pragma: no-cache\r\n"
  396. "Cache-Control: no-cache\r\n"
  397. "Connection: close\r\n"
  398. "Cookie: name4=value4;\r\n"
  399. "\r\n";
  400. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  401. request->setUri("http://example.org/aria2-1.0.0.tar.bz2");
  402. expectedText = "GET /aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  403. "User-Agent: aria2\r\n"
  404. "Accept: */*\r\n"
  405. "Host: example.org\r\n"
  406. "Pragma: no-cache\r\n"
  407. "Cache-Control: no-cache\r\n"
  408. "Connection: close\r\n"
  409. "Cookie: name5=value5;\r\n"
  410. "\r\n";
  411. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  412. }
  413. void HttpRequestTest::testCreateRequest_query()
  414. {
  415. auto request = std::make_shared<Request>();
  416. request->setUri(
  417. "http://localhost/wiki?id=9ad5109a-b8a5-4edf-9373-56a1c34ae138");
  418. HttpRequest httpRequest;
  419. httpRequest.disableContentEncoding();
  420. httpRequest.setRequest(request);
  421. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  422. httpRequest.setOption(option_.get());
  423. httpRequest.setNoWantDigest(true);
  424. std::string expectedText =
  425. "GET /wiki?id=9ad5109a-b8a5-4edf-9373-56a1c34ae138 HTTP/1.1\r\n"
  426. "User-Agent: aria2\r\n"
  427. "Accept: */*\r\n"
  428. "Host: localhost\r\n"
  429. "Pragma: no-cache\r\n"
  430. "Cache-Control: no-cache\r\n"
  431. "Connection: close\r\n"
  432. "\r\n";
  433. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  434. }
  435. void HttpRequestTest::testCreateRequest_head()
  436. {
  437. auto request = std::make_shared<Request>();
  438. request->setMethod(Request::METHOD_HEAD);
  439. request->setUri("http://localhost/aria2-1.0.0.tar.bz2");
  440. HttpRequest httpRequest;
  441. httpRequest.setRequest(request);
  442. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  443. httpRequest.setOption(option_.get());
  444. std::stringstream result(httpRequest.createRequest());
  445. std::string line;
  446. CPPUNIT_ASSERT(getline(result, line));
  447. line = util::strip(line);
  448. CPPUNIT_ASSERT_EQUAL(std::string("HEAD /aria2-1.0.0.tar.bz2 HTTP/1.1"), line);
  449. }
  450. void HttpRequestTest::testCreateRequest_endOffsetOverride()
  451. {
  452. auto request = std::make_shared<Request>();
  453. request->setUri("http://localhost/myfile");
  454. HttpRequest httpRequest;
  455. httpRequest.disableContentEncoding();
  456. httpRequest.setRequest(request);
  457. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  458. httpRequest.setOption(option_.get());
  459. httpRequest.setNoWantDigest(true);
  460. auto p = std::make_shared<Piece>(0, 1_m);
  461. auto segment = std::make_shared<PiecedSegment>(1_m, p);
  462. httpRequest.setSegment(segment);
  463. httpRequest.setEndOffsetOverride(1_g);
  464. auto fileEntry = std::make_shared<FileEntry>("file", 10_g, 0);
  465. httpRequest.setFileEntry(fileEntry);
  466. // End byte is passed if it is not 0
  467. std::string expectedText = "GET /myfile HTTP/1.1\r\n"
  468. "User-Agent: aria2\r\n"
  469. "Accept: */*\r\n"
  470. "Host: localhost\r\n"
  471. "Pragma: no-cache\r\n"
  472. "Cache-Control: no-cache\r\n"
  473. "Connection: close\r\n"
  474. "Range: bytes=0-1073741823\r\n"
  475. "\r\n";
  476. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  477. segment->updateWrittenLength(1);
  478. expectedText = "GET /myfile HTTP/1.1\r\n"
  479. "User-Agent: aria2\r\n"
  480. "Accept: */*\r\n"
  481. "Host: localhost\r\n"
  482. "Pragma: no-cache\r\n"
  483. "Cache-Control: no-cache\r\n"
  484. "Connection: close\r\n"
  485. "Range: bytes=1-1073741823\r\n"
  486. "\r\n";
  487. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  488. }
  489. void HttpRequestTest::testCreateRequest_wantDigest()
  490. {
  491. auto request = std::make_shared<Request>();
  492. request->setUri("http://localhost/");
  493. HttpRequest httpRequest;
  494. httpRequest.setRequest(request);
  495. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  496. httpRequest.setOption(option_.get());
  497. std::string wantDigest;
  498. if (MessageDigest::supports("sha-512")) {
  499. wantDigest += "SHA-512;q=1, ";
  500. }
  501. if (MessageDigest::supports("sha-256")) {
  502. wantDigest += "SHA-256;q=1, ";
  503. }
  504. if (MessageDigest::supports("sha-1")) {
  505. wantDigest += "SHA;q=0.1, ";
  506. }
  507. if (!wantDigest.empty()) {
  508. wantDigest.erase(wantDigest.size() - 2);
  509. }
  510. std::string expectedText = "GET / HTTP/1.1\r\n"
  511. "User-Agent: aria2\r\n"
  512. "Accept: */*\r\n"
  513. "Host: localhost\r\n"
  514. "Pragma: no-cache\r\n"
  515. "Cache-Control: no-cache\r\n"
  516. "Connection: close\r\n"
  517. "Want-Digest: " +
  518. wantDigest +
  519. "\r\n"
  520. "\r\n";
  521. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  522. }
  523. void HttpRequestTest::testCreateProxyRequest()
  524. {
  525. auto request = std::make_shared<Request>();
  526. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  527. auto p = std::make_shared<Piece>(0, 1_m);
  528. auto segment = std::make_shared<PiecedSegment>(1_m, p);
  529. auto proxyRequest = std::make_shared<Request>();
  530. CPPUNIT_ASSERT(proxyRequest->setUri("http://localhost:9000"));
  531. HttpRequest httpRequest;
  532. httpRequest.setRequest(request);
  533. httpRequest.setSegment(segment);
  534. httpRequest.setProxyRequest(proxyRequest);
  535. request->supportsPersistentConnection(true);
  536. std::string expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
  537. "User-Agent: aria2\r\n"
  538. "Host: localhost:80\r\n"
  539. //"Proxy-Connection: close\r\n"
  540. "\r\n";
  541. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
  542. // adds Keep-Alive header.
  543. request->setKeepAliveHint(true);
  544. expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
  545. "User-Agent: aria2\r\n"
  546. "Host: localhost:80\r\n"
  547. //"Proxy-Connection: Keep-Alive\r\n"
  548. "\r\n";
  549. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
  550. request->setKeepAliveHint(false);
  551. // pipelining also adds Keep-Alive header.
  552. request->setPipeliningHint(true);
  553. expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
  554. "User-Agent: aria2\r\n"
  555. "Host: localhost:80\r\n"
  556. //"Proxy-Connection: Keep-Alive\r\n"
  557. "\r\n";
  558. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
  559. // test proxy authorization
  560. CPPUNIT_ASSERT(proxyRequest->setUri(
  561. "http://aria2proxyuser:aria2proxypasswd@localhost:9000"));
  562. expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
  563. "User-Agent: aria2\r\n"
  564. "Host: localhost:80\r\n"
  565. //"Proxy-Connection: Keep-Alive\r\n"
  566. "Proxy-Authorization: Basic "
  567. "YXJpYTJwcm94eXVzZXI6YXJpYTJwcm94eXBhc3N3ZA==\r\n"
  568. "\r\n";
  569. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
  570. }
  571. void HttpRequestTest::testIsRangeSatisfied()
  572. {
  573. auto request = std::make_shared<Request>();
  574. request->supportsPersistentConnection(true);
  575. request->setUri("http://localhost:8080/archives/aria2-1.0.0.tar.bz2");
  576. request->setPipeliningHint(false); // default: false
  577. auto p = std::make_shared<Piece>(0, 1_m);
  578. auto segment = std::make_shared<PiecedSegment>(1_m, p);
  579. auto fileEntry = std::make_shared<FileEntry>("file", 0, 0);
  580. HttpRequest httpRequest;
  581. httpRequest.setRequest(request);
  582. httpRequest.setSegment(segment);
  583. httpRequest.setFileEntry(fileEntry);
  584. Range range;
  585. CPPUNIT_ASSERT(httpRequest.isRangeSatisfied(range));
  586. p.reset(new Piece(1, 1_m));
  587. segment.reset(new PiecedSegment(1_m, p));
  588. httpRequest.setSegment(segment);
  589. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  590. uint64_t entityLength = segment->getSegmentLength() * 10;
  591. range = Range(segment->getPosition(), 0, entityLength);
  592. CPPUNIT_ASSERT(httpRequest.isRangeSatisfied(range));
  593. fileEntry->setLength(entityLength - 1);
  594. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  595. fileEntry->setLength(entityLength);
  596. CPPUNIT_ASSERT(httpRequest.isRangeSatisfied(range));
  597. request->setPipeliningHint(true);
  598. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  599. range =
  600. Range(segment->getPosition(),
  601. segment->getPosition() + segment->getLength() - 1, entityLength);
  602. CPPUNIT_ASSERT(httpRequest.isRangeSatisfied(range));
  603. range = Range(segment->getPosition(),
  604. segment->getPosition() + segment->getLength() - 1, 0);
  605. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  606. range =
  607. Range(0, segment->getPosition() + segment->getLength() - 1, entityLength);
  608. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  609. }
  610. void HttpRequestTest::testUserAgent()
  611. {
  612. auto request = std::make_shared<Request>();
  613. request->setUri("http://localhost:8080/archives/aria2-1.0.0.tar.bz2");
  614. // std::shared_ptr<Piece> p(new Piece(0, 1_k));
  615. // std::shared_ptr<Segment> segment(new PiecedSegment(1_k, p));
  616. HttpRequest httpRequest;
  617. httpRequest.disableContentEncoding();
  618. httpRequest.setRequest(request);
  619. // httpRequest.setSegment(segment);
  620. httpRequest.setUserAgent("aria2 (Linux)");
  621. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  622. httpRequest.setOption(option_.get());
  623. httpRequest.setNoWantDigest(true);
  624. std::string expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  625. "User-Agent: aria2 (Linux)\r\n"
  626. "Accept: */*\r\n"
  627. "Host: localhost:8080\r\n"
  628. "Pragma: no-cache\r\n"
  629. "Cache-Control: no-cache\r\n"
  630. "Connection: close\r\n"
  631. "\r\n";
  632. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  633. auto proxyRequest = std::make_shared<Request>();
  634. CPPUNIT_ASSERT(proxyRequest->setUri("http://localhost:9000"));
  635. httpRequest.setProxyRequest(proxyRequest);
  636. std::string expectedTextForProxy = "CONNECT localhost:8080 HTTP/1.1\r\n"
  637. "User-Agent: aria2 (Linux)\r\n"
  638. "Host: localhost:8080\r\n"
  639. //"Proxy-Connection: close\r\n"
  640. "\r\n";
  641. CPPUNIT_ASSERT_EQUAL(expectedTextForProxy, httpRequest.createProxyRequest());
  642. }
  643. void HttpRequestTest::testAddHeader()
  644. {
  645. auto request = std::make_shared<Request>();
  646. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  647. HttpRequest httpRequest;
  648. httpRequest.disableContentEncoding();
  649. httpRequest.setRequest(request);
  650. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  651. httpRequest.setOption(option_.get());
  652. httpRequest.addHeader("X-ARIA2: v0.13\nX-ARIA2-DISTRIBUTE: enabled\n");
  653. httpRequest.addHeader("Accept: text/html");
  654. httpRequest.setNoWantDigest(true);
  655. std::string expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  656. "User-Agent: aria2\r\n"
  657. "Host: localhost\r\n"
  658. "Pragma: no-cache\r\n"
  659. "Cache-Control: no-cache\r\n"
  660. "Connection: close\r\n"
  661. "X-ARIA2: v0.13\r\n"
  662. "X-ARIA2-DISTRIBUTE: enabled\r\n"
  663. "Accept: text/html\r\n"
  664. "\r\n";
  665. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  666. }
  667. void HttpRequestTest::testAcceptMetalink()
  668. {
  669. auto request = std::make_shared<Request>();
  670. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  671. HttpRequest httpRequest;
  672. httpRequest.disableContentEncoding();
  673. httpRequest.setRequest(request);
  674. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  675. httpRequest.setOption(option_.get());
  676. httpRequest.setAcceptMetalink(true);
  677. httpRequest.setNoWantDigest(true);
  678. std::string expectedText =
  679. "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  680. "User-Agent: aria2\r\n"
  681. "Accept: */*,application/metalink4+xml,application/metalink+xml\r\n"
  682. "Host: localhost\r\n"
  683. "Pragma: no-cache\r\n"
  684. "Cache-Control: no-cache\r\n"
  685. "Connection: close\r\n"
  686. "\r\n";
  687. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  688. }
  689. void HttpRequestTest::testEnableAcceptEncoding()
  690. {
  691. auto request = std::make_shared<Request>();
  692. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  693. HttpRequest httpRequest;
  694. httpRequest.setRequest(request);
  695. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  696. httpRequest.setOption(option_.get());
  697. httpRequest.setNoWantDigest(true);
  698. std::string acceptEncodings;
  699. #ifdef HAVE_ZLIB
  700. acceptEncodings += "deflate, gzip";
  701. #endif // HAVE_ZLIB
  702. std::string expectedTextHead =
  703. "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  704. "User-Agent: aria2\r\n"
  705. "Accept: */*\r\n";
  706. std::string expectedTextTail = "Host: localhost\r\n"
  707. "Pragma: no-cache\r\n"
  708. "Cache-Control: no-cache\r\n"
  709. "Connection: close\r\n"
  710. "\r\n";
  711. std::string expectedText = expectedTextHead;
  712. expectedText += expectedTextTail;
  713. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  714. expectedText = expectedTextHead;
  715. if (!acceptEncodings.empty()) {
  716. expectedText += "Accept-Encoding: ";
  717. expectedText += acceptEncodings;
  718. expectedText += "\r\n";
  719. }
  720. expectedText += expectedTextTail;
  721. httpRequest.enableAcceptGZip();
  722. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  723. }
  724. void HttpRequestTest::testCreateRequest_ipv6LiteralAddr()
  725. {
  726. auto request = std::make_shared<Request>();
  727. request->setUri("http://[::1]/path");
  728. HttpRequest httpRequest;
  729. httpRequest.disableContentEncoding();
  730. httpRequest.setRequest(request);
  731. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  732. httpRequest.setOption(option_.get());
  733. CPPUNIT_ASSERT(httpRequest.createRequest().find("Host: [::1]") !=
  734. std::string::npos);
  735. auto proxy = std::make_shared<Request>();
  736. proxy->setUri("http://proxy");
  737. httpRequest.setProxyRequest(proxy);
  738. std::string proxyRequest = httpRequest.createProxyRequest();
  739. CPPUNIT_ASSERT(proxyRequest.find("Host: [::1]:80") != std::string::npos);
  740. CPPUNIT_ASSERT(proxyRequest.find("CONNECT [::1]:80 ") != std::string::npos);
  741. }
  742. void HttpRequestTest::testConditionalRequest()
  743. {
  744. HttpRequest httpRequest;
  745. CPPUNIT_ASSERT(!httpRequest.conditionalRequest());
  746. httpRequest.setIfModifiedSinceHeader("dummy");
  747. CPPUNIT_ASSERT(httpRequest.conditionalRequest());
  748. httpRequest.setIfModifiedSinceHeader("");
  749. CPPUNIT_ASSERT(!httpRequest.conditionalRequest());
  750. httpRequest.addHeader("If-None-Match: *");
  751. CPPUNIT_ASSERT(httpRequest.conditionalRequest());
  752. httpRequest.clearHeader();
  753. httpRequest.addHeader("If-Modified-Since: dummy");
  754. CPPUNIT_ASSERT(httpRequest.conditionalRequest());
  755. }
  756. } // namespace aria2