Index: chrome/browser/renderer_host/resource_dispatcher_host.cc |
=================================================================== |
--- chrome/browser/renderer_host/resource_dispatcher_host.cc (revision 60222) |
+++ chrome/browser/renderer_host/resource_dispatcher_host.cc (working copy) |
@@ -71,6 +71,7 @@ |
#include "webkit/appcache/appcache_interceptor.h" |
#include "webkit/appcache/appcache_interfaces.h" |
#include "webkit/blob/blob_storage_controller.h" |
+#include "webkit/blob/deletable_file_reference.h" |
// TODO(oshima): Enable this for other platforms. |
#if defined(OS_CHROMEOS) |
@@ -89,6 +90,7 @@ |
using base::Time; |
using base::TimeDelta; |
using base::TimeTicks; |
+using webkit_blob::DeletableFileReference; |
// ---------------------------------------------------------------------------- |
@@ -321,7 +323,10 @@ |
IPC_BEGIN_MESSAGE_MAP_EX(ResourceDispatcherHost, message, *message_was_ok) |
IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) |
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad) |
+ IPC_MESSAGE_HANDLER(ViewHostMsg_ResourceLoaderDeleted, |
+ OnResourceLoaderDeleted) |
IPC_MESSAGE_HANDLER(ViewHostMsg_DataReceived_ACK, OnDataReceivedACK) |
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DataDownloaded_ACK, OnDataDownloadedACK) |
IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK) |
IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest) |
IPC_MESSAGE_HANDLER(ViewHostMsg_FollowRedirect, OnFollowRedirect) |
@@ -375,7 +380,7 @@ |
} |
// Might need to resolve the blob references in the upload data. |
- if (request_data.upload_data) { |
+ if (request_data.upload_data && context) { |
context->blob_storage_context()->controller()-> |
ResolveBlobReferencesInUploadData(request_data.upload_data.get()); |
} |
@@ -423,6 +428,7 @@ |
this); |
} |
+ // The RedirectToFileResourceHandler depends on being next in the chain. |
if (request_data.download_to_file) |
handler = new RedirectToFileResourceHandler(handler, child_id, this); |
@@ -517,6 +523,15 @@ |
chrome_browser_net::SetOriginProcessUniqueIDForRequest( |
request_data.origin_child_id, request); |
+ if (request->url().SchemeIs(chrome::kBlobScheme) && context) { |
+ // Hang on to a reference to ensure the blob is not released prior |
+ // to the job being started. |
+ webkit_blob::BlobStorageController* controller = |
+ context->blob_storage_context()->controller(); |
+ extra_info->set_requested_blob_data( |
+ controller->GetBlobDataFromUrl(request->url())); |
+ } |
+ |
// Have the appcache associate its extra info with the request. |
appcache::AppCacheInterceptor::SetExtraRequestInfo( |
request, context ? context->appcache_service() : NULL, child_id, |
@@ -525,6 +540,12 @@ |
BeginRequestInternal(request); |
} |
+void ResourceDispatcherHost::OnResourceLoaderDeleted(int request_id) { |
+ DCHECK(pending_requests_.end() == |
+ pending_requests_.find(GlobalRequestID(receiver_->id(), request_id))); |
+ UnregisterDownloadedTempFile(receiver_->id(), request_id); |
+} |
+ |
void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { |
DataReceivedACK(receiver_->id(), request_id); |
} |
@@ -552,6 +573,29 @@ |
} |
} |
+void ResourceDispatcherHost::OnDataDownloadedACK(int request_id) { |
+ // TODO(michaeln): maybe throttle DataDownloaded messages |
+} |
+ |
+void ResourceDispatcherHost::RegisterDownloadedTempFile( |
+ int receiver_id, int request_id, DeletableFileReference* reference) { |
+ // Note: receiver_id is the child_id is the render_process_id... |
+ registered_temp_files_[receiver_id][request_id] = reference; |
+ ChildProcessSecurityPolicy::GetInstance()->GrantUploadFile( |
+ receiver_id, reference->path()); |
+} |
+ |
+void ResourceDispatcherHost::UnregisterDownloadedTempFile( |
+ int receiver_id, int request_id) { |
+ DeletableFilesMap& map = registered_temp_files_[receiver_id]; |
+ DeletableFilesMap::iterator found = map.find(request_id); |
+ if (found == map.end()) |
+ return; |
+ map.erase(found); |
+ // TODO(michaeln): revoke access to this file upon the file's deletion. |
+} |
+ |
+ |
bool ResourceDispatcherHost::Send(IPC::Message* message) { |
delete message; |
return false; |
@@ -847,6 +891,7 @@ |
void ResourceDispatcherHost::CancelRequestsForProcess(int child_id) { |
socket_stream_dispatcher_host_->CancelRequestsForProcess(child_id); |
CancelRequestsForRoute(child_id, -1 /* cancel all */); |
+ registered_temp_files_.erase(child_id); |
} |
void ResourceDispatcherHost::CancelRequestsForRoute(int child_id, |
@@ -1798,8 +1843,9 @@ |
case ViewHostMsg_CancelRequest::ID: |
case ViewHostMsg_FollowRedirect::ID: |
case ViewHostMsg_ClosePage_ACK::ID: |
+ case ViewHostMsg_ResourceLoaderDeleted::ID: |
case ViewHostMsg_DataReceived_ACK::ID: |
- case ViewHostMsg_DownloadProgress_ACK::ID: |
+ case ViewHostMsg_DataDownloaded_ACK::ID: |
case ViewHostMsg_UploadProgress_ACK::ID: |
case ViewHostMsg_SyncLoad::ID: |
return true; |