// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ppapi/proxy/ppb_url_request_info_proxy.h" #include "ppapi/c/ppb_url_request_info.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/ppapi_messages.h" namespace pp { namespace proxy { class URLRequestInfo : public PluginResource { public: URLRequestInfo(const HostResource& resource) : PluginResource(resource) { } virtual ~URLRequestInfo() { } // Resource overrides. virtual URLRequestInfo* AsURLRequestInfo() { return this; } private: DISALLOW_COPY_AND_ASSIGN(URLRequestInfo); }; namespace { // Computes the dispatcher and request object for the given plugin resource, // returning true on success. bool DispatcherFromURLRequestInfo(PP_Resource resource, PluginDispatcher** dispatcher, URLRequestInfo** request_info) { *request_info = PluginResource::GetAs(resource); if (!*request_info) return false; *dispatcher = PluginDispatcher::GetForInstance((*request_info)->instance()); return !!*dispatcher; } PP_Resource Create(PP_Instance instance) { PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); if (!dispatcher) return 0; HostResource result; dispatcher->Send(new PpapiHostMsg_PPBURLRequestInfo_Create( INTERFACE_ID_PPB_URL_REQUEST_INFO, instance, &result)); if (result.is_null()) return 0; linked_ptr object(new URLRequestInfo(result)); return PluginResourceTracker::GetInstance()->AddResource(object); } PP_Bool IsURLRequestInfo(PP_Resource resource) { URLRequestInfo* object = PluginResource::GetAs(resource); return BoolToPPBool(!!object); } PP_Bool SetProperty(PP_Resource request_id, PP_URLRequestProperty property, PP_Var var) { PluginDispatcher* dispatcher; URLRequestInfo* request_info; if (!DispatcherFromURLRequestInfo(request_id, &dispatcher, &request_info)) return PP_FALSE; dispatcher->Send(new PpapiHostMsg_PPBURLRequestInfo_SetProperty( INTERFACE_ID_PPB_URL_REQUEST_INFO, request_info->host_resource(), static_cast(property), SerializedVarSendInput(dispatcher, var))); // TODO(brettw) do some validation on the types. We should be able to tell on // the plugin side whether the request will succeed or fail in the renderer. return PP_TRUE; } PP_Bool AppendDataToBody(PP_Resource request_id, const char* data, uint32_t len) { PluginDispatcher* dispatcher; URLRequestInfo* request_info; if (!DispatcherFromURLRequestInfo(request_id, &dispatcher, &request_info)) return PP_FALSE; dispatcher->Send(new PpapiHostMsg_PPBURLRequestInfo_AppendDataToBody( INTERFACE_ID_PPB_URL_REQUEST_INFO, request_info->host_resource(), std::string(data, len))); // TODO(brettw) do some validation. We should be able to tell on the plugin // side whether the request will succeed or fail in the renderer. return PP_TRUE; } PP_Bool AppendFileToBody(PP_Resource request_id, PP_Resource file_ref_id, int64_t start_offset, int64_t number_of_bytes, PP_Time expected_last_modified_time) { PluginDispatcher* dispatcher; URLRequestInfo* request_info; if (!DispatcherFromURLRequestInfo(request_id, &dispatcher, &request_info)) return PP_FALSE; PluginResource* file_ref_object = PluginResourceTracker::GetInstance()->GetResourceObject(file_ref_id); if (!file_ref_object) return PP_FALSE; dispatcher->Send(new PpapiHostMsg_PPBURLRequestInfo_AppendFileToBody( INTERFACE_ID_PPB_URL_REQUEST_INFO, request_info->host_resource(), file_ref_object->host_resource(), start_offset, number_of_bytes, expected_last_modified_time)); // TODO(brettw) do some validation. We should be able to tell on the plugin // side whether the request will succeed or fail in the renderer. return PP_TRUE; } const PPB_URLRequestInfo urlrequestinfo_interface = { &Create, &IsURLRequestInfo, &SetProperty, &AppendDataToBody, &AppendFileToBody }; InterfaceProxy* CreateURLRequestInfoProxy(Dispatcher* dispatcher, const void* target_interface) { return new PPB_URLRequestInfo_Proxy(dispatcher, target_interface); } } // namespace PPB_URLRequestInfo_Proxy::PPB_URLRequestInfo_Proxy( Dispatcher* dispatcher, const void* target_interface) : InterfaceProxy(dispatcher, target_interface) { } PPB_URLRequestInfo_Proxy::~PPB_URLRequestInfo_Proxy() { } // static const InterfaceProxy::Info* PPB_URLRequestInfo_Proxy::GetInfo() { static const Info info = { &urlrequestinfo_interface, PPB_URLREQUESTINFO_INTERFACE, INTERFACE_ID_PPB_URL_REQUEST_INFO, false, &CreateURLRequestInfoProxy, }; return &info; } bool PPB_URLRequestInfo_Proxy::OnMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPB_URLRequestInfo_Proxy, msg) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLRequestInfo_Create, OnMsgCreate) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLRequestInfo_SetProperty, OnMsgSetProperty) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLRequestInfo_AppendDataToBody, OnMsgAppendDataToBody) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLRequestInfo_AppendFileToBody, OnMsgAppendFileToBody) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() // TODO(brettw): handle bad messages. return handled; } void PPB_URLRequestInfo_Proxy::OnMsgCreate( PP_Instance instance, HostResource* result) { result->SetHostResource(instance, ppb_url_request_info_target()->Create(instance)); } void PPB_URLRequestInfo_Proxy::OnMsgSetProperty( HostResource request, int32_t property, SerializedVarReceiveInput value) { ppb_url_request_info_target()->SetProperty(request.host_resource(), static_cast(property), value.Get(dispatcher())); } void PPB_URLRequestInfo_Proxy::OnMsgAppendDataToBody( HostResource request, const std::string& data) { ppb_url_request_info_target()->AppendDataToBody(request.host_resource(), data.c_str(), data.size()); } void PPB_URLRequestInfo_Proxy::OnMsgAppendFileToBody( HostResource request, HostResource file_ref, int64_t start_offset, int64_t number_of_bytes, double expected_last_modified_time) { ppb_url_request_info_target()->AppendFileToBody( request.host_resource(), file_ref.host_resource(), start_offset, number_of_bytes, expected_last_modified_time); } } // namespace proxy } // namespace pp