diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-30 04:55:29 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-30 04:55:29 +0000 |
commit | a033865a389642cc4160901e3343c8635cc005e0 (patch) | |
tree | 59cc21d4dca5e8965d9f2c612fd62f357c8bb67f | |
parent | 71e4087a14a8e82c95869ce133c4077397830ff2 (diff) | |
download | chromium_src-a033865a389642cc4160901e3343c8635cc005e0.zip chromium_src-a033865a389642cc4160901e3343c8635cc005e0.tar.gz chromium_src-a033865a389642cc4160901e3343c8635cc005e0.tar.bz2 |
Add basic Pepper URLLoader implementation.
R=jam
BUG=47222
TEST=none
Review URL: http://codereview.chromium.org/2861036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51228 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_instance.h | 2 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_url_loader.cc | 136 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_url_loader.h | 36 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_url_request_info.cc | 43 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_url_request_info.h | 14 | ||||
-rw-r--r-- | webkit/glue/resource_loader_bridge.h | 2 |
6 files changed, 219 insertions, 14 deletions
diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h index aaf9bc0..bc55025 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.h +++ b/webkit/glue/plugins/pepper_plugin_instance.h @@ -50,6 +50,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> { PluginDelegate* delegate() const { return delegate_; } PluginModule* module() const { return module_.get(); } + WebKit::WebPluginContainer* container() const { return container_; } + const gfx::Rect& position() const { return position_; } const gfx::Rect& clip() const { return clip_; } diff --git a/webkit/glue/plugins/pepper_url_loader.cc b/webkit/glue/plugins/pepper_url_loader.cc index 4c38ef4..f9b6d22 100644 --- a/webkit/glue/plugins/pepper_url_loader.cc +++ b/webkit/glue/plugins/pepper_url_loader.cc @@ -8,10 +8,28 @@ #include "third_party/ppapi/c/pp_completion_callback.h" #include "third_party/ppapi/c/pp_errors.h" #include "third_party/ppapi/c/ppb_url_loader.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" +#include "third_party/WebKit/WebKit/chromium/public/WebElement.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebKit.h" +#include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_url_request_info.h" #include "webkit/glue/plugins/pepper_url_response_info.h" +using WebKit::WebFrame; +using WebKit::WebURL; +using WebKit::WebURLError; +using WebKit::WebURLLoader; +using WebKit::WebURLRequest; +using WebKit::WebURLResponse; + +#ifdef _MSC_VER +// Do not warn about use of std::copy with raw pointers. +#pragma warning(disable : 4996) +#endif + namespace pepper { namespace { @@ -127,6 +145,8 @@ const PPB_URLLoader ppb_urlloader = { URLLoader::URLLoader(PluginInstance* instance) : Resource(instance->module()), + instance_(instance), + pending_callback_(), bytes_sent_(0), total_bytes_to_be_sent_(0), bytes_received_(0), @@ -136,10 +156,39 @@ URLLoader::URLLoader(PluginInstance* instance) URLLoader::~URLLoader() { } +// static +const PPB_URLLoader* URLLoader::GetInterface() { + return &ppb_urlloader; +} + int32_t URLLoader::Open(URLRequestInfo* request, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me. - return PP_Error_Failed; + if (loader_.get()) + return PP_Error_InProgress; + + // We only support non-blocking calls. + if (!callback.func) + return PP_Error_BadArgument; + + WebURLRequest web_request(request->web_request()); + + WebFrame* frame = instance_->container()->element().document().frame(); + if (!frame) + return PP_Error_Failed; + frame->setReferrerForRequest(web_request, WebURL()); // Use default. + frame->dispatchWillSendRequest(web_request); + + loader_.reset(WebKit::webKitClient()->createURLLoader()); + if (!loader_.get()) { + loader_.reset(); + return PP_Error_Failed; + } + loader_->loadAsynchronously(web_request, this); + + pending_callback_ = callback; + + // Notify completion when we receive a redirect or response headers. + return PP_Error_WouldBlock; } int32_t URLLoader::FollowRedirect(PP_CompletionCallback callback) { @@ -149,17 +198,90 @@ int32_t URLLoader::FollowRedirect(PP_CompletionCallback callback) { int32_t URLLoader::ReadResponseBody(char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me. - return PP_Error_Failed; + if (bytes_to_read <= 0 || !buffer) + return PP_Error_BadArgument; + if (pending_callback_.func) + return PP_Error_InProgress; + + // We only support non-blocking calls. + if (!callback.func) + return PP_Error_BadArgument; + + user_buffer_ = buffer; + user_buffer_size_ = bytes_to_read; + + if (!buffer_.empty()) + return FillUserBuffer(); + + pending_callback_ = callback; + return PP_Error_WouldBlock; } void URLLoader::Close() { NOTIMPLEMENTED(); // TODO(darin): Implement me. } -// static -const PPB_URLLoader* URLLoader::GetInterface() { - return &ppb_urlloader; +void URLLoader::RunCallback(int32_t result) { + if (!pending_callback_.func) + return; + + PP_CompletionCallback callback = {0}; + std::swap(callback, pending_callback_); + PP_RunCompletionCallback(&callback, result); +} + +size_t URLLoader::FillUserBuffer() { + DCHECK(user_buffer_); + DCHECK(user_buffer_size_); + + size_t bytes_to_copy = std::min(buffer_.size(), user_buffer_size_); + std::copy(buffer_.begin(), buffer_.begin() + bytes_to_copy, user_buffer_); + buffer_.erase(buffer_.begin(), buffer_.begin() + bytes_to_copy); + + // Reset for next time. + user_buffer_ = NULL; + user_buffer_size_ = 0; + return bytes_to_copy; +} + +void URLLoader::willSendRequest(WebURLLoader* loader, + WebURLRequest& new_request, + const WebURLResponse& redirect_response) { + NOTIMPLEMENTED(); // TODO(darin): Allow the plugin to inspect redirects. +} + +void URLLoader::didSendData(WebURLLoader* loader, + unsigned long long bytes_sent, + unsigned long long total_bytes_to_be_sent) { + // TODO(darin): Bounds check input? + bytes_sent_ = static_cast<int64_t>(bytes_sent); + total_bytes_to_be_sent_ = static_cast<int64_t>(total_bytes_to_be_sent); +} + +void URLLoader::didReceiveResponse(WebURLLoader* loader, + const WebURLResponse& response) { + // TODO(darin): Initialize response_info_. + RunCallback(PP_OK); +} + +void URLLoader::didReceiveData(WebURLLoader* loader, + const char* data, + int data_length) { + buffer_.insert(buffer_.end(), data, data + data_length); + if (user_buffer_) { + RunCallback(FillUserBuffer()); + } else { + DCHECK(!pending_callback_.func); + } +} + +void URLLoader::didFinishLoading(WebURLLoader* loader) { + RunCallback(PP_OK); +} + +void URLLoader::didFail(WebURLLoader* loader, const WebURLError& error) { + // TODO(darin): Provide more detailed error information. + RunCallback(PP_Error_Failed); } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_url_loader.h b/webkit/glue/plugins/pepper_url_loader.h index 9ba1d00b..3bb05ac 100644 --- a/webkit/glue/plugins/pepper_url_loader.h +++ b/webkit/glue/plugins/pepper_url_loader.h @@ -5,9 +5,14 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_URL_LOADER_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_URL_LOADER_H_ +#include <deque> + +#include "base/scoped_ptr.h" +#include "third_party/ppapi/c/pp_completion_callback.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" -typedef struct _pp_CompletionCallback PP_CompletionCallback; typedef struct _ppb_URLLoader PPB_URLLoader; namespace pepper { @@ -16,7 +21,7 @@ class PluginInstance; class URLRequestInfo; class URLResponseInfo; -class URLLoader : public Resource { +class URLLoader : public Resource, public WebKit::WebURLLoaderClient { public: explicit URLLoader(PluginInstance* instance); virtual ~URLLoader(); @@ -37,7 +42,7 @@ class URLLoader : public Resource { URLResponseInfo* response_info() const { return response_info_; } - // Progress counters: + // Progress counters. int64_t bytes_sent() const { return bytes_sent_; } int64_t total_bytes_to_be_sent() const { return total_bytes_to_be_sent_; } int64_t bytes_received() const { return bytes_received_; } @@ -46,11 +51,36 @@ class URLLoader : public Resource { } private: + void RunCallback(int32_t result); + size_t FillUserBuffer(); + + // WebKit::WebURLLoaderClient implementation. + virtual void willSendRequest(WebKit::WebURLLoader* loader, + WebKit::WebURLRequest& new_request, + const WebKit::WebURLResponse& redir_response); + virtual void didSendData(WebKit::WebURLLoader* loader, + unsigned long long bytes_sent, + unsigned long long total_bytes_to_be_sent); + virtual void didReceiveResponse(WebKit::WebURLLoader* loader, + const WebKit::WebURLResponse& response); + virtual void didReceiveData(WebKit::WebURLLoader* loader, + const char* data, + int data_length); + virtual void didFinishLoading(WebKit::WebURLLoader* loader); + virtual void didFail(WebKit::WebURLLoader* loader, + const WebKit::WebURLError& error); + + scoped_refptr<PluginInstance> instance_; + scoped_ptr<WebKit::WebURLLoader> loader_; scoped_refptr<URLResponseInfo> response_info_; + PP_CompletionCallback pending_callback_; + std::deque<char> buffer_; int64_t bytes_sent_; int64_t total_bytes_to_be_sent_; int64_t bytes_received_; int64_t total_bytes_to_be_received_; + char* user_buffer_; + size_t user_buffer_size_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_url_request_info.cc b/webkit/glue/plugins/pepper_url_request_info.cc index 0f48a7b..a95af65 100644 --- a/webkit/glue/plugins/pepper_url_request_info.cc +++ b/webkit/glue/plugins/pepper_url_request_info.cc @@ -5,11 +5,16 @@ #include "webkit/glue/plugins/pepper_url_request_info.h" #include "base/logging.h" +#include "googleurl/src/gurl.h" #include "third_party/ppapi/c/pp_var.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURL.h" +#include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_string.h" #include "webkit/glue/plugins/pepper_var.h" +using WebKit::WebString; + namespace pepper { namespace { @@ -64,8 +69,19 @@ bool AppendFileToBody(PP_Resource request_id, int64_t start_offset, int64_t number_of_bytes, PP_Time expected_last_modified_time) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return false; + scoped_refptr<URLRequestInfo> request( + Resource::GetAs<URLRequestInfo>(request_id)); + if (!request.get()) + return false; + + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref.get()) + return false; + + return request->AppendFileToBody(file_ref, + start_offset, + number_of_bytes, + expected_last_modified_time); } const PPB_URLRequestInfo ppb_urlrequestinfo = { @@ -80,6 +96,7 @@ const PPB_URLRequestInfo ppb_urlrequestinfo = { URLRequestInfo::URLRequestInfo(PluginModule* module) : Resource(module) { + web_request_.initialize(); } URLRequestInfo::~URLRequestInfo() { @@ -98,7 +115,19 @@ bool URLRequestInfo::SetBooleanProperty(PP_URLRequestProperty property, bool URLRequestInfo::SetStringProperty(PP_URLRequestProperty property, const std::string& value) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! + // TODO(darin): Validate input. Perhaps at a different layer? + switch (property) { + case PP_URLRequestProperty_URL: + web_request_.setURL(GURL(value)); + return true; + case PP_URLRequestProperty_Method: + web_request_.setHTTPMethod(WebString::fromUTF8(value)); + return true; + case PP_URLRequestProperty_Headers: + // TODO(darin): Support extra request headers + NOTIMPLEMENTED(); + return false; + } return false; } @@ -107,4 +136,12 @@ bool URLRequestInfo::AppendDataToBody(const std::string& data) { return false; } +bool URLRequestInfo::AppendFileToBody(FileRef* file_ref, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time) { + NOTIMPLEMENTED(); // TODO(darin): Implement me! + return false; +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_url_request_info.h b/webkit/glue/plugins/pepper_url_request_info.h index 4a63cee..c419ed2 100644 --- a/webkit/glue/plugins/pepper_url_request_info.h +++ b/webkit/glue/plugins/pepper_url_request_info.h @@ -8,10 +8,13 @@ #include <string> #include "third_party/ppapi/c/ppb_url_request_info.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" #include "webkit/glue/plugins/pepper_resource.h" namespace pepper { +class FileRef; + class URLRequestInfo : public Resource { public: explicit URLRequestInfo(PluginModule* module); @@ -29,6 +32,17 @@ class URLRequestInfo : public Resource { bool SetStringProperty(PP_URLRequestProperty property, const std::string& value); bool AppendDataToBody(const std::string& data); + bool AppendFileToBody(FileRef* file_ref, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time); + + const WebKit::WebURLRequest& web_request() const { + return web_request_; + } + + private: + WebKit::WebURLRequest web_request_; }; } // namespace pepper diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h index 1d76625..ba88271 100644 --- a/webkit/glue/resource_loader_bridge.h +++ b/webkit/glue/resource_loader_bridge.h @@ -79,7 +79,7 @@ class ResourceLoaderBridge { // Used for plugin to browser requests. uint32 request_context; - // Identifies that appcache host this request is associated with. + // Identifies what appcache host this request is associated with. int appcache_host_id; // Used to associated the bridge with a frame's network context. |