| 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 "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "net/http/http_util.h" | 9 #include "net/http/http_util.h" |
| 10 #include "ppapi/c/pp_errors.h" | 10 #include "ppapi/c/pp_errors.h" |
| 11 #include "ppapi/cpp/url_loader.h" | 11 #include "ppapi/cpp/url_loader.h" |
| 12 #include "ppapi/cpp/url_request_info.h" | 12 #include "ppapi/cpp/url_request_info.h" |
| 13 #include "ppapi/cpp/url_response_info.h" | 13 #include "ppapi/cpp/url_response_info.h" |
| 14 | 14 |
| 15 namespace chrome_pdf { | 15 namespace chrome_pdf { |
| 16 | 16 |
| 17 namespace { |
| 18 |
| 17 // Document below size will be downloaded in one chunk. | 19 // Document below size will be downloaded in one chunk. |
| 18 const uint32 kMinFileSize = 64*1024; | 20 const uint32 kMinFileSize = 64*1024; |
| 19 | 21 |
| 22 bool IsValidContentType(const std::string& type) { |
| 23 return (EndsWith(type, "/pdf", false) || |
| 24 EndsWith(type, ".pdf", false) || |
| 25 EndsWith(type, "/x-pdf", false) || |
| 26 EndsWith(type, "/*", false) || |
| 27 EndsWith(type, "/acrobat", false) || |
| 28 EndsWith(type, "/unknown", false)); |
| 29 } |
| 30 |
| 31 } // namespace |
| 32 |
| 20 DocumentLoader::DocumentLoader(Client* client) | 33 DocumentLoader::DocumentLoader(Client* client) |
| 21 : client_(client), partial_document_(false), request_pending_(false), | 34 : client_(client), partial_document_(false), request_pending_(false), |
| 22 current_pos_(0), current_chunk_size_(0), current_chunk_read_(0), | 35 current_pos_(0), current_chunk_size_(0), current_chunk_read_(0), |
| 23 document_size_(0), header_request_(true), is_multipart_(false) { | 36 document_size_(0), header_request_(true), is_multipart_(false) { |
| 24 loader_factory_.Initialize(this); | 37 loader_factory_.Initialize(this); |
| 25 } | 38 } |
| 26 | 39 |
| 27 DocumentLoader::~DocumentLoader() { | 40 DocumentLoader::~DocumentLoader() { |
| 28 } | 41 } |
| 29 | 42 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 44 if (headers_var.is_string()) { | 57 if (headers_var.is_string()) { |
| 45 response_headers = headers_var.AsString(); | 58 response_headers = headers_var.AsString(); |
| 46 } | 59 } |
| 47 } | 60 } |
| 48 | 61 |
| 49 bool accept_ranges_bytes = false; | 62 bool accept_ranges_bytes = false; |
| 50 bool content_encoded = false; | 63 bool content_encoded = false; |
| 51 uint32 content_length = 0; | 64 uint32 content_length = 0; |
| 52 std::string type; | 65 std::string type; |
| 53 std::string disposition; | 66 std::string disposition; |
| 54 if (!response_headers.empty()) { | 67 |
| 68 // This happens for PDFs not loaded from http(s) sources. |
| 69 if (response_headers == "Content-Type: text/plain") { |
| 70 if (!StartsWithASCII(url, "http://", false) && |
| 71 !StartsWithASCII(url, "https://", false)) { |
| 72 type = "application/pdf"; |
| 73 } |
| 74 } |
| 75 if (type.empty() && !response_headers.empty()) { |
| 55 net::HttpUtil::HeadersIterator it(response_headers.begin(), | 76 net::HttpUtil::HeadersIterator it(response_headers.begin(), |
| 56 response_headers.end(), "\n"); | 77 response_headers.end(), "\n"); |
| 57 while (it.GetNext()) { | 78 while (it.GetNext()) { |
| 58 if (LowerCaseEqualsASCII(it.name(), "content-length")) { | 79 if (LowerCaseEqualsASCII(it.name(), "content-length")) { |
| 59 content_length = atoi(it.values().c_str()); | 80 content_length = atoi(it.values().c_str()); |
| 60 } else if (LowerCaseEqualsASCII(it.name(), "accept-ranges")) { | 81 } else if (LowerCaseEqualsASCII(it.name(), "accept-ranges")) { |
| 61 accept_ranges_bytes = LowerCaseEqualsASCII(it.values(), "bytes"); | 82 accept_ranges_bytes = LowerCaseEqualsASCII(it.values(), "bytes"); |
| 62 } else if (LowerCaseEqualsASCII(it.name(), "content-encoding")) { | 83 } else if (LowerCaseEqualsASCII(it.name(), "content-encoding")) { |
| 63 content_encoded = true; | 84 content_encoded = true; |
| 64 } else if (LowerCaseEqualsASCII(it.name(), "content-type")) { | 85 } else if (LowerCaseEqualsASCII(it.name(), "content-type")) { |
| 65 type = it.values(); | 86 type = it.values(); |
| 66 size_t semi_colon_pos = type.find(';'); | 87 size_t semi_colon_pos = type.find(';'); |
| 67 if (semi_colon_pos != std::string::npos) { | 88 if (semi_colon_pos != std::string::npos) { |
| 68 type = type.substr(0, semi_colon_pos); | 89 type = type.substr(0, semi_colon_pos); |
| 69 } | 90 } |
| 70 TrimWhitespace(type, base::TRIM_ALL, &type); | 91 TrimWhitespace(type, base::TRIM_ALL, &type); |
| 71 } else if (LowerCaseEqualsASCII(it.name(), "content-disposition")) { | 92 } else if (LowerCaseEqualsASCII(it.name(), "content-disposition")) { |
| 72 disposition = it.values(); | 93 disposition = it.values(); |
| 73 } | 94 } |
| 74 } | 95 } |
| 75 } | 96 } |
| 76 if (!type.empty() && | 97 if (!type.empty() && !IsValidContentType(type)) |
| 77 !EndsWith(type, "/pdf", false) && | |
| 78 !EndsWith(type, ".pdf", false) && | |
| 79 !EndsWith(type, "/x-pdf", false) && | |
| 80 !EndsWith(type, "/*", false) && | |
| 81 !EndsWith(type, "/acrobat", false) && | |
| 82 !EndsWith(type, "/unknown", false)) { | |
| 83 return false; | 98 return false; |
| 84 } | 99 if (StartsWithASCII(disposition, "attachment", false)) |
| 85 if (StartsWithASCII(disposition, "attachment", false)) { | |
| 86 return false; | 100 return false; |
| 87 } | |
| 88 | 101 |
| 89 if (content_length > 0) | 102 if (content_length > 0) |
| 90 chunk_stream_.Preallocate(content_length); | 103 chunk_stream_.Preallocate(content_length); |
| 91 | 104 |
| 92 document_size_ = content_length; | 105 document_size_ = content_length; |
| 93 requests_count_ = 0; | 106 requests_count_ = 0; |
| 94 | 107 |
| 95 // Enable partial loading only if file size is above the threshold. | 108 // Enable partial loading only if file size is above the threshold. |
| 96 // It will allow avoiding latency for multiple requests. | 109 // It will allow avoiding latency for multiple requests. |
| 97 if (content_length > kMinFileSize && | 110 if (content_length > kMinFileSize && |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 uint32 DocumentLoader::GetRequestSize() const { | 518 uint32 DocumentLoader::GetRequestSize() const { |
| 506 // Document loading strategy: | 519 // Document loading strategy: |
| 507 // For first 10 requests, we use 32k chunk sizes, for the next 10 requests we | 520 // For first 10 requests, we use 32k chunk sizes, for the next 10 requests we |
| 508 // double the size (64k), and so on, until we cap max request size at 2M for | 521 // double the size (64k), and so on, until we cap max request size at 2M for |
| 509 // 71 or more requests. | 522 // 71 or more requests. |
| 510 uint32 limited_count = std::min(std::max(requests_count_, 10u), 70u); | 523 uint32 limited_count = std::min(std::max(requests_count_, 10u), 70u); |
| 511 return 32*1024 * (1 << ((limited_count - 1) / 10u)); | 524 return 32*1024 * (1 << ((limited_count - 1) / 10u)); |
| 512 } | 525 } |
| 513 | 526 |
| 514 } // namespace chrome_pdf | 527 } // namespace chrome_pdf |
| OLD | NEW |