summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/ui/ppapi_uitest.cc3
-rw-r--r--ppapi/tests/test_url_loader.cc32
-rw-r--r--ppapi/tests/test_url_loader.h1
-rw-r--r--webkit/glue/plugins/pepper_url_loader.cc66
-rw-r--r--webkit/glue/plugins/pepper_url_loader.h12
-rw-r--r--webkit/glue/plugins/pepper_url_request_info.cc4
-rw-r--r--webkit/glue/plugins/pepper_url_request_info.h3
-rw-r--r--webkit/glue/plugins/pepper_url_response_info.cc24
-rw-r--r--webkit/glue/plugins/pepper_url_response_info.h4
9 files changed, 132 insertions, 17 deletions
diff --git a/chrome/test/ui/ppapi_uitest.cc b/chrome/test/ui/ppapi_uitest.cc
index 9de0e3b..a145c8e 100644
--- a/chrome/test/ui/ppapi_uitest.cc
+++ b/chrome/test/ui/ppapi_uitest.cc
@@ -109,8 +109,7 @@ TEST_F(PPAPITest, Buffer) {
RunTest("Buffer");
}
-// http://bugs.chromium.org/51345
-TEST_F(PPAPITest, DISABLED_URLLoader) {
+TEST_F(PPAPITest, URLLoader) {
RunTestViaHTTP("URLLoader");
}
diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc
index b1cdd6f..3203f39 100644
--- a/ppapi/tests/test_url_loader.cc
+++ b/ppapi/tests/test_url_loader.cc
@@ -38,6 +38,7 @@ void TestURLLoader::RunTest() {
RUN_TEST(IgnoresBogusContentLength);
RUN_TEST(SameOriginRestriction);
RUN_TEST(StreamToFile);
+ RUN_TEST(AuditURLRedirect);
}
std::string TestURLLoader::ReadEntireFile(pp::FileIO_Dev* file_io,
@@ -255,4 +256,35 @@ std::string TestURLLoader::TestSameOriginRestriction() {
return "";
}
+// This test should cause a redirect and ensure that the loader runs
+// the callback, rather than following the redirect.
+std::string TestURLLoader::TestAuditURLRedirect() {
+ pp::URLRequestInfo_Dev request;
+ // This path will cause the server to return a 301 redirect.
+ request.SetURL("/server-redirect?www.google.com");
+ request.SetFollowRedirects(false);
+
+ TestCompletionCallback callback;
+
+ pp::URLLoader_Dev loader(*instance_);
+ int32_t rv = loader.Open(request, callback);
+ if (rv == PP_ERROR_WOULDBLOCK)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("URLLoader::Open", rv);
+
+ // Checks that the response indicates a redirect, and that the URL
+ // is correct.
+ pp::URLResponseInfo_Dev response_info(loader.GetResponseInfo());
+ if (response_info.is_null())
+ return "URLLoader::GetResponseInfo returned null";
+ int32_t status_code = response_info.GetStatusCode();
+ if (status_code != 301)
+ return "Response status should be 301";
+ if (response_info.GetRedirectURL().AsString() != "www.google.com")
+ return "Redirect URL should be www.google.com";
+
+ return "";
+}
+
// TODO(darin): Add a test for GrantUniversalAccess.
diff --git a/ppapi/tests/test_url_loader.h b/ppapi/tests/test_url_loader.h
index 9664508..681016d 100644
--- a/ppapi/tests/test_url_loader.h
+++ b/ppapi/tests/test_url_loader.h
@@ -39,6 +39,7 @@ class TestURLLoader : public TestCase {
std::string TestIgnoresBogusContentLength();
std::string TestStreamToFile();
std::string TestSameOriginRestriction();
+ std::string TestAuditURLRedirect();
};
#endif // PAPPI_TESTS_TEST_URL_LOADER_H_
diff --git a/webkit/glue/plugins/pepper_url_loader.cc b/webkit/glue/plugins/pepper_url_loader.cc
index 9c3b03a..cb7cb5f 100644
--- a/webkit/glue/plugins/pepper_url_loader.cc
+++ b/webkit/glue/plugins/pepper_url_loader.cc
@@ -16,6 +16,7 @@
#include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebURLLoader.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h"
#include "webkit/appcache/web_application_cache_host_impl.h"
@@ -175,6 +176,10 @@ const PPB_URLLoaderTrusted_Dev ppb_urlloadertrusted = {
&SetStatusCallback
};
+WebKit::WebFrame* GetFrame(PluginInstance* instance) {
+ return instance->container()->element().document().frame();
+}
+
} // namespace
URLLoader::URLLoader(PluginInstance* instance, bool main_document_loader)
@@ -217,15 +222,14 @@ int32_t URLLoader::Open(URLRequestInfo* request,
if (!callback.func)
return PP_ERROR_BADARGUMENT;
- WebFrame* frame = instance_->container()->element().document().frame();
+ WebFrame* frame = GetFrame(instance_);
if (!frame)
return PP_ERROR_FAILED;
WebURLRequest web_request(request->ToWebURLRequest(frame));
- // Check if we are allowed to access this URL.
- if (!has_universal_access_ &&
- !frame->securityOrigin().canRequest(web_request.url()))
- return PP_ERROR_NOACCESS;
+ int32_t rv = CanRequest(frame, web_request.url());
+ if (rv != PP_OK)
+ return rv;
frame->dispatchWillSendRequest(web_request);
@@ -238,8 +242,10 @@ int32_t URLLoader::Open(URLRequestInfo* request,
loader_.reset(WebKit::webKitClient()->createURLLoader());
if (!loader_.get())
return PP_ERROR_FAILED;
+
loader_->loadAsynchronously(web_request, this);
+ request_info_ = scoped_refptr<URLRequestInfo>(request);
pending_callback_ = callback;
record_download_progress_ = request->record_download_progress();
record_upload_progress_ = request->record_upload_progress();
@@ -249,8 +255,22 @@ int32_t URLLoader::Open(URLRequestInfo* request,
}
int32_t URLLoader::FollowRedirect(PP_CompletionCallback callback) {
- NOTIMPLEMENTED(); // TODO(darin): Implement me.
- return PP_ERROR_FAILED;
+ if (pending_callback_.func)
+ return PP_ERROR_INPROGRESS;
+
+ // We only support non-blocking calls.
+ if (!callback.func)
+ return PP_ERROR_BADARGUMENT;
+
+ WebURL redirect_url = GURL(response_info_->redirect_url());
+
+ int32_t rv = CanRequest(GetFrame(instance_), redirect_url);
+ if (rv != PP_OK)
+ return rv;
+
+ pending_callback_ = callback;
+ loader_->setDefersLoading(false); // Allow the redirect to continue.
+ return PP_ERROR_WOULDBLOCK;
}
bool URLLoader::GetUploadProgress(int64_t* bytes_sent,
@@ -342,7 +362,17 @@ void URLLoader::SetStatusCallback(PP_URLLoaderTrusted_StatusCallback cb) {
void URLLoader::willSendRequest(WebURLLoader* loader,
WebURLRequest& new_request,
const WebURLResponse& redirect_response) {
- NOTIMPLEMENTED(); // TODO(darin): Allow the plugin to inspect redirects.
+ if (!request_info_->follow_redirects()) {
+ SaveResponse(redirect_response);
+ loader_->setDefersLoading(true);
+ RunCallback(PP_OK);
+ } else {
+ int32_t rv = CanRequest(GetFrame(instance_), new_request.url());
+ if (rv != PP_OK) {
+ loader_->setDefersLoading(true);
+ RunCallback(rv);
+ }
+ }
}
void URLLoader::didSendData(WebURLLoader* loader,
@@ -356,9 +386,7 @@ void URLLoader::didSendData(WebURLLoader* loader,
void URLLoader::didReceiveResponse(WebURLLoader* loader,
const WebURLResponse& response) {
- scoped_refptr<URLResponseInfo> response_info(new URLResponseInfo(module()));
- if (response_info->Initialize(response))
- response_info_ = response_info;
+ SaveResponse(response);
// Sets -1 if the content length is unknown.
total_bytes_to_be_received_ = response.expectedContentLength();
@@ -420,6 +448,22 @@ size_t URLLoader::FillUserBuffer() {
return bytes_to_copy;
}
+void URLLoader::SaveResponse(const WebKit::WebURLResponse& response) {
+ scoped_refptr<URLResponseInfo> response_info(new URLResponseInfo(module()));
+ if (response_info->Initialize(response))
+ response_info_ = response_info;
+}
+
+// Checks that the client can request the URL. Returns a PPAPI error code.
+int32_t URLLoader::CanRequest(const WebKit::WebFrame* frame,
+ const WebKit::WebURL& url) {
+ if (!has_universal_access_ &&
+ !frame->securityOrigin().canRequest(url))
+ return PP_ERROR_NOACCESS;
+
+ return PP_OK;
+}
+
void URLLoader::UpdateStatus() {
if (status_callback_ &&
(record_download_progress_ || record_upload_progress_)) {
diff --git a/webkit/glue/plugins/pepper_url_loader.h b/webkit/glue/plugins/pepper_url_loader.h
index e018555..fbeb163 100644
--- a/webkit/glue/plugins/pepper_url_loader.h
+++ b/webkit/glue/plugins/pepper_url_loader.h
@@ -10,13 +10,17 @@
#include "base/scoped_ptr.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/dev/ppb_url_loader_trusted_dev.h"
-#include "third_party/WebKit/WebKit/chromium/public/WebURLLoader.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h"
#include "webkit/glue/plugins/pepper_resource.h"
struct PPB_URLLoader_Dev;
struct PPB_URLLoaderTrusted_Dev;
+namespace WebKit {
+class WebFrame;
+class WebURL;
+}
+
namespace pepper {
class PluginInstance;
@@ -80,6 +84,11 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient {
void RunCallback(int32_t result);
size_t FillUserBuffer();
+ // Converts a WebURLResponse to a URLResponseInfo and saves it.
+ void SaveResponse(const WebKit::WebURLResponse& response);
+
+ int32_t CanRequest(const WebKit::WebFrame* frame, const WebKit::WebURL& url);
+
// Calls the status_callback_ (if any) with the current upload and download
// progress. Call this function if you update any of these values to
// synchronize an out-of-process plugin's state.
@@ -90,6 +99,7 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient {
// wrapping the main document's loader (i.e. loader_ is null).
bool main_document_loader_;
scoped_ptr<WebKit::WebURLLoader> loader_;
+ scoped_refptr<URLRequestInfo> request_info_;
scoped_refptr<URLResponseInfo> response_info_;
PP_CompletionCallback pending_callback_;
std::deque<char> buffer_;
diff --git a/webkit/glue/plugins/pepper_url_request_info.cc b/webkit/glue/plugins/pepper_url_request_info.cc
index a7a6589..ae0c280 100644
--- a/webkit/glue/plugins/pepper_url_request_info.cc
+++ b/webkit/glue/plugins/pepper_url_request_info.cc
@@ -155,6 +155,7 @@ struct URLRequestInfo::BodyItem {
URLRequestInfo::URLRequestInfo(PluginModule* module)
: Resource(module),
stream_to_file_(false),
+ follow_redirects_(true),
record_download_progress_(false),
record_upload_progress_(false) {
}
@@ -173,6 +174,9 @@ bool URLRequestInfo::SetBooleanProperty(PP_URLRequestProperty_Dev property,
case PP_URLREQUESTPROPERTY_STREAMTOFILE:
stream_to_file_ = value;
return true;
+ case PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS:
+ follow_redirects_ = value;
+ return true;
case PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS:
record_download_progress_ = value;
return true;
diff --git a/webkit/glue/plugins/pepper_url_request_info.h b/webkit/glue/plugins/pepper_url_request_info.h
index 067756f..4fd4e26 100644
--- a/webkit/glue/plugins/pepper_url_request_info.h
+++ b/webkit/glue/plugins/pepper_url_request_info.h
@@ -44,6 +44,8 @@ class URLRequestInfo : public Resource {
WebKit::WebURLRequest ToWebURLRequest(WebKit::WebFrame* frame) const;
+ bool follow_redirects() { return follow_redirects_; }
+
bool record_download_progress() const { return record_download_progress_; }
bool record_upload_progress() const { return record_upload_progress_; }
@@ -57,6 +59,7 @@ class URLRequestInfo : public Resource {
Body body_;
bool stream_to_file_;
+ bool follow_redirects_;
bool record_download_progress_;
bool record_upload_progress_;
};
diff --git a/webkit/glue/plugins/pepper_url_response_info.cc b/webkit/glue/plugins/pepper_url_response_info.cc
index ee27003..2e7202f 100644
--- a/webkit/glue/plugins/pepper_url_response_info.cc
+++ b/webkit/glue/plugins/pepper_url_response_info.cc
@@ -73,6 +73,10 @@ const PPB_URLResponseInfo_Dev ppb_urlresponseinfo = {
&GetBody
};
+bool IsRedirect(int32_t status) {
+ return status >= 300 && status <= 399;
+}
+
} // namespace
URLResponseInfo::URLResponseInfo(PluginModule* module)
@@ -92,19 +96,33 @@ PP_Var URLResponseInfo::GetProperty(PP_URLResponseProperty_Dev property) {
switch (property) {
case PP_URLRESPONSEPROPERTY_URL:
return StringVar::StringToPPVar(module(), url_);
+ case PP_URLRESPONSEPROPERTY_REDIRECTURL:
+ if (IsRedirect(status_code_))
+ return StringVar::StringToPPVar(module(), redirect_url_);
+ break;
+ case PP_URLRESPONSEPROPERTY_REDIRECTMETHOD:
+ if (IsRedirect(status_code_))
+ return StringVar::StringToPPVar(module(), status_text_);
+ break;
case PP_URLRESPONSEPROPERTY_STATUSCODE:
return PP_MakeInt32(status_code_);
+ case PP_URLRESPONSEPROPERTY_STATUSLINE:
+ return StringVar::StringToPPVar(module(), status_text_);
case PP_URLRESPONSEPROPERTY_HEADERS:
return StringVar::StringToPPVar(module(), headers_);
- default:
- NOTIMPLEMENTED(); // TODO(darin): Implement me!
- return PP_MakeUndefined();
}
+ // The default is to return an undefined PP_Var.
+ return PP_MakeUndefined();
}
bool URLResponseInfo::Initialize(const WebURLResponse& response) {
url_ = response.url().spec();
status_code_ = response.httpStatusCode();
+ status_text_ = response.httpStatusText().utf8();
+ if (IsRedirect(status_code_)) {
+ redirect_url_ = response.httpHeaderField(
+ WebString::fromUTF8("Location")).utf8();
+ }
HeaderFlattener flattener;
response.visitHTTPHeaderFields(&flattener);
diff --git a/webkit/glue/plugins/pepper_url_response_info.h b/webkit/glue/plugins/pepper_url_response_info.h
index b73ec67..ff3a832 100644
--- a/webkit/glue/plugins/pepper_url_response_info.h
+++ b/webkit/glue/plugins/pepper_url_response_info.h
@@ -35,10 +35,14 @@ class URLResponseInfo : public Resource {
FileRef* body() { return body_; }
+ std::string redirect_url() { return redirect_url_; }
+
private:
std::string url_;
std::string headers_;
int32_t status_code_;
+ std::string status_text_;
+ std::string redirect_url_;
scoped_refptr<FileRef> body_;
};