document_loader_impl_unittest.cc 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "pdf/loader/document_loader_impl.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <string>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/callback.h"
  11. #include "base/check.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/test/scoped_feature_list.h"
  14. #include "pdf/loader/url_loader_wrapper.h"
  15. #include "pdf/pdf_features.h"
  16. #include "testing/gmock/include/gmock/gmock.h"
  17. #include "testing/gtest/include/gtest/gtest.h"
  18. #include "ui/gfx/range/range.h"
  19. using ::testing::_;
  20. using ::testing::Mock;
  21. using ::testing::NiceMock;
  22. using ::testing::Return;
  23. using ::testing::Sequence;
  24. namespace chrome_pdf {
  25. namespace {
  26. constexpr uint32_t kDefaultRequestSize =
  27. DocumentLoaderImpl::kDefaultRequestSize;
  28. class TestURLLoader : public URLLoaderWrapper {
  29. public:
  30. class LoaderData {
  31. public:
  32. LoaderData() = default;
  33. LoaderData(const LoaderData&) = delete;
  34. LoaderData& operator=(const LoaderData&) = delete;
  35. ~LoaderData() {
  36. // We should call callbacks to prevent memory leaks.
  37. // The callbacks don't do anything, because the objects that created the
  38. // callbacks have been destroyed.
  39. if (IsWaitRead())
  40. CallReadCallback(-1);
  41. if (IsWaitOpen())
  42. CallOpenCallback(-1);
  43. }
  44. int content_length() const { return content_length_; }
  45. void set_content_length(int content_length) {
  46. content_length_ = content_length;
  47. }
  48. bool accept_ranges_bytes() const { return accept_ranges_bytes_; }
  49. void set_accept_ranges_bytes(bool accept_ranges_bytes) {
  50. accept_ranges_bytes_ = accept_ranges_bytes;
  51. }
  52. bool content_encoded() const { return content_encoded_; }
  53. void set_content_encoded(bool content_encoded) {
  54. content_encoded_ = content_encoded;
  55. }
  56. const std::string& content_type() const { return content_type_; }
  57. void set_content_type(const std::string& content_type) {
  58. content_type_ = content_type;
  59. }
  60. const std::string& content_disposition() const {
  61. return content_disposition_;
  62. }
  63. void set_content_disposition(const std::string& content_disposition) {
  64. content_disposition_ = content_disposition;
  65. }
  66. const std::string& multipart_boundary() const {
  67. return multipart_boundary_;
  68. }
  69. void set_multipart_boundary(const std::string& multipart_boundary) {
  70. multipart_boundary_ = multipart_boundary;
  71. }
  72. const gfx::Range& byte_range() const { return byte_range_; }
  73. void set_byte_range(const gfx::Range& byte_range) {
  74. byte_range_ = byte_range;
  75. }
  76. bool is_multipart() const { return is_multipart_; }
  77. void set_is_multipart(bool is_multipart) { is_multipart_ = is_multipart; }
  78. int status_code() const { return status_code_; }
  79. void set_status_code(int status_code) { status_code_ = status_code; }
  80. bool closed() const { return closed_; }
  81. void set_closed(bool closed) { closed_ = closed; }
  82. const gfx::Range& open_byte_range() const { return open_byte_range_; }
  83. void set_open_byte_range(const gfx::Range& open_byte_range) {
  84. open_byte_range_ = open_byte_range;
  85. }
  86. bool IsWaitRead() const { return !did_read_callback_.is_null(); }
  87. bool IsWaitOpen() const { return !did_open_callback_.is_null(); }
  88. char* buffer() const { return buffer_; }
  89. int buffer_size() const { return buffer_size_; }
  90. void SetReadCallback(base::OnceCallback<void(int)> read_callback,
  91. char* buffer,
  92. int buffer_size) {
  93. did_read_callback_ = std::move(read_callback);
  94. buffer_ = buffer;
  95. buffer_size_ = buffer_size;
  96. }
  97. void SetOpenCallback(base::OnceCallback<void(int)> open_callback,
  98. gfx::Range req_byte_range) {
  99. did_open_callback_ = std::move(open_callback);
  100. set_open_byte_range(req_byte_range);
  101. }
  102. void CallOpenCallback(int result) {
  103. DCHECK(IsWaitOpen());
  104. std::move(did_open_callback_).Run(result);
  105. }
  106. void CallReadCallback(int result) {
  107. DCHECK(IsWaitRead());
  108. std::move(did_read_callback_).Run(result);
  109. }
  110. private:
  111. base::OnceCallback<void(int)> did_open_callback_;
  112. base::OnceCallback<void(int)> did_read_callback_;
  113. raw_ptr<char> buffer_ = nullptr;
  114. int buffer_size_ = 0;
  115. int content_length_ = -1;
  116. bool accept_ranges_bytes_ = false;
  117. bool content_encoded_ = false;
  118. std::string content_type_;
  119. std::string content_disposition_;
  120. std::string multipart_boundary_;
  121. gfx::Range byte_range_ = gfx::Range::InvalidRange();
  122. bool is_multipart_ = false;
  123. int status_code_ = 0;
  124. bool closed_ = true;
  125. gfx::Range open_byte_range_ = gfx::Range::InvalidRange();
  126. };
  127. explicit TestURLLoader(LoaderData* data) : data_(data) {
  128. data_->set_closed(false);
  129. }
  130. TestURLLoader(const TestURLLoader&) = delete;
  131. TestURLLoader& operator=(const TestURLLoader&) = delete;
  132. ~TestURLLoader() override { Close(); }
  133. int GetContentLength() const override { return data_->content_length(); }
  134. bool IsAcceptRangesBytes() const override {
  135. return data_->accept_ranges_bytes();
  136. }
  137. bool IsContentEncoded() const override { return data_->content_encoded(); }
  138. std::string GetContentType() const override { return data_->content_type(); }
  139. std::string GetContentDisposition() const override {
  140. return data_->content_disposition();
  141. }
  142. int GetStatusCode() const override { return data_->status_code(); }
  143. bool IsMultipart() const override { return data_->is_multipart(); }
  144. bool GetByteRangeStart(int* start) const override {
  145. *start = data_->byte_range().start();
  146. return data_->byte_range().IsValid();
  147. }
  148. void Close() override { data_->set_closed(true); }
  149. void OpenRange(const std::string& url,
  150. const std::string& referrer_url,
  151. uint32_t position,
  152. uint32_t size,
  153. base::OnceCallback<void(int)> callback) override {
  154. data_->SetOpenCallback(std::move(callback),
  155. gfx::Range(position, position + size));
  156. }
  157. void ReadResponseBody(char* buffer,
  158. int buffer_size,
  159. base::OnceCallback<void(int)> callback) override {
  160. data_->SetReadCallback(std::move(callback), buffer, buffer_size);
  161. }
  162. private:
  163. raw_ptr<LoaderData> data_;
  164. };
  165. class TestClient : public DocumentLoader::Client {
  166. public:
  167. TestClient() { full_page_loader_data()->set_content_type("application/pdf"); }
  168. TestClient(const TestClient&) = delete;
  169. TestClient& operator=(const TestClient&) = delete;
  170. ~TestClient() override = default;
  171. // DocumentLoader::Client overrides:
  172. std::unique_ptr<URLLoaderWrapper> CreateURLLoader() override {
  173. return std::unique_ptr<URLLoaderWrapper>(
  174. new TestURLLoader(partial_loader_data()));
  175. }
  176. void OnPendingRequestComplete() override {}
  177. void OnNewDataReceived() override {}
  178. void OnDocumentComplete() override {}
  179. void OnDocumentCanceled() override {}
  180. std::unique_ptr<URLLoaderWrapper> CreateFullPageLoader() {
  181. return std::unique_ptr<URLLoaderWrapper>(
  182. new TestURLLoader(full_page_loader_data()));
  183. }
  184. TestURLLoader::LoaderData* full_page_loader_data() {
  185. return &full_page_loader_data_;
  186. }
  187. TestURLLoader::LoaderData* partial_loader_data() {
  188. return &partial_loader_data_;
  189. }
  190. void SetCanUsePartialLoading() {
  191. full_page_loader_data()->set_content_length(10 * 1024 * 1024);
  192. full_page_loader_data()->set_content_encoded(false);
  193. full_page_loader_data()->set_accept_ranges_bytes(true);
  194. }
  195. void SendAllPartialData() {
  196. partial_loader_data_.set_byte_range(partial_loader_data_.open_byte_range());
  197. partial_loader_data_.CallOpenCallback(0);
  198. uint32_t length = partial_loader_data_.byte_range().length();
  199. while (length > 0) {
  200. constexpr uint32_t max_part_len = kDefaultRequestSize;
  201. const uint32_t part_len = std::min(length, max_part_len);
  202. partial_loader_data_.CallReadCallback(part_len);
  203. length -= part_len;
  204. }
  205. if (partial_loader_data_.IsWaitRead()) {
  206. partial_loader_data_.CallReadCallback(0);
  207. }
  208. }
  209. private:
  210. TestURLLoader::LoaderData full_page_loader_data_;
  211. TestURLLoader::LoaderData partial_loader_data_;
  212. };
  213. class MockClient : public TestClient {
  214. public:
  215. MockClient() = default;
  216. MockClient(const MockClient&) = delete;
  217. MockClient& operator=(const MockClient&) = delete;
  218. MOCK_METHOD(void, OnPendingRequestComplete, (), (override));
  219. MOCK_METHOD(void, OnNewDataReceived, (), (override));
  220. MOCK_METHOD(void, OnDocumentComplete, (), (override));
  221. MOCK_METHOD(void, OnDocumentCanceled, (), (override));
  222. };
  223. } // namespace
  224. class DocumentLoaderImplTest : public testing::Test {
  225. protected:
  226. DocumentLoaderImplTest() {
  227. scoped_feature_list_.InitAndEnableFeature(features::kPdfPartialLoading);
  228. }
  229. base::test::ScopedFeatureList scoped_feature_list_;
  230. };
  231. TEST_F(DocumentLoaderImplTest, PartialLoadingFeatureDefault) {
  232. scoped_feature_list_.Reset();
  233. scoped_feature_list_.Init();
  234. // Test that partial loading is disabled when feature is defaulted.
  235. TestClient client;
  236. client.SetCanUsePartialLoading();
  237. DocumentLoaderImpl loader(&client);
  238. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  239. loader.RequestData(1000000, 1);
  240. EXPECT_FALSE(loader.is_partial_loader_active());
  241. // Always send initial data from FullPageLoader.
  242. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  243. EXPECT_FALSE(loader.is_partial_loader_active());
  244. }
  245. TEST_F(DocumentLoaderImplTest, PartialLoadingFeatureDisabled) {
  246. scoped_feature_list_.Reset();
  247. scoped_feature_list_.InitAndDisableFeature(features::kPdfPartialLoading);
  248. // Test that partial loading is disabled when feature is disabled.
  249. TestClient client;
  250. client.SetCanUsePartialLoading();
  251. DocumentLoaderImpl loader(&client);
  252. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  253. loader.RequestData(1000000, 1);
  254. EXPECT_FALSE(loader.is_partial_loader_active());
  255. // Always send initial data from FullPageLoader.
  256. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  257. EXPECT_FALSE(loader.is_partial_loader_active());
  258. }
  259. TEST_F(DocumentLoaderImplTest, PartialLoadingEnabled) {
  260. // Test that partial loading is enabled. (Fixture enables PdfPartialLoading.)
  261. TestClient client;
  262. client.SetCanUsePartialLoading();
  263. DocumentLoaderImpl loader(&client);
  264. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  265. loader.RequestData(1000000, 1);
  266. EXPECT_FALSE(loader.is_partial_loader_active());
  267. // Always send initial data from FullPageLoader.
  268. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  269. EXPECT_TRUE(loader.is_partial_loader_active());
  270. }
  271. TEST_F(DocumentLoaderImplTest, PartialLoadingDisabledOnSmallFiles) {
  272. TestClient client;
  273. client.SetCanUsePartialLoading();
  274. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 2);
  275. DocumentLoaderImpl loader(&client);
  276. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  277. loader.RequestData(1000000, 1);
  278. EXPECT_FALSE(loader.is_partial_loader_active());
  279. // Always send initial data from FullPageLoader.
  280. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  281. EXPECT_FALSE(loader.is_partial_loader_active());
  282. }
  283. TEST_F(DocumentLoaderImplTest, PartialLoadingDisabledIfContentEncoded) {
  284. TestClient client;
  285. client.SetCanUsePartialLoading();
  286. client.full_page_loader_data()->set_content_encoded(true);
  287. DocumentLoaderImpl loader(&client);
  288. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  289. loader.RequestData(1000000, 1);
  290. EXPECT_FALSE(loader.is_partial_loader_active());
  291. // Always send initial data from FullPageLoader.
  292. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  293. EXPECT_FALSE(loader.is_partial_loader_active());
  294. }
  295. TEST_F(DocumentLoaderImplTest, PartialLoadingDisabledNoAcceptRangeBytes) {
  296. TestClient client;
  297. client.SetCanUsePartialLoading();
  298. client.full_page_loader_data()->set_accept_ranges_bytes(false);
  299. DocumentLoaderImpl loader(&client);
  300. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  301. loader.RequestData(1000000, 1);
  302. EXPECT_FALSE(loader.is_partial_loader_active());
  303. // Always send initial data from FullPageLoader.
  304. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  305. EXPECT_FALSE(loader.is_partial_loader_active());
  306. }
  307. TEST_F(DocumentLoaderImplTest, PartialLoadingReallyDisabledRequestFromBegin) {
  308. TestClient client;
  309. DocumentLoaderImpl loader(&client);
  310. client.SetCanUsePartialLoading();
  311. loader.SetPartialLoadingEnabled(false);
  312. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  313. // We should not start partial loading if requested data is beside full page
  314. // loading position.
  315. loader.RequestData(kDefaultRequestSize, 1);
  316. EXPECT_FALSE(loader.is_partial_loader_active());
  317. // Always send initial data from FullPageLoader.
  318. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  319. EXPECT_FALSE(loader.is_partial_loader_active());
  320. }
  321. TEST_F(DocumentLoaderImplTest, PartialLoadingReallyDisabledRequestFromMiddle) {
  322. TestClient client;
  323. client.SetCanUsePartialLoading();
  324. DocumentLoaderImpl loader(&client);
  325. loader.SetPartialLoadingEnabled(false);
  326. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  327. loader.RequestData(1000000, 1);
  328. EXPECT_FALSE(loader.is_partial_loader_active());
  329. // Always send initial data from FullPageLoader.
  330. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  331. EXPECT_FALSE(loader.is_partial_loader_active());
  332. }
  333. TEST_F(DocumentLoaderImplTest, PartialLoadingSimple) {
  334. TestClient client;
  335. client.SetCanUsePartialLoading();
  336. DocumentLoaderImpl loader(&client);
  337. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  338. // While we have no requests, we should not start partial loading.
  339. EXPECT_FALSE(loader.is_partial_loader_active());
  340. loader.RequestData(5000000, 1);
  341. EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  342. EXPECT_FALSE(loader.is_partial_loader_active());
  343. // Always send initial data from FullPageLoader.
  344. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  345. // Partial loader should request headers.
  346. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  347. EXPECT_TRUE(loader.is_partial_loader_active());
  348. // Loader should be stopped.
  349. EXPECT_TRUE(client.full_page_loader_data()->closed());
  350. EXPECT_EQ("{4980736,10485760}",
  351. client.partial_loader_data()->open_byte_range().ToString());
  352. }
  353. TEST_F(DocumentLoaderImplTest, PartialLoadingBackOrder) {
  354. TestClient client;
  355. client.SetCanUsePartialLoading();
  356. DocumentLoaderImpl loader(&client);
  357. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  358. // While we have no requests, we should not start partial loading.
  359. EXPECT_FALSE(loader.is_partial_loader_active());
  360. loader.RequestData(client.full_page_loader_data()->content_length() - 1, 1);
  361. EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  362. EXPECT_FALSE(loader.is_partial_loader_active());
  363. // Always send initial data from FullPageLoader.
  364. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  365. // Partial loader should request headers.
  366. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  367. EXPECT_TRUE(loader.is_partial_loader_active());
  368. // Loader should be stopped.
  369. EXPECT_TRUE(client.full_page_loader_data()->closed());
  370. // Requested range should be enlarged.
  371. EXPECT_GT(client.partial_loader_data()->open_byte_range().length(), 1u);
  372. EXPECT_EQ("{9830400,10485760}",
  373. client.partial_loader_data()->open_byte_range().ToString());
  374. }
  375. TEST_F(DocumentLoaderImplTest, CompleteWithoutPartial) {
  376. TestClient client;
  377. client.SetCanUsePartialLoading();
  378. DocumentLoaderImpl loader(&client);
  379. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  380. EXPECT_FALSE(client.full_page_loader_data()->closed());
  381. while (client.full_page_loader_data()->IsWaitRead()) {
  382. client.full_page_loader_data()->CallReadCallback(1000);
  383. }
  384. EXPECT_TRUE(loader.IsDocumentComplete());
  385. EXPECT_TRUE(client.full_page_loader_data()->closed());
  386. }
  387. TEST_F(DocumentLoaderImplTest, ErrorDownloadFullDocument) {
  388. TestClient client;
  389. client.SetCanUsePartialLoading();
  390. DocumentLoaderImpl loader(&client);
  391. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  392. EXPECT_TRUE(client.full_page_loader_data()->IsWaitRead());
  393. EXPECT_FALSE(client.full_page_loader_data()->closed());
  394. client.full_page_loader_data()->CallReadCallback(-3);
  395. EXPECT_TRUE(client.full_page_loader_data()->closed());
  396. EXPECT_FALSE(loader.IsDocumentComplete());
  397. }
  398. TEST_F(DocumentLoaderImplTest, CompleteNoContentLength) {
  399. TestClient client;
  400. DocumentLoaderImpl loader(&client);
  401. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  402. EXPECT_FALSE(client.full_page_loader_data()->closed());
  403. for (int i = 0; i < 10; ++i) {
  404. EXPECT_TRUE(client.full_page_loader_data()->IsWaitRead());
  405. client.full_page_loader_data()->CallReadCallback(1000);
  406. }
  407. EXPECT_TRUE(client.full_page_loader_data()->IsWaitRead());
  408. client.full_page_loader_data()->CallReadCallback(0);
  409. EXPECT_EQ(10000ul, loader.GetDocumentSize());
  410. EXPECT_TRUE(loader.IsDocumentComplete());
  411. EXPECT_TRUE(client.full_page_loader_data()->closed());
  412. }
  413. TEST_F(DocumentLoaderImplTest, CompleteWithPartial) {
  414. TestClient client;
  415. client.SetCanUsePartialLoading();
  416. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  417. DocumentLoaderImpl loader(&client);
  418. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  419. loader.RequestData(19 * kDefaultRequestSize, kDefaultRequestSize);
  420. EXPECT_FALSE(client.full_page_loader_data()->closed());
  421. EXPECT_FALSE(client.partial_loader_data()->IsWaitRead());
  422. EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  423. // Always send initial data from FullPageLoader.
  424. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  425. EXPECT_TRUE(client.full_page_loader_data()->closed());
  426. EXPECT_FALSE(client.partial_loader_data()->closed());
  427. client.SendAllPartialData();
  428. // Now we should send other document data.
  429. client.SendAllPartialData();
  430. EXPECT_TRUE(client.full_page_loader_data()->closed());
  431. EXPECT_TRUE(client.partial_loader_data()->closed());
  432. }
  433. TEST_F(DocumentLoaderImplTest, PartialRequestLastChunk) {
  434. constexpr uint32_t kLastChunkSize = 300;
  435. TestClient client;
  436. client.SetCanUsePartialLoading();
  437. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20 +
  438. kLastChunkSize);
  439. DocumentLoaderImpl loader(&client);
  440. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  441. loader.RequestData(20 * kDefaultRequestSize, 1);
  442. // Always send initial data from FullPageLoader.
  443. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  444. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  445. EXPECT_EQ(
  446. static_cast<int>(client.partial_loader_data()->open_byte_range().end()),
  447. client.full_page_loader_data()->content_length());
  448. client.partial_loader_data()->set_byte_range(
  449. client.partial_loader_data()->open_byte_range());
  450. client.partial_loader_data()->CallOpenCallback(0);
  451. uint32_t data_length = client.partial_loader_data()->byte_range().length();
  452. while (data_length > kDefaultRequestSize) {
  453. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  454. data_length -= kDefaultRequestSize;
  455. }
  456. EXPECT_EQ(kLastChunkSize, data_length);
  457. client.partial_loader_data()->CallReadCallback(kLastChunkSize);
  458. EXPECT_TRUE(loader.IsDataAvailable(kDefaultRequestSize * 20, kLastChunkSize));
  459. }
  460. TEST_F(DocumentLoaderImplTest, DocumentSize) {
  461. TestClient client;
  462. client.SetCanUsePartialLoading();
  463. client.full_page_loader_data()->set_content_length(123456789);
  464. DocumentLoaderImpl loader(&client);
  465. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  466. EXPECT_EQ(static_cast<int>(loader.GetDocumentSize()),
  467. client.full_page_loader_data()->content_length());
  468. }
  469. TEST_F(DocumentLoaderImplTest, DocumentSizeNoContentLength) {
  470. TestClient client;
  471. DocumentLoaderImpl loader(&client);
  472. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  473. EXPECT_EQ(0ul, loader.GetDocumentSize());
  474. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  475. client.full_page_loader_data()->CallReadCallback(1000);
  476. client.full_page_loader_data()->CallReadCallback(500);
  477. client.full_page_loader_data()->CallReadCallback(0);
  478. EXPECT_EQ(kDefaultRequestSize + 1000ul + 500ul, loader.GetDocumentSize());
  479. EXPECT_TRUE(loader.IsDocumentComplete());
  480. }
  481. TEST_F(DocumentLoaderImplTest, ClearPendingRequests) {
  482. TestClient client;
  483. client.SetCanUsePartialLoading();
  484. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 100 +
  485. 58383);
  486. DocumentLoaderImpl loader(&client);
  487. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  488. loader.RequestData(17 * kDefaultRequestSize + 100, 10);
  489. loader.ClearPendingRequests();
  490. loader.RequestData(15 * kDefaultRequestSize + 200, 20);
  491. // pending requests are accumulating, and will be processed after initial data
  492. // load.
  493. EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  494. // Send initial data from FullPageLoader.
  495. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  496. {
  497. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  498. constexpr gfx::Range range_requested(15 * kDefaultRequestSize,
  499. 16 * kDefaultRequestSize);
  500. EXPECT_EQ(range_requested.start(),
  501. client.partial_loader_data()->open_byte_range().start());
  502. EXPECT_LE(range_requested.end(),
  503. client.partial_loader_data()->open_byte_range().end());
  504. client.partial_loader_data()->set_byte_range(
  505. client.partial_loader_data()->open_byte_range());
  506. }
  507. // clear requests before Open callback.
  508. loader.ClearPendingRequests();
  509. // Current request should continue loading.
  510. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  511. client.partial_loader_data()->CallOpenCallback(0);
  512. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  513. EXPECT_FALSE(client.partial_loader_data()->closed());
  514. // Current request should continue loading, because no other request queued.
  515. loader.RequestData(18 * kDefaultRequestSize + 200, 20);
  516. // Requests queue is processed only on receiving data.
  517. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  518. // New request within close distance from the one currently loading. Loading
  519. // isn't restarted.
  520. EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  521. loader.ClearPendingRequests();
  522. // request again two.
  523. loader.RequestData(60 * kDefaultRequestSize + 100, 10);
  524. loader.RequestData(35 * kDefaultRequestSize + 200, 20);
  525. // Requests queue is processed only on receiving data.
  526. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  527. {
  528. // new requset not with in close distance from current loading.
  529. // Loading should be restarted.
  530. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  531. // The first requested chunk should be processed.
  532. constexpr gfx::Range range_requested(35 * kDefaultRequestSize,
  533. 36 * kDefaultRequestSize);
  534. EXPECT_EQ(range_requested.start(),
  535. client.partial_loader_data()->open_byte_range().start());
  536. EXPECT_LE(range_requested.end(),
  537. client.partial_loader_data()->open_byte_range().end());
  538. client.partial_loader_data()->set_byte_range(
  539. client.partial_loader_data()->open_byte_range());
  540. }
  541. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  542. client.partial_loader_data()->CallOpenCallback(0);
  543. // Override pending requests.
  544. loader.ClearPendingRequests();
  545. loader.RequestData(70 * kDefaultRequestSize + 100, 10);
  546. // Requests queue is processed only on receiving data.
  547. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  548. {
  549. // New requset not with in close distance from current loading.
  550. // Loading should be restarted .
  551. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  552. // The first requested chunk should be processed.
  553. constexpr gfx::Range range_requested(70 * kDefaultRequestSize,
  554. 71 * kDefaultRequestSize);
  555. EXPECT_EQ(range_requested.start(),
  556. client.partial_loader_data()->open_byte_range().start());
  557. EXPECT_LE(range_requested.end(),
  558. client.partial_loader_data()->open_byte_range().end());
  559. client.partial_loader_data()->set_byte_range(
  560. client.partial_loader_data()->open_byte_range());
  561. }
  562. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  563. }
  564. TEST_F(DocumentLoaderImplTest, GetBlock) {
  565. std::vector<char> buffer(kDefaultRequestSize);
  566. TestClient client;
  567. client.SetCanUsePartialLoading();
  568. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20 +
  569. 58383);
  570. DocumentLoaderImpl loader(&client);
  571. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  572. EXPECT_FALSE(loader.GetBlock(0, 1000, buffer.data()));
  573. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  574. EXPECT_TRUE(loader.GetBlock(0, 1000, buffer.data()));
  575. EXPECT_FALSE(loader.GetBlock(kDefaultRequestSize, 1500, buffer.data()));
  576. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  577. EXPECT_TRUE(loader.GetBlock(kDefaultRequestSize, 1500, buffer.data()));
  578. EXPECT_FALSE(loader.GetBlock(17 * kDefaultRequestSize, 3000, buffer.data()));
  579. loader.RequestData(17 * kDefaultRequestSize + 100, 10);
  580. EXPECT_FALSE(loader.GetBlock(17 * kDefaultRequestSize, 3000, buffer.data()));
  581. // Requests queue is processed only on receiving data.
  582. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  583. client.SendAllPartialData();
  584. EXPECT_TRUE(loader.GetBlock(17 * kDefaultRequestSize, 3000, buffer.data()));
  585. }
  586. TEST_F(DocumentLoaderImplTest, IsDataAvailable) {
  587. TestClient client;
  588. client.SetCanUsePartialLoading();
  589. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20 +
  590. 58383);
  591. DocumentLoaderImpl loader(&client);
  592. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  593. EXPECT_FALSE(loader.IsDataAvailable(0, 1000));
  594. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  595. EXPECT_TRUE(loader.IsDataAvailable(0, 1000));
  596. EXPECT_FALSE(loader.IsDataAvailable(kDefaultRequestSize, 1500));
  597. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  598. EXPECT_TRUE(loader.IsDataAvailable(kDefaultRequestSize, 1500));
  599. EXPECT_FALSE(loader.IsDataAvailable(17 * kDefaultRequestSize, 3000));
  600. loader.RequestData(17 * kDefaultRequestSize + 100, 10);
  601. EXPECT_FALSE(loader.IsDataAvailable(17 * kDefaultRequestSize, 3000));
  602. // Requests queue is processed only on receiving data.
  603. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  604. client.SendAllPartialData();
  605. EXPECT_TRUE(loader.IsDataAvailable(17 * kDefaultRequestSize, 3000));
  606. }
  607. TEST_F(DocumentLoaderImplTest, RequestData) {
  608. TestClient client;
  609. client.SetCanUsePartialLoading();
  610. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 100 +
  611. 58383);
  612. DocumentLoaderImpl loader(&client);
  613. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  614. loader.RequestData(37 * kDefaultRequestSize + 200, 10);
  615. loader.RequestData(25 * kDefaultRequestSize + 600, 100);
  616. loader.RequestData(13 * kDefaultRequestSize + 900, 500);
  617. // Send initial data from FullPageLoader.
  618. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  619. {
  620. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  621. constexpr gfx::Range range_requested(13 * kDefaultRequestSize,
  622. 14 * kDefaultRequestSize);
  623. EXPECT_EQ(range_requested.start(),
  624. client.partial_loader_data()->open_byte_range().start());
  625. EXPECT_LE(range_requested.end(),
  626. client.partial_loader_data()->open_byte_range().end());
  627. client.partial_loader_data()->set_byte_range(
  628. client.partial_loader_data()->open_byte_range());
  629. }
  630. client.partial_loader_data()->CallOpenCallback(0);
  631. // Override pending requests.
  632. loader.ClearPendingRequests();
  633. loader.RequestData(38 * kDefaultRequestSize + 200, 10);
  634. loader.RequestData(26 * kDefaultRequestSize + 600, 100);
  635. // Requests queue is processed only on receiving data.
  636. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  637. {
  638. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  639. constexpr gfx::Range range_requested(26 * kDefaultRequestSize,
  640. 27 * kDefaultRequestSize);
  641. EXPECT_EQ(range_requested.start(),
  642. client.partial_loader_data()->open_byte_range().start());
  643. EXPECT_LE(range_requested.end(),
  644. client.partial_loader_data()->open_byte_range().end());
  645. client.partial_loader_data()->set_byte_range(
  646. client.partial_loader_data()->open_byte_range());
  647. }
  648. client.partial_loader_data()->CallOpenCallback(0);
  649. // Override pending requests.
  650. loader.ClearPendingRequests();
  651. loader.RequestData(39 * kDefaultRequestSize + 200, 10);
  652. // Requests queue is processed only on receiving data.
  653. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  654. {
  655. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  656. constexpr gfx::Range range_requested(39 * kDefaultRequestSize,
  657. 40 * kDefaultRequestSize);
  658. EXPECT_EQ(range_requested.start(),
  659. client.partial_loader_data()->open_byte_range().start());
  660. EXPECT_LE(range_requested.end(),
  661. client.partial_loader_data()->open_byte_range().end());
  662. client.partial_loader_data()->set_byte_range(
  663. client.partial_loader_data()->open_byte_range());
  664. }
  665. // Fill all gaps.
  666. while (!loader.IsDocumentComplete()) {
  667. client.SendAllPartialData();
  668. }
  669. EXPECT_TRUE(client.partial_loader_data()->closed());
  670. }
  671. TEST_F(DocumentLoaderImplTest, DoNotLoadAvailablePartialData) {
  672. TestClient client;
  673. client.SetCanUsePartialLoading();
  674. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20 +
  675. 58383);
  676. DocumentLoaderImpl loader(&client);
  677. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  678. // Send initial data from FullPageLoader.
  679. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  680. // Send more data from FullPageLoader.
  681. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  682. loader.RequestData(2 * kDefaultRequestSize + 200, 10);
  683. // Send more data from FullPageLoader.
  684. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  685. // Partial loading should not have started for already available data.
  686. EXPECT_TRUE(client.partial_loader_data()->closed());
  687. }
  688. TEST_F(DocumentLoaderImplTest, DoNotLoadDataAfterComplete) {
  689. TestClient client;
  690. client.SetCanUsePartialLoading();
  691. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  692. DocumentLoaderImpl loader(&client);
  693. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  694. for (int i = 0; i < 20; ++i) {
  695. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  696. }
  697. EXPECT_TRUE(loader.IsDocumentComplete());
  698. loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  699. EXPECT_TRUE(client.partial_loader_data()->closed());
  700. EXPECT_TRUE(client.full_page_loader_data()->closed());
  701. }
  702. TEST_F(DocumentLoaderImplTest, DoNotLoadPartialDataAboveDocumentSize) {
  703. TestClient client;
  704. client.SetCanUsePartialLoading();
  705. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  706. DocumentLoaderImpl loader(&client);
  707. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  708. loader.RequestData(20 * kDefaultRequestSize + 200, 10);
  709. // Send initial data from FullPageLoader.
  710. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  711. EXPECT_TRUE(client.partial_loader_data()->closed());
  712. }
  713. TEST_F(DocumentLoaderImplTest, MergePendingRequests) {
  714. TestClient client;
  715. client.SetCanUsePartialLoading();
  716. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 50 +
  717. 58383);
  718. DocumentLoaderImpl loader(&client);
  719. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  720. loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  721. loader.RequestData(16 * kDefaultRequestSize + 600, 100);
  722. // Send initial data from FullPageLoader.
  723. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  724. constexpr gfx::Range range_requested(16 * kDefaultRequestSize,
  725. 18 * kDefaultRequestSize);
  726. EXPECT_EQ(range_requested.start(),
  727. client.partial_loader_data()->open_byte_range().start());
  728. EXPECT_LE(range_requested.end(),
  729. client.partial_loader_data()->open_byte_range().end());
  730. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  731. // Fill all gaps.
  732. while (!loader.IsDocumentComplete()) {
  733. client.SendAllPartialData();
  734. }
  735. EXPECT_TRUE(client.partial_loader_data()->closed());
  736. }
  737. TEST_F(DocumentLoaderImplTest, PartialStopOnStatusCodeError) {
  738. TestClient client;
  739. client.SetCanUsePartialLoading();
  740. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  741. DocumentLoaderImpl loader(&client);
  742. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  743. loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  744. // Send initial data from FullPageLoader.
  745. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  746. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  747. client.partial_loader_data()->set_status_code(404);
  748. client.partial_loader_data()->CallOpenCallback(0);
  749. EXPECT_TRUE(client.partial_loader_data()->closed());
  750. }
  751. TEST_F(DocumentLoaderImplTest,
  752. PartialAsFullDocumentLoadingRangeRequestNoRangeField) {
  753. TestClient client;
  754. client.SetCanUsePartialLoading();
  755. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  756. DocumentLoaderImpl loader(&client);
  757. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  758. loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  759. // Send initial data from FullPageLoader.
  760. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  761. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  762. client.partial_loader_data()->set_byte_range(gfx::Range::InvalidRange());
  763. client.partial_loader_data()->CallOpenCallback(0);
  764. EXPECT_FALSE(client.partial_loader_data()->closed());
  765. // Partial loader is used to load the whole page, like full page loader.
  766. EXPECT_FALSE(loader.is_partial_loader_active());
  767. }
  768. TEST_F(DocumentLoaderImplTest, PartialMultiPart) {
  769. TestClient client;
  770. client.SetCanUsePartialLoading();
  771. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  772. DocumentLoaderImpl loader(&client);
  773. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  774. loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  775. // Send initial data from FullPageLoader.
  776. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  777. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  778. client.partial_loader_data()->set_is_multipart(true);
  779. client.partial_loader_data()->CallOpenCallback(0);
  780. client.partial_loader_data()->set_byte_range(
  781. gfx::Range(17 * kDefaultRequestSize, 18 * kDefaultRequestSize));
  782. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  783. EXPECT_TRUE(
  784. loader.IsDataAvailable(17 * kDefaultRequestSize, kDefaultRequestSize));
  785. }
  786. TEST_F(DocumentLoaderImplTest, PartialMultiPartRangeError) {
  787. TestClient client;
  788. client.SetCanUsePartialLoading();
  789. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  790. DocumentLoaderImpl loader(&client);
  791. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  792. loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  793. // Send initial data from FullPageLoader.
  794. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  795. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  796. client.partial_loader_data()->set_is_multipart(true);
  797. client.partial_loader_data()->CallOpenCallback(0);
  798. client.partial_loader_data()->set_byte_range(gfx::Range::InvalidRange());
  799. client.partial_loader_data()->CallReadCallback(kDefaultRequestSize);
  800. EXPECT_FALSE(
  801. loader.IsDataAvailable(17 * kDefaultRequestSize, kDefaultRequestSize));
  802. EXPECT_TRUE(client.partial_loader_data()->closed());
  803. }
  804. TEST_F(DocumentLoaderImplTest, PartialConnectionErrorOnOpen) {
  805. TestClient client;
  806. client.SetCanUsePartialLoading();
  807. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  808. DocumentLoaderImpl loader(&client);
  809. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  810. loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  811. // Send initial data from FullPageLoader.
  812. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  813. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  814. client.partial_loader_data()->CallOpenCallback(-3);
  815. EXPECT_TRUE(client.partial_loader_data()->closed());
  816. // Partial loading should not restart after any error.
  817. loader.RequestData(18 * kDefaultRequestSize + 200, 10);
  818. EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  819. EXPECT_TRUE(client.partial_loader_data()->closed());
  820. }
  821. TEST_F(DocumentLoaderImplTest, PartialConnectionErrorOnRead) {
  822. TestClient client;
  823. client.SetCanUsePartialLoading();
  824. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  825. DocumentLoaderImpl loader(&client);
  826. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  827. loader.RequestData(17 * kDefaultRequestSize + 200, 10);
  828. // Send initial data from FullPageLoader.
  829. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  830. EXPECT_TRUE(client.partial_loader_data()->IsWaitOpen());
  831. client.partial_loader_data()->set_byte_range(
  832. gfx::Range(17 * kDefaultRequestSize, 18 * kDefaultRequestSize));
  833. client.partial_loader_data()->CallOpenCallback(0);
  834. EXPECT_TRUE(client.partial_loader_data()->IsWaitRead());
  835. client.partial_loader_data()->CallReadCallback(-3);
  836. EXPECT_TRUE(client.partial_loader_data()->closed());
  837. // Partial loading should not restart after any error.
  838. loader.RequestData(18 * kDefaultRequestSize + 200, 10);
  839. EXPECT_FALSE(client.partial_loader_data()->IsWaitOpen());
  840. EXPECT_TRUE(client.partial_loader_data()->closed());
  841. }
  842. TEST_F(DocumentLoaderImplTest, ClientCompleteCallbacks) {
  843. MockClient client;
  844. client.SetCanUsePartialLoading();
  845. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  846. DocumentLoaderImpl loader(&client);
  847. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  848. EXPECT_CALL(client, OnDocumentComplete()).Times(0);
  849. for (int i = 0; i < 19; ++i)
  850. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  851. Mock::VerifyAndClear(&client);
  852. EXPECT_CALL(client, OnDocumentComplete()).Times(1);
  853. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  854. Mock::VerifyAndClear(&client);
  855. }
  856. TEST_F(DocumentLoaderImplTest, ClientCompleteCallbacksNoContentLength) {
  857. MockClient client;
  858. DocumentLoaderImpl loader(&client);
  859. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  860. EXPECT_CALL(client, OnDocumentCanceled()).Times(0);
  861. EXPECT_CALL(client, OnDocumentComplete()).Times(0);
  862. for (int i = 0; i < 20; ++i)
  863. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  864. Mock::VerifyAndClear(&client);
  865. EXPECT_CALL(client, OnDocumentCanceled()).Times(0);
  866. EXPECT_CALL(client, OnDocumentComplete()).Times(1);
  867. client.full_page_loader_data()->CallReadCallback(0);
  868. Mock::VerifyAndClear(&client);
  869. }
  870. TEST_F(DocumentLoaderImplTest, ClientCancelCallback) {
  871. MockClient client;
  872. client.SetCanUsePartialLoading();
  873. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  874. DocumentLoaderImpl loader(&client);
  875. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  876. EXPECT_CALL(client, OnDocumentCanceled()).Times(0);
  877. EXPECT_CALL(client, OnDocumentComplete()).Times(0);
  878. for (int i = 0; i < 10; ++i)
  879. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  880. Mock::VerifyAndClear(&client);
  881. EXPECT_CALL(client, OnDocumentComplete()).Times(0);
  882. EXPECT_CALL(client, OnDocumentCanceled()).Times(1);
  883. client.full_page_loader_data()->CallReadCallback(-3);
  884. Mock::VerifyAndClear(&client);
  885. }
  886. TEST_F(DocumentLoaderImplTest, NewDataAvailable) {
  887. MockClient client;
  888. client.SetCanUsePartialLoading();
  889. client.full_page_loader_data()->set_content_length(kDefaultRequestSize * 20);
  890. DocumentLoaderImpl loader(&client);
  891. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  892. EXPECT_CALL(client, OnNewDataReceived()).Times(1);
  893. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  894. Mock::VerifyAndClear(&client);
  895. EXPECT_CALL(client, OnNewDataReceived()).Times(1);
  896. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize - 100);
  897. Mock::VerifyAndClear(&client);
  898. EXPECT_CALL(client, OnNewDataReceived()).Times(1);
  899. client.full_page_loader_data()->CallReadCallback(100);
  900. Mock::VerifyAndClear(&client);
  901. }
  902. TEST_F(DocumentLoaderImplTest, ClientPendingRequestCompleteFullLoader) {
  903. MockClient client;
  904. client.SetCanUsePartialLoading();
  905. DocumentLoaderImpl loader(&client);
  906. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  907. loader.RequestData(1000, 4000);
  908. EXPECT_CALL(client, OnPendingRequestComplete()).Times(1);
  909. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  910. Mock::VerifyAndClear(&client);
  911. }
  912. TEST_F(DocumentLoaderImplTest, ClientPendingRequestCompletePartialLoader) {
  913. MockClient client;
  914. client.SetCanUsePartialLoading();
  915. DocumentLoaderImpl loader(&client);
  916. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  917. EXPECT_CALL(client, OnPendingRequestComplete()).Times(1);
  918. loader.RequestData(15 * kDefaultRequestSize + 4000, 4000);
  919. // Always send initial data from FullPageLoader.
  920. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  921. client.SendAllPartialData();
  922. Mock::VerifyAndClear(&client);
  923. }
  924. TEST_F(DocumentLoaderImplTest,
  925. ClientPendingRequestCompletePartialAndFullLoader) {
  926. MockClient client;
  927. client.SetCanUsePartialLoading();
  928. DocumentLoaderImpl loader(&client);
  929. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  930. EXPECT_CALL(client, OnPendingRequestComplete()).Times(1);
  931. loader.RequestData(16 * kDefaultRequestSize + 4000, 4000);
  932. loader.RequestData(4 * kDefaultRequestSize + 4000, 4000);
  933. for (int i = 0; i < 5; ++i)
  934. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  935. Mock::VerifyAndClear(&client);
  936. EXPECT_CALL(client, OnPendingRequestComplete()).Times(1);
  937. client.SendAllPartialData();
  938. Mock::VerifyAndClear(&client);
  939. }
  940. TEST_F(DocumentLoaderImplTest, IgnoreDataMoreThanExpectedWithPartial) {
  941. static constexpr uint32_t kDocSize = kDefaultRequestSize * 80 - 321;
  942. TestClient client;
  943. client.SetCanUsePartialLoading();
  944. client.full_page_loader_data()->set_content_length(kDocSize);
  945. DocumentLoaderImpl loader(&client);
  946. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  947. // Request data at and.
  948. loader.RequestData(kDocSize - 100, 100);
  949. // Always send initial data from FullPageLoader.
  950. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  951. EXPECT_TRUE(client.full_page_loader_data()->closed());
  952. EXPECT_FALSE(client.partial_loader_data()->closed());
  953. // Request data at middle to continue loading partial, but not all remaining
  954. // data.
  955. loader.RequestData(kDocSize / 2, 100);
  956. // Fill data at the end, the partial loding should be started for second
  957. // requested data after receive data for first request.
  958. client.SendAllPartialData();
  959. ASSERT_TRUE(client.partial_loader_data()->IsWaitOpen());
  960. // Process second request.
  961. const uint32_t expected_length =
  962. client.partial_loader_data()->open_byte_range().length();
  963. // Send data.
  964. client.partial_loader_data()->set_byte_range(
  965. client.partial_loader_data()->open_byte_range());
  966. client.partial_loader_data()->CallOpenCallback(0);
  967. uint32_t length = expected_length;
  968. while (length > 0) {
  969. constexpr uint32_t max_part_len = kDefaultRequestSize;
  970. const uint32_t part_len = std::min(length, max_part_len);
  971. client.partial_loader_data()->CallReadCallback(part_len);
  972. length -= part_len;
  973. }
  974. // The partial loading should be finished for current chunks sequence, if
  975. // expected range was received, and remaining sequence should start loading.
  976. EXPECT_FALSE(client.partial_loader_data()->IsWaitRead());
  977. ASSERT_TRUE(client.partial_loader_data()->IsWaitOpen());
  978. // Send other document data.
  979. client.SendAllPartialData();
  980. // The downloads should be finished.
  981. EXPECT_TRUE(client.full_page_loader_data()->closed());
  982. EXPECT_TRUE(client.partial_loader_data()->closed());
  983. }
  984. TEST_F(DocumentLoaderImplTest, IgnoreDataMoreThanExpectedWithPartialAtFileEnd) {
  985. static constexpr uint32_t kExtraSize = 100;
  986. static constexpr uint32_t kRealSize = kDefaultRequestSize * 20 - 300;
  987. static constexpr uint32_t kDocSize = kRealSize - kExtraSize;
  988. TestClient client;
  989. client.SetCanUsePartialLoading();
  990. client.full_page_loader_data()->set_content_length(kDocSize);
  991. DocumentLoaderImpl loader(&client);
  992. loader.Init(client.CreateFullPageLoader(), "http://url.com");
  993. // Request data at middle.
  994. static constexpr uint32_t kFirstPartial = kDefaultRequestSize * 11;
  995. loader.RequestData(kFirstPartial, kDefaultRequestSize);
  996. // Always send initial data from FullPageLoader.
  997. client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize);
  998. EXPECT_TRUE(client.full_page_loader_data()->closed());
  999. EXPECT_FALSE(client.partial_loader_data()->closed());
  1000. // Send data to file end and extra non expected data.
  1001. client.partial_loader_data()->set_byte_range(
  1002. gfx::Range(kFirstPartial, kRealSize));
  1003. client.partial_loader_data()->CallOpenCallback(0);
  1004. uint32_t length = client.partial_loader_data()->byte_range().length();
  1005. while (length > 0) {
  1006. constexpr uint32_t max_part_len = kDefaultRequestSize;
  1007. const uint32_t part_len = std::min(length, max_part_len);
  1008. client.partial_loader_data()->CallReadCallback(part_len);
  1009. length -= part_len;
  1010. }
  1011. // The partial loading should be finished for current chunks sequence, if
  1012. // eof was reached, and remaining sequence should start loading.
  1013. EXPECT_FALSE(client.partial_loader_data()->IsWaitRead());
  1014. EXPECT_EQ(gfx::Range(kDefaultRequestSize, kFirstPartial),
  1015. client.partial_loader_data()->open_byte_range());
  1016. // Send other document data.
  1017. client.SendAllPartialData();
  1018. // The downloads should be finished.
  1019. EXPECT_TRUE(client.full_page_loader_data()->closed());
  1020. EXPECT_TRUE(client.partial_loader_data()->closed());
  1021. }
  1022. } // namespace chrome_pdf