| Index: webkit/glue/plugins/pepper_url_loader.cc
|
| ===================================================================
|
| --- webkit/glue/plugins/pepper_url_loader.cc (revision 51226)
|
| +++ webkit/glue/plugins/pepper_url_loader.cc (working copy)
|
| @@ -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 @@
|
|
|
| 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() {
|
| }
|
|
|
| +// 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::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
|
|
|