summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/async_resource_handler.cc6
-rw-r--r--chrome/browser/renderer_host/async_resource_handler.h1
-rw-r--r--chrome/browser/renderer_host/redirect_to_file_resource_handler.cc32
-rw-r--r--chrome/browser/renderer_host/redirect_to_file_resource_handler.h9
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc49
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.h24
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host_request_info.cc6
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host_request_info.h12
-rw-r--r--chrome/browser/renderer_host/resource_handler.h6
-rw-r--r--chrome/browser/renderer_host/sync_resource_handler.cc1
10 files changed, 127 insertions, 19 deletions
diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc
index 5e5dfa5..803b91b 100644
--- a/chrome/browser/renderer_host/async_resource_handler.cc
+++ b/chrome/browser/renderer_host/async_resource_handler.cc
@@ -217,6 +217,12 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
return true;
}
+void AsyncResourceHandler::OnDataDownloaded(
+ int request_id, int bytes_downloaded) {
+ receiver_->Send(new ViewMsg_Resource_DataDownloaded(
+ routing_id_, request_id, bytes_downloaded));
+}
+
bool AsyncResourceHandler::OnResponseCompleted(
int request_id,
const URLRequestStatus& status,
diff --git a/chrome/browser/renderer_host/async_resource_handler.h b/chrome/browser/renderer_host/async_resource_handler.h
index 191fdb8..be89d87 100644
--- a/chrome/browser/renderer_host/async_resource_handler.h
+++ b/chrome/browser/renderer_host/async_resource_handler.h
@@ -38,6 +38,7 @@ class AsyncResourceHandler : public ResourceHandler {
const URLRequestStatus& status,
const std::string& security_info);
void OnRequestClosed();
+ void OnDataDownloaded(int request_id, int bytes_downloaded);
static void GlobalCleanup();
diff --git a/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc b/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc
index a2509fb..94a5c77 100644
--- a/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc
+++ b/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc
@@ -16,6 +16,9 @@
#include "net/base/io_buffer.h"
#include "net/base/mime_sniffer.h"
#include "net/base/net_errors.h"
+#include "webkit/blob/deletable_file_reference.h"
+
+using webkit_blob::DeletableFileReference;
// TODO(darin): Use the buffer sizing algorithm from AsyncResourceHandler.
static const int kReadBufSize = 32768;
@@ -56,8 +59,8 @@ bool RedirectToFileResourceHandler::OnResponseStarted(
int request_id,
ResourceResponse* response) {
if (response->response_head.status.is_success()) {
- DCHECK(!file_path_.empty());
- response->response_head.download_file_path = file_path_;
+ DCHECK(deletable_file_ && !deletable_file_->path().empty());
+ response->response_head.download_file_path = deletable_file_->path();
}
return next_handler_->OnResponseStarted(request_id, response);
}
@@ -66,7 +69,7 @@ bool RedirectToFileResourceHandler::OnWillStart(int request_id,
const GURL& url,
bool* defer) {
request_id_ = request_id;
- if (file_path_.empty()) {
+ if (!deletable_file_) {
// Defer starting the request until we have created the temporary file.
// TODO(darin): This is sub-optimal. We should not delay starting the
// network request like this.
@@ -123,6 +126,9 @@ bool RedirectToFileResourceHandler::OnReadCompleted(int request_id,
if (BufIsFull())
host_->PauseRequest(process_id_, request_id, true);
+ if (*bytes_read > 0)
+ next_handler_->OnDataDownloaded(request_id, *bytes_read);
+
return WriteMore();
}
@@ -134,21 +140,13 @@ bool RedirectToFileResourceHandler::OnResponseCompleted(
}
void RedirectToFileResourceHandler::OnRequestClosed() {
- next_handler_->OnRequestClosed();
-
- // The renderer no longer has a WebURLLoader open to this request, so we can
- // close and unlink the file.
-
// We require this explicit call to Close since file_stream_ was constructed
// directly from a PlatformFile.
file_stream_->Close();
file_stream_.reset();
+ deletable_file_ = NULL;
- // TODO(dumi): delete the temp file when it's no longer needed.
- // TODO(dumi): revoke the privilege to upload this file.
- // base::FileUtilProxy::Delete(
- // ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE),
- // file_path_, NULL);
+ next_handler_->OnRequestClosed();
}
RedirectToFileResourceHandler::~RedirectToFileResourceHandler() {
@@ -159,12 +157,14 @@ void RedirectToFileResourceHandler::DidCreateTemporaryFile(
base::PlatformFileError /*error_code*/,
base::PassPlatformFile file_handle,
FilePath file_path) {
- file_path_ = file_path;
+ deletable_file_ = DeletableFileReference::GetOrCreate(
+ file_path,
+ ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE));
file_stream_.reset(new net::FileStream(file_handle.ReleaseValue(),
base::PLATFORM_FILE_WRITE |
base::PLATFORM_FILE_ASYNC));
- ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
- process_id_, file_path);
+ host_->RegisterDownloadedTempFile(
+ process_id_, request_id_, deletable_file_.get());
host_->StartDeferredRequest(process_id_, request_id_);
}
diff --git a/chrome/browser/renderer_host/redirect_to_file_resource_handler.h b/chrome/browser/renderer_host/redirect_to_file_resource_handler.h
index 0e82e3b..4929711 100644
--- a/chrome/browser/renderer_host/redirect_to_file_resource_handler.h
+++ b/chrome/browser/renderer_host/redirect_to_file_resource_handler.h
@@ -21,6 +21,10 @@ class FileStream;
class GrowableIOBuffer;
}
+namespace webkit_blob {
+class DeletableFileReference;
+}
+
// Redirects network data to a file. This is intended to be layered in front
// of either the AsyncResourceHandler or the SyncResourceHandler.
class RedirectToFileResourceHandler : public ResourceHandler {
@@ -71,11 +75,14 @@ class RedirectToFileResourceHandler : public ResourceHandler {
bool buf_write_pending_;
int write_cursor_;
- FilePath file_path_;
scoped_ptr<net::FileStream> file_stream_;
net::CompletionCallbackImpl<RedirectToFileResourceHandler> write_callback_;
bool write_callback_pending_;
+ // We create a DeletableFileReference for the temp file created as
+ // a result of the download.
+ scoped_refptr<webkit_blob::DeletableFileReference> deletable_file_;
+
DISALLOW_COPY_AND_ASSIGN(RedirectToFileResourceHandler);
};
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index 8085d93..9126eb9 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -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 @@ bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message,
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_ReleaseDownloadedFile,
+ OnReleaseDownloadedFile)
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 @@ void ResourceDispatcherHost::BeginRequest(
}
// 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 @@ void ResourceDispatcherHost::BeginRequest(
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 @@ void ResourceDispatcherHost::BeginRequest(
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 @@ void ResourceDispatcherHost::BeginRequest(
BeginRequestInternal(request);
}
+void ResourceDispatcherHost::OnReleaseDownloadedFile(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,28 @@ void ResourceDispatcherHost::DataReceivedACK(int child_id,
}
}
+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()->GrantReadFile(
+ 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.
+}
+
bool ResourceDispatcherHost::Send(IPC::Message* message) {
delete message;
return false;
@@ -847,6 +890,7 @@ int ResourceDispatcherHost::GetOutstandingRequestsMemoryCost(
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 +1842,9 @@ bool ResourceDispatcherHost::IsResourceDispatcherHostMessage(
case ViewHostMsg_CancelRequest::ID:
case ViewHostMsg_FollowRedirect::ID:
case ViewHostMsg_ClosePage_ACK::ID:
+ case ViewHostMsg_ReleaseDownloadedFile::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;
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h
index 1878177..95909d3be 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.h
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.h
@@ -47,6 +47,10 @@ struct GlobalRequestID;
struct ViewHostMsg_Resource_Request;
struct ViewMsg_ClosePage_Params;
+namespace webkit_blob {
+class DeletableFileReference;
+}
+
class ResourceDispatcherHost : public URLRequest::Delegate {
public:
// Implemented by the client of ResourceDispatcherHost to receive messages in
@@ -264,6 +268,15 @@ class ResourceDispatcherHost : public URLRequest::Delegate {
// messages sent.
void DataReceivedACK(int process_unique_id, int request_id);
+ // Maintains a collection of temp files created in support of
+ // the download_to_file capability. Used to grant access to the
+ // child process and to defer deletion of the file until it's
+ // no longer needed.
+ void RegisterDownloadedTempFile(
+ int receiver_id, int request_id,
+ webkit_blob::DeletableFileReference* reference);
+ void UnregisterDownloadedTempFile(int receiver_id, int request_id);
+
// Needed for the sync IPC message dispatcher macros.
bool Send(IPC::Message* message);
@@ -397,11 +410,13 @@ class ResourceDispatcherHost : public URLRequest::Delegate {
IPC::Message* sync_result, // only valid for sync
int route_id); // only valid for async
void OnDataReceivedACK(int request_id);
+ void OnDataDownloadedACK(int request_id);
void OnUploadProgressACK(int request_id);
void OnCancelRequest(int request_id);
void OnFollowRedirect(int request_id,
bool has_new_first_party_for_cookies,
const GURL& new_first_party_for_cookies);
+ void OnReleaseDownloadedFile(int request_id);
ResourceHandler* CreateSafeBrowsingResourceHandler(
ResourceHandler* handler, int child_id, int route_id,
@@ -432,6 +447,15 @@ class ResourceDispatcherHost : public URLRequest::Delegate {
PendingRequestList pending_requests_;
+ // Collection of temp files downloaded for child processes via
+ // the download_to_file mechanism. We avoid deleting them until
+ // the client no longer needs them.
+ typedef std::map<int, scoped_refptr<webkit_blob::DeletableFileReference> >
+ DeletableFilesMap; // key is request id
+ typedef std::map<int, DeletableFilesMap>
+ RegisteredTempFiles; // key is child process id
+ RegisteredTempFiles registered_temp_files_;
+
// A timer that periodically calls UpdateLoadStates while pending_requests_
// is not empty.
base::RepeatingTimer<ResourceDispatcherHost> update_load_states_timer_;
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host_request_info.cc b/chrome/browser/renderer_host/resource_dispatcher_host_request_info.cc
index eeac6f0..30ca189 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host_request_info.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host_request_info.cc
@@ -7,6 +7,7 @@
#include "chrome/browser/login_prompt.h"
#include "chrome/browser/renderer_host/resource_handler.h"
#include "chrome/browser/ssl/ssl_client_auth_handler.h"
+#include "webkit/blob/blob_data.h"
ResourceDispatcherHostRequestInfo::ResourceDispatcherHostRequestInfo(
ResourceHandler* handler,
@@ -61,3 +62,8 @@ void ResourceDispatcherHostRequestInfo::set_ssl_client_auth_handler(
SSLClientAuthHandler* s) {
ssl_client_auth_handler_ = s;
}
+
+void ResourceDispatcherHostRequestInfo::set_requested_blob_data(
+ webkit_blob::BlobData* data) {
+ requested_blob_data_ = data;
+}
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host_request_info.h b/chrome/browser/renderer_host/resource_dispatcher_host_request_info.h
index f5b7535..9d5e386 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host_request_info.h
+++ b/chrome/browser/renderer_host/resource_dispatcher_host_request_info.h
@@ -21,6 +21,10 @@ class ResourceDispatcherHost;
class ResourceHandler;
class SSLClientAuthHandler;
+namespace webkit_blob {
+class BlobData;
+}
+
// Holds the data ResourceDispatcherHost associates with each request.
// Retrieve this data by calling ResourceDispatcherHost::InfoForRequest.
class ResourceDispatcherHostRequestInfo : public URLRequest::UserData {
@@ -160,6 +164,13 @@ class ResourceDispatcherHostRequestInfo : public URLRequest::UserData {
int host_renderer_id() const { return host_renderer_id_; }
int host_render_view_id() const { return host_render_view_id_; }
+ // We hold a reference to the requested blob data to ensure it doesn't
+ // get finally released prior to the URLRequestJob being started.
+ webkit_blob::BlobData* requested_blob_data() const {
+ return requested_blob_data_.get();
+ }
+ void set_requested_blob_data(webkit_blob::BlobData* data);
+
private:
friend class ResourceDispatcherHost;
@@ -214,6 +225,7 @@ class ResourceDispatcherHostRequestInfo : public URLRequest::UserData {
base::TimeTicks last_upload_ticks_;
bool waiting_for_upload_progress_ack_;
int memory_cost_;
+ scoped_refptr<webkit_blob::BlobData> requested_blob_data_;
// "Private" data accessible only to ResourceDispatcherHost (use the
// accessors above for consistency).
diff --git a/chrome/browser/renderer_host/resource_handler.h b/chrome/browser/renderer_host/resource_handler.h
index a03e50d..b6758ae 100644
--- a/chrome/browser/renderer_host/resource_handler.h
+++ b/chrome/browser/renderer_host/resource_handler.h
@@ -80,6 +80,12 @@ class ResourceHandler
// This is a signal that the associated URLRequest isn't valid anymore.
virtual void OnRequestClosed() = 0;
+ // This notification is synthesized by the RedirectToFileResourceHandler
+ // to indicate progress of 'download_to_file' requests. OnReadCompleted
+ // calls are consumed by the RedirectToFileResourceHandler and replaced
+ // with OnDataDownloaded calls.
+ virtual void OnDataDownloaded(int request_id, int bytes_downloaded) {}
+
protected:
friend class ChromeThread;
friend class DeleteTask<ResourceHandler>;
diff --git a/chrome/browser/renderer_host/sync_resource_handler.cc b/chrome/browser/renderer_host/sync_resource_handler.cc
index 6638084..16c057a 100644
--- a/chrome/browser/renderer_host/sync_resource_handler.cc
+++ b/chrome/browser/renderer_host/sync_resource_handler.cc
@@ -63,6 +63,7 @@ bool SyncResourceHandler::OnResponseStarted(int request_id,
result_.headers = response->response_head.headers;
result_.mime_type = response->response_head.mime_type;
result_.charset = response->response_head.charset;
+ result_.download_file_path = response->response_head.download_file_path;
result_.request_time = response->response_head.request_time;
result_.response_time = response->response_head.response_time;
result_.connection_id = response->response_head.connection_id;