| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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_dispatcher_host.h" | 5 #include "content/browser/blob_storage/blob_dispatcher_host.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "content/browser/bad_message.h" | 10 #include "content/browser/bad_message.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 return handled; | 56 return handled; |
| 57 } | 57 } |
| 58 | 58 |
| 59 void BlobDispatcherHost::OnRegisterBlobUUID( | 59 void BlobDispatcherHost::OnRegisterBlobUUID( |
| 60 const std::string& uuid, | 60 const std::string& uuid, |
| 61 const std::string& content_type, | 61 const std::string& content_type, |
| 62 const std::string& content_disposition, | 62 const std::string& content_disposition, |
| 63 const std::set<std::string>& referenced_blob_uuids) { | 63 const std::set<std::string>& referenced_blob_uuids) { |
| 64 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 64 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 65 BlobStorageContext* context = this->context(); | 65 BlobStorageContext* context = this->context(); |
| 66 if (uuid.empty() || context->registry().HasEntry(uuid)) { | 66 if (uuid.empty() || context->registry().HasEntry(uuid) || |
| 67 async_builder_.IsBeingBuilt(uuid)) { |
| 67 bad_message::ReceivedBadMessage(this, bad_message::BDH_UUID_REGISTERED); | 68 bad_message::ReceivedBadMessage(this, bad_message::BDH_UUID_REGISTERED); |
| 68 return; | 69 return; |
| 69 } | 70 } |
| 70 blobs_inuse_map_[uuid] = 1; | 71 blobs_inuse_map_[uuid] = 1; |
| 71 BlobTransportResult result = async_builder_.RegisterBlobUUID( | 72 BlobTransportResult result = async_builder_.RegisterBlobUUID( |
| 72 uuid, content_type, content_disposition, referenced_blob_uuids, context); | 73 uuid, content_type, content_disposition, referenced_blob_uuids, context); |
| 73 switch (result) { | 74 switch (result) { |
| 74 case BlobTransportResult::BAD_IPC: | 75 case BlobTransportResult::BAD_IPC: |
| 75 blobs_inuse_map_.erase(uuid); | 76 blobs_inuse_map_.erase(uuid); |
| 76 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_OPERATION); | 77 bad_message::ReceivedBadMessage(this, |
| 78 bad_message::BDH_CONSTRUCTION_FAILED); |
| 77 break; | 79 break; |
| 78 ; | |
| 79 case BlobTransportResult::CANCEL_REFERENCED_BLOB_BROKEN: | 80 case BlobTransportResult::CANCEL_REFERENCED_BLOB_BROKEN: |
| 80 // The async builder builds the blob as broken, and we just need to send | 81 // The async builder builds the blob as broken, and we just need to send |
| 81 // the cancel message back to the renderer. | 82 // the cancel message back to the renderer. |
| 82 Send(new BlobStorageMsg_CancelBuildingBlob( | 83 Send(new BlobStorageMsg_CancelBuildingBlob( |
| 83 uuid, IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN)); | 84 uuid, IPCBlobCreationCancelCode::REFERENCED_BLOB_BROKEN)); |
| 84 break; | 85 break; |
| 85 case BlobTransportResult::DONE: | 86 case BlobTransportResult::DONE: |
| 86 break; | 87 break; |
| 87 case BlobTransportResult::CANCEL_MEMORY_FULL: | 88 case BlobTransportResult::CANCEL_MEMORY_FULL: |
| 88 case BlobTransportResult::CANCEL_FILE_ERROR: | 89 case BlobTransportResult::CANCEL_FILE_ERROR: |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 } | 202 } |
| 202 VLOG(1) << "Blob construction of " << uuid << " cancelled by renderer. " | 203 VLOG(1) << "Blob construction of " << uuid << " cancelled by renderer. " |
| 203 << " Reason: " << static_cast<int>(code) << "."; | 204 << " Reason: " << static_cast<int>(code) << "."; |
| 204 async_builder_.CancelBuildingBlob(uuid, code, context); | 205 async_builder_.CancelBuildingBlob(uuid, code, context); |
| 205 } | 206 } |
| 206 | 207 |
| 207 void BlobDispatcherHost::OnIncrementBlobRefCount(const std::string& uuid) { | 208 void BlobDispatcherHost::OnIncrementBlobRefCount(const std::string& uuid) { |
| 208 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 209 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 209 BlobStorageContext* context = this->context(); | 210 BlobStorageContext* context = this->context(); |
| 210 if (uuid.empty() || !context->registry().HasEntry(uuid)) { | 211 if (uuid.empty() || !context->registry().HasEntry(uuid)) { |
| 211 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_OPERATION); | 212 bad_message::ReceivedBadMessage( |
| 213 this, bad_message::BDH_INVALID_REFCOUNT_OPERATION); |
| 212 return; | 214 return; |
| 213 } | 215 } |
| 214 context->IncrementBlobRefCount(uuid); | 216 context->IncrementBlobRefCount(uuid); |
| 215 blobs_inuse_map_[uuid] += 1; | 217 blobs_inuse_map_[uuid] += 1; |
| 216 } | 218 } |
| 217 | 219 |
| 218 void BlobDispatcherHost::OnDecrementBlobRefCount(const std::string& uuid) { | 220 void BlobDispatcherHost::OnDecrementBlobRefCount(const std::string& uuid) { |
| 219 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 221 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 220 if (uuid.empty() || !IsInUseInHost(uuid)) { | 222 if (uuid.empty() || !IsInUseInHost(uuid)) { |
| 221 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_OPERATION); | 223 bad_message::ReceivedBadMessage( |
| 224 this, bad_message::BDH_INVALID_REFCOUNT_OPERATION); |
| 222 return; | 225 return; |
| 223 } | 226 } |
| 224 BlobStorageContext* context = this->context(); | 227 BlobStorageContext* context = this->context(); |
| 225 context->DecrementBlobRefCount(uuid); | 228 context->DecrementBlobRefCount(uuid); |
| 226 blobs_inuse_map_[uuid] -= 1; | 229 blobs_inuse_map_[uuid] -= 1; |
| 227 if (blobs_inuse_map_[uuid] == 0) { | 230 if (blobs_inuse_map_[uuid] == 0) { |
| 228 blobs_inuse_map_.erase(uuid); | 231 blobs_inuse_map_.erase(uuid); |
| 229 // If the blob has been deleted in the context and we're still building it, | 232 // If the blob has been deleted in the context and we're still building it, |
| 230 // this means we have no references waiting to read it. Clear the building | 233 // this means we have no references waiting to read it. Clear the building |
| 231 // state and send a cancel message to the renderer. | 234 // state and send a cancel message to the renderer. |
| 232 if (async_builder_.IsBeingBuilt(uuid) && | 235 if (async_builder_.IsBeingBuilt(uuid) && |
| 233 !context->registry().HasEntry(uuid)) { | 236 !context->registry().HasEntry(uuid)) { |
| 234 async_builder_.CancelBuildingBlob( | 237 async_builder_.CancelBuildingBlob( |
| 235 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING, | 238 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING, |
| 236 context); | 239 context); |
| 237 Send(new BlobStorageMsg_CancelBuildingBlob( | 240 Send(new BlobStorageMsg_CancelBuildingBlob( |
| 238 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING)); | 241 uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING)); |
| 239 } | 242 } |
| 240 } | 243 } |
| 241 } | 244 } |
| 242 | 245 |
| 243 void BlobDispatcherHost::OnRegisterPublicBlobURL(const GURL& public_url, | 246 void BlobDispatcherHost::OnRegisterPublicBlobURL(const GURL& public_url, |
| 244 const std::string& uuid) { | 247 const std::string& uuid) { |
| 245 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 248 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 246 BlobStorageContext* context = this->context(); | 249 BlobStorageContext* context = this->context(); |
| 247 if (uuid.empty() || !IsInUseInHost(uuid) || | 250 if (uuid.empty() || !IsInUseInHost(uuid) || |
| 248 context->registry().IsURLMapped(public_url)) { | 251 context->registry().IsURLMapped(public_url)) { |
| 249 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_OPERATION); | 252 bad_message::ReceivedBadMessage(this, |
| 253 bad_message::BDH_INVALID_URL_OPERATION); |
| 250 return; | 254 return; |
| 251 } | 255 } |
| 252 context->RegisterPublicBlobURL(public_url, uuid); | 256 context->RegisterPublicBlobURL(public_url, uuid); |
| 253 public_blob_urls_.insert(public_url); | 257 public_blob_urls_.insert(public_url); |
| 254 } | 258 } |
| 255 | 259 |
| 256 void BlobDispatcherHost::OnRevokePublicBlobURL(const GURL& public_url) { | 260 void BlobDispatcherHost::OnRevokePublicBlobURL(const GURL& public_url) { |
| 257 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 261 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 258 if (!IsUrlRegisteredInHost(public_url)) { | 262 if (!IsUrlRegisteredInHost(public_url)) { |
| 259 bad_message::ReceivedBadMessage(this, bad_message::BDH_INVALID_OPERATION); | 263 bad_message::ReceivedBadMessage(this, |
| 264 bad_message::BDH_INVALID_URL_OPERATION); |
| 260 return; | 265 return; |
| 261 } | 266 } |
| 262 context()->RevokePublicBlobURL(public_url); | 267 context()->RevokePublicBlobURL(public_url); |
| 263 public_blob_urls_.erase(public_url); | 268 public_blob_urls_.erase(public_url); |
| 264 } | 269 } |
| 265 | 270 |
| 266 storage::BlobStorageContext* BlobDispatcherHost::context() { | 271 storage::BlobStorageContext* BlobDispatcherHost::context() { |
| 267 return blob_storage_context_->context(); | 272 return blob_storage_context_->context(); |
| 268 } | 273 } |
| 269 | 274 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 context->RevokePublicBlobURL(url); | 331 context->RevokePublicBlobURL(url); |
| 327 } | 332 } |
| 328 for (const auto& uuid_refnum_pair : blobs_inuse_map_) { | 333 for (const auto& uuid_refnum_pair : blobs_inuse_map_) { |
| 329 for (int i = 0; i < uuid_refnum_pair.second; ++i) | 334 for (int i = 0; i < uuid_refnum_pair.second; ++i) |
| 330 context->DecrementBlobRefCount(uuid_refnum_pair.first); | 335 context->DecrementBlobRefCount(uuid_refnum_pair.first); |
| 331 } | 336 } |
| 332 async_builder_.CancelAll(context); | 337 async_builder_.CancelAll(context); |
| 333 } | 338 } |
| 334 | 339 |
| 335 } // namespace content | 340 } // namespace content |
| OLD | NEW |