summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-30 04:55:29 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-30 04:55:29 +0000
commita033865a389642cc4160901e3343c8635cc005e0 (patch)
tree59cc21d4dca5e8965d9f2c612fd62f357c8bb67f
parent71e4087a14a8e82c95869ce133c4077397830ff2 (diff)
downloadchromium_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.h2
-rw-r--r--webkit/glue/plugins/pepper_url_loader.cc136
-rw-r--r--webkit/glue/plugins/pepper_url_loader.h36
-rw-r--r--webkit/glue/plugins/pepper_url_request_info.cc43
-rw-r--r--webkit/glue/plugins/pepper_url_request_info.h14
-rw-r--r--webkit/glue/resource_loader_bridge.h2
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.