HttpRequestTest.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  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 + "\r\n"
  519. "\r\n";
  520. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  521. }
  522. void HttpRequestTest::testCreateProxyRequest()
  523. {
  524. auto request = std::make_shared<Request>();
  525. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  526. auto p = std::make_shared<Piece>(0, 1_m);
  527. auto segment = std::make_shared<PiecedSegment>(1_m, p);
  528. auto proxyRequest = std::make_shared<Request>();
  529. CPPUNIT_ASSERT(proxyRequest->setUri("http://localhost:9000"));
  530. HttpRequest httpRequest;
  531. httpRequest.setRequest(request);
  532. httpRequest.setSegment(segment);
  533. httpRequest.setProxyRequest(proxyRequest);
  534. request->supportsPersistentConnection(true);
  535. std::string expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
  536. "User-Agent: aria2\r\n"
  537. "Host: localhost:80\r\n"
  538. //"Proxy-Connection: close\r\n"
  539. "\r\n";
  540. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
  541. // adds Keep-Alive header.
  542. request->setKeepAliveHint(true);
  543. expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
  544. "User-Agent: aria2\r\n"
  545. "Host: localhost:80\r\n"
  546. //"Proxy-Connection: Keep-Alive\r\n"
  547. "\r\n";
  548. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
  549. request->setKeepAliveHint(false);
  550. // pipelining also adds Keep-Alive header.
  551. request->setPipeliningHint(true);
  552. expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
  553. "User-Agent: aria2\r\n"
  554. "Host: localhost:80\r\n"
  555. //"Proxy-Connection: Keep-Alive\r\n"
  556. "\r\n";
  557. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
  558. // test proxy authorization
  559. CPPUNIT_ASSERT(proxyRequest->setUri(
  560. "http://aria2proxyuser:aria2proxypasswd@localhost:9000"));
  561. expectedText = "CONNECT localhost:80 HTTP/1.1\r\n"
  562. "User-Agent: aria2\r\n"
  563. "Host: localhost:80\r\n"
  564. //"Proxy-Connection: Keep-Alive\r\n"
  565. "Proxy-Authorization: Basic "
  566. "YXJpYTJwcm94eXVzZXI6YXJpYTJwcm94eXBhc3N3ZA==\r\n"
  567. "\r\n";
  568. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createProxyRequest());
  569. }
  570. void HttpRequestTest::testIsRangeSatisfied()
  571. {
  572. auto request = std::make_shared<Request>();
  573. request->supportsPersistentConnection(true);
  574. request->setUri("http://localhost:8080/archives/aria2-1.0.0.tar.bz2");
  575. request->setPipeliningHint(false); // default: false
  576. auto p = std::make_shared<Piece>(0, 1_m);
  577. auto segment = std::make_shared<PiecedSegment>(1_m, p);
  578. auto fileEntry = std::make_shared<FileEntry>("file", 0, 0);
  579. HttpRequest httpRequest;
  580. httpRequest.setRequest(request);
  581. httpRequest.setSegment(segment);
  582. httpRequest.setFileEntry(fileEntry);
  583. Range range;
  584. CPPUNIT_ASSERT(httpRequest.isRangeSatisfied(range));
  585. p.reset(new Piece(1, 1_m));
  586. segment.reset(new PiecedSegment(1_m, p));
  587. httpRequest.setSegment(segment);
  588. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  589. uint64_t entityLength = segment->getSegmentLength() * 10;
  590. range = Range(segment->getPosition(), 0, entityLength);
  591. CPPUNIT_ASSERT(httpRequest.isRangeSatisfied(range));
  592. fileEntry->setLength(entityLength - 1);
  593. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  594. fileEntry->setLength(entityLength);
  595. CPPUNIT_ASSERT(httpRequest.isRangeSatisfied(range));
  596. request->setPipeliningHint(true);
  597. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  598. range =
  599. Range(segment->getPosition(),
  600. segment->getPosition() + segment->getLength() - 1, entityLength);
  601. CPPUNIT_ASSERT(httpRequest.isRangeSatisfied(range));
  602. range = Range(segment->getPosition(),
  603. segment->getPosition() + segment->getLength() - 1, 0);
  604. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  605. range =
  606. Range(0, segment->getPosition() + segment->getLength() - 1, entityLength);
  607. CPPUNIT_ASSERT(!httpRequest.isRangeSatisfied(range));
  608. }
  609. void HttpRequestTest::testUserAgent()
  610. {
  611. auto request = std::make_shared<Request>();
  612. request->setUri("http://localhost:8080/archives/aria2-1.0.0.tar.bz2");
  613. // std::shared_ptr<Piece> p(new Piece(0, 1_k));
  614. // std::shared_ptr<Segment> segment(new PiecedSegment(1_k, p));
  615. HttpRequest httpRequest;
  616. httpRequest.disableContentEncoding();
  617. httpRequest.setRequest(request);
  618. // httpRequest.setSegment(segment);
  619. httpRequest.setUserAgent("aria2 (Linux)");
  620. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  621. httpRequest.setOption(option_.get());
  622. httpRequest.setNoWantDigest(true);
  623. std::string expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  624. "User-Agent: aria2 (Linux)\r\n"
  625. "Accept: */*\r\n"
  626. "Host: localhost:8080\r\n"
  627. "Pragma: no-cache\r\n"
  628. "Cache-Control: no-cache\r\n"
  629. "Connection: close\r\n"
  630. "\r\n";
  631. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  632. auto proxyRequest = std::make_shared<Request>();
  633. CPPUNIT_ASSERT(proxyRequest->setUri("http://localhost:9000"));
  634. httpRequest.setProxyRequest(proxyRequest);
  635. std::string expectedTextForProxy = "CONNECT localhost:8080 HTTP/1.1\r\n"
  636. "User-Agent: aria2 (Linux)\r\n"
  637. "Host: localhost:8080\r\n"
  638. //"Proxy-Connection: close\r\n"
  639. "\r\n";
  640. CPPUNIT_ASSERT_EQUAL(expectedTextForProxy, httpRequest.createProxyRequest());
  641. }
  642. void HttpRequestTest::testAddHeader()
  643. {
  644. auto request = std::make_shared<Request>();
  645. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  646. HttpRequest httpRequest;
  647. httpRequest.disableContentEncoding();
  648. httpRequest.setRequest(request);
  649. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  650. httpRequest.setOption(option_.get());
  651. httpRequest.addHeader("X-ARIA2: v0.13\nX-ARIA2-DISTRIBUTE: enabled\n");
  652. httpRequest.addHeader("Accept: text/html");
  653. httpRequest.setNoWantDigest(true);
  654. std::string expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  655. "User-Agent: aria2\r\n"
  656. "Host: localhost\r\n"
  657. "Pragma: no-cache\r\n"
  658. "Cache-Control: no-cache\r\n"
  659. "Connection: close\r\n"
  660. "X-ARIA2: v0.13\r\n"
  661. "X-ARIA2-DISTRIBUTE: enabled\r\n"
  662. "Accept: text/html\r\n"
  663. "\r\n";
  664. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  665. }
  666. void HttpRequestTest::testAcceptMetalink()
  667. {
  668. auto request = std::make_shared<Request>();
  669. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  670. HttpRequest httpRequest;
  671. httpRequest.disableContentEncoding();
  672. httpRequest.setRequest(request);
  673. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  674. httpRequest.setOption(option_.get());
  675. httpRequest.setAcceptMetalink(true);
  676. httpRequest.setNoWantDigest(true);
  677. std::string expectedText =
  678. "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  679. "User-Agent: aria2\r\n"
  680. "Accept: */*,application/metalink4+xml,application/metalink+xml\r\n"
  681. "Host: localhost\r\n"
  682. "Pragma: no-cache\r\n"
  683. "Cache-Control: no-cache\r\n"
  684. "Connection: close\r\n"
  685. "\r\n";
  686. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  687. }
  688. void HttpRequestTest::testEnableAcceptEncoding()
  689. {
  690. auto request = std::make_shared<Request>();
  691. request->setUri("http://localhost/archives/aria2-1.0.0.tar.bz2");
  692. HttpRequest httpRequest;
  693. httpRequest.setRequest(request);
  694. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  695. httpRequest.setOption(option_.get());
  696. httpRequest.setNoWantDigest(true);
  697. std::string acceptEncodings;
  698. #ifdef HAVE_ZLIB
  699. acceptEncodings += "deflate, gzip";
  700. #endif // HAVE_ZLIB
  701. std::string expectedTextHead =
  702. "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
  703. "User-Agent: aria2\r\n"
  704. "Accept: */*\r\n";
  705. std::string expectedTextTail = "Host: localhost\r\n"
  706. "Pragma: no-cache\r\n"
  707. "Cache-Control: no-cache\r\n"
  708. "Connection: close\r\n"
  709. "\r\n";
  710. std::string expectedText = expectedTextHead;
  711. expectedText += expectedTextTail;
  712. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  713. expectedText = expectedTextHead;
  714. if (!acceptEncodings.empty()) {
  715. expectedText += "Accept-Encoding: ";
  716. expectedText += acceptEncodings;
  717. expectedText += "\r\n";
  718. }
  719. expectedText += expectedTextTail;
  720. httpRequest.enableAcceptGZip();
  721. CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
  722. }
  723. void HttpRequestTest::testCreateRequest_ipv6LiteralAddr()
  724. {
  725. auto request = std::make_shared<Request>();
  726. request->setUri("http://[::1]/path");
  727. HttpRequest httpRequest;
  728. httpRequest.disableContentEncoding();
  729. httpRequest.setRequest(request);
  730. httpRequest.setAuthConfigFactory(authConfigFactory_.get());
  731. httpRequest.setOption(option_.get());
  732. CPPUNIT_ASSERT(httpRequest.createRequest().find("Host: [::1]") !=
  733. std::string::npos);
  734. auto proxy = std::make_shared<Request>();
  735. proxy->setUri("http://proxy");
  736. httpRequest.setProxyRequest(proxy);
  737. std::string proxyRequest = httpRequest.createProxyRequest();
  738. CPPUNIT_ASSERT(proxyRequest.find("Host: [::1]:80") != std::string::npos);
  739. CPPUNIT_ASSERT(proxyRequest.find("CONNECT [::1]:80 ") != std::string::npos);
  740. }
  741. void HttpRequestTest::testConditionalRequest()
  742. {
  743. HttpRequest httpRequest;
  744. CPPUNIT_ASSERT(!httpRequest.conditionalRequest());
  745. httpRequest.setIfModifiedSinceHeader("dummy");
  746. CPPUNIT_ASSERT(httpRequest.conditionalRequest());
  747. httpRequest.setIfModifiedSinceHeader("");
  748. CPPUNIT_ASSERT(!httpRequest.conditionalRequest());
  749. httpRequest.addHeader("If-None-Match: *");
  750. CPPUNIT_ASSERT(httpRequest.conditionalRequest());
  751. httpRequest.clearHeader();
  752. httpRequest.addHeader("If-Modified-Since: dummy");
  753. CPPUNIT_ASSERT(httpRequest.conditionalRequest());
  754. }
  755. } // namespace aria2