OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "pdf/document_loader.h" | 5 #include "pdf/document_loader.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 | 11 |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/numerics/safe_math.h" | 14 #include "base/numerics/safe_math.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "pdf/url_loader_wrapper.h" | 16 #include "pdf/url_loader_wrapper.h" |
17 #include "ppapi/c/pp_errors.h" | 17 #include "ppapi/c/pp_errors.h" |
18 #include "ui/gfx/range/range.h" | 18 #include "ui/gfx/range/range.h" |
19 | 19 |
20 namespace chrome_pdf { | 20 namespace chrome_pdf { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // The distance from last received chunk, when we wait requesting data, using | 24 // The distance from last received chunk, when we wait requesting data, using |
25 // current connection (like playing a cassette tape) and do not send new range | 25 // current connection (like playing a cassette tape) and do not send new range |
26 // request (like rewind a cassette tape, and continue playing after). | 26 // request (like rewind a cassette tape, and continue playing after). |
27 // Experimentally chosen value. | 27 // Experimentally chosen value. |
28 const int kChunkCloseDistance = 10; | 28 const int kChunkCloseDistance = 10; |
29 | 29 |
| 30 // Return true if the HTTP response of |loader| is a successful one and loading |
| 31 // should continue. 4xx error indicate subsequent requests will fail too. |
| 32 // e.g. resource has been removed from the server while loading it. 301 |
| 33 // indicates a redirect was returned which won't be successful because we |
| 34 // disable following redirects for PDF loading (we assume they are already |
| 35 // resolved by the browser. |
| 36 bool ResponseStatusSuccess(const URLLoaderWrapper* loader) { |
| 37 int32_t http_code = loader->GetStatusCode(); |
| 38 return (http_code < 400 && http_code != 301) || http_code >= 500; |
| 39 } |
| 40 |
30 bool IsValidContentType(const std::string& type) { | 41 bool IsValidContentType(const std::string& type) { |
31 return (base::EndsWith(type, "/pdf", base::CompareCase::INSENSITIVE_ASCII) || | 42 return (base::EndsWith(type, "/pdf", base::CompareCase::INSENSITIVE_ASCII) || |
32 base::EndsWith(type, ".pdf", base::CompareCase::INSENSITIVE_ASCII) || | 43 base::EndsWith(type, ".pdf", base::CompareCase::INSENSITIVE_ASCII) || |
33 base::EndsWith(type, "/x-pdf", | 44 base::EndsWith(type, "/x-pdf", |
34 base::CompareCase::INSENSITIVE_ASCII) || | 45 base::CompareCase::INSENSITIVE_ASCII) || |
35 base::EndsWith(type, "/*", base::CompareCase::INSENSITIVE_ASCII) || | 46 base::EndsWith(type, "/*", base::CompareCase::INSENSITIVE_ASCII) || |
36 base::EndsWith(type, "/acrobat", | 47 base::EndsWith(type, "/acrobat", |
37 base::CompareCase::INSENSITIVE_ASCII) || | 48 base::CompareCase::INSENSITIVE_ASCII) || |
38 base::EndsWith(type, "/unknown", | 49 base::EndsWith(type, "/unknown", |
39 base::CompareCase::INSENSITIVE_ASCII)); | 50 base::CompareCase::INSENSITIVE_ASCII)); |
(...skipping 18 matching lines...) Expand all Loading... |
58 : client_(client), loader_factory_(this) {} | 69 : client_(client), loader_factory_(this) {} |
59 | 70 |
60 DocumentLoader::~DocumentLoader() { | 71 DocumentLoader::~DocumentLoader() { |
61 } | 72 } |
62 | 73 |
63 bool DocumentLoader::Init(std::unique_ptr<URLLoaderWrapper> loader, | 74 bool DocumentLoader::Init(std::unique_ptr<URLLoaderWrapper> loader, |
64 const std::string& url) { | 75 const std::string& url) { |
65 DCHECK(url_.empty()); | 76 DCHECK(url_.empty()); |
66 DCHECK(!loader_); | 77 DCHECK(!loader_); |
67 | 78 |
| 79 // Check that the initial response status is a valid one. |
| 80 if (!ResponseStatusSuccess(loader.get())) |
| 81 return false; |
| 82 |
68 std::string type = loader->GetContentType(); | 83 std::string type = loader->GetContentType(); |
69 | 84 |
70 // This happens for PDFs not loaded from http(s) sources. | 85 // This happens for PDFs not loaded from http(s) sources. |
71 if (type == "text/plain") { | 86 if (type == "text/plain") { |
72 if (!base::StartsWith(url, "http://", | 87 if (!base::StartsWith(url, "http://", |
73 base::CompareCase::INSENSITIVE_ASCII) && | 88 base::CompareCase::INSENSITIVE_ASCII) && |
74 !base::StartsWith(url, "https://", | 89 !base::StartsWith(url, "https://", |
75 base::CompareCase::INSENSITIVE_ASCII)) { | 90 base::CompareCase::INSENSITIVE_ASCII)) { |
76 type = "application/pdf"; | 91 type = "application/pdf"; |
77 } | 92 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 loader_->OpenRange( | 252 loader_->OpenRange( |
238 url_, url_, start, length, | 253 url_, url_, start, length, |
239 loader_factory_.NewCallback(&DocumentLoader::DidOpenPartial)); | 254 loader_factory_.NewCallback(&DocumentLoader::DidOpenPartial)); |
240 } | 255 } |
241 | 256 |
242 void DocumentLoader::DidOpenPartial(int32_t result) { | 257 void DocumentLoader::DidOpenPartial(int32_t result) { |
243 if (result != PP_OK) { | 258 if (result != PP_OK) { |
244 return ReadComplete(); | 259 return ReadComplete(); |
245 } | 260 } |
246 | 261 |
247 int32_t http_code = loader_->GetStatusCode(); | 262 if (!ResponseStatusSuccess(loader_.get())) |
248 if (http_code >= 400 && http_code < 500) { | |
249 // Error accessing resource. 4xx error indicate subsequent requests | |
250 // will fail too. | |
251 // E.g. resource has been removed from the server while loading it. | |
252 return ReadComplete(); | 263 return ReadComplete(); |
253 } | |
254 | 264 |
255 // Leave position untouched for multiparted responce for now, when we read the | 265 // Leave position untouched for multiparted responce for now, when we read the |
256 // data we'll get it. | 266 // data we'll get it. |
257 if (!loader_->IsMultipart()) { | 267 if (!loader_->IsMultipart()) { |
258 // Need to make sure that the server returned a byte-range, since it's | 268 // Need to make sure that the server returned a byte-range, since it's |
259 // possible for a server to just ignore our byte-range request and just | 269 // possible for a server to just ignore our byte-range request and just |
260 // return the entire document even if it supports byte-range requests. | 270 // return the entire document even if it supports byte-range requests. |
261 // i.e. sniff response to | 271 // i.e. sniff response to |
262 // http://www.act.org/compass/sample/pdf/geometry.pdf | 272 // http://www.act.org/compass/sample/pdf/geometry.pdf |
263 int start_pos = 0; | 273 int start_pos = 0; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 float DocumentLoader::GetProgress() const { | 393 float DocumentLoader::GetProgress() const { |
384 if (!GetDocumentSize()) | 394 if (!GetDocumentSize()) |
385 return -1; | 395 return -1; |
386 if (IsDocumentComplete()) | 396 if (IsDocumentComplete()) |
387 return 1; | 397 return 1; |
388 return static_cast<float>(chunk_stream_.filled_chunks_count()) / | 398 return static_cast<float>(chunk_stream_.filled_chunks_count()) / |
389 chunk_stream_.total_chunks_count(); | 399 chunk_stream_.total_chunks_count(); |
390 } | 400 } |
391 | 401 |
392 } // namespace chrome_pdf | 402 } // namespace chrome_pdf |
OLD | NEW |