summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/media/buffered_data_source.cc6
-rw-r--r--webkit/glue/media/buffered_data_source.h4
-rw-r--r--webkit/glue/media/simple_data_source.cc5
-rw-r--r--webkit/glue/media/simple_data_source.h4
-rw-r--r--webkit/glue/resource_loader_bridge.h8
-rw-r--r--webkit/glue/weburlloader_impl.cc37
-rw-r--r--webkit/tools/test_shell/simple_resource_loader_bridge.cc63
7 files changed, 90 insertions, 37 deletions
diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc
index 4fc3549..738f30d 100644
--- a/webkit/glue/media/buffered_data_source.cc
+++ b/webkit/glue/media/buffered_data_source.cc
@@ -194,7 +194,9 @@ void BufferedResourceLoader::Read(int64 position,
/////////////////////////////////////////////////////////////////////////////
// BufferedResourceLoader,
// webkit_glue::ResourceLoaderBridge::Peer implementations
-void BufferedResourceLoader::OnReceivedRedirect(const GURL& new_url) {
+bool BufferedResourceLoader::OnReceivedRedirect(
+ const GURL& new_url,
+ const webkit_glue::ResourceLoaderBridge::ResponseInfo& info) {
DCHECK(bridge_.get());
DCHECK(start_callback_.get());
@@ -206,6 +208,8 @@ void BufferedResourceLoader::OnReceivedRedirect(const GURL& new_url) {
DoneStart(net::ERR_ADDRESS_INVALID);
Stop();
}
+
+ return true;
}
void BufferedResourceLoader::OnReceivedResponse(
diff --git a/webkit/glue/media/buffered_data_source.h b/webkit/glue/media/buffered_data_source.h
index 6dd51a7..ef46477 100644
--- a/webkit/glue/media/buffered_data_source.h
+++ b/webkit/glue/media/buffered_data_source.h
@@ -86,7 +86,9 @@ class BufferedResourceLoader : public webkit_glue::ResourceLoaderBridge::Peer {
/////////////////////////////////////////////////////////////////////////////
// webkit_glue::ResourceLoaderBridge::Peer implementations.
virtual void OnUploadProgress(uint64 position, uint64 size) {}
- virtual void OnReceivedRedirect(const GURL& new_url);
+ virtual bool OnReceivedRedirect(
+ const GURL& new_url,
+ const webkit_glue::ResourceLoaderBridge::ResponseInfo& info);
virtual void OnReceivedResponse(
const webkit_glue::ResourceLoaderBridge::ResponseInfo& info,
bool content_filtered);
diff --git a/webkit/glue/media/simple_data_source.cc b/webkit/glue/media/simple_data_source.cc
index 48c7138..639aa5f 100644
--- a/webkit/glue/media/simple_data_source.cc
+++ b/webkit/glue/media/simple_data_source.cc
@@ -109,8 +109,11 @@ void SimpleDataSource::OnDownloadProgress(uint64 position, uint64 size) {}
void SimpleDataSource::OnUploadProgress(uint64 position, uint64 size) {}
-void SimpleDataSource::OnReceivedRedirect(const GURL& new_url) {
+bool SimpleDataSource::OnReceivedRedirect(
+ const GURL& new_url,
+ const webkit_glue::ResourceLoaderBridge::ResponseInfo& info) {
SetURL(new_url);
+ return true;
}
void SimpleDataSource::OnReceivedResponse(
diff --git a/webkit/glue/media/simple_data_source.h b/webkit/glue/media/simple_data_source.h
index acfc503..e458c57 100644
--- a/webkit/glue/media/simple_data_source.h
+++ b/webkit/glue/media/simple_data_source.h
@@ -49,7 +49,9 @@ class SimpleDataSource : public media::DataSource,
// webkit_glue::ResourceLoaderBridge::Peer implementation.
virtual void OnDownloadProgress(uint64 position, uint64 size);
virtual void OnUploadProgress(uint64 position, uint64 size);
- virtual void OnReceivedRedirect(const GURL& new_url);
+ virtual bool OnReceivedRedirect(
+ const GURL& new_url,
+ const webkit_glue::ResourceLoaderBridge::ResponseInfo& info);
virtual void OnReceivedResponse(
const webkit_glue::ResourceLoaderBridge::ResponseInfo& info,
bool content_filtered);
diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h
index 2d7ba77..b76fd56 100644
--- a/webkit/glue/resource_loader_bridge.h
+++ b/webkit/glue/resource_loader_bridge.h
@@ -105,8 +105,12 @@ class ResourceLoaderBridge {
// note: only for requests with LOAD_ENABLE_UPLOAD_PROGRESS set
virtual void OnUploadProgress(uint64 position, uint64 size) = 0;
- // Called when a redirect occurs.
- virtual void OnReceivedRedirect(const GURL& new_url) = 0;
+ // Called when a redirect occurs. The implementation may return false to
+ // suppress the redirect. The given ResponseInfo provides complete
+ // information about the redirect, and new_url is the URL that will be
+ // loaded if this method returns true.
+ virtual bool OnReceivedRedirect(const GURL& new_url,
+ const ResponseInfo& info) = 0;
// Called when response headers are available (after all redirects have
// been followed). |content_filtered| is set to true if the contents is
diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc
index d0158f6..3041049 100644
--- a/webkit/glue/weburlloader_impl.cc
+++ b/webkit/glue/weburlloader_impl.cc
@@ -205,7 +205,8 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context>,
// ResourceLoaderBridge::Peer methods:
virtual void OnUploadProgress(uint64 position, uint64 size);
- virtual void OnReceivedRedirect(const GURL& new_url);
+ virtual bool OnReceivedRedirect(
+ const GURL& new_url, const ResourceLoaderBridge::ResponseInfo& info);
virtual void OnReceivedResponse(
const ResourceLoaderBridge::ResponseInfo& info, bool content_filtered);
virtual void OnReceivedData(const char* data, int len);
@@ -371,30 +372,32 @@ void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) {
client_->didSendData(loader_, position, size);
}
-void WebURLLoaderImpl::Context::OnReceivedRedirect(const GURL& new_url) {
+bool WebURLLoaderImpl::Context::OnReceivedRedirect(
+ const GURL& new_url,
+ const ResourceLoaderBridge::ResponseInfo& info) {
if (!client_)
- return;
+ return false;
- // TODO(darin): We lack sufficient information to construct the
- // actual redirect response, so we just simulate it here.
- WebURLResponse response(url_);
+ WebURLResponse response;
+ response.initialize();
+ PopulateURLResponse(url_, info, &response);
- // TODO(darin): We lack sufficient information to construct the
- // actual request that resulted from the redirect, so we just
- // report a GET navigation to the new location.
+ // TODO(darin): We lack sufficient information to construct the actual
+ // request that resulted from the redirect, so we just report a GET
+ // navigation to the new location.
WebURLRequest new_request(new_url);
url_ = new_url;
client_->willSendRequest(loader_, new_request, response);
- // TODO(darin): since new_request is sent as a mutable reference, it is
- // possible that willSendRequest may have modified it.
- //
- // andresca on #webkit confirms that that is intentional, so we'll need
- // to rework the ResourceLoaderBridge to give us control over what URL
- // is really loaded (and with what headers) when a redirect is encountered.
- // TODO(darin): we fail this assertion in some layout tests!
- //DCHECK(GURL(new_request.url()) == new_url);
+ // Only follow the redirect if WebKit left the URL unmodified.
+ if (url_ == new_request.url())
+ return true;
+
+ // We assume that WebKit only changes the URL to suppress a redirect, and we
+ // assume that it does so by setting it to be invalid.
+ DCHECK(!new_request.url().isValid());
+ return false;
}
void WebURLLoaderImpl::Context::OnReceivedResponse(
diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
index c11bcec..a7d27a0 100644
--- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc
+++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
@@ -151,9 +151,14 @@ class RequestProxy : public URLRequest::Delegate,
// various URLRequest callbacks. The event hooks, defined below, trigger
// these methods asynchronously.
- void NotifyReceivedRedirect(const GURL& new_url) {
- if (peer_)
- peer_->OnReceivedRedirect(new_url);
+ void NotifyReceivedRedirect(const GURL& new_url,
+ const ResourceLoaderBridge::ResponseInfo& info) {
+ if (peer_ && peer_->OnReceivedRedirect(new_url, info)) {
+ io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &RequestProxy::AsyncFollowDeferredRedirect));
+ } else {
+ Cancel();
+ }
}
void NotifyReceivedResponse(const ResourceLoaderBridge::ResponseInfo& info,
@@ -230,6 +235,14 @@ class RequestProxy : public URLRequest::Delegate,
Done();
}
+ void AsyncFollowDeferredRedirect() {
+ // This can be null in cases where the request is already done.
+ if (!request_.get())
+ return;
+
+ request_->FollowDeferredRedirect();
+ }
+
void AsyncReadData() {
// This can be null in cases where the request is already done.
if (!request_.get())
@@ -252,9 +265,13 @@ class RequestProxy : public URLRequest::Delegate,
// callbacks) that run on the IO thread. They are designed to be overridden
// by the SyncRequestProxy subclass.
- virtual void OnReceivedRedirect(const GURL& new_url) {
+ virtual void OnReceivedRedirect(
+ const GURL& new_url,
+ const ResourceLoaderBridge::ResponseInfo& info,
+ bool* defer_redirect) {
+ *defer_redirect = true; // See AsyncFollowDeferredRedirect
owner_loop_->PostTask(FROM_HERE, NewRunnableMethod(
- this, &RequestProxy::NotifyReceivedRedirect, new_url));
+ this, &RequestProxy::NotifyReceivedRedirect, new_url, info));
}
virtual void OnReceivedResponse(
@@ -282,19 +299,15 @@ class RequestProxy : public URLRequest::Delegate,
const GURL& new_url,
bool* defer_redirect) {
DCHECK(request->status().is_success());
- OnReceivedRedirect(new_url);
+ ResourceLoaderBridge::ResponseInfo info;
+ PopulateResponseInfo(request, &info);
+ OnReceivedRedirect(new_url, info, defer_redirect);
}
virtual void OnResponseStarted(URLRequest* request) {
if (request->status().is_success()) {
ResourceLoaderBridge::ResponseInfo info;
- info.request_time = request->request_time();
- info.response_time = request->response_time();
- info.headers = request->response_headers();
- info.app_cache_id = WebAppCacheContext::kNoAppCacheId;
- request->GetMimeType(&info.mime_type);
- request->GetCharset(&info.charset);
- info.content_length = request->GetExpectedContentSize();
+ PopulateResponseInfo(request, &info);
OnReceivedResponse(info, false);
AsyncReadData(); // start reading
} else {
@@ -358,6 +371,17 @@ class RequestProxy : public URLRequest::Delegate,
}
}
+ void PopulateResponseInfo(URLRequest* request,
+ ResourceLoaderBridge::ResponseInfo* info) const {
+ info->request_time = request->request_time();
+ info->response_time = request->response_time();
+ info->headers = request->response_headers();
+ info->app_cache_id = WebAppCacheContext::kNoAppCacheId;
+ request->GetMimeType(&info->mime_type);
+ request->GetCharset(&info->charset);
+ info->content_length = request->GetExpectedContentSize();
+ }
+
scoped_ptr<URLRequest> request_;
// Size of our async IO data buffers
@@ -397,7 +421,18 @@ class SyncRequestProxy : public RequestProxy {
// --------------------------------------------------------------------------
// Event hooks that run on the IO thread:
- virtual void OnReceivedRedirect(const GURL& new_url) {
+ virtual void OnReceivedRedirect(
+ const GURL& new_url,
+ const ResourceLoaderBridge::ResponseInfo& info,
+ bool* defer_redirect) {
+ // TODO(darin): It would be much better if this could live in WebCore, but
+ // doing so requires API changes at all levels. Similar code exists in
+ // WebCore/platform/network/cf/ResourceHandleCFNet.cpp :-(
+ if (new_url.GetOrigin() != result_->url.GetOrigin()) {
+ LOG(ERROR) << "Cross origin redirect denied";
+ Cancel();
+ return;
+ }
result_->url = new_url;
}