summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-13 20:06:57 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-13 20:06:57 +0000
commit363347b61871d82d0f84d14d5a24288ac79eddc3 (patch)
tree5cfc6dc4c874e9d23d3fc66ae4b9294bf549921b
parentcc7948aeb5fe21af08a2d5e868c0087ded0d244a (diff)
downloadchromium_src-363347b61871d82d0f84d14d5a24288ac79eddc3.zip
chromium_src-363347b61871d82d0f84d14d5a24288ac79eddc3.tar.gz
chromium_src-363347b61871d82d0f84d14d5a24288ac79eddc3.tar.bz2
Highlights of changes:
1. Added entry to ResourceResponseHead so that it contains either a base::PlatformFile (OS_WIN) or base::FileDescriptor (OS_POSIX) for passing the file handle from browser to renderer process. 2. Also added IPC messages for reporting download progress and ACK message for it. ResourceLoaderBridge::Peer::OnDownloadProgress is added so that the peer is notified of the download progress in the renderer process. 3. Load flag to kick start the resource loading for media files. LOAD_MEDIA_RESOURCE is added so that ResourceDispatcherHost knows how to use a different ResourceHandler for handling media resource request. Review URL: http://codereview.chromium.org/27168 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11661 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser.scons2
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/profile.cc2
-rw-r--r--chrome/browser/renderer_host/media_resource_handler.cc98
-rw-r--r--chrome/browser/renderer_host/media_resource_handler.h50
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc26
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.h4
-rw-r--r--chrome/browser/renderer_host/resource_handler.h19
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc22
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h4
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--[-rwxr-xr-x]chrome/common/render_messages.h7
-rw-r--r--chrome/common/render_messages_internal.h18
-rw-r--r--chrome/common/resource_dispatcher.cc9
-rw-r--r--chrome/common/resource_dispatcher.h1
-rw-r--r--net/base/load_flags.h3
-rw-r--r--net/disk_cache/disk_cache.h13
-rw-r--r--net/disk_cache/entry_impl.cc10
-rw-r--r--net/http/http_cache.cc20
-rw-r--r--net/http/http_cache_unittest.cc1
-rw-r--r--net/http/http_response_info.cc4
-rw-r--r--net/url_request/url_request.h7
-rw-r--r--webkit/glue/resource_loader_bridge.h9
23 files changed, 317 insertions, 22 deletions
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index 6949384..52dada2 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -533,6 +533,8 @@ input_files = ChromeFileList([
'renderer_host/download_resource_handler.h',
'renderer_host/download_throttling_resource_handler.cc',
'renderer_host/download_throttling_resource_handler.h',
+ 'renderer_host/media_resource_handler.cc',
+ 'renderer_host/media_resource_handler.h',
'renderer_host/render_process_host.cc',
'renderer_host/render_process_host.h',
'renderer_host/render_view_host.cc',
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index eeff546..2880e43 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -2022,6 +2022,14 @@
>
</File>
<File
+ RelativePath=".\renderer_host\media_resource_handler.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\renderer_host\media_resource_handler.h"
+ >
+ </File>
+ <File
RelativePath=".\renderer_host\render_process_host.cc"
>
</File>
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 526e528..352d96582 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -99,6 +99,7 @@ class OffTheRecordProfileImpl : public Profile,
public:
explicit OffTheRecordProfileImpl(Profile* real_profile)
: profile_(real_profile),
+ media_request_context_(NULL),
start_time_(Time::Now()) {
request_context_ = ChromeURLRequestContext::CreateOffTheRecord(this);
request_context_->AddRef();
@@ -352,6 +353,7 @@ ProfileImpl::ProfileImpl(const FilePath& path)
personalization_(NULL),
#endif
request_context_(NULL),
+ media_request_context_(NULL),
history_service_created_(false),
created_web_data_service_(false),
created_download_manager_(false),
diff --git a/chrome/browser/renderer_host/media_resource_handler.cc b/chrome/browser/renderer_host/media_resource_handler.cc
new file mode 100644
index 0000000..ca79b0d
--- /dev/null
+++ b/chrome/browser/renderer_host/media_resource_handler.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/renderer_host/media_resource_handler.h"
+
+#include "base/process.h"
+#include "chrome/common/render_messages.h"
+#include "net/base/load_flags.h"
+
+MediaResourceHandler::MediaResourceHandler(
+ ResourceHandler* resource_handler,
+ ResourceDispatcherHost::Receiver* receiver,
+ int render_process_host_id,
+ int routing_id,
+ base::ProcessHandle render_process,
+ ResourceDispatcherHost* resource_dispatcher_host)
+ : receiver_(receiver),
+ render_process_host_id_(render_process_host_id),
+ routing_id_(routing_id),
+ render_process_(render_process),
+ handler_(resource_handler),
+ rdh_(resource_dispatcher_host),
+ has_file_handle_(false),
+ position_(0),
+ size_(-1) {
+}
+
+bool MediaResourceHandler::OnUploadProgress(int request_id,
+ uint64 position,
+ uint64 size) {
+ return handler_->OnUploadProgress(request_id, position, size);
+}
+
+bool MediaResourceHandler::OnRequestRedirected(int request_id,
+ const GURL& new_url) {
+ return handler_->OnRequestRedirected(request_id, new_url);
+}
+
+bool MediaResourceHandler::OnResponseStarted(int request_id,
+ ResourceResponse* response) {
+#if defined(OS_POSIX)
+ if (response->response_head.response_data_file.fd !=
+ base::kInvalidPlatformFileValue) {
+ // On POSIX, we will just set auto_close to true, and the IPC infrastructure
+ // will send this file handle through and close it automatically.
+ response->response_head.response_data_file.auto_close = true;
+ has_file_handle_ = true;
+ }
+#elif defined(OS_WIN)
+ if (response->response_head.response_data_file !=
+ base::kInvalidPlatformFileValue) {
+ // On Windows, we duplicate the file handle for the renderer process and
+ // close the original manually.
+ base::PlatformFile foreign_handle;
+ if (DuplicateHandle(GetCurrentProcess(),
+ response->response_head.response_data_file,
+ render_process_,
+ &foreign_handle,
+ FILE_READ_DATA, // Only allow read access to data.
+ false, // Foreign handle is not inheritable.
+ // Close the file handle after duplication.
+ DUPLICATE_CLOSE_SOURCE)){
+ response->response_head.response_data_file = foreign_handle;
+ has_file_handle_ = true;
+ } else {
+ has_file_handle_ = false;
+ }
+ }
+#endif
+ size_ = response->response_head.content_length;
+ return handler_->OnResponseStarted(request_id, response);
+}
+
+bool MediaResourceHandler::OnWillRead(int request_id,
+ net::IOBuffer** buf, int* buf_size,
+ int min_size) {
+ return handler_->OnWillRead(request_id, buf, buf_size, min_size);
+}
+
+bool MediaResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
+ if (has_file_handle_) {
+ // If we have received a file handle before we will be sending a progress
+ // update for download.
+ // TODO(hclam): rate limit this message so we won't be sending too much to
+ // the renderer process.
+ receiver_->Send(
+ new ViewMsg_Resource_DownloadProgress(routing_id_, request_id,
+ position_, size_));
+ position_ += *bytes_read;
+ }
+ return handler_->OnReadCompleted(request_id, bytes_read);
+}
+
+bool MediaResourceHandler::OnResponseCompleted(int request_id,
+ const URLRequestStatus& status, const std::string& security_info) {
+ return handler_->OnResponseCompleted(request_id, status, security_info);
+}
diff --git a/chrome/browser/renderer_host/media_resource_handler.h b/chrome/browser/renderer_host/media_resource_handler.h
new file mode 100644
index 0000000..93be6d706
--- /dev/null
+++ b/chrome/browser/renderer_host/media_resource_handler.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_RENDERER_HOST_MEDIA_RESOURCE_HANDLER_H_
+#define CHROME_BROWSER_RENDERER_HOST_MEDIA_RESOURCE_HANDLER_H_
+
+#include "base/process.h"
+#include "base/platform_file.h"
+#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
+#include "chrome/browser/renderer_host/resource_handler.h"
+
+// Used to complete a media resource request in response to resource load events
+// from the resource dispatcher host. This handler only works asynchronously and
+// tries to work with file for response data if possible. If a response data
+// file is not available, it redirects calls to underlying handler.
+class MediaResourceHandler : public ResourceHandler {
+ public:
+ MediaResourceHandler(ResourceHandler* resource_handler,
+ ResourceDispatcherHost::Receiver* receiver,
+ int render_process_host_id,
+ int routing_id,
+ base::ProcessHandle render_process,
+ ResourceDispatcherHost* resource_dispatcher_host);
+
+ // ResourceHandler implementation:
+ bool OnUploadProgress(int request_id, uint64 position, uint64 size);
+ bool OnRequestRedirected(int request_id, const GURL& new_url);
+ bool OnResponseStarted(int request_id, ResourceResponse* response);
+ bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size,
+ int min_size);
+ bool OnReadCompleted(int request_id, int* bytes_read);
+ bool OnResponseCompleted(int request_id, const URLRequestStatus& status,
+ const std::string& security_info);
+
+ private:
+ ResourceDispatcherHost::Receiver* receiver_;
+ int render_process_host_id_;
+ int routing_id_;
+ base::ProcessHandle render_process_;
+ scoped_refptr<ResourceHandler> handler_;
+ ResourceDispatcherHost* rdh_;
+ bool has_file_handle_;
+ int64 position_;
+ int64 size_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaResourceHandler);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_MEDIA_RESOURCE_HANDLER_H_
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index b4535ca..057343d 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/renderer_host/buffered_resource_handler.h"
#include "chrome/browser/renderer_host/cross_site_resource_handler.h"
#include "chrome/browser/renderer_host/download_resource_handler.h"
+#include "chrome/browser/renderer_host/media_resource_handler.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/renderer_security_policy.h"
#include "chrome/browser/renderer_host/resource_request_details.h"
@@ -248,6 +249,17 @@ void ResourceDispatcherHost::BeginRequest(
process_handle,
request_data.url,
this);
+ // If the resource type is ResourceType::MEDIA and LOAD_ENABLE_DOWNLOAD_FILE
+ // is enabled we insert a media resource handler.
+ if (request_data.resource_type == ResourceType::MEDIA &&
+ (request_data.load_flags & net::LOAD_ENABLE_DOWNLOAD_FILE)) {
+ handler = new MediaResourceHandler(handler,
+ receiver,
+ process_id,
+ route_id,
+ process_handle,
+ this);
+ }
}
if (HandleExternalProtocol(request_id, process_id, route_id,
@@ -513,6 +525,11 @@ void ResourceDispatcherHost::OnDataReceivedACK(int process_id,
}
}
+void ResourceDispatcherHost::OnDownloadProgressACK(int process_id,
+ int request_id) {
+ // TODO(hclam): do something to help rate limiting the message.
+}
+
void ResourceDispatcherHost::OnUploadProgressACK(int process_id,
int request_id) {
PendingRequestList::iterator i = pending_requests_.find(
@@ -811,6 +828,15 @@ bool ResourceDispatcherHost::CompleteResponseStarted(URLRequest* request) {
response->response_head.content_length = request->GetExpectedContentSize();
request->GetMimeType(&response->response_head.mime_type);
+ // Make sure we don't get a file handle if LOAD_ENABLE_FILE is not set.
+ DCHECK((request->load_flags() & net::LOAD_ENABLE_DOWNLOAD_FILE) ||
+ request->response_data_file() == base::kInvalidPlatformFileValue);
+#if defined(OS_POSIX)
+ response->response_head.response_data_file.fd = request->response_data_file();
+#elif defined(OS_WIN)
+ response->response_head.response_data_file = request->response_data_file();
+#endif
+
if (request->ssl_info().cert) {
int cert_id =
CertStore::GetSharedInstance()->StoreCert(
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h
index 931401e..3d14213 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.h
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.h
@@ -237,6 +237,10 @@ class ResourceDispatcherHost : public URLRequest::Delegate {
// messages sent.
void OnDataReceivedACK(int process_id, int request_id);
+ // Called when the renderer process confirms the reception of a download
+ // progress message.
+ void OnDownloadProgressACK(int process_id, int request_id);
+
// Resets the waiting_for_upload_progress_ack flag.
void OnUploadProgressACK(int process_id, int request_id);
diff --git a/chrome/browser/renderer_host/resource_handler.h b/chrome/browser/renderer_host/resource_handler.h
index 2b843f9..e0713d9 100644
--- a/chrome/browser/renderer_host/resource_handler.h
+++ b/chrome/browser/renderer_host/resource_handler.h
@@ -14,6 +14,11 @@
#include <string>
+#include "build/build_config.h"
+#if defined(OS_POSIX)
+#include "base/file_descriptor_posix.h"
+#endif
+#include "base/platform_file.h"
#include "chrome/common/filter_policy.h"
#include "net/url_request/url_request_status.h"
#include "webkit/glue/resource_loader_bridge.h"
@@ -31,6 +36,20 @@ struct ResourceResponseHead
// Specifies if the resource should be filtered before being displayed
// (insecure resources can be filtered to keep the page secure).
FilterPolicy::Type filter_policy;
+
+ // A platform specific handle for a file that carries response data. This
+ // entry is used if the resource request is of type ResourceType::MEDIA and
+ // the underlying cache layer keeps the response data in a standalone file.
+#if defined(OS_POSIX)
+ // If the response data file is available, the file handle is stored in
+ // response_data_file.fd, its value is base::kInvalidPlatformFileValue
+ // otherwise.
+ base::FileDescriptor response_data_file;
+#elif defined(OS_WIN)
+ // An asynchronous file handle to the response data file, its value is
+ // base::kInvalidPlatformFileValue if the file is not available.
+ base::PlatformFile response_data_file;
+#endif
};
// Parameters for a synchronous resource response.
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 02ae30a..404e68b 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -32,6 +32,7 @@
#include "chrome/common/render_messages.h"
#include "net/base/cookie_monster.h"
#include "net/base/mime_util.h"
+#include "net/base/load_flags.h"
#include "net/url_request/url_request_context.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webplugin.h"
@@ -114,11 +115,14 @@ ResourceMessageFilter::ResourceMessageFilter(
ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)),
render_handle_(NULL),
request_context_(profile->GetRequestContext()),
+ media_request_context_(profile->GetRequestContextForMedia()),
profile_(profile),
render_widget_helper_(render_widget_helper),
audio_renderer_host_(audio_renderer_host) {
DCHECK(request_context_.get());
DCHECK(request_context_->cookie_store());
+ DCHECK(media_request_context_.get());
+ DCHECK(media_request_context_->cookie_store());
DCHECK(audio_renderer_host_.get());
}
@@ -188,6 +192,7 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest)
IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK)
IPC_MESSAGE_HANDLER(ViewHostMsg_DataReceived_ACK, OnDataReceivedACK)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadProgress_ACK, OnDownloadProgressACK)
IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad)
@@ -333,6 +338,16 @@ void ResourceMessageFilter::OnRequestResource(
const IPC::Message& message,
int request_id,
const ViewHostMsg_Resource_Request& request) {
+ URLRequestContext* request_context = request_context_;
+ // If the request has resource type of ResourceType::MEDIA and
+ // LOAD_ENABLE_DOWNLOAD_FILE is set as a load flag, we use a request context
+ // specific to media for handling it because these resources have specific
+ // needs for caching and data passing.
+ if (request.resource_type == ResourceType::MEDIA &&
+ (request.load_flags & net::LOAD_ENABLE_DOWNLOAD_FILE)) {
+ request_context = media_request_context_;
+ }
+
resource_dispatcher_host_->BeginRequest(this,
ChildProcessInfo::RENDER_PROCESS,
render_handle_,
@@ -340,7 +355,7 @@ void ResourceMessageFilter::OnRequestResource(
message.routing_id(),
request_id,
request,
- request_context_,
+ request_context,
NULL);
}
@@ -348,6 +363,11 @@ void ResourceMessageFilter::OnDataReceivedACK(int request_id) {
resource_dispatcher_host_->OnDataReceivedACK(render_process_id_, request_id);
}
+void ResourceMessageFilter::OnDownloadProgressACK(int request_id) {
+ resource_dispatcher_host_->OnDownloadProgressACK(render_process_id_,
+ request_id);
+}
+
void ResourceMessageFilter::OnUploadProgressACK(int request_id) {
resource_dispatcher_host_->OnUploadProgressACK(render_process_id_,
request_id);
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 10a12ed..3269c89 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -101,6 +101,7 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
void OnCancelRequest(int request_id);
void OnClosePageACK(int new_render_process_host_id, int new_request_id);
void OnDataReceivedACK(int request_id);
+ void OnDownloadProgressACK(int request_id);
void OnUploadProgressACK(int request_id);
void OnSyncLoad(int request_id,
const ViewHostMsg_Resource_Request& request,
@@ -251,6 +252,9 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
// Contextual information to be used for requests created here.
scoped_refptr<URLRequestContext> request_context_;
+ // A request context specific for media resources.
+ scoped_refptr<URLRequestContext> media_request_context_;
+
// A pointer to the profile associated with this filter.
//
// DANGER! Do not dereference this pointer! This class lives on the I/O thread
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 0068bf6..dc0d55f 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -839,6 +839,8 @@
'browser/renderer_host/download_resource_handler.h',
'browser/renderer_host/download_throttling_resource_handler.cc',
'browser/renderer_host/download_throttling_resource_handler.h',
+ 'browser/renderer_host/media_resource_handler.cc',
+ 'browser/renderer_host/media_resource_handler.h',
'browser/renderer_host/render_process_host.cc',
'browser/renderer_host/render_process_host.h',
'browser/renderer_host/render_view_host.cc',
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 462d853..048a0a6 100755..100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -377,6 +377,9 @@ struct ParamTraits<ResourceType::Type> {
case ResourceType::OBJECT:
type = L"OBJECT";
break;
+ case ResourceType::MEDIA:
+ type = L"MEDIA";
+ break;
default:
type = L"UNKNOWN";
break;
@@ -1334,6 +1337,7 @@ struct ParamTraits<ResourceResponseHead> {
ParamTraits<webkit_glue::ResourceLoaderBridge::ResponseInfo>::Write(m, p);
WriteParam(m, p.status);
WriteParam(m, p.filter_policy);
+ WriteParam(m, p.response_data_file);
}
static bool Read(const Message* m, void** iter, param_type* r) {
return
@@ -1341,7 +1345,8 @@ struct ParamTraits<ResourceResponseHead> {
iter,
r) &&
ReadParam(m, iter, &r->status) &&
- ReadParam(m, iter, &r->filter_policy);
+ ReadParam(m, iter, &r->filter_policy) &&
+ ReadParam(m, iter, &r->response_data_file);
}
static void Log(const param_type& p, std::wstring* l) {
// log more?
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 6416a4b..5ebe6e9 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -168,7 +168,14 @@ IPC_BEGIN_MESSAGES(View)
int /* request_id */,
ResourceResponseHead)
- // Sent as upload progress is being made
+ // Sent as download progress is being made, size of the resource may be
+ // unknown, in that case |size| is -1.
+ IPC_MESSAGE_ROUTED3(ViewMsg_Resource_DownloadProgress,
+ int /* request_id */,
+ int64 /* position */,
+ int64 /* size */)
+
+ // Sent as upload progress is being made.
IPC_MESSAGE_ROUTED3(ViewMsg_Resource_UploadProgress,
int /* request_id */,
int64 /* position */,
@@ -1104,8 +1111,13 @@ IPC_BEGIN_MESSAGES(ViewHost)
GURL /* last url */,
GURL /* url redirected to */)
- // Sent when the renderer process to acknowlege receipt of and UploadProgress
- // message.
+ // Sent by the renderer process to acknowledge receipt of a
+ // DownloadProgress message.
+ IPC_MESSAGE_ROUTED1(ViewHostMsg_DownloadProgress_ACK,
+ int /* request_id */)
+
+ // Sent by the renderer process to acknowledge receipt of a
+ // UploadProgress message.
IPC_MESSAGE_ROUTED1(ViewHostMsg_UploadProgress_ACK,
int /* request_id */)
diff --git a/chrome/common/resource_dispatcher.cc b/chrome/common/resource_dispatcher.cc
index 61c5013..32f15b1 100644
--- a/chrome/common/resource_dispatcher.cc
+++ b/chrome/common/resource_dispatcher.cc
@@ -275,6 +275,13 @@ bool ResourceDispatcher::OnMessageReceived(const IPC::Message& message) {
return true;
}
+void ResourceDispatcher::OnDownloadProgress(
+ int request_id, int64 position, int64 size) {
+ // TODO(hclam): delegate this message to
+ // ResourceLoaderBridge::Peer::OnDownloadProgress and send an ACK message
+ // back to ResourceDispatcherHost.
+}
+
void ResourceDispatcher::OnUploadProgress(
const IPC::Message& message, int request_id, int64 position, int64 size) {
PendingRequestList::iterator it = pending_requests_.find(request_id);
@@ -453,6 +460,7 @@ void ResourceDispatcher::SetDefersLoading(int request_id, bool value) {
void ResourceDispatcher::DispatchMessage(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message)
IPC_MESSAGE_HANDLER(ViewMsg_Resource_UploadProgress, OnUploadProgress)
+ IPC_MESSAGE_HANDLER(ViewMsg_Resource_DownloadProgress, OnDownloadProgress)
IPC_MESSAGE_HANDLER(ViewMsg_Resource_ReceivedResponse, OnReceivedResponse)
IPC_MESSAGE_HANDLER(ViewMsg_Resource_ReceivedRedirect, OnReceivedRedirect)
IPC_MESSAGE_HANDLER(ViewMsg_Resource_DataReceived, OnReceivedData)
@@ -502,6 +510,7 @@ webkit_glue::ResourceLoaderBridge* ResourceDispatcher::CreateBridge(
bool ResourceDispatcher::IsResourceMessage(const IPC::Message& message) const {
switch (message.type()) {
+ case ViewMsg_Resource_DownloadProgress::ID:
case ViewMsg_Resource_UploadProgress::ID:
case ViewMsg_Resource_ReceivedResponse::ID:
case ViewMsg_Resource_ReceivedRedirect::ID:
diff --git a/chrome/common/resource_dispatcher.h b/chrome/common/resource_dispatcher.h
index 3cdf1ee..04db7a1 100644
--- a/chrome/common/resource_dispatcher.h
+++ b/chrome/common/resource_dispatcher.h
@@ -98,6 +98,7 @@ class ResourceDispatcher {
int request_id,
int64 position,
int64 size);
+ void OnDownloadProgress(int request_id, int64 position, int64 size);
void OnReceivedResponse(int request_id, const ResourceResponseHead&);
void OnReceivedRedirect(int request_id, const GURL& new_url);
void OnReceivedData(const IPC::Message& message,
diff --git a/net/base/load_flags.h b/net/base/load_flags.h
index 8557126..354980c 100644
--- a/net/base/load_flags.h
+++ b/net/base/load_flags.h
@@ -37,6 +37,9 @@ enum {
// If present, upload progress messages should be provided to initiator.
LOAD_ENABLE_UPLOAD_PROGRESS = 1 << 6,
+ // If present, try to download the resource to a standalone file.
+ LOAD_ENABLE_DOWNLOAD_FILE = 1 << 7,
+
// If present, ignores certificate mismatches with the domain name.
// (The default behavior is to trigger an OnSSLCertificateError callback.)
LOAD_IGNORE_CERT_COMMON_NAME_INVALID = 1 << 8,
diff --git a/net/disk_cache/disk_cache.h b/net/disk_cache/disk_cache.h
index 48b7ba5..3ea3b25 100644
--- a/net/disk_cache/disk_cache.h
+++ b/net/disk_cache/disk_cache.h
@@ -160,9 +160,8 @@ class Entry {
// not base::kInvalidPlatformFileValue), there is no guarantee that the file
// is truncated. Implementor can always return base::kInvalidPlatformFileValue
// if external file is not available in that particular implementation.
- // Caller should never close the file handle returned by this method, since
- // the handle should be managed by the implementor of this class. Caller
- // should never save the handle for future use.
+ // The caller should close the file handle returned by this method or there
+ // will be a leak.
// With a stream prepared as an external file, the stream would always be
// kept in an external file since creation, even if the stream has 0 bytes.
// So we need to be cautious about using this option for preparing a stream or
@@ -171,10 +170,10 @@ class Entry {
// directly *without* buffering.
virtual base::PlatformFile UseExternalFile(int index) = 0;
- // Returns a read file handle for the cache stream referenced by |index|.
- // Caller should never close the handle returned by this method and should
- // not save it for future use. The lifetime of the base::PlatformFile handle
- // is managed by the implementor of this class.
+ // Returns an asynchronous read file handle for the cache stream referenced by
+ // |index|. Values other than base::kInvalidPlatformFileValue are successful
+ // and the file handle should be managed by the caller, i.e. caller should
+ // close the handle after use or there will be a leak.
virtual base::PlatformFile GetPlatformFile(int index) = 0;
protected:
diff --git a/net/disk_cache/entry_impl.cc b/net/disk_cache/entry_impl.cc
index 361a7ee..446138e 100644
--- a/net/disk_cache/entry_impl.cc
+++ b/net/disk_cache/entry_impl.cc
@@ -379,11 +379,11 @@ base::PlatformFile EntryImpl::GetPlatformFile(int index) {
if (!address.is_initialized() || !address.is_separate_file())
return base::kInvalidPlatformFileValue;
- File* cache_file = GetExternalFile(address, index);
- if (!cache_file)
- return base::kInvalidPlatformFileValue;
-
- return cache_file->platform_file();
+ return base::CreatePlatformFile(backend_->GetFileName(address),
+ base::PLATFORM_FILE_OPEN |
+ base::PLATFORM_FILE_READ |
+ base::PLATFORM_FILE_ASYNC,
+ NULL);
}
uint32 EntryImpl::GetHash() {
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index 75f0256..8637f2d 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -7,6 +7,11 @@
#include <algorithm>
#include "base/compiler_specific.h"
+
+#if defined(OS_POSIX)
+#include <unistd.h>
+#endif
+
#include "base/message_loop.h"
#include "base/pickle.h"
#include "base/ref_counted.h"
@@ -607,6 +612,15 @@ void HttpCache::Transaction::SetRequest(const HttpRequestInfo* request) {
if (cache_->mode() == RECORD)
effective_load_flags_ |= LOAD_BYPASS_CACHE;
+ // If HttpCache has type MEDIA make sure LOAD_ENABLE_DOWNLOAD_FILE is set,
+ // otherwise make sure LOAD_ENABLE_DOWNLOAD_FILE is not set when HttpCache
+ // has type other than MEDIA.
+ if (cache_->type() == HttpCache::MEDIA) {
+ DCHECK(effective_load_flags_ & LOAD_ENABLE_DOWNLOAD_FILE);
+ } else {
+ DCHECK(!(effective_load_flags_ & LOAD_ENABLE_DOWNLOAD_FILE));
+ }
+
// Some headers imply load flags. The order here is significant.
//
// LOAD_DISABLE_CACHE : no cache read or write
@@ -796,9 +810,10 @@ int HttpCache::Transaction::ReadResponseInfoFromEntry() {
// If the cache object is used for media file, we want the file handle of
// response data.
- if (cache_->type() == HttpCache::MEDIA)
+ if (cache_->type() == HttpCache::MEDIA) {
response_.response_data_file =
entry_->disk_entry->GetPlatformFile(kResponseContentIndex);
+ }
return OK;
}
@@ -869,9 +884,10 @@ void HttpCache::Transaction::TruncateResponseData() {
// if we get a valid response from server, i.e. 200. We don't want empty
// cache files for redirection or external files for erroneous requests.
response_.response_data_file = base::kInvalidPlatformFileValue;
- if (cache_->type() == HttpCache::MEDIA)
+ if (cache_->type() == HttpCache::MEDIA) {
response_.response_data_file =
entry_->disk_entry->UseExternalFile(kResponseContentIndex);
+ }
// Truncate the stream.
WriteToEntry(kResponseContentIndex, 0, NULL, 0);
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index 92980e1..61c2908 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -1227,6 +1227,7 @@ TEST(HttpCache, SimpleGET_MediaCache) {
#endif
ScopedMockTransaction trans_info(kSimpleGET_Transaction);
+ trans_info.load_flags |= net::LOAD_ENABLE_DOWNLOAD_FILE;
TestCompletionCallback callback;
{
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc
index ad6ef87..536d42b 100644
--- a/net/http/http_response_info.cc
+++ b/net/http/http_response_info.cc
@@ -3,12 +3,12 @@
// found in the LICENSE file.
#include "net/http/http_response_info.h"
-
#include "net/http/http_response_headers.h"
namespace net {
-HttpResponseInfo::HttpResponseInfo() {
+HttpResponseInfo::HttpResponseInfo()
+ : response_data_file(base::kInvalidPlatformFileValue) {
}
HttpResponseInfo::~HttpResponseInfo() {
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index 4309689..dcc999e 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -307,6 +307,13 @@ class URLRequest {
return response_info_.ssl_info;
}
+ // Returns the platform specific file handle for the standalone file that
+ // contains response data. base::kInvalidPlatformFileValue is returned if
+ // such file is not available.
+ base::PlatformFile response_data_file() {
+ return response_info_.response_data_file;
+ }
+
// Returns the cookie values included in the response, if the request is one
// that can have cookies. Returns true if the request is a cookie-bearing
// type, false otherwise. This method may only be called once the
diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h
index 8d32f0c..bd5ad42 100644
--- a/webkit/glue/resource_loader_bridge.h
+++ b/webkit/glue/resource_loader_bridge.h
@@ -91,6 +91,13 @@ class ResourceLoaderBridge {
public:
virtual ~Peer() {}
+ // Called as download progress is made.
+ // note: only for requests with LOAD_ENABLE_DOWNLOAD_FILE set and the
+ // resource is downloaded to a standalone file and the file handle to it is
+ // passed in ResponseInfo during OnReceivedResponse. Note that size may be
+ // unknown and |size| will be kuint64max in that case.
+ virtual void OnDownloadProgress(uint64 position, uint64 size) {}
+
// Called as upload progress is made.
// note: only for requests with LOAD_ENABLE_UPLOAD_PROGRESS set
virtual void OnUploadProgress(uint64 position, uint64 size) = 0;
@@ -105,7 +112,7 @@ class ResourceLoaderBridge {
virtual void OnReceivedResponse(const ResponseInfo& info,
bool content_filtered) = 0;
- // Called when a chunk of response data is available. This method may
+ // Called when a chunk of response data is available. This method may
// be called multiple times or not at all if an error occurs.
virtual void OnReceivedData(const char* data, int len) = 0;