This source file includes following definitions.
- weak_factory_
- OnResourceMessageReceived
- willSendRequest
- didSendData
- didReceiveResponse
- didDownloadData
- didReceiveData
- didFinishLoading
- didFail
- DidConnectPendingHostToResource
- OnHostMsgOpen
- InternalOnHostMsgOpen
- OnHostMsgSetDeferLoading
- OnHostMsgClose
- OnHostMsgGrantUniversalAccess
- SendUpdateToPlugin
- SendOrderedUpdateToPlugin
- Close
- GetFrame
- SetDefersLoading
- SaveResponse
- DidDataFromWebURLResponse
- UpdateProgress
#include "content/renderer/pepper/pepper_url_loader_host.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
#include "content/renderer/pepper/url_request_info_util.h"
#include "content/renderer/pepper/url_response_info_util.h"
#include "net/base/net_errors.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLLoader.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"
#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
#include "third_party/WebKit/public/web/WebURLLoaderOptions.h"
using blink::WebFrame;
using blink::WebString;
using blink::WebURL;
using blink::WebURLError;
using blink::WebURLLoader;
using blink::WebURLLoaderOptions;
using blink::WebURLRequest;
using blink::WebURLResponse;
#ifdef _MSC_VER
#pragma warning(disable : 4996)
#endif
namespace content {
PepperURLLoaderHost::PepperURLLoaderHost(RendererPpapiHostImpl* host,
bool main_document_loader,
PP_Instance instance,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
renderer_ppapi_host_(host),
main_document_loader_(main_document_loader),
has_universal_access_(false),
bytes_sent_(0),
total_bytes_to_be_sent_(-1),
bytes_received_(0),
total_bytes_to_be_received_(-1),
pending_response_(false),
weak_factory_(this) {
DCHECK((main_document_loader && !resource) ||
(!main_document_loader && resource));
}
PepperURLLoaderHost::~PepperURLLoaderHost() {
if (main_document_loader_) {
PepperPluginInstanceImpl* instance_object =
renderer_ppapi_host_->GetPluginInstanceImpl(pp_instance());
if (instance_object) {
DCHECK(instance_object->document_loader() == this);
instance_object->set_document_loader(NULL);
}
}
scoped_ptr<blink::WebURLLoader> for_destruction_only(loader_.release());
}
int32_t PepperURLLoaderHost::OnResourceMessageReceived(
const IPC::Message& msg,
ppapi::host::HostMessageContext* context) {
IPC_BEGIN_MESSAGE_MAP(PepperURLLoaderHost, msg)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
PpapiHostMsg_URLLoader_Open,
OnHostMsgOpen)
PPAPI_DISPATCH_HOST_RESOURCE_CALL(
PpapiHostMsg_URLLoader_SetDeferLoading,
OnHostMsgSetDeferLoading)
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
PpapiHostMsg_URLLoader_Close,
OnHostMsgClose);
PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
PpapiHostMsg_URLLoader_GrantUniversalAccess,
OnHostMsgGrantUniversalAccess)
IPC_END_MESSAGE_MAP()
return PP_ERROR_FAILED;
}
void PepperURLLoaderHost::willSendRequest(
WebURLLoader* loader,
WebURLRequest& new_request,
const WebURLResponse& redirect_response) {
DCHECK(out_of_order_replies_.empty());
if (!request_data_.follow_redirects) {
SaveResponse(redirect_response);
SetDefersLoading(true);
}
}
void PepperURLLoaderHost::didSendData(
WebURLLoader* loader,
unsigned long long bytes_sent,
unsigned long long total_bytes_to_be_sent) {
bytes_sent_ = static_cast<int64_t>(bytes_sent);
total_bytes_to_be_sent_ = static_cast<int64_t>(total_bytes_to_be_sent);
UpdateProgress();
}
void PepperURLLoaderHost::didReceiveResponse(WebURLLoader* loader,
const WebURLResponse& response) {
total_bytes_to_be_received_ = response.expectedContentLength();
UpdateProgress();
SaveResponse(response);
}
void PepperURLLoaderHost::didDownloadData(WebURLLoader* loader,
int data_length,
int encoded_data_length) {
bytes_received_ += data_length;
UpdateProgress();
}
void PepperURLLoaderHost::didReceiveData(WebURLLoader* loader,
const char* data,
int data_length,
int encoded_data_length) {
bytes_received_ += data_length;
UpdateProgress();
PpapiPluginMsg_URLLoader_SendData* message =
new PpapiPluginMsg_URLLoader_SendData;
message->WriteData(data, data_length);
SendUpdateToPlugin(message);
}
void PepperURLLoaderHost::didFinishLoading(WebURLLoader* loader,
double finish_time,
int64_t total_encoded_data_length) {
SendUpdateToPlugin(new PpapiPluginMsg_URLLoader_FinishedLoading(PP_OK));
}
void PepperURLLoaderHost::didFail(WebURLLoader* loader,
const WebURLError& error) {
int32_t pp_error = PP_ERROR_FAILED;
if (error.domain.equals(WebString::fromUTF8(net::kErrorDomain))) {
switch (error.reason) {
case net::ERR_ACCESS_DENIED:
case net::ERR_NETWORK_ACCESS_DENIED:
pp_error = PP_ERROR_NOACCESS;
break;
}
} else {
pp_error = PP_ERROR_NOACCESS;
}
SendUpdateToPlugin(new PpapiPluginMsg_URLLoader_FinishedLoading(pp_error));
}
void PepperURLLoaderHost::DidConnectPendingHostToResource() {
for (size_t i = 0; i < pending_replies_.size(); i++)
host()->SendUnsolicitedReply(pp_resource(), *pending_replies_[i]);
pending_replies_.clear();
}
int32_t PepperURLLoaderHost::OnHostMsgOpen(
ppapi::host::HostMessageContext* context,
const ppapi::URLRequestInfoData& request_data) {
int32_t ret = InternalOnHostMsgOpen(context, request_data);
DCHECK(ret != PP_OK_COMPLETIONPENDING);
if (ret != PP_OK)
SendUpdateToPlugin(new PpapiPluginMsg_URLLoader_FinishedLoading(ret));
return PP_OK;
}
int32_t PepperURLLoaderHost::InternalOnHostMsgOpen(
ppapi::host::HostMessageContext* context,
const ppapi::URLRequestInfoData& request_data) {
if (main_document_loader_)
return PP_ERROR_INPROGRESS;
ppapi::URLRequestInfoData filled_in_request_data = request_data;
if (URLRequestRequiresUniversalAccess(filled_in_request_data) &&
!has_universal_access_) {
ppapi::PpapiGlobals::Get()->LogWithSource(
pp_instance(), PP_LOGLEVEL_ERROR, std::string(),
"PPB_URLLoader.Open: The URL you're requesting is "
" on a different security origin than your plugin. To request "
" cross-origin resources, see "
" PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS.");
return PP_ERROR_NOACCESS;
}
if (loader_.get())
return PP_ERROR_INPROGRESS;
WebFrame* frame = GetFrame();
if (!frame)
return PP_ERROR_FAILED;
WebURLRequest web_request;
if (!CreateWebURLRequest(pp_instance(),
&filled_in_request_data,
frame,
&web_request)) {
return PP_ERROR_FAILED;
}
web_request.setTargetType(WebURLRequest::TargetIsObject);
web_request.setRequestorProcessID(renderer_ppapi_host_->GetPluginPID());
WebURLLoaderOptions options;
if (has_universal_access_) {
options.allowCredentials = true;
options.crossOriginRequestPolicy =
WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
} else {
options.untrustedHTTP = true;
if (filled_in_request_data.allow_cross_origin_requests) {
options.allowCredentials = filled_in_request_data.allow_credentials;
options.crossOriginRequestPolicy =
WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
} else {
options.allowCredentials = true;
}
}
loader_.reset(frame->createAssociatedURLLoader(options));
if (!loader_.get())
return PP_ERROR_FAILED;
request_data_ = filled_in_request_data;
loader_->loadAsynchronously(web_request, this);
return PP_OK;
}
int32_t PepperURLLoaderHost::OnHostMsgSetDeferLoading(
ppapi::host::HostMessageContext* context,
bool defers_loading) {
SetDefersLoading(defers_loading);
return PP_OK;
}
int32_t PepperURLLoaderHost::OnHostMsgClose(
ppapi::host::HostMessageContext* context) {
Close();
return PP_OK;
}
int32_t PepperURLLoaderHost::OnHostMsgGrantUniversalAccess(
ppapi::host::HostMessageContext* context) {
if (!host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE))
return PP_ERROR_FAILED;
has_universal_access_ = true;
return PP_OK;
}
void PepperURLLoaderHost::SendUpdateToPlugin(IPC::Message* message) {
if (message->type() == PpapiPluginMsg_URLLoader_SendData::ID ||
message->type() == PpapiPluginMsg_URLLoader_FinishedLoading::ID) {
if (pending_response_) {
out_of_order_replies_.push_back(message);
} else {
SendOrderedUpdateToPlugin(message);
}
} else if (message->type() == PpapiPluginMsg_URLLoader_ReceivedResponse::ID) {
DCHECK(pending_response_);
SendOrderedUpdateToPlugin(message);
for (size_t i = 0; i < out_of_order_replies_.size(); i++)
SendOrderedUpdateToPlugin(out_of_order_replies_[i]);
out_of_order_replies_.weak_clear();
pending_response_ = false;
} else {
SendOrderedUpdateToPlugin(message);
}
}
void PepperURLLoaderHost::SendOrderedUpdateToPlugin(IPC::Message* message) {
if (pp_resource() == 0) {
pending_replies_.push_back(message);
} else {
host()->SendUnsolicitedReply(pp_resource(), *message);
delete message;
}
}
void PepperURLLoaderHost::Close() {
if (loader_.get())
loader_->cancel();
else if (main_document_loader_)
GetFrame()->stopLoading();
}
blink::WebFrame* PepperURLLoaderHost::GetFrame() {
PepperPluginInstance* instance_object =
renderer_ppapi_host_->GetPluginInstance(pp_instance());
if (!instance_object)
return NULL;
return instance_object->GetContainer()->element().document().frame();
}
void PepperURLLoaderHost::SetDefersLoading(bool defers_loading) {
if (loader_.get())
loader_->setDefersLoading(defers_loading);
}
void PepperURLLoaderHost::SaveResponse(const WebURLResponse& response) {
if (!main_document_loader_) {
DCHECK(!pending_response_);
pending_response_ = true;
DataFromWebURLResponse(
renderer_ppapi_host_,
pp_instance(),
response,
base::Bind(&PepperURLLoaderHost::DidDataFromWebURLResponse,
weak_factory_.GetWeakPtr()));
}
}
void PepperURLLoaderHost::DidDataFromWebURLResponse(
const ppapi::URLResponseInfoData& data) {
SendUpdateToPlugin(new PpapiPluginMsg_URLLoader_ReceivedResponse(data));
}
void PepperURLLoaderHost::UpdateProgress() {
bool record_download = request_data_.record_download_progress;
bool record_upload = request_data_.record_upload_progress;
if (record_download || record_upload) {
ppapi::proxy::ResourceMessageReplyParams params;
SendUpdateToPlugin(new PpapiPluginMsg_URLLoader_UpdateProgress(
record_upload ? bytes_sent_ : -1,
record_upload ? total_bytes_to_be_sent_ : -1,
record_download ? bytes_received_ : -1,
record_download ? total_bytes_to_be_received_ : -1));
}
}
}