| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "content/browser/blob_storage/blob_url_loader_factory.h" | 5 #include "content/browser/blob_storage/blob_url_loader_factory.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "storage/browser/blob/blob_storage_context.h" | 27 #include "storage/browser/blob/blob_storage_context.h" |
| 28 #include "storage/browser/blob/blob_url_request_job.h" | 28 #include "storage/browser/blob/blob_url_request_job.h" |
| 29 #include "storage/browser/fileapi/file_system_context.h" | 29 #include "storage/browser/fileapi/file_system_context.h" |
| 30 | 30 |
| 31 namespace content { | 31 namespace content { |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 constexpr size_t kDefaultAllocationSize = 512 * 1024; | 34 constexpr size_t kDefaultAllocationSize = 512 * 1024; |
| 35 | 35 |
| 36 // This class handles a request for a blob:// url. It self-destructs (see | 36 // This class handles a request for a blob:// url. It self-destructs (see |
| 37 // DeleteIfNeeded) when it has finished responding. | 37 // DeleteIfNeeded) when it has finished responding once Start() is called. |
| 38 // Note: some of this code is duplicated from storage::BlobURLRequestJob. | 38 // Note: some of this code is duplicated from storage::BlobURLRequestJob. |
| 39 class BlobURLLoader : public mojom::URLLoader { | 39 class BlobURLLoader : public mojom::URLLoader { |
| 40 public: | 40 public: |
| 41 BlobURLLoader(mojom::URLLoaderAssociatedRequest url_loader_request, | 41 BlobURLLoader(const ResourceRequest& request, |
| 42 const ResourceRequest& request, | |
| 43 mojom::URLLoaderClientPtr client, | |
| 44 storage::BlobStorageContext* blob_storage_context, | 42 storage::BlobStorageContext* blob_storage_context, |
| 45 scoped_refptr<storage::FileSystemContext> file_system_context) | 43 scoped_refptr<storage::FileSystemContext> file_system_context) |
| 46 : binding_(this, std::move(url_loader_request)), | 44 : binding_(this), |
| 47 request_(request), | 45 request_(request), |
| 48 client_(std::move(client)), | |
| 49 writable_handle_watcher_(FROM_HERE, | 46 writable_handle_watcher_(FROM_HERE, |
| 50 mojo::SimpleWatcher::ArmingPolicy::MANUAL), | 47 mojo::SimpleWatcher::ArmingPolicy::MANUAL), |
| 51 peer_closed_handle_watcher_(FROM_HERE, | 48 peer_closed_handle_watcher_(FROM_HERE, |
| 52 mojo::SimpleWatcher::ArmingPolicy::MANUAL), | 49 mojo::SimpleWatcher::ArmingPolicy::MANUAL), |
| 53 weak_factory_(this) { | 50 weak_factory_(this) { |
| 54 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 51 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 52 |
| 55 if (blob_storage_context) { | 53 if (blob_storage_context) { |
| 56 blob_handle_ = | 54 blob_handle_ = |
| 57 blob_storage_context->GetBlobDataFromPublicURL(request.url); | 55 blob_storage_context->GetBlobDataFromPublicURL(request.url); |
| 58 } | 56 } |
| 59 | 57 |
| 58 if (blob_handle_) { |
| 59 base::SequencedTaskRunner* file_task_runner = |
| 60 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get(); |
| 61 blob_reader_ = blob_handle_->CreateReader(file_system_context.get(), |
| 62 file_task_runner); |
| 63 } |
| 64 } |
| 65 |
| 66 ~BlobURLLoader() override {} |
| 67 |
| 68 // mojom::URLLoader implementation: |
| 69 void Start(mojom::URLLoaderAssociatedRequest url_loader_request, |
| 70 mojom::URLLoaderClientPtr client) override { |
| 71 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 72 DCHECK(!binding_.is_bound()); |
| 73 binding_.Bind(std::move(url_loader_request)); |
| 74 client_ = std::move(client); |
| 75 |
| 60 // PostTask since it might destruct. | 76 // PostTask since it might destruct. |
| 61 base::ThreadTaskRunnerHandle::Get()->PostTask( | 77 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 62 FROM_HERE, base::Bind(&BlobURLLoader::Start, weak_factory_.GetWeakPtr(), | 78 FROM_HERE, |
| 63 request, file_system_context)); | 79 base::Bind(&BlobURLLoader::StartRequest, weak_factory_.GetWeakPtr())); |
| 64 } | 80 } |
| 65 | 81 |
| 66 void Start(const ResourceRequest& request, | 82 private: |
| 67 scoped_refptr<storage::FileSystemContext> file_system_context) { | 83 // mojom::URLLoader implementation: |
| 84 void FollowRedirect() override { NOTREACHED(); } |
| 85 |
| 86 void SetPriority(net::RequestPriority priority, |
| 87 int32_t intra_priority_value) override {} |
| 88 |
| 89 void StartRequest() { |
| 68 if (!blob_handle_) { | 90 if (!blob_handle_) { |
| 69 NotifyCompleted(net::ERR_FILE_NOT_FOUND); | 91 NotifyCompleted(net::ERR_FILE_NOT_FOUND); |
| 70 return; | 92 return; |
| 71 } | 93 } |
| 72 | 94 |
| 73 base::SequencedTaskRunner* file_task_runner = | |
| 74 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get(); | |
| 75 blob_reader_ = | |
| 76 blob_handle_->CreateReader(file_system_context.get(), file_task_runner); | |
| 77 | |
| 78 // We only support GET request per the spec. | 95 // We only support GET request per the spec. |
| 79 if (request.method != "GET") { | 96 if (request_.method != "GET") { |
| 80 NotifyCompleted(net::ERR_METHOD_NOT_SUPPORTED); | 97 NotifyCompleted(net::ERR_METHOD_NOT_SUPPORTED); |
| 81 return; | 98 return; |
| 82 } | 99 } |
| 83 | 100 |
| 84 if (blob_reader_->net_error()) { | 101 if (blob_reader_->net_error()) { |
| 85 NotifyCompleted(blob_reader_->net_error()); | 102 NotifyCompleted(blob_reader_->net_error()); |
| 86 return; | 103 return; |
| 87 } | 104 } |
| 88 | 105 |
| 89 net::HttpRequestHeaders request_headers; | 106 net::HttpRequestHeaders request_headers; |
| 90 request_headers.AddHeadersFromString(request.headers); | 107 request_headers.AddHeadersFromString(request_.headers); |
| 91 std::string range_header; | 108 std::string range_header; |
| 92 if (request_headers.GetHeader(net::HttpRequestHeaders::kRange, | 109 if (request_headers.GetHeader(net::HttpRequestHeaders::kRange, |
| 93 &range_header)) { | 110 &range_header)) { |
| 94 // We only care about "Range" header here. | 111 // We only care about "Range" header here. |
| 95 std::vector<net::HttpByteRange> ranges; | 112 std::vector<net::HttpByteRange> ranges; |
| 96 if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { | 113 if (net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { |
| 97 if (ranges.size() == 1) { | 114 if (ranges.size() == 1) { |
| 98 byte_range_set_ = true; | 115 byte_range_set_ = true; |
| 99 byte_range_ = ranges[0]; | 116 byte_range_ = ranges[0]; |
| 100 } else { | 117 } else { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 116 case storage::BlobReader::Status::IO_PENDING: | 133 case storage::BlobReader::Status::IO_PENDING: |
| 117 return; | 134 return; |
| 118 case storage::BlobReader::Status::DONE: | 135 case storage::BlobReader::Status::DONE: |
| 119 DidCalculateSize(net::OK); | 136 DidCalculateSize(net::OK); |
| 120 return; | 137 return; |
| 121 } | 138 } |
| 122 | 139 |
| 123 NOTREACHED(); | 140 NOTREACHED(); |
| 124 } | 141 } |
| 125 | 142 |
| 126 ~BlobURLLoader() override {} | |
| 127 | |
| 128 private: | |
| 129 // mojom::URLLoader implementation: | |
| 130 void FollowRedirect() override { NOTREACHED(); } | |
| 131 | |
| 132 void SetPriority(net::RequestPriority priority, | |
| 133 int32_t intra_priority_value) override {} | |
| 134 | 143 |
| 135 // Notifies the client that the request completed. Takes care of deleting this | 144 // Notifies the client that the request completed. Takes care of deleting this |
| 136 // object now if possible (i.e. no outstanding data pipe), otherwise this | 145 // object now if possible (i.e. no outstanding data pipe), otherwise this |
| 137 // object will be deleted when the data pipe is closed. | 146 // object will be deleted when the data pipe is closed. |
| 138 void NotifyCompleted(int error_code) { | 147 void NotifyCompleted(int error_code) { |
| 139 if (error_code != net::OK && !sent_headers_) { | 148 if (error_code != net::OK && !sent_headers_) { |
| 140 net::HttpStatusCode status_code = | 149 net::HttpStatusCode status_code = |
| 141 storage::BlobURLRequestJob::NetErrorToHttpStatusCode(error_code); | 150 storage::BlobURLRequestJob::NetErrorToHttpStatusCode(error_code); |
| 142 ResourceResponseHead response; | 151 ResourceResponseHead response; |
| 143 response.headers = storage::BlobURLRequestJob::GenerateHeaders( | 152 response.headers = storage::BlobURLRequestJob::GenerateHeaders( |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 } | 393 } |
| 385 | 394 |
| 386 void BlobURLLoaderFactory::CreateLoaderAndStart( | 395 void BlobURLLoaderFactory::CreateLoaderAndStart( |
| 387 mojom::URLLoaderAssociatedRequest loader, | 396 mojom::URLLoaderAssociatedRequest loader, |
| 388 int32_t routing_id, | 397 int32_t routing_id, |
| 389 int32_t request_id, | 398 int32_t request_id, |
| 390 uint32_t options, | 399 uint32_t options, |
| 391 const ResourceRequest& request, | 400 const ResourceRequest& request, |
| 392 mojom::URLLoaderClientPtr client) { | 401 mojom::URLLoaderClientPtr client) { |
| 393 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 402 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 394 new BlobURLLoader(std::move(loader), request, std::move(client), | 403 BlobURLLoader* url_loader = new BlobURLLoader( |
| 395 blob_storage_context_.get(), file_system_context_); | 404 request, blob_storage_context_.get(), file_system_context_); |
| 405 url_loader->Start(std::move(loader), std::move(client)); |
| 396 } | 406 } |
| 397 | 407 |
| 398 void BlobURLLoaderFactory::SyncLoad(int32_t routing_id, | 408 void BlobURLLoaderFactory::SyncLoad(int32_t routing_id, |
| 399 int32_t request_id, | 409 int32_t request_id, |
| 400 const ResourceRequest& request, | 410 const ResourceRequest& request, |
| 401 SyncLoadCallback callback) { | 411 SyncLoadCallback callback) { |
| 402 NOTREACHED(); | 412 NOTREACHED(); |
| 403 } | 413 } |
| 404 | 414 |
| 405 } // namespace content | 415 } // namespace content |
| OLD | NEW |