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 "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 // e.g. resource has been removed from the server while loading it. 301 | 73 // e.g. resource has been removed from the server while loading it. 301 |
74 // indicates a redirect was returned which won't be successful because we | 74 // indicates a redirect was returned which won't be successful because we |
75 // disable following redirects for PDF loading (we assume they are already | 75 // disable following redirects for PDF loading (we assume they are already |
76 // resolved by the browser. | 76 // resolved by the browser. |
77 bool ResponseStatusSuccess(const pp::URLLoader& loader) { | 77 bool ResponseStatusSuccess(const pp::URLLoader& loader) { |
78 int32_t http_code = loader.GetResponseInfo().GetStatusCode(); | 78 int32_t http_code = loader.GetResponseInfo().GetStatusCode(); |
79 return (http_code < 400 && http_code != 301) || http_code >= 500; | 79 return (http_code < 400 && http_code != 301) || http_code >= 500; |
80 } | 80 } |
81 | 81 |
82 bool IsValidContentType(const std::string& type) { | 82 bool IsValidContentType(const std::string& type) { |
83 return (base::EndsWith(type, "/pdf", base::CompareCase::INSENSITIVE_ASCII) || | 83 return base::EndsWith(type, "/pdf", base::CompareCase::INSENSITIVE_ASCII) || |
84 base::EndsWith(type, ".pdf", base::CompareCase::INSENSITIVE_ASCII) || | 84 base::EndsWith(type, ".pdf", base::CompareCase::INSENSITIVE_ASCII) || |
85 base::EndsWith(type, "/x-pdf", | 85 base::EndsWith(type, "/x-pdf", base::CompareCase::INSENSITIVE_ASCII) || |
86 base::CompareCase::INSENSITIVE_ASCII) || | 86 base::EndsWith(type, "/*", base::CompareCase::INSENSITIVE_ASCII) || |
87 base::EndsWith(type, "/*", base::CompareCase::INSENSITIVE_ASCII) || | 87 base::EndsWith(type, "/acrobat", |
88 base::EndsWith(type, "/acrobat", | 88 base::CompareCase::INSENSITIVE_ASCII) || |
89 base::CompareCase::INSENSITIVE_ASCII) || | 89 base::EndsWith(type, "/unknown", base::CompareCase::INSENSITIVE_ASCII); |
90 base::EndsWith(type, "/unknown", | |
91 base::CompareCase::INSENSITIVE_ASCII)); | |
92 } | 90 } |
93 | 91 |
94 } // namespace | 92 } // namespace |
95 | 93 |
96 DocumentLoader::Client::~Client() { | 94 DocumentLoader::Client::~Client() {} |
97 } | |
98 | 95 |
99 DocumentLoader::DocumentLoader(Client* client) | 96 DocumentLoader::DocumentLoader(Client* client) |
100 : client_(client), partial_document_(false), request_pending_(false), | 97 : client_(client), |
101 current_pos_(0), current_chunk_size_(0), current_chunk_read_(0), | 98 partial_document_(false), |
102 document_size_(0), header_request_(true), is_multipart_(false) { | 99 request_pending_(false), |
| 100 current_pos_(0), |
| 101 current_chunk_size_(0), |
| 102 current_chunk_read_(0), |
| 103 document_size_(0), |
| 104 header_request_(true), |
| 105 is_multipart_(false) { |
103 loader_factory_.Initialize(this); | 106 loader_factory_.Initialize(this); |
104 } | 107 } |
105 | 108 |
106 DocumentLoader::~DocumentLoader() { | 109 DocumentLoader::~DocumentLoader() {} |
107 } | |
108 | 110 |
109 bool DocumentLoader::Init(const pp::URLLoader& loader, | 111 bool DocumentLoader::Init(const pp::URLLoader& loader, |
110 const std::string& url, | 112 const std::string& url, |
111 const std::string& headers) { | 113 const std::string& headers) { |
112 DCHECK(url_.empty()); | 114 DCHECK(url_.empty()); |
113 | 115 |
114 // Check that the initial response status is a valid one. | 116 // Check that the initial response status is a valid one. |
115 if (!ResponseStatusSuccess(loader)) | 117 if (!ResponseStatusSuccess(loader)) |
116 return false; | 118 return false; |
117 | 119 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 return false; | 176 return false; |
175 | 177 |
176 if (content_length > 0) | 178 if (content_length > 0) |
177 chunk_stream_.Preallocate(content_length); | 179 chunk_stream_.Preallocate(content_length); |
178 | 180 |
179 document_size_ = content_length; | 181 document_size_ = content_length; |
180 requests_count_ = 0; | 182 requests_count_ = 0; |
181 | 183 |
182 // Enable partial loading only if file size is above the threshold. | 184 // Enable partial loading only if file size is above the threshold. |
183 // It will allow avoiding latency for multiple requests. | 185 // It will allow avoiding latency for multiple requests. |
184 if (content_length > kMinFileSize && | 186 if (content_length > kMinFileSize && accept_ranges_bytes && |
185 accept_ranges_bytes && | |
186 !content_encoded) { | 187 !content_encoded) { |
187 LoadPartialDocument(); | 188 LoadPartialDocument(); |
188 } else { | 189 } else { |
189 LoadFullDocument(); | 190 LoadFullDocument(); |
190 } | 191 } |
191 return true; | 192 return true; |
192 } | 193 } |
193 | 194 |
194 void DocumentLoader::LoadPartialDocument() { | 195 void DocumentLoader::LoadPartialDocument() { |
195 // The current request is a full request (not a range request) so it starts at | 196 // The current request is a full request (not a range request) so it starts at |
(...skipping 20 matching lines...) Expand all Loading... |
216 if (document_size_ == 0) // Document size unknown. | 217 if (document_size_ == 0) // Document size unknown. |
217 return false; | 218 return false; |
218 return IsDataAvailable(0, document_size_); | 219 return IsDataAvailable(0, document_size_); |
219 } | 220 } |
220 | 221 |
221 uint32_t DocumentLoader::GetAvailableData() const { | 222 uint32_t DocumentLoader::GetAvailableData() const { |
222 if (document_size_ == 0) { // If document size is unknown. | 223 if (document_size_ == 0) { // If document size is unknown. |
223 return current_pos_; | 224 return current_pos_; |
224 } | 225 } |
225 | 226 |
226 std::vector<std::pair<size_t, size_t> > ranges; | 227 std::vector<std::pair<size_t, size_t>> ranges; |
227 chunk_stream_.GetMissedRanges(0, document_size_, &ranges); | 228 chunk_stream_.GetMissedRanges(0, document_size_, &ranges); |
228 uint32_t available = document_size_; | 229 uint32_t available = document_size_; |
229 for (const auto& range : ranges) | 230 for (const auto& range : ranges) |
230 available -= range.second; | 231 available -= range.second; |
231 return available; | 232 return available; |
232 } | 233 } |
233 | 234 |
234 void DocumentLoader::ClearPendingRequests() { | 235 void DocumentLoader::ClearPendingRequests() { |
235 pending_requests_.erase(pending_requests_.begin(), | 236 pending_requests_.erase(pending_requests_.begin(), pending_requests_.end()); |
236 pending_requests_.end()); | |
237 } | 237 } |
238 | 238 |
239 bool DocumentLoader::GetBlock(uint32_t position, | 239 bool DocumentLoader::GetBlock(uint32_t position, |
240 uint32_t size, | 240 uint32_t size, |
241 void* buf) const { | 241 void* buf) const { |
242 return chunk_stream_.ReadData(position, size, buf); | 242 return chunk_stream_.ReadData(position, size, buf); |
243 } | 243 } |
244 | 244 |
245 bool DocumentLoader::IsDataAvailable(uint32_t position, uint32_t size) const { | 245 bool DocumentLoader::IsDataAvailable(uint32_t position, uint32_t size) const { |
246 return chunk_stream_.IsRangeAvailable(position, size); | 246 return chunk_stream_.IsRangeAvailable(position, size); |
(...skipping 12 matching lines...) Expand all Loading... |
259 if (IsDocumentComplete()) | 259 if (IsDocumentComplete()) |
260 return; | 260 return; |
261 | 261 |
262 pending_requests_.push_back(std::pair<size_t, size_t>(position, size)); | 262 pending_requests_.push_back(std::pair<size_t, size_t>(position, size)); |
263 DownloadPendingRequests(); | 263 DownloadPendingRequests(); |
264 } | 264 } |
265 | 265 |
266 void DocumentLoader::RemoveCompletedRanges() { | 266 void DocumentLoader::RemoveCompletedRanges() { |
267 // Split every request that has been partially downloaded already into smaller | 267 // Split every request that has been partially downloaded already into smaller |
268 // requests. | 268 // requests. |
269 std::vector<std::pair<size_t, size_t> > ranges; | 269 std::vector<std::pair<size_t, size_t>> ranges; |
270 auto it = pending_requests_.begin(); | 270 auto it = pending_requests_.begin(); |
271 while (it != pending_requests_.end()) { | 271 while (it != pending_requests_.end()) { |
272 chunk_stream_.GetMissedRanges(it->first, it->second, &ranges); | 272 chunk_stream_.GetMissedRanges(it->first, it->second, &ranges); |
273 pending_requests_.insert(it, ranges.begin(), ranges.end()); | 273 pending_requests_.insert(it, ranges.begin(), ranges.end()); |
274 ranges.clear(); | 274 ranges.clear(); |
275 pending_requests_.erase(it++); | 275 pending_requests_.erase(it++); |
276 } | 276 } |
277 } | 277 } |
278 | 278 |
279 void DocumentLoader::DownloadPendingRequests() { | 279 void DocumentLoader::DownloadPendingRequests() { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 } else { | 409 } else { |
410 partial_document_ = false; | 410 partial_document_ = false; |
411 } | 411 } |
412 } | 412 } |
413 | 413 |
414 ReadMore(); | 414 ReadMore(); |
415 } | 415 } |
416 | 416 |
417 void DocumentLoader::ReadMore() { | 417 void DocumentLoader::ReadMore() { |
418 pp::CompletionCallback callback = | 418 pp::CompletionCallback callback = |
419 loader_factory_.NewCallback(&DocumentLoader::DidRead); | 419 loader_factory_.NewCallback(&DocumentLoader::DidRead); |
420 int rv = loader_.ReadResponseBody(buffer_, sizeof(buffer_), callback); | 420 int rv = loader_.ReadResponseBody(buffer_, sizeof(buffer_), callback); |
421 if (rv != PP_OK_COMPLETIONPENDING) | 421 if (rv != PP_OK_COMPLETIONPENDING) |
422 callback.Run(rv); | 422 callback.Run(rv); |
423 } | 423 } |
424 | 424 |
425 void DocumentLoader::DidRead(int32_t result) { | 425 void DocumentLoader::DidRead(int32_t result) { |
426 if (result <= 0) { | 426 if (result <= 0) { |
427 // If |result| == PP_OK, the document was loaded, otherwise an error was | 427 // If |result| == PP_OK, the document was loaded, otherwise an error was |
428 // encountered. Either way we want to stop processing the response. In the | 428 // encountered. Either way we want to stop processing the response. In the |
429 // case where an error occurred, the renderer will detect that we're missing | 429 // case where an error occurred, the renderer will detect that we're missing |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 current_request_offset_ + current_request_extended_size_) { | 508 current_request_offset_ + current_request_extended_size_) { |
509 loader_.Close(); | 509 loader_.Close(); |
510 } | 510 } |
511 } | 511 } |
512 | 512 |
513 ReadMore(); | 513 ReadMore(); |
514 } | 514 } |
515 | 515 |
516 bool DocumentLoader::SatisfyingRequest(size_t offset, size_t size) const { | 516 bool DocumentLoader::SatisfyingRequest(size_t offset, size_t size) const { |
517 return offset <= current_pos_ + kDefaultRequestSize && | 517 return offset <= current_pos_ + kDefaultRequestSize && |
518 current_pos_ < offset + size; | 518 current_pos_ < offset + size; |
519 } | 519 } |
520 | 520 |
521 void DocumentLoader::ReadComplete() { | 521 void DocumentLoader::ReadComplete() { |
522 if (!partial_document_) { | 522 if (!partial_document_) { |
523 if (document_size_ == 0) { | 523 if (document_size_ == 0) { |
524 // For the document with no 'content-length" specified we've collected all | 524 // For the document with no 'content-length" specified we've collected all |
525 // the chunks already. Let's allocate final document buffer and copy them | 525 // the chunks already. Let's allocate final document buffer and copy them |
526 // over. | 526 // over. |
527 chunk_stream_.Preallocate(current_pos_); | 527 chunk_stream_.Preallocate(current_pos_); |
528 uint32_t pos = 0; | 528 uint32_t pos = 0; |
(...skipping 21 matching lines...) Expand all Loading... |
550 | 550 |
551 void DocumentLoader::UpdateRendering() { | 551 void DocumentLoader::UpdateRendering() { |
552 if (header_request_) | 552 if (header_request_) |
553 client_->OnPartialDocumentLoaded(); | 553 client_->OnPartialDocumentLoaded(); |
554 else | 554 else |
555 client_->OnPendingRequestComplete(); | 555 client_->OnPendingRequestComplete(); |
556 header_request_ = false; | 556 header_request_ = false; |
557 } | 557 } |
558 | 558 |
559 } // namespace chrome_pdf | 559 } // namespace chrome_pdf |
OLD | NEW |