diff options
49 files changed, 1204 insertions, 942 deletions
diff --git a/chrome/test/nacl_test_injection/buildbot_nacl_integration.py b/chrome/test/nacl_test_injection/buildbot_nacl_integration.py index 1e572c6..36d4aaf 100755 --- a/chrome/test/nacl_test_injection/buildbot_nacl_integration.py +++ b/chrome/test/nacl_test_injection/buildbot_nacl_integration.py @@ -35,6 +35,9 @@ def Main(args): # See http://code.google.com/p/nativeclient/issues/detail?id=2124 # TODO(mseaborn): Reenable when this issue is resolved. tests_to_disable.append('run_ppapi_ppb_var_browser_test') + # Te behavior of the URLRequest changed slightly and this test needs to be + # updated. http://code.google.com/p/chromium/issues/detail?id=94352 + tests_to_disable.append('run_ppapi_ppb_url_request_info_browser_test') if sys.platform == 'darwin': # The following test is failing on Mac OS X 10.5. This may be diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index b4ab027..51fa35b 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -32,6 +32,8 @@ 'shared_impl/char_set_impl.h', 'shared_impl/crypto_impl.cc', 'shared_impl/crypto_impl.h', + 'shared_impl/file_ref_impl.cc', + 'shared_impl/file_ref_impl.h', 'shared_impl/font_impl.cc', 'shared_impl/font_impl.h', 'shared_impl/function_group_base.cc', @@ -63,6 +65,8 @@ 'shared_impl/time_conversion.h', 'shared_impl/tracker_base.cc', 'shared_impl/tracker_base.h', + 'shared_impl/url_request_info_impl.cc', + 'shared_impl/url_request_info_impl.h', 'shared_impl/url_util_impl.cc', 'shared_impl/url_util_impl.h', 'shared_impl/var.cc', diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index cd1efe1..f786163 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -34,6 +34,7 @@ #include "ppapi/proxy/serialized_structs.h" #include "ppapi/shared_impl/input_event_impl.h" #include "ppapi/shared_impl/ppapi_preferences.h" +#include "ppapi/shared_impl/url_request_info_impl.h" #define IPC_MESSAGE_START PpapiMsgStart @@ -108,6 +109,35 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::InputEventData) IPC_STRUCT_TRAITS_MEMBER(character_text) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(ppapi::PPB_URLRequestInfo_Data) + IPC_STRUCT_TRAITS_MEMBER(url) + IPC_STRUCT_TRAITS_MEMBER(method) + IPC_STRUCT_TRAITS_MEMBER(headers) + IPC_STRUCT_TRAITS_MEMBER(stream_to_file) + IPC_STRUCT_TRAITS_MEMBER(follow_redirects) + IPC_STRUCT_TRAITS_MEMBER(record_download_progress) + IPC_STRUCT_TRAITS_MEMBER(record_upload_progress) + IPC_STRUCT_TRAITS_MEMBER(has_custom_referrer_url) + IPC_STRUCT_TRAITS_MEMBER(custom_referrer_url) + IPC_STRUCT_TRAITS_MEMBER(allow_cross_origin_requests) + IPC_STRUCT_TRAITS_MEMBER(allow_credentials) + IPC_STRUCT_TRAITS_MEMBER(has_custom_content_transfer_encoding) + IPC_STRUCT_TRAITS_MEMBER(custom_content_transfer_encoding) + IPC_STRUCT_TRAITS_MEMBER(prefetch_buffer_upper_threshold) + IPC_STRUCT_TRAITS_MEMBER(prefetch_buffer_lower_threshold) + IPC_STRUCT_TRAITS_MEMBER(body) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(ppapi::PPB_URLRequestInfo_Data::BodyItem) + IPC_STRUCT_TRAITS_MEMBER(is_file) + IPC_STRUCT_TRAITS_MEMBER(data) + // Note: we don't serialize file_ref. + IPC_STRUCT_TRAITS_MEMBER(file_ref_host_resource) + IPC_STRUCT_TRAITS_MEMBER(start_offset) + IPC_STRUCT_TRAITS_MEMBER(number_of_bytes) + IPC_STRUCT_TRAITS_MEMBER(expected_last_modified_time) +IPC_STRUCT_TRAITS_END() + // These are from the browser to the plugin. // Loads the given plugin. IPC_MESSAGE_CONTROL1(PpapiMsg_LoadPlugin, FilePath /* path */) @@ -189,7 +219,7 @@ IPC_MESSAGE_ROUTED3( PpapiMsg_PPBFileChooser_ChooseComplete, ppapi::HostResource /* chooser */, int32_t /* result_code (will be != PP_OK on failure */, - std::vector<ppapi::proxy::PPBFileRef_CreateInfo> /* chosen_files */) + std::vector<ppapi::PPB_FileRef_CreateInfo> /* chosen_files */) // PPB_FileSystem. IPC_MESSAGE_ROUTED2( @@ -531,10 +561,10 @@ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBFileChooser_Show, IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFileRef_Create, ppapi::HostResource /* file_system */, std::string /* path */, - ppapi::proxy::PPBFileRef_CreateInfo /* result */) + ppapi::PPB_FileRef_CreateInfo /* result */) IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBFileRef_GetParent, ppapi::HostResource /* file_ref */, - ppapi::proxy::PPBFileRef_CreateInfo /* result */) + ppapi::PPB_FileRef_CreateInfo /* result */) IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBFileRef_MakeDirectory, ppapi::HostResource /* file_ref */, PP_Bool /* make_ancestors */, @@ -575,8 +605,9 @@ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFlash_GetProxyForURL, PP_Instance /* instance */, std::string /* url */, ppapi::proxy::SerializedVar /* result */) -IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBFlash_Navigate, - ppapi::HostResource /* request_info */, +IPC_SYNC_MESSAGE_ROUTED4_1(PpapiHostMsg_PPBFlash_Navigate, + PP_Instance /* instance */, + ppapi::PPB_URLRequestInfo_Data /* request_data */, std::string /* target */, bool /* from_user_action */, int32_t /* result */) @@ -840,7 +871,7 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLLoader_Create, ppapi::HostResource /* result */) IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBURLLoader_Open, ppapi::HostResource /* loader */, - ppapi::HostResource /*request_info */, + ppapi::PPB_URLRequestInfo_Data /* request_data */, uint32_t /* serialized_callback */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLLoader_FollowRedirect, ppapi::HostResource /* loader */, @@ -860,24 +891,6 @@ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBURLLoader_Close, IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBURLLoader_GrantUniversalAccess, ppapi::HostResource /* loader */) -// PPB_URLRequestInfo. -IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLRequestInfo_Create, - PP_Instance /* instance */, - ppapi::HostResource /* result */) -IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBURLRequestInfo_SetProperty, - ppapi::HostResource /* request */, - int32_t /* property */, - ppapi::proxy::SerializedVar /* value */) -IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLRequestInfo_AppendDataToBody, - ppapi::HostResource /* request */, - std::string /* data */) -IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBURLRequestInfo_AppendFileToBody, - ppapi::HostResource /* request */, - ppapi::HostResource /* file_ref */, - int64_t /* start_offset */, - int64_t /* number_of_bytes */, - double /* expected_last_modified_time */) - // PPB_URLResponseInfo. IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBURLResponseInfo_GetProperty, ppapi::HostResource /* response */, @@ -885,7 +898,7 @@ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBURLResponseInfo_GetProperty, ppapi::proxy::SerializedVar /* result */) IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLResponseInfo_GetBodyAsFileRef, ppapi::HostResource /* response */, - ppapi::proxy::PPBFileRef_CreateInfo /* result */) + ppapi::PPB_FileRef_CreateInfo /* result */) // PPB_URLUtil. IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBURLUtil_ResolveRelativeToDocument, diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc index 0e3c6de..b80df34 100644 --- a/ppapi/proxy/ppapi_param_traits.cc +++ b/ppapi/proxy/ppapi_param_traits.cc @@ -248,33 +248,31 @@ void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Log( std::string* l) { } -// PPBFileRef_CreateInfo ------------------------------------------------------- +// PPB_FileRef_CreateInfo ------------------------------------------------------ // static -void ParamTraits<ppapi::proxy::PPBFileRef_CreateInfo>::Write( - Message* m, - const param_type& p) { +void ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Write(Message* m, + const param_type& p) { ParamTraits<ppapi::HostResource>::Write(m, p.resource); ParamTraits<int>::Write(m, p.file_system_type); - ParamTraits<ppapi::proxy::SerializedVar>::Write(m, p.path); - ParamTraits<ppapi::proxy::SerializedVar>::Write(m, p.name); + ParamTraits<std::string>::Write(m, p.path); + ParamTraits<std::string>::Write(m, p.name); } // static -bool ParamTraits<ppapi::proxy::PPBFileRef_CreateInfo>::Read(const Message* m, - void** iter, - param_type* r) { +bool ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Read(const Message* m, + void** iter, + param_type* r) { return ParamTraits<ppapi::HostResource>::Read(m, iter, &r->resource) && ParamTraits<int>::Read(m, iter, &r->file_system_type) && - ParamTraits<ppapi::proxy::SerializedVar>::Read(m, iter, &r->path) && - ParamTraits<ppapi::proxy::SerializedVar>::Read(m, iter, &r->name); + ParamTraits<std::string>::Read(m, iter, &r->path) && + ParamTraits<std::string>::Read(m, iter, &r->name); } // static -void ParamTraits<ppapi::proxy::PPBFileRef_CreateInfo>::Log( - const param_type& p, - std::string* l) { +void ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Log(const param_type& p, + std::string* l) { } // PPBURLLoader_UpdateProgress_Params ------------------------------------------ @@ -440,16 +438,16 @@ void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Log( std::string* l) { } -// std::vector<PPBFileRef_CreateInfo> ------------------------------------------ +// std::vector<PPB_FileRef_CreateInfo> ----------------------------------------- -void ParamTraits< std::vector<ppapi::proxy::PPBFileRef_CreateInfo> >::Write( +void ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Write( Message* m, const param_type& p) { WriteVectorWithoutCopy(m, p); } // static -bool ParamTraits< std::vector<ppapi::proxy::PPBFileRef_CreateInfo> >::Read( +bool ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Read( const Message* m, void** iter, param_type* r) { @@ -457,7 +455,7 @@ bool ParamTraits< std::vector<ppapi::proxy::PPBFileRef_CreateInfo> >::Read( } // static -void ParamTraits< std::vector<ppapi::proxy::PPBFileRef_CreateInfo> >::Log( +void ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Log( const param_type& p, std::string* l) { } diff --git a/ppapi/proxy/ppapi_param_traits.h b/ppapi/proxy/ppapi_param_traits.h index b53d5f5..71fa9cb 100644 --- a/ppapi/proxy/ppapi_param_traits.h +++ b/ppapi/proxy/ppapi_param_traits.h @@ -13,6 +13,7 @@ #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_rect.h" #include "ppapi/c/pp_var.h" +#include "ppapi/shared_impl/file_ref_impl.h" struct PP_FileInfo; struct PP_ObjectProperty; @@ -22,10 +23,10 @@ struct PP_Flash_NetAddress; namespace ppapi { class HostResource; +//struct PPB_FileRef_CreateInfo; namespace proxy { -struct PPBFileRef_CreateInfo; struct PPBFlash_DrawGlyphs_Params; struct PPBURLLoader_UpdateProgress_Params; struct SerializedDirEntry; @@ -79,8 +80,8 @@ struct ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params> { }; template<> -struct ParamTraits<ppapi::proxy::PPBFileRef_CreateInfo> { - typedef ppapi::proxy::PPBFileRef_CreateInfo param_type; +struct ParamTraits<ppapi::PPB_FileRef_CreateInfo> { + typedef ppapi::PPB_FileRef_CreateInfo param_type; static void Write(Message* m, const param_type& p); static bool Read(const Message* m, void** iter, param_type* r); static void Log(const param_type& p, std::string* l); @@ -135,8 +136,8 @@ struct ParamTraits< std::vector<ppapi::proxy::SerializedVar> > { }; template<> -struct ParamTraits< std::vector<ppapi::proxy::PPBFileRef_CreateInfo> > { - typedef std::vector<ppapi::proxy::PPBFileRef_CreateInfo> param_type; +struct ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> > { + typedef std::vector<ppapi::PPB_FileRef_CreateInfo> param_type; static void Write(Message* m, const param_type& p); static bool Read(const Message* m, void** iter, param_type* r); static void Log(const param_type& p, std::string* l); diff --git a/ppapi/proxy/ppb_file_chooser_proxy.cc b/ppapi/proxy/ppb_file_chooser_proxy.cc index 10ed0d9..f13ea86 100644 --- a/ppapi/proxy/ppb_file_chooser_proxy.cc +++ b/ppapi/proxy/ppb_file_chooser_proxy.cc @@ -39,7 +39,7 @@ class FileChooser : public Resource, // Handles the choose complete notification from the host. void ChooseComplete( int32_t result_code, - const std::vector<PPBFileRef_CreateInfo>& chosen_files); + const std::vector<PPB_FileRef_CreateInfo>& chosen_files); private: PP_CompletionCallback current_show_callback_; @@ -106,7 +106,7 @@ PP_Resource FileChooser::GetNextChosenFile() { void FileChooser::ChooseComplete( int32_t result_code, - const std::vector<PPBFileRef_CreateInfo>& chosen_files) { + const std::vector<PPB_FileRef_CreateInfo>& chosen_files) { // Convert each of the passed in file infos to resources. These will be owned // by the FileChooser object until they're passed to the plugin. DCHECK(file_queue_.empty()); @@ -245,7 +245,7 @@ void PPB_FileChooser_Proxy::OnMsgShow(const HostResource& chooser) { void PPB_FileChooser_Proxy::OnMsgChooseComplete( const HostResource& chooser, int32_t result_code, - const std::vector<PPBFileRef_CreateInfo>& chosen_files) { + const std::vector<PPB_FileRef_CreateInfo>& chosen_files) { EnterPluginFromHostResource<PPB_FileChooser_API> enter(chooser); if (enter.succeeded()) { static_cast<FileChooser*>(enter.object())->ChooseComplete( @@ -255,7 +255,7 @@ void PPB_FileChooser_Proxy::OnMsgChooseComplete( void PPB_FileChooser_Proxy::OnShowCallback(int32_t result, const HostResource& chooser) { - std::vector<PPBFileRef_CreateInfo> files; + std::vector<PPB_FileRef_CreateInfo> files; if (result == PP_OK) { // Jump through some hoops to get the FileRef proxy. Since we know we're // in the host at this point, we can ask the host dispatcher for it. @@ -268,7 +268,7 @@ void PPB_FileChooser_Proxy::OnShowCallback(int32_t result, while (PP_Resource cur_file_resource = ppb_file_chooser_target()->GetNextChosenFile( chooser.host_resource())) { - PPBFileRef_CreateInfo cur_create_info; + PPB_FileRef_CreateInfo cur_create_info; file_ref_proxy->SerializeFileRef(cur_file_resource, &cur_create_info); files.push_back(cur_create_info); } diff --git a/ppapi/proxy/ppb_file_chooser_proxy.h b/ppapi/proxy/ppb_file_chooser_proxy.h index 322edc2..4f3bc84 100644 --- a/ppapi/proxy/ppb_file_chooser_proxy.h +++ b/ppapi/proxy/ppb_file_chooser_proxy.h @@ -20,10 +20,10 @@ struct PPB_FileChooser_Dev; namespace ppapi { class HostResource; +struct PPB_FileRef_CreateInfo; namespace proxy { -struct PPBFileRef_CreateInfo; class SerializedVarReceiveInput; class PPB_FileChooser_Proxy : public InterfaceProxy { @@ -58,7 +58,7 @@ class PPB_FileChooser_Proxy : public InterfaceProxy { void OnMsgChooseComplete( const ppapi::HostResource& chooser, int32_t result_code, - const std::vector<PPBFileRef_CreateInfo>& chosen_files); + const std::vector<PPB_FileRef_CreateInfo>& chosen_files); // Called when the show is complete in the host. This will notify the plugin // via IPC and OnMsgChooseComplete will be called there. diff --git a/ppapi/proxy/ppb_file_ref_proxy.cc b/ppapi/proxy/ppb_file_ref_proxy.cc index 9ad0635..0cf26bd 100644 --- a/ppapi/proxy/ppb_file_ref_proxy.cc +++ b/ppapi/proxy/ppb_file_ref_proxy.cc @@ -12,7 +12,7 @@ #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/serialized_var.h" -#include "ppapi/thunk/ppb_file_ref_api.h" +#include "ppapi/shared_impl/file_ref_impl.h" #include "ppapi/thunk/resource_creation_api.h" #include "ppapi/thunk/thunk.h" @@ -33,18 +33,12 @@ InterfaceProxy* CreateFileRefProxy(Dispatcher* dispatcher, } // namespace -class FileRef : public Resource, public PPB_FileRef_API { +class FileRef : public FileRefImpl { public: - explicit FileRef(const PPBFileRef_CreateInfo& info); + explicit FileRef(const PPB_FileRef_CreateInfo& info); virtual ~FileRef(); - // Resource overrides. - virtual PPB_FileRef_API* AsPPB_FileRef_API() OVERRIDE; - - // PPB_FileRef_API implementation. - virtual PP_FileSystemType GetFileSystemType() const OVERRIDE; - virtual PP_Var GetName() const OVERRIDE; - virtual PP_Var GetPath() const OVERRIDE; + // PPB_FileRef_API implementation (not provided by FileRefImpl). virtual PP_Resource GetParent() OVERRIDE; virtual int32_t MakeDirectory(PP_Bool make_ancestors, PP_CompletionCallback callback) OVERRIDE; @@ -60,50 +54,18 @@ class FileRef : public Resource, public PPB_FileRef_API { return PluginDispatcher::GetForResource(this); } - PP_FileSystemType file_system_type_; - PP_Var path_; - PP_Var name_; - - DISALLOW_COPY_AND_ASSIGN(FileRef); + DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef); }; -FileRef::FileRef(const PPBFileRef_CreateInfo& info) - : Resource(info.resource) { - Dispatcher* dispatcher = PluginDispatcher::GetForResource(this); - - file_system_type_ = static_cast<PP_FileSystemType>(info.file_system_type); - - name_ = ReceiveSerializedVarReturnValue(info.name).Return(dispatcher); - path_ = ReceiveSerializedVarReturnValue(info.path).Return(dispatcher); +FileRef::FileRef(const PPB_FileRef_CreateInfo& info) + : FileRefImpl(FileRefImpl::InitAsProxy(), info) { } FileRef::~FileRef() { - PluginVarTracker& var_tracker = - PluginResourceTracker::GetInstance()->var_tracker(); - var_tracker.ReleaseVar(path_); - var_tracker.ReleaseVar(name_); -} - -PPB_FileRef_API* FileRef::AsPPB_FileRef_API() { - return this; -} - -PP_FileSystemType FileRef::GetFileSystemType() const { - return file_system_type_; -} - -PP_Var FileRef::GetName() const { - PluginResourceTracker::GetInstance()->var_tracker().AddRefVar(name_); - return name_; -} - -PP_Var FileRef::GetPath() const { - PluginResourceTracker::GetInstance()->var_tracker().AddRefVar(path_); - return path_; } PP_Resource FileRef::GetParent() { - PPBFileRef_CreateInfo create_info; + PPB_FileRef_CreateInfo create_info; GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetParent( INTERFACE_ID_PPB_FILE_REF, host_resource(), &create_info)); return PPB_FileRef_Proxy::DeserializeFileRef(create_info); @@ -176,7 +138,7 @@ PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Resource file_system, if (!file_system_object) return 0; - PPBFileRef_CreateInfo create_info; + PPB_FileRef_CreateInfo create_info; PluginDispatcher::GetForResource(file_system_object)->Send( new PpapiHostMsg_PPBFileRef_Create( INTERFACE_ID_PPB_FILE_REF, file_system_object->host_resource(), @@ -200,35 +162,15 @@ bool PPB_FileRef_Proxy::OnMessageReceived(const IPC::Message& msg) { } void PPB_FileRef_Proxy::SerializeFileRef(PP_Resource file_ref, - PPBFileRef_CreateInfo* result) { + PPB_FileRef_CreateInfo* result) { EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, false); - if (enter.failed()) { - NOTREACHED(); - return; - } - - // We need the instance out of the resource for serializing back to the - // plugin. This code can only run in the host. - if (dispatcher()->IsPlugin()) { - NOTREACHED(); - return; - } - HostDispatcher* host_dispatcher = static_cast<HostDispatcher*>(dispatcher()); - PP_Instance instance = - host_dispatcher->ppb_proxy()->GetInstanceForResource(file_ref); - - result->resource.SetHostResource(instance, file_ref); - result->file_system_type = - static_cast<int>(enter.object()->GetFileSystemType()); - result->path = SerializedVarReturnValue::Convert(dispatcher(), - enter.object()->GetPath()); - result->name = SerializedVarReturnValue::Convert(dispatcher(), - enter.object()->GetName()); + if (enter.succeeded()) + *result = enter.object()->GetCreateInfo(); } // static PP_Resource PPB_FileRef_Proxy::DeserializeFileRef( - const PPBFileRef_CreateInfo& serialized) { + const PPB_FileRef_CreateInfo& serialized) { if (serialized.resource.is_null()) return 0; // Resource invalid. return (new FileRef(serialized))->GetReference(); @@ -236,7 +178,7 @@ PP_Resource PPB_FileRef_Proxy::DeserializeFileRef( void PPB_FileRef_Proxy::OnMsgCreate(const HostResource& file_system, const std::string& path, - PPBFileRef_CreateInfo* result) { + PPB_FileRef_CreateInfo* result) { EnterFunctionNoLock<ResourceCreationAPI> enter(file_system.instance(), true); if (enter.failed()) return; @@ -248,7 +190,7 @@ void PPB_FileRef_Proxy::OnMsgCreate(const HostResource& file_system, } void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource, - PPBFileRef_CreateInfo* result) { + PPB_FileRef_CreateInfo* result) { EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); if (enter.succeeded()) SerializeFileRef(enter.object()->GetParent(), result); diff --git a/ppapi/proxy/ppb_file_ref_proxy.h b/ppapi/proxy/ppb_file_ref_proxy.h index 3ae502d..1241343 100644 --- a/ppapi/proxy/ppb_file_ref_proxy.h +++ b/ppapi/proxy/ppb_file_ref_proxy.h @@ -18,11 +18,10 @@ struct PPB_FileRef_Dev; namespace ppapi { class HostResource; +struct PPB_FileRef_CreateInfo; namespace proxy { -struct PPBFileRef_CreateInfo; - class PPB_FileRef_Proxy : public InterfaceProxy { public: PPB_FileRef_Proxy(Dispatcher* dispatcher, const void* target_interface); @@ -46,7 +45,7 @@ class PPB_FileRef_Proxy : public InterfaceProxy { // Various PPAPI functions return file refs from various interfaces, so this // function is public so anybody can send a file ref. void SerializeFileRef(PP_Resource file_ref, - PPBFileRef_CreateInfo* result); + PPB_FileRef_CreateInfo* result); // Creates a plugin resource from the given CreateInfo sent from the host. // The value will be the result of calling SerializeFileRef on the host. @@ -56,15 +55,15 @@ class PPB_FileRef_Proxy : public InterfaceProxy { // Various PPAPI functions return file refs from various interfaces, so this // function is public so anybody can receive a file ref. static PP_Resource DeserializeFileRef( - const PPBFileRef_CreateInfo& serialized); + const PPB_FileRef_CreateInfo& serialized); private: // Message handlers. void OnMsgCreate(const ppapi::HostResource& file_system, const std::string& path, - PPBFileRef_CreateInfo* result); + PPB_FileRef_CreateInfo* result); void OnMsgGetParent(const ppapi::HostResource& host_resource, - PPBFileRef_CreateInfo* result); + PPB_FileRef_CreateInfo* result); void OnMsgMakeDirectory(const ppapi::HostResource& host_resource, PP_Bool make_ancestors, uint32_t serialized_callback); diff --git a/ppapi/proxy/ppb_flash_proxy.cc b/ppapi/proxy/ppb_flash_proxy.cc index 725af5f..c551ace 100644 --- a/ppapi/proxy/ppb_flash_proxy.cc +++ b/ppapi/proxy/ppb_flash_proxy.cc @@ -19,6 +19,10 @@ #include "ppapi/proxy/proxy_module.h" #include "ppapi/proxy/serialized_var.h" #include "ppapi/shared_impl/resource.h" +#include "ppapi/shared_impl/scoped_pp_resource.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_url_request_info_api.h" +#include "ppapi/thunk/resource_creation_api.h" namespace ppapi { namespace proxy { @@ -95,20 +99,19 @@ PP_Var GetProxyForURL(PP_Instance instance, const char* url) { int32_t Navigate(PP_Resource request_id, const char* target, bool from_user_action) { - Resource* request_object = - PluginResourceTracker::GetInstance()->GetResource(request_id); - if (!request_object) + thunk::EnterResource<thunk::PPB_URLRequestInfo_API> enter(request_id, true); + if (enter.failed()) return PP_ERROR_BADRESOURCE; + PP_Instance instance = enter.resource()->pp_instance(); - PluginDispatcher* dispatcher = - PluginDispatcher::GetForInstance(request_object->pp_instance()); + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); if (!dispatcher) return PP_ERROR_FAILED; int32_t result = PP_ERROR_FAILED; dispatcher->Send(new PpapiHostMsg_PPBFlash_Navigate( INTERFACE_ID_PPB_FLASH, - request_object->host_resource(), target, from_user_action, + instance, enter.object()->GetData(), target, from_user_action, &result)); return result; } @@ -256,18 +259,40 @@ void PPB_Flash_Proxy::OnMsgGetProxyForURL(PP_Instance instance, instance, url.c_str())); } -void PPB_Flash_Proxy::OnMsgNavigate(const HostResource& request_info, +void PPB_Flash_Proxy::OnMsgNavigate(PP_Instance instance, + const PPB_URLRequestInfo_Data& data, const std::string& target, bool from_user_action, int32_t* result) { DCHECK(!dispatcher()->IsPlugin()); + + // Validate the PP_Instance since we'll be constructing resources on its + // behalf. + HostDispatcher* host_dispatcher = static_cast<HostDispatcher*>(dispatcher()); + if (HostDispatcher::GetForInstance(instance) != host_dispatcher) { + NOTREACHED(); + *result = PP_ERROR_BADARGUMENT; + return; + } + // We need to allow re-entrancy here, because this may call into Javascript // (e.g. with a "javascript:" URL), or do things like navigate away from the // page, either one of which will need to re-enter into the plugin. // It is safe, because it is essentially equivalent to NPN_GetURL, where Flash // would expect re-entrancy. When running in-process, it does re-enter here. - static_cast<HostDispatcher*>(dispatcher())->set_allow_plugin_reentrancy(); - *result = ppb_flash_target()->Navigate(request_info.host_resource(), + host_dispatcher->set_allow_plugin_reentrancy(); + + // Make a temporary request resource. + thunk::EnterFunctionNoLock<thunk::ResourceCreationAPI> enter(instance, true); + if (enter.failed()) { + *result = PP_ERROR_FAILED; + return; + } + ScopedPPResource request_resource( + ScopedPPResource::PassRef(), + enter.functions()->CreateURLRequestInfo(instance, data)); + + *result = ppb_flash_target()->Navigate(request_resource, target.c_str(), from_user_action); } diff --git a/ppapi/proxy/ppb_flash_proxy.h b/ppapi/proxy/ppb_flash_proxy.h index faf4222..f893ce2 100644 --- a/ppapi/proxy/ppb_flash_proxy.h +++ b/ppapi/proxy/ppb_flash_proxy.h @@ -19,6 +19,9 @@ struct PP_FileInfo; struct PPB_Flash; namespace ppapi { + +struct PPB_URLRequestInfo_Data; + namespace proxy { struct PPBFlash_DrawGlyphs_Params; @@ -47,7 +50,8 @@ class PPB_Flash_Proxy : public InterfaceProxy { void OnMsgGetProxyForURL(PP_Instance instance, const std::string& url, SerializedVarReturnValue result); - void OnMsgNavigate(const HostResource& request_info, + void OnMsgNavigate(PP_Instance instance, + const PPB_URLRequestInfo_Data& data, const std::string& target, bool from_user_action, int32_t* result); diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc index 3f6cd10..e6ef68e 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.cc +++ b/ppapi/proxy/ppb_url_loader_proxy.cc @@ -22,6 +22,7 @@ #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_url_response_info_proxy.h" +#include "ppapi/shared_impl/scoped_pp_resource.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_url_loader_api.h" #include "ppapi/thunk/resource_creation_api.h" @@ -180,16 +181,14 @@ PPB_URLLoader_API* URLLoader::AsPPB_URLLoader_API() { int32_t URLLoader::Open(PP_Resource request_id, PP_CompletionCallback callback) { - Resource* request_object = - PluginResourceTracker::GetInstance()->GetResource(request_id); - if (!request_object) - return PP_ERROR_BADARGUMENT; + EnterResourceNoLock<thunk::PPB_URLRequestInfo_API> enter(request_id, true); + if (enter.failed()) + return PP_ERROR_BADRESOURCE; // TODO(brettw) http://crbug.com/86279: SendCallback doesn't ensure that // the proper callback semantics happen if the object is deleted. GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_Open( - INTERFACE_ID_PPB_URL_LOADER, host_resource(), - request_object->host_resource(), + INTERFACE_ID_PPB_URL_LOADER, host_resource(), enter.object()->GetData(), GetDispatcher()->callback_tracker().SendCallback(callback))); return PP_OK_COMPLETIONPENDING; } @@ -453,13 +452,23 @@ void PPB_URLLoader_Proxy::OnMsgCreate(PP_Instance instance, } void PPB_URLLoader_Proxy::OnMsgOpen(const HostResource& loader, - const HostResource& request_info, + const PPB_URLRequestInfo_Data& data, uint32_t serialized_callback) { + // Have to be careful to always issue the callback, so don't return early. EnterHostFromHostResource<PPB_URLLoader_API> enter(loader); + EnterFunctionNoLock<ResourceCreationAPI> enter_creation( + loader.instance(), true); + PP_CompletionCallback callback = ReceiveCallback(serialized_callback); + int32_t result = PP_ERROR_BADRESOURCE; - if (enter.succeeded()) - result = enter.object()->Open(request_info.host_resource(), callback); + if (enter.succeeded() && enter_creation.succeeded()) { + ScopedPPResource request_resource( + ScopedPPResource::PassRef(), + enter_creation.functions()->CreateURLRequestInfo(loader.instance(), + data)); + result = enter.object()->Open(request_resource, callback); + } if (result != PP_OK_COMPLETIONPENDING) PP_RunCompletionCallback(&callback, result); // TODO(brettw) bug 73236 register for the status callbacks. diff --git a/ppapi/proxy/ppb_url_loader_proxy.h b/ppapi/proxy/ppb_url_loader_proxy.h index 7f2ec40..17825f1 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.h +++ b/ppapi/proxy/ppb_url_loader_proxy.h @@ -20,6 +20,9 @@ struct PPB_URLLoader; struct PPB_URLLoaderTrusted; namespace ppapi { + +struct PPB_URLRequestInfo_Data; + namespace proxy { struct PPBURLLoader_UpdateProgress_Params; @@ -62,7 +65,7 @@ class PPB_URLLoader_Proxy : public InterfaceProxy { void OnMsgCreate(PP_Instance instance, ppapi::HostResource* result); void OnMsgOpen(const ppapi::HostResource& loader, - const ppapi::HostResource& request_info, + const PPB_URLRequestInfo_Data& data, uint32_t serialized_callback); void OnMsgFollowRedirect(const ppapi::HostResource& loader, uint32_t serialized_callback); diff --git a/ppapi/proxy/ppb_url_request_info_proxy.cc b/ppapi/proxy/ppb_url_request_info_proxy.cc index cf9dd3d..e5861f0 100644 --- a/ppapi/proxy/ppb_url_request_info_proxy.cc +++ b/ppapi/proxy/ppb_url_request_info_proxy.cc @@ -4,18 +4,10 @@ #include "ppapi/proxy/ppb_url_request_info_proxy.h" -#include "ppapi/c/ppb_url_request_info.h" -#include "ppapi/proxy/enter_proxy.h" #include "ppapi/proxy/plugin_dispatcher.h" -#include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/thunk/ppb_url_request_info_api.h" -#include "ppapi/thunk/resource_creation_api.h" +#include "ppapi/shared_impl/url_request_info_impl.h" #include "ppapi/thunk/thunk.h" -using ppapi::thunk::EnterFunctionNoLock; -using ppapi::thunk::PPB_URLRequestInfo_API; -using ppapi::thunk::ResourceCreationAPI; - namespace ppapi { namespace proxy { @@ -28,86 +20,6 @@ InterfaceProxy* CreateURLRequestInfoProxy(Dispatcher* dispatcher, } // namespace -class URLRequestInfo : public Resource, - public PPB_URLRequestInfo_API { - public: - URLRequestInfo(const HostResource& resource); - virtual ~URLRequestInfo(); - - virtual PPB_URLRequestInfo_API* AsPPB_URLRequestInfo_API() OVERRIDE; - - // PPB_URLRequestInfo_API implementation. - virtual PP_Bool SetProperty(PP_URLRequestProperty property, - PP_Var var) OVERRIDE; - virtual PP_Bool AppendDataToBody(const void* data, uint32_t len) OVERRIDE; - virtual PP_Bool AppendFileToBody( - PP_Resource file_ref, - int64_t start_offset, - int64_t number_of_bytes, - PP_Time expected_last_modified_time) OVERRIDE; - - private: - PluginDispatcher* GetDispatcher() const { - return PluginDispatcher::GetForResource(this); - } - - DISALLOW_COPY_AND_ASSIGN(URLRequestInfo); -}; - -URLRequestInfo::URLRequestInfo(const HostResource& resource) - : Resource(resource) { -} - -URLRequestInfo::~URLRequestInfo() { -} - -PPB_URLRequestInfo_API* URLRequestInfo::AsPPB_URLRequestInfo_API() { - return this; -} - -PP_Bool URLRequestInfo::SetProperty(PP_URLRequestProperty property, - PP_Var var) { - GetDispatcher()->Send(new PpapiHostMsg_PPBURLRequestInfo_SetProperty( - INTERFACE_ID_PPB_URL_REQUEST_INFO, host_resource(), - static_cast<int32_t>(property), - SerializedVarSendInput(GetDispatcher(), 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 URLRequestInfo::AppendDataToBody(const void* data, uint32_t len) { - GetDispatcher()->Send(new PpapiHostMsg_PPBURLRequestInfo_AppendDataToBody( - INTERFACE_ID_PPB_URL_REQUEST_INFO, host_resource(), - std::string(static_cast<const char*>(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 URLRequestInfo::AppendFileToBody(PP_Resource file_ref, - int64_t start_offset, - int64_t number_of_bytes, - PP_Time expected_last_modified_time) { - Resource* file_ref_object = - PluginResourceTracker::GetInstance()->GetResource(file_ref); - if (!file_ref_object) - return PP_FALSE; - - GetDispatcher()->Send(new PpapiHostMsg_PPBURLRequestInfo_AppendFileToBody( - INTERFACE_ID_PPB_URL_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; -} - -// PPB_URLRequestInfo_Proxy ---------------------------------------------------- - PPB_URLRequestInfo_Proxy::PPB_URLRequestInfo_Proxy( Dispatcher* dispatcher, const void* target_interface) @@ -129,78 +41,9 @@ const InterfaceProxy::Info* PPB_URLRequestInfo_Proxy::GetInfo() { return &info; } -// static -PP_Resource PPB_URLRequestInfo_Proxy::CreateProxyResource( - 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; - return (new URLRequestInfo(result))->GetReference(); -} - 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) { - EnterFunctionNoLock<ResourceCreationAPI> enter(instance, true); - if (enter.succeeded()) { - result->SetHostResource(instance, - enter.functions()->CreateURLRequestInfo(instance)); - } -} - -void PPB_URLRequestInfo_Proxy::OnMsgSetProperty( - HostResource request, - int32_t property, - SerializedVarReceiveInput value) { - EnterHostFromHostResource<PPB_URLRequestInfo_API> enter(request); - if (enter.succeeded()) { - enter.object()->SetProperty(static_cast<PP_URLRequestProperty>(property), - value.Get(dispatcher())); - } -} - -void PPB_URLRequestInfo_Proxy::OnMsgAppendDataToBody( - HostResource request, - const std::string& data) { - EnterHostFromHostResource<PPB_URLRequestInfo_API> enter(request); - if (enter.succeeded()) - enter.object()->AppendDataToBody(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) { - EnterHostFromHostResource<PPB_URLRequestInfo_API> enter(request); - if (enter.succeeded()) { - enter.object()->AppendFileToBody( - file_ref.host_resource(), start_offset, number_of_bytes, - expected_last_modified_time); - } + // No messages to handle. + return false; } } // namespace proxy diff --git a/ppapi/proxy/ppb_url_request_info_proxy.h b/ppapi/proxy/ppb_url_request_info_proxy.h index e17ddb2..6242bf8 100644 --- a/ppapi/proxy/ppb_url_request_info_proxy.h +++ b/ppapi/proxy/ppb_url_request_info_proxy.h @@ -7,16 +7,13 @@ #include "base/basictypes.h" #include "ppapi/c/pp_instance.h" -#include "ppapi/c/pp_resource.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/shared_impl/host_resource.h" - -struct PPB_URLRequestInfo; namespace ppapi { -namespace proxy { -class SerializedVarReceiveInput; +struct PPB_URLRequestInfo_Data; + +namespace proxy { class PPB_URLRequestInfo_Proxy : public InterfaceProxy { public: @@ -26,25 +23,10 @@ class PPB_URLRequestInfo_Proxy : public InterfaceProxy { static const Info* GetInfo(); - static PP_Resource CreateProxyResource(PP_Instance instance); - // InterfaceProxy implementation. virtual bool OnMessageReceived(const IPC::Message& msg); private: - // Message handlers. - void OnMsgCreate(PP_Instance instance, ppapi::HostResource* result); - void OnMsgSetProperty(ppapi::HostResource request, - int32_t property, - SerializedVarReceiveInput value); - void OnMsgAppendDataToBody(ppapi::HostResource request, - const std::string& data); - void OnMsgAppendFileToBody(ppapi::HostResource request, - ppapi::HostResource file_ref, - int64_t start_offset, - int64_t number_of_bytes, - double expected_last_modified_time); - DISALLOW_COPY_AND_ASSIGN(PPB_URLRequestInfo_Proxy); }; diff --git a/ppapi/proxy/ppb_url_response_info_proxy.cc b/ppapi/proxy/ppb_url_response_info_proxy.cc index 5be2afe..3801e5f 100644 --- a/ppapi/proxy/ppb_url_response_info_proxy.cc +++ b/ppapi/proxy/ppb_url_response_info_proxy.cc @@ -71,7 +71,7 @@ PP_Resource URLResponseInfo::GetBodyAsFileRef() { // file ref when the request is streaming to a file and it's in the state // where the file is ready. This will prevent us from having to do this sync // IPC here. - PPBFileRef_CreateInfo create_info; + PPB_FileRef_CreateInfo create_info; PluginDispatcher::GetForResource(this)->Send( new PpapiHostMsg_PPBURLResponseInfo_GetBodyAsFileRef( INTERFACE_ID_PPB_URL_RESPONSE_INFO, host_resource(), &create_info)); @@ -135,7 +135,7 @@ void PPB_URLResponseInfo_Proxy::OnMsgGetProperty( void PPB_URLResponseInfo_Proxy::OnMsgGetBodyAsFileRef( const HostResource& response, - PPBFileRef_CreateInfo* result) { + PPB_FileRef_CreateInfo* result) { EnterHostFromHostResource<PPB_URLResponseInfo_API> enter(response); PP_Resource file_ref = 0; if (enter.succeeded()) diff --git a/ppapi/proxy/ppb_url_response_info_proxy.h b/ppapi/proxy/ppb_url_response_info_proxy.h index 9713256..a81549d 100644 --- a/ppapi/proxy/ppb_url_response_info_proxy.h +++ b/ppapi/proxy/ppb_url_response_info_proxy.h @@ -15,9 +15,11 @@ struct PPB_URLResponseInfo; namespace ppapi { + +struct PPB_FileRef_CreateInfo; + namespace proxy { -struct PPBFileRef_CreateInfo; class SerializedVarReturnValue; class PPB_URLResponseInfo_Proxy : public InterfaceProxy { @@ -45,7 +47,7 @@ class PPB_URLResponseInfo_Proxy : public InterfaceProxy { int32_t property, SerializedVarReturnValue result); void OnMsgGetBodyAsFileRef(const ppapi::HostResource& response, - PPBFileRef_CreateInfo* result); + PPB_FileRef_CreateInfo* result); DISALLOW_COPY_AND_ASSIGN(PPB_URLResponseInfo_Proxy); }; diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 70f3f38..89d6504 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -27,7 +27,6 @@ #include "ppapi/proxy/ppb_image_data_proxy.h" #include "ppapi/proxy/ppb_surface_3d_proxy.h" #include "ppapi/proxy/ppb_url_loader_proxy.h" -#include "ppapi/proxy/ppb_url_request_info_proxy.h" #include "ppapi/proxy/ppb_video_capture_proxy.h" #include "ppapi/proxy/ppb_video_decoder_proxy.h" #include "ppapi/shared_impl/audio_config_impl.h" @@ -35,6 +34,7 @@ #include "ppapi/shared_impl/function_group_base.h" #include "ppapi/shared_impl/host_resource.h" #include "ppapi/shared_impl/input_event_impl.h" +#include "ppapi/shared_impl/url_request_info_impl.h" #include "ppapi/shared_impl/var.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_image_data_api.h" @@ -289,8 +289,11 @@ PP_Resource ResourceCreationProxy::CreateURLLoader(PP_Instance instance) { return PPB_URLLoader_Proxy::CreateProxyResource(instance); } -PP_Resource ResourceCreationProxy::CreateURLRequestInfo(PP_Instance instance) { - return PPB_URLRequestInfo_Proxy::CreateProxyResource(instance); +PP_Resource ResourceCreationProxy::CreateURLRequestInfo( + PP_Instance instance, + const PPB_URLRequestInfo_Data& data) { + return (new URLRequestInfoImpl( + HostResource::MakeInstanceOnly(instance), data))->GetReference(); } PP_Resource ResourceCreationProxy::CreateVideoCapture(PP_Instance instance) { diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index 0cbf230..3f2e76e 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -109,7 +109,9 @@ class ResourceCreationProxy : public FunctionGroupBase, const char* name, const char* proto) OVERRIDE; virtual PP_Resource CreateURLLoader(PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateURLRequestInfo(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateURLRequestInfo( + PP_Instance instance, + const PPB_URLRequestInfo_Data& data) OVERRIDE; virtual PP_Resource CreateVideoCapture(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateVideoDecoder( PP_Instance instance, diff --git a/ppapi/proxy/serialized_structs.cc b/ppapi/proxy/serialized_structs.cc index 4fd62ca..e327b60 100644 --- a/ppapi/proxy/serialized_structs.cc +++ b/ppapi/proxy/serialized_structs.cc @@ -63,10 +63,6 @@ void SerializedFontDescription::SetToPPFontDescription( desc->word_spacing = word_spacing; } -PPBFileRef_CreateInfo::PPBFileRef_CreateInfo() - : file_system_type(PP_FILESYSTEMTYPE_EXTERNAL) { -} - PPBFlash_DrawGlyphs_Params::PPBFlash_DrawGlyphs_Params() : instance(0), font_desc(), diff --git a/ppapi/proxy/serialized_structs.h b/ppapi/proxy/serialized_structs.h index 159ee39..706d6be 100644 --- a/ppapi/proxy/serialized_structs.h +++ b/ppapi/proxy/serialized_structs.h @@ -70,17 +70,6 @@ struct SerializedDirEntry { bool is_dir; }; -// FileRefs are created in a number of places and they include a number of -// return values. This struct encapsulates everything in one place. -struct PPBFileRef_CreateInfo { - PPBFileRef_CreateInfo(); // Initializes to 0. - - ppapi::HostResource resource; - int file_system_type; // One of PP_FileSystemType values. - SerializedVar path; - SerializedVar name; -}; - struct PPBFlash_DrawGlyphs_Params { PPBFlash_DrawGlyphs_Params(); ~PPBFlash_DrawGlyphs_Params(); diff --git a/ppapi/shared_impl/file_ref_impl.cc b/ppapi/shared_impl/file_ref_impl.cc new file mode 100644 index 0000000..1eae27b --- /dev/null +++ b/ppapi/shared_impl/file_ref_impl.cc @@ -0,0 +1,65 @@ +// 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/shared_impl/file_ref_impl.h" + +#include "base/logging.h" +#include "ppapi/shared_impl/tracker_base.h" +#include "ppapi/shared_impl/var.h" + +namespace ppapi { + +FileRefImpl::FileRefImpl(const InitAsImpl&, const PPB_FileRef_CreateInfo& info) + : Resource(info.resource.instance()), + create_info_(info) { + // Should not have been passed a host resource for the trusted constructor. + DCHECK(info.resource.is_null()); + + // Resource's constructor assigned a PP_Resource, so we can fill out our + // host resource now. + create_info_.resource = host_resource(); + DCHECK(!create_info_.resource.is_null()); +} + +FileRefImpl::FileRefImpl(const InitAsProxy&, const PPB_FileRef_CreateInfo& info) + : Resource(info.resource), + create_info_(info) { +} + +FileRefImpl::~FileRefImpl() { +} + +thunk::PPB_FileRef_API* FileRefImpl::AsPPB_FileRef_API() { + return this; +} + +PP_FileSystemType FileRefImpl::GetFileSystemType() const { + return static_cast<PP_FileSystemType>(create_info_.file_system_type); +} + +PP_Var FileRefImpl::GetName() const { + if (!name_var_.get()) { + name_var_ = new StringVar( + TrackerBase::Get()->GetModuleForInstance(pp_instance()), + create_info_.name); + } + return name_var_->GetPPVar(); +} + +PP_Var FileRefImpl::GetPath() const { + if (create_info_.file_system_type == PP_FILESYSTEMTYPE_EXTERNAL) + return PP_MakeUndefined(); + if (!path_var_.get()) { + path_var_ = new StringVar( + TrackerBase::Get()->GetModuleForInstance(pp_instance()), + create_info_.path); + } + return path_var_->GetPPVar(); +} + +const PPB_FileRef_CreateInfo& FileRefImpl::GetCreateInfo() const { + return create_info_; +} + +} // namespace ppapi diff --git a/ppapi/shared_impl/file_ref_impl.h b/ppapi/shared_impl/file_ref_impl.h new file mode 100644 index 0000000..515912b --- /dev/null +++ b/ppapi/shared_impl/file_ref_impl.h @@ -0,0 +1,63 @@ +// 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. + +#ifndef PPAPI_SHARED_IMPL_FILE_REF_IMPL_H_ +#define PPAPI_SHARED_IMPL_FILE_REF_IMPL_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/thunk/ppb_file_ref_api.h" + +namespace ppapi { + +class StringVar; + +// FileRefs are created in a number of places and they include a number of +// return values. This struct encapsulates everything in one place. +struct PPB_FileRef_CreateInfo { + PPB_FileRef_CreateInfo() : file_system_type(PP_FILESYSTEMTYPE_EXTERNAL) {} + + ppapi::HostResource resource; + int file_system_type; // One of PP_FileSystemType values. + std::string path; + std::string name; +}; + +// This class provides the shared implementation of a FileRef. The functions +// that actually "do stuff" like Touch and MakeDirectory are implemented +// differently for the proxied and non-proxied derived classes. +class FileRefImpl : public Resource, public thunk::PPB_FileRef_API { + public: + struct InitAsImpl {}; + struct InitAsProxy {}; + + FileRefImpl(const InitAsImpl&, const PPB_FileRef_CreateInfo& info); + FileRefImpl(const InitAsProxy&, const PPB_FileRef_CreateInfo& info); + virtual ~FileRefImpl(); + + // Resource overrides. + virtual thunk::PPB_FileRef_API* AsPPB_FileRef_API() OVERRIDE; + + // PPB_FileRef_API implementation (partial). + virtual PP_FileSystemType GetFileSystemType() const OVERRIDE; + virtual PP_Var GetName() const OVERRIDE; + virtual PP_Var GetPath() const OVERRIDE; + virtual const PPB_FileRef_CreateInfo& GetCreateInfo() const OVERRIDE; + + private: + PPB_FileRef_CreateInfo create_info_; + + // Lazily initialized vars created from the create_info_. This is so we can + // return the identical string object every time they're requested. + mutable scoped_refptr<StringVar> name_var_; + mutable scoped_refptr<StringVar> path_var_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(FileRefImpl); +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_FILE_REF_IMPL_H_ diff --git a/ppapi/shared_impl/scoped_pp_resource.cc b/ppapi/shared_impl/scoped_pp_resource.cc index 1b8f705..d5a9748 100644 --- a/ppapi/shared_impl/scoped_pp_resource.cc +++ b/ppapi/shared_impl/scoped_pp_resource.cc @@ -17,6 +17,10 @@ ScopedPPResource::ScopedPPResource(PP_Resource resource) : id_(resource) { CallAddRef(); } +ScopedPPResource::ScopedPPResource(const PassRef&, PP_Resource resource) + : id_(resource) { +} + ScopedPPResource::ScopedPPResource(Resource* resource) : id_(resource ? resource->GetReference() : 0) { // GetReference AddRef's for us. diff --git a/ppapi/shared_impl/scoped_pp_resource.h b/ppapi/shared_impl/scoped_pp_resource.h index 74cb9eb..96db4ee 100644 --- a/ppapi/shared_impl/scoped_pp_resource.h +++ b/ppapi/shared_impl/scoped_pp_resource.h @@ -14,11 +14,16 @@ class Resource; // This is a version of scoped_refptr but for PP_Resources. class ScopedPPResource { public: + struct PassRef {}; + ScopedPPResource(); // Takes one reference to the given resource. explicit ScopedPPResource(PP_Resource resource); + // Assumes responsibility for one ref that the resource already has. + explicit ScopedPPResource(const PassRef&, PP_Resource resource); + // Helper to get the PP_Resource out of the given object and take a reference // to it. explicit ScopedPPResource(Resource* resource); diff --git a/ppapi/shared_impl/url_request_info_impl.cc b/ppapi/shared_impl/url_request_info_impl.cc new file mode 100644 index 0000000..75fcb27 --- /dev/null +++ b/ppapi/shared_impl/url_request_info_impl.cc @@ -0,0 +1,337 @@ +// 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/shared_impl/url_request_info_impl.h" + +#include "base/string_util.h" +#include "ppapi/shared_impl/var.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_file_ref_api.h" + +using ppapi::thunk::EnterResourceNoLock; + +namespace ppapi { + +namespace { + +const int32_t kDefaultPrefetchBufferUpperThreshold = 100 * 1000 * 1000; +const int32_t kDefaultPrefetchBufferLowerThreshold = 50 * 1000 * 1000; + +// These methods are not allowed by the XMLHttpRequest standard. +// http://www.w3.org/TR/XMLHttpRequest/#the-open-method +const char* const kForbiddenHttpMethods[] = { + "connect", + "trace", + "track", +}; + +// These are the "known" methods in the Webkit XHR implementation. Also see +// the XMLHttpRequest standard. +// http://www.w3.org/TR/XMLHttpRequest/#the-open-method +const char* const kKnownHttpMethods[] = { + "get", + "post", + "put", + "head", + "copy", + "delete", + "index", + "lock", + "m-post", + "mkcol", + "move", + "options", + "propfind", + "proppatch", + "unlock", +}; + +bool IsValidToken(const std::string& token) { + size_t length = token.size(); + if (length == 0) + return false; + + for (size_t i = 0; i < length; i++) { + char c = token[i]; + if (c >= 127 || c <= 32) + return false; + if (c == '(' || c == ')' || c == '<' || c == '>' || c == '@' || + c == ',' || c == ';' || c == ':' || c == '\\' || c == '\"' || + c == '/' || c == '[' || c == ']' || c == '?' || c == '=' || + c == '{' || c == '}') + return false; + } + return true; +} + +} // namespace + +PPB_URLRequestInfo_Data::BodyItem::BodyItem() + : is_file(false), + start_offset(0), + number_of_bytes(-1), + expected_last_modified_time(0.0) { +} + +PPB_URLRequestInfo_Data::BodyItem::BodyItem(const std::string& data) + : is_file(false), + data(data), + start_offset(0), + number_of_bytes(-1), + expected_last_modified_time(0.0) { +} + +PPB_URLRequestInfo_Data::BodyItem::BodyItem( + Resource* file_ref, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time) + : is_file(true), + file_ref(file_ref), + file_ref_host_resource(file_ref->host_resource()), + start_offset(start_offset), + number_of_bytes(number_of_bytes), + expected_last_modified_time(expected_last_modified_time) { +} + +PPB_URLRequestInfo_Data::PPB_URLRequestInfo_Data() + : url(), + method(), + headers(), + stream_to_file(false), + follow_redirects(true), + record_download_progress(false), + record_upload_progress(false), + has_custom_referrer_url(false), + custom_referrer_url(), + allow_cross_origin_requests(false), + allow_credentials(false), + has_custom_content_transfer_encoding(false), + custom_content_transfer_encoding(), + prefetch_buffer_upper_threshold(kDefaultPrefetchBufferUpperThreshold), + prefetch_buffer_lower_threshold(kDefaultPrefetchBufferLowerThreshold), + body() { +} + +PPB_URLRequestInfo_Data::~PPB_URLRequestInfo_Data() { +} + +URLRequestInfoImpl::URLRequestInfoImpl(PP_Instance instance, + const PPB_URLRequestInfo_Data& data) + : Resource(instance), + data_(data) { +} + +URLRequestInfoImpl::URLRequestInfoImpl(const HostResource& host_resource, + const PPB_URLRequestInfo_Data& data) + : Resource(host_resource), + data_(data) { +} + +URLRequestInfoImpl::~URLRequestInfoImpl() { +} + +thunk::PPB_URLRequestInfo_API* URLRequestInfoImpl::AsPPB_URLRequestInfo_API() { + return this; +} + +PP_Bool URLRequestInfoImpl::SetProperty(PP_URLRequestProperty property, + PP_Var var) { + // IMPORTANT: Do not do security validation of parameters at this level + // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. This + // code is used both in the plugin (which we don't trust) and in the renderer + // (which we trust more). When running out-of-process, the plugin calls this + // function to configure the PPB_URLRequestInfo_Data, which is then sent to + // the renderer and *not* run through SetProperty again. + // + // This means that anything in the PPB_URLRequestInfo_Data needs to be + // validated at the time the URL is requested (which is what ValidateData + // does). If your feature requires security checks, it should be in the + // implementation in the renderer when the WebKit request is actually + // constructed. + // + // It is legal to do some validation here if you want to report failure to + // the plugin as a convenience, as long as you also do it in the renderer + // later. + PP_Bool result = PP_FALSE; + switch (var.type) { + case PP_VARTYPE_UNDEFINED: + result = PP_FromBool(SetUndefinedProperty(property)); + break; + case PP_VARTYPE_BOOL: + result = PP_FromBool( + SetBooleanProperty(property, PP_ToBool(var.value.as_bool))); + break; + case PP_VARTYPE_INT32: + result = PP_FromBool( + SetIntegerProperty(property, var.value.as_int)); + break; + case PP_VARTYPE_STRING: { + StringVar* string = StringVar::FromPPVar(var); + if (string) + result = PP_FromBool(SetStringProperty(property, string->value())); + break; + } + default: + break; + } + return result; +} + +PP_Bool URLRequestInfoImpl::AppendDataToBody(const void* data, uint32_t len) { + if (len > 0) { + data_.body.push_back(PPB_URLRequestInfo_Data::BodyItem( + std::string(static_cast<const char*>(data), len))); + } + return PP_TRUE; +} + +PP_Bool URLRequestInfoImpl::AppendFileToBody( + PP_Resource file_ref, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time) { + EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref, true); + if (enter.failed()) + return PP_FALSE; + + // Ignore a call to append nothing. + if (number_of_bytes == 0) + return PP_TRUE; + + // Check for bad values. (-1 means read until end of file.) + if (start_offset < 0 || number_of_bytes < -1) + return PP_FALSE; + + data_.body.push_back(PPB_URLRequestInfo_Data::BodyItem( + enter.resource(), + start_offset, + number_of_bytes, + expected_last_modified_time)); + return PP_TRUE; +} + +const PPB_URLRequestInfo_Data& URLRequestInfoImpl::GetData() const { + return data_; +} + +// static +std::string URLRequestInfoImpl::ValidateMethod(const std::string& method) { + if (!IsValidToken(method)) + return std::string(); + + for (size_t i = 0; i < arraysize(kForbiddenHttpMethods); ++i) { + if (LowerCaseEqualsASCII(method, kForbiddenHttpMethods[i])) + return std::string(); + } + for (size_t i = 0; i < arraysize(kKnownHttpMethods); ++i) { + if (LowerCaseEqualsASCII(method, kKnownHttpMethods[i])) { + // Convert the method name to upper case to match Webkit and Firefox's + // XHR implementation. + return StringToUpperASCII(std::string(kKnownHttpMethods[i])); + } + } + // Pass through unknown methods that are not forbidden. + return method; +} + +bool URLRequestInfoImpl::SetUndefinedProperty(PP_URLRequestProperty property) { + // IMPORTANT: Do not do security validation of parameters at this level + // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See + // SetProperty() above for why. + switch (property) { + case PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL: + data_.has_custom_referrer_url = false; + data_.custom_referrer_url = std::string(); + return true; + case PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING: + data_.has_custom_content_transfer_encoding = false; + data_.custom_content_transfer_encoding = std::string(); + return true; + default: + return false; + } +} + +bool URLRequestInfoImpl::SetBooleanProperty(PP_URLRequestProperty property, + bool value) { + // IMPORTANT: Do not do security validation of parameters at this level + // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See + // SetProperty() above for why. + switch (property) { + case PP_URLREQUESTPROPERTY_STREAMTOFILE: + data_.stream_to_file = value; + return true; + case PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS: + data_.follow_redirects = value; + return true; + case PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS: + data_.record_download_progress = value; + return true; + case PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS: + data_.record_upload_progress = value; + return true; + case PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS: + data_.allow_cross_origin_requests = value; + return true; + case PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS: + data_.allow_credentials = value; + return true; + default: + return false; + } +} + +bool URLRequestInfoImpl::SetIntegerProperty(PP_URLRequestProperty property, + int32_t value) { + // IMPORTANT: Do not do security validation of parameters at this level + // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See + // SetProperty() above for why. + switch (property) { + case PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD: + data_.prefetch_buffer_upper_threshold = value; + return true; + case PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD: + data_.prefetch_buffer_lower_threshold = value; + return true; + default: + return false; + } +} + +bool URLRequestInfoImpl::SetStringProperty(PP_URLRequestProperty property, + const std::string& value) { + // IMPORTANT: Do not do security validation of parameters at this level + // without also adding them to PPB_URLRequestInfo_Impl::ValidateData. See + // SetProperty() above for why. + switch (property) { + case PP_URLREQUESTPROPERTY_URL: + data_.url = value; // NOTE: This may be a relative URL. + return true; + case PP_URLREQUESTPROPERTY_METHOD: { + // Convenience check for synchronously returning errors to the plugin. + // This is re-checked in ValidateData. + std::string canonicalized = ValidateMethod(value); + if (canonicalized.empty()) + return false; + data_.method = canonicalized; + return true; + } + case PP_URLREQUESTPROPERTY_HEADERS: + data_.headers = value; + return true; + case PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL: + data_.has_custom_referrer_url = true; + data_.custom_referrer_url = value; + return true; + case PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING: + data_.has_custom_content_transfer_encoding = true; + data_.custom_content_transfer_encoding = value; + return true; + default: + return false; + } +} + +} // namespace ppapi diff --git a/ppapi/shared_impl/url_request_info_impl.h b/ppapi/shared_impl/url_request_info_impl.h new file mode 100644 index 0000000..622f8c5 --- /dev/null +++ b/ppapi/shared_impl/url_request_info_impl.h @@ -0,0 +1,143 @@ +// 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. + +#ifndef PPAPI_SHARED_IMPL_URL_REQUEST_INFO_IMPL_H_ +#define PPAPI_SHARED_IMPL_URL_REQUEST_INFO_IMPL_H_ + +#include <string> +#include <vector> + +#include "base/compiler_specific.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/thunk/ppb_url_request_info_api.h" + +namespace ppapi { + +namespace thunk { +class PPB_FileRef_API; +} + +struct PPB_URLRequestInfo_Data { + struct BodyItem { + BodyItem(); + explicit BodyItem(const std::string& data); + BodyItem(Resource* file_ref, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time); + + // Set if the input is a file, false means the |data| is valid. + bool is_file; + + std::string data; + + // Is is_file is set, these variables are set. Note that the resource + // may still be NULL in some cases, such as deserialization errors. + // + // This is a bit tricky. In the plugin side of the proxy, both the file ref + // and the file_ref_host_resource will be set and valid. The scoped_ptr + // ensures that the resource is alive for as long as the BodyItem is. + // + // When we deserialize this in the renderer, only the + // file_ref_host_resource's are serialized over IPC. The file_refs won't be + // valid until the host resources are converted to Resource pointers in the + // PPB_URLRequestInfo_Impl. + scoped_refptr<Resource> file_ref; + HostResource file_ref_host_resource; + + int64_t start_offset; + int64_t number_of_bytes; + PP_Time expected_last_modified_time; + + // If you add more stuff here, be sure to modify the serialization rules in + // ppapi_messages.h + }; + + PPB_URLRequestInfo_Data(); + ~PPB_URLRequestInfo_Data(); + + std::string url; + std::string method; + std::string headers; + + bool stream_to_file; + bool follow_redirects; + bool record_download_progress; + bool record_upload_progress; + + // |has_custom_referrer_url| is set to false if a custom referrer hasn't been + // set (or has been set to an Undefined Var) and the default referrer should + // be used. (Setting the custom referrer to an empty string indicates that no + // referrer header should be generated.) + bool has_custom_referrer_url; + std::string custom_referrer_url; + + bool allow_cross_origin_requests; + bool allow_credentials; + + // Similar to the custom referrer (above), but for custom content transfer + // encoding. + bool has_custom_content_transfer_encoding; + std::string custom_content_transfer_encoding; + + int32_t prefetch_buffer_upper_threshold; + int32_t prefetch_buffer_lower_threshold; + + std::vector<BodyItem> body; + + // If you add more stuff here, be sure to modify the serialization rules in + // ppapi_messages.h +}; + +class URLRequestInfoImpl : public ::ppapi::Resource, + public ::ppapi::thunk::PPB_URLRequestInfo_API { + public: + // This constructor initializes the object as a proxy object with the given + // host resource. + URLRequestInfoImpl(const HostResource& host_resource, + const PPB_URLRequestInfo_Data& data); + + ~URLRequestInfoImpl(); + + // Resource overrides. + virtual thunk::PPB_URLRequestInfo_API* AsPPB_URLRequestInfo_API() OVERRIDE; + + // PPB_URLRequestInfo_API implementation. + virtual PP_Bool SetProperty(PP_URLRequestProperty property, + PP_Var var) OVERRIDE; + virtual PP_Bool AppendDataToBody(const void* data, uint32_t len) OVERRIDE; + virtual PP_Bool AppendFileToBody( + PP_Resource file_ref, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time) OVERRIDE; + virtual const PPB_URLRequestInfo_Data& GetData() const OVERRIDE; + + protected: + // Constructor used by the webkit implementation. + URLRequestInfoImpl(PP_Instance instance, + const PPB_URLRequestInfo_Data& data); + + // Checks that the HTTP method is valid, returning the canonicalized version + // if so. Returns empty string if it's invalid. + static std::string ValidateMethod(const std::string& method); + + bool SetUndefinedProperty(PP_URLRequestProperty property); + bool SetBooleanProperty(PP_URLRequestProperty property, bool value); + bool SetIntegerProperty(PP_URLRequestProperty property, int32_t value); + bool SetStringProperty(PP_URLRequestProperty property, + const std::string& value); + + const PPB_URLRequestInfo_Data& data() const { return data_; } + PPB_URLRequestInfo_Data& data() { return data_; } + + private: + PPB_URLRequestInfo_Data data_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(URLRequestInfoImpl); +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_URL_REQUEST_INFO_IMPL_H_ diff --git a/ppapi/shared_impl/var.cc b/ppapi/shared_impl/var.cc index 0542e50..165b8ff 100644 --- a/ppapi/shared_impl/var.cc +++ b/ppapi/shared_impl/var.cc @@ -97,6 +97,11 @@ void Var::AssignVarID(int32 id) { // StringVar ------------------------------------------------------------------- +StringVar::StringVar(PP_Module module, const std::string& str) + : Var(module), + value_(str) { +} + StringVar::StringVar(PP_Module module, const char* str, uint32 len) : Var(module), value_(str, len) { diff --git a/ppapi/shared_impl/var.h b/ppapi/shared_impl/var.h index 02553bb..ce5aa2b 100644 --- a/ppapi/shared_impl/var.h +++ b/ppapi/shared_impl/var.h @@ -90,6 +90,7 @@ class Var : public base::RefCounted<Var> { // DoSomethingWithTheString(string->value()); class StringVar : public Var { public: + StringVar(PP_Module module, const std::string& str); StringVar(PP_Module module, const char* str, uint32 len); virtual ~StringVar(); diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc index bcbef50..d28b347 100644 --- a/ppapi/tests/test_url_loader.cc +++ b/ppapi/tests/test_url_loader.cc @@ -79,7 +79,7 @@ void TestURLLoader::RunTest() { RUN_TEST_FORCEASYNC_AND_NOT(EmptyDataPOST); RUN_TEST_FORCEASYNC_AND_NOT(BinaryDataPOST); RUN_TEST_FORCEASYNC_AND_NOT(CustomRequestHeader); - RUN_TEST_FORCEASYNC_AND_NOT(IgnoresBogusContentLength); + RUN_TEST_FORCEASYNC_AND_NOT(FailsBogusContentLength); RUN_TEST_FORCEASYNC_AND_NOT(SameOriginRestriction); RUN_TEST_FORCEASYNC_AND_NOT(JavascriptURLRestriction); RUN_TEST_FORCEASYNC_AND_NOT(CrossOriginRequest); @@ -310,14 +310,25 @@ std::string TestURLLoader::TestCustomRequestHeader() { return LoadAndCompareBody(request, "1"); } -std::string TestURLLoader::TestIgnoresBogusContentLength() { +std::string TestURLLoader::TestFailsBogusContentLength() { pp::URLRequestInfo request(instance_); request.SetURL("/echo"); request.SetMethod("POST"); request.SetHeaders("Content-Length: 400"); std::string postdata("postdata"); request.AppendDataToBody(postdata.data(), postdata.length()); - return LoadAndCompareBody(request, postdata); + + TestCompletionCallback callback(instance_->pp_instance(), force_async_); + pp::URLLoader loader(*instance_); + int32_t rv = loader.Open(request, callback); + if (force_async_ && rv != PP_OK_COMPLETIONPENDING) + return ReportError("URLLoader::Open force_async", rv); + if (rv == PP_OK_COMPLETIONPENDING) + rv = callback.WaitForResult(); + + // The bad header should have made the request fail. + ASSERT_TRUE(rv == PP_ERROR_FAILED); + PASS(); } std::string TestURLLoader::TestStreamToFile() { diff --git a/ppapi/tests/test_url_loader.h b/ppapi/tests/test_url_loader.h index f88813e..18817ed 100644 --- a/ppapi/tests/test_url_loader.h +++ b/ppapi/tests/test_url_loader.h @@ -46,7 +46,7 @@ class TestURLLoader : public TestCase { std::string TestEmptyDataPOST(); std::string TestBinaryDataPOST(); std::string TestCustomRequestHeader(); - std::string TestIgnoresBogusContentLength(); + std::string TestFailsBogusContentLength(); std::string TestStreamToFile(); std::string TestSameOriginRestriction(); std::string TestJavascriptURLRestriction(); diff --git a/ppapi/thunk/enter.h b/ppapi/thunk/enter.h index e7f0d0f..e83a1a1 100644 --- a/ppapi/thunk/enter.h +++ b/ppapi/thunk/enter.h @@ -97,10 +97,9 @@ class EnterResource { public: EnterResource(PP_Resource resource, bool report_error) : object_(NULL) { - Resource* base = - TrackerBase::Get()->GetResourceTracker()->GetResource(resource); - if (base) - object_ = base->GetAs<ResourceT>(); + resource_ = TrackerBase::Get()->GetResourceTracker()->GetResource(resource); + if (resource_) + object_ = resource_->GetAs<ResourceT>(); // TODO(brettw) check error and if report_error is set, do something. } ~EnterResource() {} @@ -109,8 +108,10 @@ class EnterResource { bool failed() const { return !object_; } ResourceT* object() { return object_; } + Resource* resource() { return resource_; } private: + Resource* resource_; ResourceT* object_; DISALLOW_COPY_AND_ASSIGN(EnterResource); diff --git a/ppapi/thunk/ppb_file_ref_api.h b/ppapi/thunk/ppb_file_ref_api.h index be46cef..b2f0e9d 100644 --- a/ppapi/thunk/ppb_file_ref_api.h +++ b/ppapi/thunk/ppb_file_ref_api.h @@ -8,6 +8,9 @@ #include "ppapi/c/ppb_file_ref.h" namespace ppapi { + +struct PPB_FileRef_CreateInfo; + namespace thunk { class PPB_FileRef_API { @@ -26,6 +29,10 @@ class PPB_FileRef_API { virtual int32_t Delete(PP_CompletionCallback callback) = 0; virtual int32_t Rename(PP_Resource new_file_ref, PP_CompletionCallback callback) = 0; + + // Intermal function for use in proxying. Returns the internal CreateInfo + // (the contained resource does not carry a ref on behalf of the caller). + virtual const PPB_FileRef_CreateInfo& GetCreateInfo() const = 0; }; } // namespace thunk diff --git a/ppapi/thunk/ppb_url_request_info_api.h b/ppapi/thunk/ppb_url_request_info_api.h index 3f6d0ed..56634bc 100644 --- a/ppapi/thunk/ppb_url_request_info_api.h +++ b/ppapi/thunk/ppb_url_request_info_api.h @@ -8,6 +8,9 @@ #include "ppapi/c/ppb_url_request_info.h" namespace ppapi { + +struct PPB_URLRequestInfo_Data; + namespace thunk { class PPB_URLRequestInfo_API { @@ -21,6 +24,9 @@ class PPB_URLRequestInfo_API { int64_t start_offset, int64_t number_of_bytes, PP_Time expected_last_modified_time) = 0; + + // Internal-only function for retrieving the current config. + virtual const PPB_URLRequestInfo_Data& GetData() const = 0; }; } // namespace thunk diff --git a/ppapi/thunk/ppb_url_request_info_thunk.cc b/ppapi/thunk/ppb_url_request_info_thunk.cc index 5c99d18..4f41881 100644 --- a/ppapi/thunk/ppb_url_request_info_thunk.cc +++ b/ppapi/thunk/ppb_url_request_info_thunk.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ppapi/shared_impl/url_request_info_impl.h" #include "ppapi/thunk/thunk.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_url_request_info_api.h" @@ -16,7 +17,8 @@ PP_Resource Create(PP_Instance instance) { EnterFunction<ResourceCreationAPI> enter(instance, true); if (enter.failed()) return 0; - return enter.functions()->CreateURLRequestInfo(instance); + return enter.functions()->CreateURLRequestInfo( + instance, PPB_URLRequestInfo_Data()); } PP_Bool IsURLRequestInfo(PP_Resource resource) { diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index 948a1dd..5564eec 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h @@ -24,6 +24,9 @@ struct PP_VideoCaptureDeviceInfo_Dev; struct PP_Size; namespace ppapi { + +struct PPB_URLRequestInfo_Data; + namespace thunk { // A functional API for creating resource types. Separating out the creation @@ -108,7 +111,9 @@ class ResourceCreationAPI { const char* name, const char* proto) = 0; virtual PP_Resource CreateURLLoader(PP_Instance instance) = 0; - virtual PP_Resource CreateURLRequestInfo(PP_Instance instance) = 0; + virtual PP_Resource CreateURLRequestInfo( + PP_Instance instance, + const PPB_URLRequestInfo_Data& data) = 0; virtual PP_Resource CreateVideoCapture(PP_Instance instance) = 0; virtual PP_Resource CreateVideoDecoder( PP_Instance instance, diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc index 9fb77e07..c353ed8 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc @@ -1000,7 +1000,10 @@ int32_t PluginInstance::Navigate(PPB_URLRequestInfo_Impl* request, WebFrame* frame = document.frame(); if (!frame) return PP_ERROR_FAILED; - WebURLRequest web_request(request->ToWebURLRequest(frame)); + + WebURLRequest web_request; + if (!request->ToWebURLRequest(frame, &web_request)) + return PP_ERROR_FAILED; web_request.setFirstPartyForCookies(document.firstPartyForCookies()); web_request.setHasUserGesture(from_user_action); diff --git a/webkit/plugins/ppapi/ppb_directory_reader_impl.cc b/webkit/plugins/ppapi/ppb_directory_reader_impl.cc index 38e2179..36428d8 100644 --- a/webkit/plugins/ppapi/ppb_directory_reader_impl.cc +++ b/webkit/plugins/ppapi/ppb_directory_reader_impl.cc @@ -104,7 +104,8 @@ void PPB_DirectoryReader_Impl::AddNewEntries( const std::vector<base::FileUtilProxy::Entry>& entries, bool has_more) { DCHECK(!entries.empty() || !has_more); has_more_ = has_more; - std::string dir_path = directory_ref_->virtual_path(); + + std::string dir_path = directory_ref_->GetCreateInfo().path; if (dir_path[dir_path.size() - 1] != '/') dir_path += '/'; FilePath::StringType dir_file_path = UTF8StringToFilePathString(dir_path); @@ -127,9 +128,12 @@ bool PPB_DirectoryReader_Impl::FillUpEntry() { entries_.pop(); if (entry_->file_ref) ResourceTracker::Get()->ReleaseResource(entry_->file_ref); - PPB_FileRef_Impl* file_ref = - new PPB_FileRef_Impl(pp_instance(), directory_ref_->file_system(), - FilePathStringToUTF8String(dir_entry.name)); + + PPB_FileRef_Impl* file_ref = PPB_FileRef_Impl::CreateInternal( + directory_ref_->file_system()->pp_resource(), + FilePathStringToUTF8String(dir_entry.name)); + if (!file_ref) + return false; entry_->file_ref = file_ref->GetReference(); entry_->file_type = (dir_entry.is_directory ? PP_FILETYPE_DIRECTORY : PP_FILETYPE_REGULAR); diff --git a/webkit/plugins/ppapi/ppb_file_chooser_impl.cc b/webkit/plugins/ppapi/ppb_file_chooser_impl.cc index c9c3e08..b2acadc 100644 --- a/webkit/plugins/ppapi/ppb_file_chooser_impl.cc +++ b/webkit/plugins/ppapi/ppb_file_chooser_impl.cc @@ -110,7 +110,7 @@ void PPB_FileChooser_Impl::StoreChosenFiles( #endif chosen_files_.push_back(make_scoped_refptr( - new PPB_FileRef_Impl(pp_instance(), file_path))); + PPB_FileRef_Impl::CreateExternal(pp_instance(), file_path))); } RunCallback((chosen_files_.size() > 0) ? PP_OK : PP_ERROR_USERCANCEL); diff --git a/webkit/plugins/ppapi/ppb_file_ref_impl.cc b/webkit/plugins/ppapi/ppb_file_ref_impl.cc index d586149..c196f15 100644 --- a/webkit/plugins/ppapi/ppb_file_ref_impl.cc +++ b/webkit/plugins/ppapi/ppb_file_ref_impl.cc @@ -21,6 +21,8 @@ #include "webkit/plugins/ppapi/ppb_file_system_impl.h" #include "webkit/plugins/ppapi/resource_helper.h" +using ppapi::HostResource; +using ppapi::PPB_FileRef_CreateInfo; using ppapi::PPTimeToTime; using ppapi::StringVar; using ppapi::thunk::EnterResourceNoLock; @@ -51,35 +53,51 @@ void TrimTrailingSlash(std::string* path) { path->erase(path->size() - 1, 1); } -} // namespace +std::string GetNameForExternalFilePath(const FilePath& in_path) { + const FilePath::StringType& path = in_path.value(); + size_t pos = path.rfind(FilePath::kSeparators[0]); + CHECK(pos != FilePath::StringType::npos); +#if defined(OS_WIN) + return WideToUTF8(path.substr(pos + 1)); +#elif defined(OS_POSIX) + return path.substr(pos + 1); +#else +#error "Unsupported platform." +#endif +} -PPB_FileRef_Impl::PPB_FileRef_Impl() - : Resource(0), - file_system_() { +std::string GetNameForVirtualFilePath(const std::string& path) { + if (path.size() == 1 && path[0] == '/') + return path; + + // There should always be a leading slash at least! + size_t pos = path.rfind('/'); + CHECK(pos != std::string::npos); + return path.substr(pos + 1); } -PPB_FileRef_Impl::PPB_FileRef_Impl( - PP_Instance instance, - scoped_refptr<PPB_FileSystem_Impl> file_system, - const std::string& validated_path) - : Resource(instance), +} // namespace + +PPB_FileRef_Impl::PPB_FileRef_Impl(const PPB_FileRef_CreateInfo& info, + PPB_FileSystem_Impl* file_system) + : FileRefImpl(FileRefImpl::InitAsImpl(), info), file_system_(file_system), - virtual_path_(validated_path) { + external_file_system_path_() { } -PPB_FileRef_Impl::PPB_FileRef_Impl(PP_Instance instance, +PPB_FileRef_Impl::PPB_FileRef_Impl(const PPB_FileRef_CreateInfo& info, const FilePath& external_file_path) - : Resource(instance), - file_system_(NULL), - system_path_(external_file_path) { + : FileRefImpl(FileRefImpl::InitAsImpl(), info), + file_system_(), + external_file_system_path_(external_file_path) { } PPB_FileRef_Impl::~PPB_FileRef_Impl() { } // static -PP_Resource PPB_FileRef_Impl::Create(PP_Resource pp_file_system, - const char* path) { +PPB_FileRef_Impl* PPB_FileRef_Impl::CreateInternal(PP_Resource pp_file_system, + const std::string& path) { EnterResourceNoLock<PPB_FileSystem_API> enter(pp_file_system, true); if (enter.failed()) return 0; @@ -93,83 +111,52 @@ PP_Resource PPB_FileRef_Impl::Create(PP_Resource pp_file_system, file_system->type() != PP_FILESYSTEMTYPE_LOCALTEMPORARY) return 0; - std::string validated_path(path); - if (!IsValidLocalPath(validated_path)) - return 0; - TrimTrailingSlash(&validated_path); + PPB_FileRef_CreateInfo info; + info.resource = HostResource::MakeInstanceOnly(file_system->pp_instance()); + info.file_system_type = file_system->type(); - return (new PPB_FileRef_Impl(file_system->pp_instance(), - file_system, validated_path))->GetReference(); -} + // Validate the path. + info.path = path; + if (!IsValidLocalPath(info.path)) + return 0; + TrimTrailingSlash(&info.path); -PPB_FileRef_API* PPB_FileRef_Impl::AsPPB_FileRef_API() { - return this; -} + info.name = GetNameForVirtualFilePath(info.path); -PPB_FileRef_Impl* PPB_FileRef_Impl::AsPPB_FileRef_Impl() { - return this; + return new PPB_FileRef_Impl(info, file_system); } -PP_FileSystemType PPB_FileRef_Impl::GetFileSystemType() const { - // When the file ref exists but there's no explicit filesystem object - // associated with it, that means it's an "external" filesystem. - if (!file_system_) - return PP_FILESYSTEMTYPE_EXTERNAL; - return file_system_->type(); -} - -PP_Var PPB_FileRef_Impl::GetName() const { - std::string result; - if (GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) { - FilePath::StringType path = system_path_.value(); - size_t pos = path.rfind(FilePath::kSeparators[0]); - DCHECK(pos != FilePath::StringType::npos); -#if defined(OS_WIN) - result = WideToUTF8(path.substr(pos + 1)); -#elif defined(OS_POSIX) - result = path.substr(pos + 1); -#else -#error "Unsupported platform." -#endif - } else if (virtual_path_.size() == 1 && virtual_path_[0] == '/') { - result = virtual_path_; - } else { - // There should always be a leading slash at least! - size_t pos = virtual_path_.rfind('/'); - DCHECK(pos != std::string::npos); - result = virtual_path_.substr(pos + 1); - } - - PluginModule* plugin_module = ResourceHelper::GetPluginModule(this); - if (!plugin_module) - return PP_MakeUndefined(); - return StringVar::StringToPPVar(plugin_module->pp_module(), result); -} +// static +PPB_FileRef_Impl* PPB_FileRef_Impl::CreateExternal( + PP_Instance instance, + const FilePath& external_file_path) { + PPB_FileRef_CreateInfo info; + info.resource = HostResource::MakeInstanceOnly(instance); + info.file_system_type = PP_FILESYSTEMTYPE_EXTERNAL; + info.name = GetNameForExternalFilePath(external_file_path); -PP_Var PPB_FileRef_Impl::GetPath() const { - if (GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) - return PP_MakeUndefined(); - PluginModule* plugin_module = ResourceHelper::GetPluginModule(this); - if (!plugin_module) - return PP_MakeUndefined(); - return StringVar::StringToPPVar(plugin_module->pp_module(), virtual_path_); + return new PPB_FileRef_Impl(info, external_file_path); } PP_Resource PPB_FileRef_Impl::GetParent() { if (GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) return 0; + const std::string& virtual_path = GetCreateInfo().path; + // There should always be a leading slash at least! - size_t pos = virtual_path_.rfind('/'); - DCHECK(pos != std::string::npos); + size_t pos = virtual_path.rfind('/'); + CHECK(pos != std::string::npos); // If the path is "/foo", then we want to include the slash. if (pos == 0) pos++; - std::string parent_path = virtual_path_.substr(0, pos); + std::string parent_path = virtual_path.substr(0, pos); scoped_refptr<PPB_FileRef_Impl> parent_ref( - new PPB_FileRef_Impl(pp_instance(), file_system_, parent_path)); + CreateInternal(file_system_->pp_resource(), parent_path)); + if (!parent_ref.get()) + return 0; return parent_ref->GetReference(); } @@ -251,7 +238,7 @@ FilePath PPB_FileRef_Impl::GetSystemPath() const { NOTREACHED(); return FilePath(); } - return system_path_; + return external_file_system_path_; } GURL PPB_FileRef_Impl::GetFileSystemURL() const { @@ -260,14 +247,16 @@ GURL PPB_FileRef_Impl::GetFileSystemURL() const { NOTREACHED(); return GURL(); } - if (!virtual_path_.size()) - return file_system_->root_url(); + + const std::string& virtual_path = GetCreateInfo().path; + CHECK(!virtual_path.empty()); // Should always be at least "/". + // Since |virtual_path_| starts with a '/', it looks like an absolute path. // We need to trim off the '/' before calling Resolve, as FileSystem URLs // start with a storage type identifier that looks like a path segment. // TODO(ericu): Switch this to use Resolve after fixing GURL to understand // FileSystem URLs. - return GURL(file_system_->root_url().spec() + virtual_path_.substr(1)); + return GURL(file_system_->root_url().spec() + virtual_path.substr(1)); } bool PPB_FileRef_Impl::IsValidNonExternalFileSystem() const { diff --git a/webkit/plugins/ppapi/ppb_file_ref_impl.h b/webkit/plugins/ppapi/ppb_file_ref_impl.h index 1bd264c..de1649d 100644 --- a/webkit/plugins/ppapi/ppb_file_ref_impl.h +++ b/webkit/plugins/ppapi/ppb_file_ref_impl.h @@ -10,39 +10,30 @@ #include "base/file_path.h" #include "googleurl/src/gurl.h" #include "ppapi/c/ppb_file_ref.h" -#include "ppapi/shared_impl/resource.h" -#include "ppapi/thunk/ppb_file_ref_api.h" +#include "ppapi/shared_impl/file_ref_impl.h" namespace webkit { namespace ppapi { class PPB_FileSystem_Impl; -class PluginDelegate; -class PluginModule; -class PPB_FileRef_Impl : public ::ppapi::Resource, - public ::ppapi::thunk::PPB_FileRef_API { +class PPB_FileRef_Impl : public ::ppapi::FileRefImpl { public: - PPB_FileRef_Impl(); - PPB_FileRef_Impl(PP_Instance instance, - scoped_refptr<PPB_FileSystem_Impl> file_system, - const std::string& validated_path); - PPB_FileRef_Impl(PP_Instance instance, + PPB_FileRef_Impl(const ::ppapi::PPB_FileRef_CreateInfo& info, + PPB_FileSystem_Impl* file_system); + PPB_FileRef_Impl(const ::ppapi::PPB_FileRef_CreateInfo& info, const FilePath& external_file_path); virtual ~PPB_FileRef_Impl(); - static PP_Resource Create(PP_Resource file_system, const char* path); + // The returned object will have a refcount of 0 (just like "new"). + static PPB_FileRef_Impl* CreateInternal(PP_Resource pp_file_system, + const std::string& path); - // Resource overrides. - virtual PPB_FileRef_Impl* AsPPB_FileRef_Impl(); + // The returned object will have a refcount of 0 (just like "new"). + static PPB_FileRef_Impl* CreateExternal(PP_Instance instance, + const FilePath& external_file_path); - // Resource overrides. - virtual ::ppapi::thunk::PPB_FileRef_API* AsPPB_FileRef_API() OVERRIDE; - - // PPB_FileRef_API implementation. - virtual PP_FileSystemType GetFileSystemType() const OVERRIDE; - virtual PP_Var GetName() const OVERRIDE; - virtual PP_Var GetPath() const OVERRIDE; + // PPB_FileRef_API implementation (not provided by FileRefImpl). virtual PP_Resource GetParent() OVERRIDE; virtual int32_t MakeDirectory(PP_Bool make_ancestors, PP_CompletionCallback callback) OVERRIDE; @@ -55,10 +46,8 @@ class PPB_FileRef_Impl : public ::ppapi::Resource, PPB_FileSystem_Impl* file_system() const { return file_system_.get(); } - // Returns the virtual path (i.e., the path that the pepper plugin sees) - const std::string& virtual_path() const { return virtual_path_; } - - // Returns the system path corresponding to this file. + // Returns the system path corresponding to this file. Valid only for + // external filesystems. FilePath GetSystemPath() const; // Returns the FileSystem API URL corresponding to this file. @@ -70,9 +59,11 @@ class PPB_FileRef_Impl : public ::ppapi::Resource, // access check for these functions. bool IsValidNonExternalFileSystem() const; + // Null for external filesystems. scoped_refptr<PPB_FileSystem_Impl> file_system_; - std::string virtual_path_; // UTF-8 encoded - FilePath system_path_; + + // Used only for external filesystems. + FilePath external_file_system_path_; DISALLOW_COPY_AND_ASSIGN(PPB_FileRef_Impl); }; diff --git a/webkit/plugins/ppapi/ppb_url_loader_impl.cc b/webkit/plugins/ppapi/ppb_url_loader_impl.cc index ce58de4..edc9207 100644 --- a/webkit/plugins/ppapi/ppb_url_loader_impl.cc +++ b/webkit/plugins/ppapi/ppb_url_loader_impl.cc @@ -115,7 +115,14 @@ int32_t PPB_URLLoader_Impl::Open(PP_Resource request_id, WebFrame* frame = GetFrameForResource(this); if (!frame) return PP_ERROR_FAILED; - WebURLRequest web_request(request->ToWebURLRequest(frame)); + WebURLRequest web_request; + if (!request->ToWebURLRequest(frame, &web_request)) + return PP_ERROR_FAILED; + + // Save a copy of the request info so the plugin can continue to use and + // change it while we're doing the request without affecting us. We must do + // this after ToWebURLRequest since that fills out the file refs. + request_data_ = request->GetData(); WebURLLoaderOptions options; if (has_universal_access_) { @@ -123,11 +130,11 @@ int32_t PPB_URLLoader_Impl::Open(PP_Resource request_id, options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyAllow; options.allowCredentials = true; - } else if (request->allow_cross_origin_requests()) { + } else if (request_data_.allow_cross_origin_requests) { // Otherwise, allow cross-origin requests with access control. options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl; - options.allowCredentials = request->allow_credentials(); + options.allowCredentials = request_data_.allow_credentials; } is_asynchronous_load_suspended_ = false; @@ -137,8 +144,6 @@ int32_t PPB_URLLoader_Impl::Open(PP_Resource request_id, loader_->loadAsynchronously(web_request, this); - request_info_ = scoped_refptr<PPB_URLRequestInfo_Impl>(request); - // Notify completion when we receive a redirect or response headers. RegisterCallback(callback); return PP_OK_COMPLETIONPENDING; @@ -260,7 +265,7 @@ void PPB_URLLoader_Impl::willSendRequest( WebURLLoader* loader, WebURLRequest& new_request, const WebURLResponse& redirect_response) { - if (!request_info_->follow_redirects()) { + if (!request_data_.follow_redirects) { SaveResponse(redirect_response); loader_->setDefersLoading(true); RunCallback(PP_OK); @@ -310,14 +315,12 @@ void PPB_URLLoader_Impl::didReceiveData(WebURLLoader* loader, // To avoid letting the network stack download an entire stream all at once, // defer loading when we have enough buffer. // Check the buffer size after potentially moving some to the user buffer. - DCHECK(!request_info_ || - (request_info_->prefetch_buffer_lower_threshold() < - request_info_->prefetch_buffer_upper_threshold())); + DCHECK(request_data_.prefetch_buffer_lower_threshold < + request_data_.prefetch_buffer_upper_threshold); if (!is_streaming_to_file_ && !is_asynchronous_load_suspended_ && - request_info_ && (buffer_.size() >= static_cast<size_t>( - request_info_->prefetch_buffer_upper_threshold()))) { + request_data_.prefetch_buffer_upper_threshold))) { DVLOG(1) << "Suspending async load - buffer size: " << buffer_.size(); loader->setDefersLoading(true); is_asynchronous_load_suspended_ = true; @@ -402,10 +405,10 @@ size_t PPB_URLLoader_Impl::FillUserBuffer() { buffer_.erase(buffer_.begin(), buffer_.begin() + bytes_to_copy); // If the buffer is getting too empty, resume asynchronous loading. - DCHECK(!is_asynchronous_load_suspended_ || request_info_); + DCHECK(!is_asynchronous_load_suspended_); if (is_asynchronous_load_suspended_ && buffer_.size() <= static_cast<size_t>( - request_info_->prefetch_buffer_lower_threshold())) { + request_data_.prefetch_buffer_lower_threshold)) { DVLOG(1) << "Resuming async load - buffer size: " << buffer_.size(); loader_->setDefersLoading(false); is_asynchronous_load_suspended_ = false; @@ -442,11 +445,11 @@ void PPB_URLLoader_Impl::UpdateStatus() { } bool PPB_URLLoader_Impl::RecordDownloadProgress() const { - return request_info_ && request_info_->record_download_progress(); + return request_data_.record_download_progress; } bool PPB_URLLoader_Impl::RecordUploadProgress() const { - return request_info_ && request_info_->record_upload_progress(); + return request_data_.record_upload_progress; } } // namespace ppapi diff --git a/webkit/plugins/ppapi/ppb_url_loader_impl.h b/webkit/plugins/ppapi/ppb_url_loader_impl.h index 429a042..f45181b 100644 --- a/webkit/plugins/ppapi/ppb_url_loader_impl.h +++ b/webkit/plugins/ppapi/ppb_url_loader_impl.h @@ -12,6 +12,7 @@ #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" #include "ppapi/shared_impl/resource.h" +#include "ppapi/shared_impl/url_request_info_impl.h" #include "ppapi/thunk/ppb_url_loader_api.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderClient.h" #include "webkit/plugins/ppapi/callbacks.h" @@ -121,8 +122,13 @@ class PPB_URLLoader_Impl : public ::ppapi::Resource, // If true, then the plugin instance is a full-frame plugin and we're just // wrapping the main document's loader (i.e. loader_ is null). bool main_document_loader_; + + // Keep a copy of the request data. We specifically do this instead of + // keeping a reference to the request resource, because the plugin might + // change the request info resource out from under us. + ::ppapi::PPB_URLRequestInfo_Data request_data_; + scoped_ptr<WebKit::WebURLLoader> loader_; - scoped_refptr<PPB_URLRequestInfo_Impl> request_info_; scoped_refptr<PPB_URLResponseInfo_Impl> response_info_; scoped_refptr<TrackedCompletionCallback> pending_callback_; std::deque<char> buffer_; diff --git a/webkit/plugins/ppapi/ppb_url_request_info_impl.cc b/webkit/plugins/ppapi/ppb_url_request_info_impl.cc index 30ed504..0ebffb7 100644 --- a/webkit/plugins/ppapi/ppb_url_request_info_impl.cc +++ b/webkit/plugins/ppapi/ppb_url_request_info_impl.cc @@ -9,10 +9,8 @@ #include "googleurl/src/gurl.h" #include "googleurl/src/url_util.h" #include "net/http/http_util.h" -#include "ppapi/c/pp_var.h" #include "ppapi/shared_impl/var.h" #include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppb_file_ref_api.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" @@ -22,16 +20,14 @@ #include "webkit/glue/webkit_glue.h" #include "webkit/plugins/ppapi/common.h" #include "webkit/plugins/ppapi/plugin_module.h" -#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppb_file_ref_impl.h" #include "webkit/plugins/ppapi/ppb_file_system_impl.h" #include "webkit/plugins/ppapi/resource_helper.h" -#include "webkit/plugins/ppapi/string.h" -using ppapi::StringVar; +using ppapi::PPB_URLRequestInfo_Data; +using ppapi::Resource; using ppapi::thunk::EnterResourceNoLock; using ppapi::thunk::PPB_FileRef_API; -using ppapi::thunk::PPB_URLRequestInfo_API; using WebKit::WebData; using WebKit::WebHTTPBody; using WebKit::WebString; @@ -65,51 +61,6 @@ bool IsValidToken(const std::string& token) { return true; } -// These methods are not allowed by the XMLHttpRequest standard. -// http://www.w3.org/TR/XMLHttpRequest/#the-open-method -const char* const kForbiddenHttpMethods[] = { - "connect", - "trace", - "track", -}; - -// These are the "known" methods in the Webkit XHR implementation. Also see -// the XMLHttpRequest standard. -// http://www.w3.org/TR/XMLHttpRequest/#the-open-method -const char* const kKnownHttpMethods[] = { - "get", - "post", - "put", - "head", - "copy", - "delete", - "index", - "lock", - "m-post", - "mkcol", - "move", - "options", - "propfind", - "proppatch", - "unlock", -}; - -std::string ValidateMethod(const std::string& method) { - for (size_t i = 0; i < arraysize(kForbiddenHttpMethods); ++i) { - if (LowerCaseEqualsASCII(method, kForbiddenHttpMethods[i])) - return std::string(); - } - for (size_t i = 0; i < arraysize(kKnownHttpMethods); ++i) { - if (LowerCaseEqualsASCII(method, kKnownHttpMethods[i])) { - // Convert the method name to upper case to match Webkit and Firefox's - // XHR implementation. - return StringToUpperASCII(std::string(kKnownHttpMethods[i])); - } - } - // Pass through unknown methods that are not forbidden. - return method; -} - // A header string containing any of the following fields will cause // an error. The list comes from the XMLHttpRequest standard. // http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method @@ -159,282 +110,161 @@ bool AreValidHeaders(const std::string& headers) { } // namespace -struct PPB_URLRequestInfo_Impl::BodyItem { - explicit BodyItem(const std::string& data) - : data(data), - start_offset(0), - number_of_bytes(-1), - expected_last_modified_time(0.0) { - } - - BodyItem(PPB_FileRef_Impl* file_ref, - int64_t start_offset, - int64_t number_of_bytes, - PP_Time expected_last_modified_time) - : file_ref(file_ref), - start_offset(start_offset), - number_of_bytes(number_of_bytes), - expected_last_modified_time(expected_last_modified_time) { - } - std::string data; - scoped_refptr<PPB_FileRef_Impl> file_ref; - int64_t start_offset; - int64_t number_of_bytes; - PP_Time expected_last_modified_time; -}; - -PPB_URLRequestInfo_Impl::PPB_URLRequestInfo_Impl(PP_Instance instance) - : Resource(instance), - stream_to_file_(false), - follow_redirects_(true), - record_download_progress_(false), - record_upload_progress_(false), - has_custom_referrer_url_(false), - allow_cross_origin_requests_(false), - allow_credentials_(false), - has_custom_content_transfer_encoding_(false), - prefetch_buffer_upper_threshold_(kDefaultPrefetchBufferUpperThreshold), - prefetch_buffer_lower_threshold_(kDefaultPrefetchBufferLowerThreshold) { +PPB_URLRequestInfo_Impl::PPB_URLRequestInfo_Impl( + PP_Instance instance, + const PPB_URLRequestInfo_Data& data) + : URLRequestInfoImpl(instance, data) { } PPB_URLRequestInfo_Impl::~PPB_URLRequestInfo_Impl() { } -PPB_URLRequestInfo_API* PPB_URLRequestInfo_Impl::AsPPB_URLRequestInfo_API() { - return this; -} - -PP_Bool PPB_URLRequestInfo_Impl::SetProperty(PP_URLRequestProperty property, - PP_Var var) { - PP_Bool result = PP_FALSE; - switch (var.type) { - case PP_VARTYPE_UNDEFINED: - result = PP_FromBool(SetUndefinedProperty(property)); - break; - case PP_VARTYPE_BOOL: - result = PP_FromBool( - SetBooleanProperty(property, PP_ToBool(var.value.as_bool))); - break; - case PP_VARTYPE_INT32: - result = PP_FromBool( - SetIntegerProperty(property, var.value.as_int)); - break; - case PP_VARTYPE_STRING: { - StringVar* string = StringVar::FromPPVar(var); - if (string) - result = PP_FromBool(SetStringProperty(property, string->value())); - break; - } - default: - break; - } - return result; -} - -PP_Bool PPB_URLRequestInfo_Impl::AppendDataToBody(const void* data, - uint32_t len) { - if (len > 0) - body_.push_back(BodyItem(std::string(static_cast<const char*>(data), len))); - return PP_TRUE; -} - -PP_Bool PPB_URLRequestInfo_Impl::AppendFileToBody( - PP_Resource file_ref, - int64_t start_offset, - int64_t number_of_bytes, - PP_Time expected_last_modified_time) { - // Ignore a call to append nothing. - if (number_of_bytes == 0) - return PP_TRUE; - - // Check for bad values. (-1 means read until end of file.) - if (start_offset < 0 || number_of_bytes < -1) - return PP_FALSE; - - EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true); - if (enter.failed()) - return PP_FALSE; - - body_.push_back(BodyItem(static_cast<PPB_FileRef_Impl*>(enter.object()), - start_offset, - number_of_bytes, - expected_last_modified_time)); - return PP_TRUE; -} +bool PPB_URLRequestInfo_Impl::ToWebURLRequest(WebFrame* frame, + WebURLRequest* dest) { + // In the out-of-process case, we've received the PPB_URLRequestInfo_Data + // from the untrusted plugin and done no validation on it. We need to be + // sure it's not being malicious by checking everything for consistency. + if (!ValidateData()) + return false; -WebURLRequest PPB_URLRequestInfo_Impl::ToWebURLRequest(WebFrame* frame) const { - WebURLRequest web_request; - web_request.initialize(); - web_request.setURL(frame->document().completeURL(WebString::fromUTF8(url_))); - web_request.setDownloadToFile(stream_to_file_); - web_request.setReportUploadProgress(record_upload_progress()); + dest->initialize(); + dest->setURL(frame->document().completeURL(WebString::fromUTF8(data().url))); + dest->setDownloadToFile(data().stream_to_file); + dest->setReportUploadProgress(data().record_upload_progress); - if (!method_.empty()) - web_request.setHTTPMethod(WebString::fromUTF8(method_)); + if (!data().method.empty()) + dest->setHTTPMethod(WebString::fromUTF8(data().method)); - web_request.setFirstPartyForCookies( - frame->document().firstPartyForCookies()); + dest->setFirstPartyForCookies(frame->document().firstPartyForCookies()); - if (!headers_.empty()) { - net::HttpUtil::HeadersIterator it(headers_.begin(), headers_.end(), "\n"); + const std::string& headers = data().headers; + if (!headers.empty()) { + net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n"); while (it.GetNext()) { - web_request.addHTTPHeaderField( + dest->addHTTPHeaderField( WebString::fromUTF8(it.name()), WebString::fromUTF8(it.values())); } } - if (!body_.empty()) { + // Append the upload data. + if (!data().body.empty()) { WebHTTPBody http_body; http_body.initialize(); - for (size_t i = 0; i < body_.size(); ++i) { - if (body_[i].file_ref) { - FilePath platform_path; - switch (body_[i].file_ref->GetFileSystemType()) { - case PP_FILESYSTEMTYPE_LOCALTEMPORARY: - case PP_FILESYSTEMTYPE_LOCALPERSISTENT: { - // TODO(kinuko): remove this sync IPC when we add more generic - // AppendURLRange solution that works for both Blob/FileSystem URL. - PluginDelegate* plugin_delegate = - ResourceHelper::GetPluginDelegate(this); - if (plugin_delegate) { - plugin_delegate->SyncGetFileSystemPlatformPath( - body_[i].file_ref->GetFileSystemURL(), &platform_path); - } - break; - } - case PP_FILESYSTEMTYPE_EXTERNAL: - platform_path = body_[i].file_ref->GetSystemPath(); - break; - default: - NOTREACHED(); - } - http_body.appendFileRange( - webkit_glue::FilePathToWebString(platform_path), - body_[i].start_offset, - body_[i].number_of_bytes, - body_[i].expected_last_modified_time); + for (size_t i = 0; i < data().body.size(); ++i) { + const PPB_URLRequestInfo_Data::BodyItem& item = data().body[i]; + if (item.is_file) { + if (!AppendFileRefToBody(item.file_ref, + item.start_offset, + item.number_of_bytes, + item.expected_last_modified_time, + &http_body)) + return false; } else { - DCHECK(!body_[i].data.empty()); - http_body.appendData(WebData(body_[i].data)); + DCHECK(!item.data.empty()); + http_body.appendData(WebData(item.data)); } } - web_request.setHTTPBody(http_body); + dest->setHTTPBody(http_body); } - if (has_custom_referrer_url_) { - if (!custom_referrer_url_.empty()) - frame->setReferrerForRequest(web_request, GURL(custom_referrer_url_)); - } else if (!allow_cross_origin_requests_) { + if (data().has_custom_referrer_url) { + if (!data().custom_referrer_url.empty()) + frame->setReferrerForRequest(*dest, GURL(data().custom_referrer_url)); + } else if (!data().allow_cross_origin_requests) { // Use default, except for cross-origin requests, since 'referer' is not // whitelisted and will cause the request to fail. - frame->setReferrerForRequest(web_request, WebURL()); + frame->setReferrerForRequest(*dest, WebURL()); } - if (has_custom_content_transfer_encoding_) { - if (!custom_content_transfer_encoding_.empty()) { - web_request.addHTTPHeaderField( + if (data().has_custom_content_transfer_encoding) { + if (!data().custom_content_transfer_encoding.empty()) { + dest->addHTTPHeaderField( WebString::fromUTF8("Content-Transfer-Encoding"), - WebString::fromUTF8(custom_content_transfer_encoding_)); + WebString::fromUTF8(data().custom_content_transfer_encoding)); } } - return web_request; + return true; } bool PPB_URLRequestInfo_Impl::RequiresUniversalAccess() const { return - has_custom_referrer_url_ || - has_custom_content_transfer_encoding_ || - url_util::FindAndCompareScheme(url_, "javascript", NULL); + data().has_custom_referrer_url || + data().has_custom_content_transfer_encoding || + url_util::FindAndCompareScheme(data().url, "javascript", NULL); } -bool PPB_URLRequestInfo_Impl::SetUndefinedProperty( - PP_URLRequestProperty property) { - switch (property) { - case PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL: - has_custom_referrer_url_ = false; - custom_referrer_url_ = std::string(); - return true; - case PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING: - has_custom_content_transfer_encoding_ = false; - custom_content_transfer_encoding_ = std::string(); - return true; - default: +bool PPB_URLRequestInfo_Impl::ValidateData() { + // Method should either be empty or a valid one. + if (!data().method.empty()) { + std::string canonicalized = ValidateMethod(data().method); + if (canonicalized.empty()) return false; + data().method = canonicalized; } -} -bool PPB_URLRequestInfo_Impl::SetBooleanProperty(PP_URLRequestProperty property, - bool value) { - switch (property) { - case PP_URLREQUESTPROPERTY_STREAMTOFILE: - stream_to_file_ = value; - return true; - case PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS: - follow_redirects_ = value; - return true; - case PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS: - record_download_progress_ = value; - return true; - case PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS: - record_upload_progress_ = value; - return true; - case PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS: - allow_cross_origin_requests_ = value; - return true; - case PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS: - allow_credentials_ = value; - return true; - default: - return false; - } -} + if (!AreValidHeaders(data().headers)) + return false; -bool PPB_URLRequestInfo_Impl::SetIntegerProperty(PP_URLRequestProperty property, - int32_t value) { - switch (property) { - case PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD: - prefetch_buffer_upper_threshold_ = value; - return true; - case PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD: - prefetch_buffer_lower_threshold_ = value; - return true; - default: - return false; + // Get the Resource objects for any file refs with only host resource (this + // is the state of the request as it comes off IPC). + for (size_t i = 0; i < data().body.size(); ++i) { + PPB_URLRequestInfo_Data::BodyItem& item = data().body[i]; + if (item.is_file && !item.file_ref) { + EnterResourceNoLock<PPB_FileRef_API> enter( + item.file_ref_host_resource.host_resource(), false); + if (!enter.succeeded()) + return false; + item.file_ref = enter.resource(); + } } + return true; } -bool PPB_URLRequestInfo_Impl::SetStringProperty(PP_URLRequestProperty property, - const std::string& value) { - // TODO(darin): Validate input. Perhaps at a different layer? - switch (property) { - case PP_URLREQUESTPROPERTY_URL: - url_ = value; // NOTE: This may be a relative URL. - return true; - case PP_URLREQUESTPROPERTY_METHOD: - if (!IsValidToken(value)) - return false; - method_ = ValidateMethod(value); - return !method_.empty(); - case PP_URLREQUESTPROPERTY_HEADERS: - if (!AreValidHeaders(value)) - return false; - headers_ = value; - return true; - case PP_URLREQUESTPROPERTY_CUSTOMREFERRERURL: - has_custom_referrer_url_ = true; - custom_referrer_url_ = value; - return true; - case PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING: - has_custom_content_transfer_encoding_ = true; - custom_content_transfer_encoding_ = value; - return true; +bool PPB_URLRequestInfo_Impl::AppendFileRefToBody( + Resource* file_ref_resource, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time, + WebHTTPBody *http_body) { + // Get the underlying file ref impl. + if (!file_ref_resource) + return false; + PPB_FileRef_API* file_ref_api = file_ref_resource->AsPPB_FileRef_API(); + if (!file_ref_api) + return false; + const PPB_FileRef_Impl* file_ref = + static_cast<PPB_FileRef_Impl*>(file_ref_api); + + PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this); + if (!plugin_delegate) + return false; + + FilePath platform_path; + switch (file_ref->GetFileSystemType()) { + case PP_FILESYSTEMTYPE_LOCALTEMPORARY: + case PP_FILESYSTEMTYPE_LOCALPERSISTENT: + // TODO(kinuko): remove this sync IPC when we add more generic + // AppendURLRange solution that works for both Blob/FileSystem URL. + plugin_delegate->SyncGetFileSystemPlatformPath( + file_ref->GetFileSystemURL(), &platform_path); + break; + case PP_FILESYSTEMTYPE_EXTERNAL: + platform_path = file_ref->GetSystemPath(); + break; default: - return false; + NOTREACHED(); } + http_body->appendFileRange( + webkit_glue::FilePathToWebString(platform_path), + start_offset, + number_of_bytes, + expected_last_modified_time); + return true; } + } // namespace ppapi } // namespace webkit diff --git a/webkit/plugins/ppapi/ppb_url_request_info_impl.h b/webkit/plugins/ppapi/ppb_url_request_info_impl.h index 277edfb..a534002 100644 --- a/webkit/plugins/ppapi/ppb_url_request_info_impl.h +++ b/webkit/plugins/ppapi/ppb_url_request_info_impl.h @@ -5,105 +5,49 @@ #ifndef WEBKIT_PLUGINS_PPAPI_PPB_URL_REQUEST_INFO_IMPL_H_ #define WEBKIT_PLUGINS_PPAPI_PPB_URL_REQUEST_INFO_IMPL_H_ -#include <string> -#include <vector> - -#include "base/compiler_specific.h" #include "base/memory/ref_counted.h" -#include "ppapi/c/ppb_url_request_info.h" #include "ppapi/thunk/ppb_url_request_info_api.h" -#include "ppapi/shared_impl/resource.h" +#include "ppapi/shared_impl/url_request_info_impl.h" namespace WebKit { class WebFrame; +class WebHTTPBody; class WebURLRequest; } namespace webkit { namespace ppapi { -class PPB_FileRef_Impl; - -class PPB_URLRequestInfo_Impl : public ::ppapi::Resource, - public ::ppapi::thunk::PPB_URLRequestInfo_API { +class PPB_URLRequestInfo_Impl : public ::ppapi::URLRequestInfoImpl { public: - explicit PPB_URLRequestInfo_Impl(PP_Instance instance); + explicit PPB_URLRequestInfo_Impl( + PP_Instance instance, + const ::ppapi::PPB_URLRequestInfo_Data& data); virtual ~PPB_URLRequestInfo_Impl(); - // Resource overrides. - virtual PPB_URLRequestInfo_API* AsPPB_URLRequestInfo_API() OVERRIDE; - - // PPB_URLRequestInfo implementation. - virtual PP_Bool SetProperty(PP_URLRequestProperty property, - PP_Var var) OVERRIDE; - virtual PP_Bool AppendDataToBody(const void* data, uint32_t len) OVERRIDE; - virtual PP_Bool AppendFileToBody( - PP_Resource file_ref, - int64_t start_offset, - int64_t number_of_bytes, - PP_Time expected_last_modified_time) OVERRIDE; - - WebKit::WebURLRequest ToWebURLRequest(WebKit::WebFrame* frame) const; + // Creates the WebKit URL request from the current request info. Returns + // true on success, false if the request is invalid (in which case *dest may + // be partially initialized). + bool ToWebURLRequest(WebKit::WebFrame* frame, + WebKit::WebURLRequest* dest); // Whether universal access is required to use this request. bool RequiresUniversalAccess() const; - bool SetUndefinedProperty(PP_URLRequestProperty property); - bool SetBooleanProperty(PP_URLRequestProperty property, bool value); - bool SetIntegerProperty(PP_URLRequestProperty property, int32_t value); - bool SetStringProperty(PP_URLRequestProperty property, - const std::string& value); - - - bool follow_redirects() { return follow_redirects_; } - - bool record_download_progress() const { return record_download_progress_; } - bool record_upload_progress() const { return record_upload_progress_; } - - bool allow_cross_origin_requests() const { - return allow_cross_origin_requests_; - } - bool allow_credentials() const { return allow_credentials_; } - - int32_t prefetch_buffer_upper_threshold() const { - return prefetch_buffer_upper_threshold_; - } - int32_t prefetch_buffer_lower_threshold() const { - return prefetch_buffer_lower_threshold_; - } - private: - struct BodyItem; - typedef std::vector<BodyItem> Body; - - std::string url_; - std::string method_; - std::string headers_; - Body body_; - - bool stream_to_file_; - bool follow_redirects_; - bool record_download_progress_; - bool record_upload_progress_; - - // |has_custom_referrer_url_| is set to false if a custom referrer hasn't been - // set (or has been set to an Undefined Var) and the default referrer should - // be used. (Setting the custom referrer to an empty string indicates that no - // referrer header should be generated.) - bool has_custom_referrer_url_; - std::string custom_referrer_url_; - - bool allow_cross_origin_requests_; - bool allow_credentials_; - - // Similar to the custom referrer (above), but for custom content transfer - // encoding. - bool has_custom_content_transfer_encoding_; - std::string custom_content_transfer_encoding_; - - // Specify permitted range for the size of the buffer unconsumed by plugin. - int32_t prefetch_buffer_upper_threshold_; - int32_t prefetch_buffer_lower_threshold_; + friend class URLRequestInfoTest; + + // Checks that the request data is valid and does some canonicalization of + // it. Returns false on failure + bool ValidateData(); + + // Appends the file ref given the Resource pointer associated with it to the + // given HTTP body, returning true on success. + bool AppendFileRefToBody(::ppapi::Resource* file_ref_resource, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time, + WebKit::WebHTTPBody *http_body); DISALLOW_COPY_AND_ASSIGN(PPB_URLRequestInfo_Impl); }; diff --git a/webkit/plugins/ppapi/ppb_url_response_info_impl.cc b/webkit/plugins/ppapi/ppb_url_response_info_impl.cc index fa35c0d..eb5e2ff 100644 --- a/webkit/plugins/ppapi/ppb_url_response_info_impl.cc +++ b/webkit/plugins/ppapi/ppb_url_response_info_impl.cc @@ -74,8 +74,8 @@ bool PPB_URLResponseInfo_Impl::Initialize(const WebURLResponse& response) { WebString file_path = response.downloadFilePath(); if (!file_path.isEmpty()) { - body_ = new PPB_FileRef_Impl(pp_instance(), - webkit_glue::WebStringToFilePath(file_path)); + body_ = PPB_FileRef_Impl::CreateExternal( + pp_instance(), webkit_glue::WebStringToFilePath(file_path)); } return true; } @@ -114,7 +114,6 @@ PP_Var PPB_URLResponseInfo_Impl::GetProperty(PP_URLResponseProperty property) { PP_Resource PPB_URLResponseInfo_Impl::GetBodyAsFileRef() { if (!body_.get()) return 0; - body_->AddRef(); // AddRef for the caller. return body_->GetReference(); } diff --git a/webkit/plugins/ppapi/resource_creation_impl.cc b/webkit/plugins/ppapi/resource_creation_impl.cc index 15436f1..05f09cc 100644 --- a/webkit/plugins/ppapi/resource_creation_impl.cc +++ b/webkit/plugins/ppapi/resource_creation_impl.cc @@ -118,7 +118,8 @@ PP_Resource ResourceCreationImpl::CreateFileIO(PP_Instance instance) { PP_Resource ResourceCreationImpl::CreateFileRef(PP_Resource file_system, const char* path) { - return PPB_FileRef_Impl::Create(file_system, path); + PPB_FileRef_Impl* res = PPB_FileRef_Impl::CreateInternal(file_system, path); + return res ? res->GetReference() : 0; } PP_Resource ResourceCreationImpl::CreateFileSystem( @@ -256,8 +257,10 @@ PP_Resource ResourceCreationImpl::CreateURLLoader(PP_Instance instance) { return (new PPB_URLLoader_Impl(instance, false))->GetReference(); } -PP_Resource ResourceCreationImpl::CreateURLRequestInfo(PP_Instance instance) { - return (new PPB_URLRequestInfo_Impl(instance))->GetReference(); +PP_Resource ResourceCreationImpl::CreateURLRequestInfo( + PP_Instance instance, + const ::ppapi::PPB_URLRequestInfo_Data& data) { + return (new PPB_URLRequestInfo_Impl(instance, data))->GetReference(); } PP_Resource ResourceCreationImpl::CreateVideoCapture(PP_Instance instance) { diff --git a/webkit/plugins/ppapi/resource_creation_impl.h b/webkit/plugins/ppapi/resource_creation_impl.h index 64d0ff9..211f1cd 100644 --- a/webkit/plugins/ppapi/resource_creation_impl.h +++ b/webkit/plugins/ppapi/resource_creation_impl.h @@ -98,7 +98,9 @@ class ResourceCreationImpl : public ::ppapi::FunctionGroupBase, const char* name, const char* proto) OVERRIDE; virtual PP_Resource CreateURLLoader(PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateURLRequestInfo(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateURLRequestInfo( + PP_Instance instance, + const ::ppapi::PPB_URLRequestInfo_Data& data) OVERRIDE; virtual PP_Resource CreateVideoCapture(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateVideoDecoder( PP_Instance instance, diff --git a/webkit/plugins/ppapi/url_request_info_unittest.cc b/webkit/plugins/ppapi/url_request_info_unittest.cc index adeffca..dd8d0f7 100644 --- a/webkit/plugins/ppapi/url_request_info_unittest.cc +++ b/webkit/plugins/ppapi/url_request_info_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ppapi/shared_impl/url_request_info_impl.h" #include "ppapi/thunk/thunk.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h" @@ -52,7 +53,8 @@ class URLRequestInfoTest : public PpapiUnittest { PpapiUnittest::SetUp(); // Must be after our base class's SetUp for the instance to be valid. - info_ = new PPB_URLRequestInfo_Impl(instance()->pp_instance()); + info_ = new PPB_URLRequestInfo_Impl(instance()->pp_instance(), + ::ppapi::PPB_URLRequestInfo_Data()); } static void SetUpTestCase() { @@ -71,25 +73,40 @@ class URLRequestInfoTest : public PpapiUnittest { } bool GetDownloadToFile() { - WebURLRequest web_request = info_->ToWebURLRequest(frame_); + WebURLRequest web_request; + if (!info_->ToWebURLRequest(frame_, &web_request)) + return false; return web_request.downloadToFile(); } WebCString GetURL() { - WebURLRequest web_request = info_->ToWebURLRequest(frame_); + WebURLRequest web_request; + if (!info_->ToWebURLRequest(frame_, &web_request)) + return WebCString(); return web_request.url().spec(); } WebString GetMethod() { - WebURLRequest web_request = info_->ToWebURLRequest(frame_); + WebURLRequest web_request; + if (!info_->ToWebURLRequest(frame_, &web_request)) + return WebString(); return web_request.httpMethod(); } WebString GetHeaderValue(const char* field) { - WebURLRequest web_request = info_->ToWebURLRequest(frame_); + WebURLRequest web_request; + if (!info_->ToWebURLRequest(frame_, &web_request)) + return WebString(); return web_request.httpHeaderField(WebString::fromUTF8(field)); } + bool SetBooleanProperty(PP_URLRequestProperty prop, bool b) { + return info_->SetBooleanProperty(prop, b); + } + bool SetStringProperty(PP_URLRequestProperty prop, const std::string& s) { + return info_->SetStringProperty(prop, s); + } + scoped_refptr<PPB_URLRequestInfo_Impl> info_; static TestWebFrameClient web_frame_client_; @@ -104,160 +121,160 @@ WebFrame* URLRequestInfoTest::frame_; TEST_F(URLRequestInfoTest, GetInterface) { const PPB_URLRequestInfo* interface = ::ppapi::thunk::GetPPB_URLRequestInfo_Thunk(); - ASSERT_TRUE(interface); - ASSERT_TRUE(interface->Create); - ASSERT_TRUE(interface->IsURLRequestInfo); - ASSERT_TRUE(interface->SetProperty); - ASSERT_TRUE(interface->AppendDataToBody); - ASSERT_TRUE(interface->AppendFileToBody); - ASSERT_TRUE(interface->Create); - ASSERT_TRUE(interface->Create); + EXPECT_TRUE(interface); + EXPECT_TRUE(interface->Create); + EXPECT_TRUE(interface->IsURLRequestInfo); + EXPECT_TRUE(interface->SetProperty); + EXPECT_TRUE(interface->AppendDataToBody); + EXPECT_TRUE(interface->AppendFileToBody); + EXPECT_TRUE(interface->Create); + EXPECT_TRUE(interface->Create); } TEST_F(URLRequestInfoTest, AsURLRequestInfo) { - ASSERT_EQ(info_, info_->AsPPB_URLRequestInfo_API()); + EXPECT_EQ(info_, info_->AsPPB_URLRequestInfo_API()); } TEST_F(URLRequestInfoTest, StreamToFile) { - info_->SetStringProperty(PP_URLREQUESTPROPERTY_URL, "http://www.google.com"); + SetStringProperty(PP_URLREQUESTPROPERTY_URL, "http://www.google.com"); - ASSERT_FALSE(GetDownloadToFile()); + EXPECT_FALSE(GetDownloadToFile()); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_STREAMTOFILE, true)); - ASSERT_TRUE(GetDownloadToFile()); + EXPECT_TRUE(GetDownloadToFile()); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_STREAMTOFILE, false)); - ASSERT_FALSE(GetDownloadToFile()); + EXPECT_FALSE(GetDownloadToFile()); } TEST_F(URLRequestInfoTest, FollowRedirects) { - ASSERT_TRUE(info_->follow_redirects()); + EXPECT_TRUE(info_->GetData().follow_redirects); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, false)); - ASSERT_FALSE(info_->follow_redirects()); + EXPECT_FALSE(info_->GetData().follow_redirects); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, true)); - ASSERT_TRUE(info_->follow_redirects()); + EXPECT_TRUE(info_->GetData().follow_redirects); } TEST_F(URLRequestInfoTest, RecordDownloadProgress) { - ASSERT_FALSE(info_->record_download_progress()); + EXPECT_FALSE(info_->GetData().record_download_progress); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, true)); - ASSERT_TRUE(info_->record_download_progress()); + EXPECT_TRUE(info_->GetData().record_download_progress); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, false)); - ASSERT_FALSE(info_->record_download_progress()); + EXPECT_FALSE(info_->GetData().record_download_progress); } TEST_F(URLRequestInfoTest, RecordUploadProgress) { - ASSERT_FALSE(info_->record_upload_progress()); + EXPECT_FALSE(info_->GetData().record_upload_progress); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS, true)); - ASSERT_TRUE(info_->record_upload_progress()); + EXPECT_TRUE(info_->GetData().record_upload_progress); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS, false)); - ASSERT_FALSE(info_->record_upload_progress()); + EXPECT_FALSE(info_->GetData().record_upload_progress); } TEST_F(URLRequestInfoTest, AllowCrossOriginRequests) { - ASSERT_FALSE(info_->allow_cross_origin_requests()); + EXPECT_FALSE(info_->GetData().allow_cross_origin_requests); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, true)); - ASSERT_TRUE(info_->allow_cross_origin_requests()); + EXPECT_TRUE(info_->GetData().allow_cross_origin_requests); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, false)); - ASSERT_FALSE(info_->allow_cross_origin_requests()); + EXPECT_FALSE(info_->GetData().allow_cross_origin_requests); } TEST_F(URLRequestInfoTest, AllowCredentials) { - ASSERT_FALSE(info_->allow_credentials()); + EXPECT_FALSE(info_->GetData().allow_credentials); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS, true)); - ASSERT_TRUE(info_->allow_credentials()); + EXPECT_TRUE(info_->GetData().allow_credentials); - ASSERT_TRUE(info_->SetBooleanProperty( + EXPECT_TRUE(SetBooleanProperty( PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS, false)); - ASSERT_FALSE(info_->allow_credentials()); + EXPECT_FALSE(info_->GetData().allow_credentials); } TEST_F(URLRequestInfoTest, SetURL) { // Test default URL is "about:blank". - ASSERT_TRUE(IsExpected(GetURL(), "about:blank")); + EXPECT_TRUE(IsExpected(GetURL(), "about:blank")); const char* url = "http://www.google.com/"; - ASSERT_TRUE(info_->SetStringProperty( + EXPECT_TRUE(SetStringProperty( PP_URLREQUESTPROPERTY_URL, url)); - ASSERT_TRUE(IsExpected(GetURL(), url)); + EXPECT_TRUE(IsExpected(GetURL(), url)); } TEST_F(URLRequestInfoTest, JavascriptURL) { const char* url = "javascript:foo = bar"; - ASSERT_FALSE(info_->RequiresUniversalAccess()); - info_->SetStringProperty(PP_URLREQUESTPROPERTY_URL, url); - ASSERT_TRUE(info_->RequiresUniversalAccess()); + EXPECT_FALSE(info_->RequiresUniversalAccess()); + SetStringProperty(PP_URLREQUESTPROPERTY_URL, url); + EXPECT_TRUE(info_->RequiresUniversalAccess()); } TEST_F(URLRequestInfoTest, SetMethod) { // Test default method is "GET". - ASSERT_TRUE(IsExpected(GetMethod(), "GET")); - ASSERT_TRUE(info_->SetStringProperty( + EXPECT_TRUE(IsExpected(GetMethod(), "GET")); + EXPECT_TRUE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "POST")); - ASSERT_TRUE(IsExpected(GetMethod(), "POST")); + EXPECT_TRUE(IsExpected(GetMethod(), "POST")); // Test that method names are converted to upper case. - ASSERT_TRUE(info_->SetStringProperty( + EXPECT_TRUE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "get")); - ASSERT_TRUE(IsExpected(GetMethod(), "GET")); - ASSERT_TRUE(info_->SetStringProperty( + EXPECT_TRUE(IsExpected(GetMethod(), "GET")); + EXPECT_TRUE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "post")); - ASSERT_TRUE(IsExpected(GetMethod(), "POST")); + EXPECT_TRUE(IsExpected(GetMethod(), "POST")); } TEST_F(URLRequestInfoTest, SetInvalidMethod) { - ASSERT_FALSE(info_->SetStringProperty( + EXPECT_FALSE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "CONNECT")); - ASSERT_FALSE(info_->SetStringProperty( + EXPECT_FALSE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "connect")); - ASSERT_FALSE(info_->SetStringProperty( + EXPECT_FALSE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "TRACE")); - ASSERT_FALSE(info_->SetStringProperty( + EXPECT_FALSE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "trace")); - ASSERT_FALSE(info_->SetStringProperty( + EXPECT_FALSE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "TRACK")); - ASSERT_FALSE(info_->SetStringProperty( + EXPECT_FALSE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "track")); - ASSERT_FALSE(info_->SetStringProperty( + EXPECT_FALSE(SetStringProperty( PP_URLREQUESTPROPERTY_METHOD, "POST\x0d\x0ax-csrf-token:\x20test1234")); } TEST_F(URLRequestInfoTest, SetValidHeaders) { // Test default header field. - ASSERT_TRUE(IsExpected( + EXPECT_TRUE(IsExpected( GetHeaderValue("foo"), "")); // Test that we can set a header field. - ASSERT_TRUE(info_->SetStringProperty( + EXPECT_TRUE(SetStringProperty( PP_URLREQUESTPROPERTY_HEADERS, "foo: bar")); - ASSERT_TRUE(IsExpected( + EXPECT_TRUE(IsExpected( GetHeaderValue("foo"), "bar")); // Test that we can set multiple header fields using \n delimiter. - ASSERT_TRUE(info_->SetStringProperty( + EXPECT_TRUE(SetStringProperty( PP_URLREQUESTPROPERTY_HEADERS, "foo: bar\nbar: baz")); - ASSERT_TRUE(IsExpected( + EXPECT_TRUE(IsExpected( GetHeaderValue("foo"), "bar")); - ASSERT_TRUE(IsExpected( + EXPECT_TRUE(IsExpected( GetHeaderValue("bar"), "baz")); } @@ -291,20 +308,18 @@ TEST_F(URLRequestInfoTest, SetInvalidHeaders) { for (size_t i = 0; i < arraysize(kForbiddenHeaderFields); ++i) { std::string headers(kForbiddenHeaderFields[i]); headers.append(": foo"); - ASSERT_FALSE(info_->SetStringProperty( - PP_URLREQUESTPROPERTY_HEADERS, headers.c_str())); - ASSERT_TRUE(IsNullOrEmpty(GetHeaderValue(kForbiddenHeaderFields[i]))); + SetStringProperty( + PP_URLREQUESTPROPERTY_HEADERS, headers.c_str()); + EXPECT_TRUE(IsNullOrEmpty(GetHeaderValue(kForbiddenHeaderFields[i]))); } // Test that forbidden header can't be set in various ways. - ASSERT_FALSE(info_->SetStringProperty( - PP_URLREQUESTPROPERTY_HEADERS, "cookie : foo")); - ASSERT_TRUE(IsNullOrEmpty(GetHeaderValue("cookie"))); + SetStringProperty(PP_URLREQUESTPROPERTY_HEADERS, "cookie : foo"); + EXPECT_TRUE(IsNullOrEmpty(GetHeaderValue("cookie"))); // Test that forbidden header can't be set with an allowed one. - ASSERT_FALSE(info_->SetStringProperty( - PP_URLREQUESTPROPERTY_HEADERS, "foo: bar\ncookie: foo")); - ASSERT_TRUE(IsNullOrEmpty(GetHeaderValue("cookie"))); + SetStringProperty(PP_URLREQUESTPROPERTY_HEADERS, "foo: bar\ncookie: foo"); + EXPECT_TRUE(IsNullOrEmpty(GetHeaderValue("cookie"))); } // TODO(bbudge) Unit tests for AppendDataToBody, AppendFileToBody. |