diff options
33 files changed, 668 insertions, 417 deletions
diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.cc b/content/renderer/pepper/pepper_in_process_resource_creation.cc index 1854e9e..37599ff 100644 --- a/content/renderer/pepper/pepper_in_process_resource_creation.cc +++ b/content/renderer/pepper/pepper_in_process_resource_creation.cc @@ -17,6 +17,7 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/printing_resource.h" #include "ppapi/proxy/url_request_info_resource.h" +#include "ppapi/proxy/url_response_info_resource.h" #include "ppapi/proxy/websocket_resource.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/ppapi_permissions.h" @@ -65,6 +66,15 @@ PP_Resource PepperInProcessResourceCreation::CreateURLRequestInfo( instance, data))->GetReference(); } +PP_Resource PepperInProcessResourceCreation::CreateURLResponseInfo( + PP_Instance instance, + const ::ppapi::URLResponseInfoData& data, + PP_Resource file_ref_resource) { + return (new ppapi::proxy::URLResponseInfoResource( + host_impl_->in_process_router()->GetPluginConnection(), + instance, data, file_ref_resource))->GetReference(); +} + PP_Resource PepperInProcessResourceCreation::CreateWebSocket( PP_Instance instance) { return (new ppapi::proxy::WebSocketResource( diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.h b/content/renderer/pepper/pepper_in_process_resource_creation.h index e5b3fa5..8b5374d 100644 --- a/content/renderer/pepper/pepper_in_process_resource_creation.h +++ b/content/renderer/pepper/pepper_in_process_resource_creation.h @@ -51,6 +51,10 @@ class PepperInProcessResourceCreation virtual PP_Resource CreateURLRequestInfo( PP_Instance instance, const ::ppapi::URLRequestInfoData& data) OVERRIDE; + virtual PP_Resource CreateURLResponseInfo( + PP_Instance instance, + const ::ppapi::URLResponseInfoData& data, + PP_Resource file_ref_resource) OVERRIDE; virtual PP_Resource CreateWebSocket( PP_Instance instance) OVERRIDE; diff --git a/ppapi/api/ppb_file_io.idl b/ppapi/api/ppb_file_io.idl index 23e97ca..a8b4baf 100644 --- a/ppapi/api/ppb_file_io.idl +++ b/ppapi/api/ppb_file_io.idl @@ -144,7 +144,8 @@ interface PPB_FileIO { /** * Read() reads from an offset in the file. The size of the buffer must be * large enough to hold the specified number of bytes to read. This function - * might perform a partial read. + * might perform a partial read, meaning all the requested bytes + * might not be returned, even if the end of the file has not been reached. * * ReadToArray() is preferred to Read() when doing asynchronous operations. * diff --git a/ppapi/c/ppb_file_io.h b/ppapi/c/ppb_file_io.h index 43fcdb9..da3747a 100644 --- a/ppapi/c/ppb_file_io.h +++ b/ppapi/c/ppb_file_io.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From ppb_file_io.idl modified Thu Nov 15 08:08:30 2012. */ +/* From ppb_file_io.idl modified Fri Nov 16 10:46:53 2012. */ #ifndef PPAPI_C_PPB_FILE_IO_H_ #define PPAPI_C_PPB_FILE_IO_H_ @@ -161,7 +161,8 @@ struct PPB_FileIO_1_1 { /** * Read() reads from an offset in the file. The size of the buffer must be * large enough to hold the specified number of bytes to read. This function - * might perform a partial read. + * might perform a partial read, meaning all the requested bytes + * might not be returned, even if the end of the file has not been reached. * * ReadToArray() is preferred to Read() when doing asynchronous operations. * diff --git a/ppapi/cpp/file_io.h b/ppapi/cpp/file_io.h index 3b93bfe..bf2c857 100644 --- a/ppapi/cpp/file_io.h +++ b/ppapi/cpp/file_io.h @@ -45,8 +45,17 @@ class FileIO : public Resource { /// /// @param[in] file_ref A <code>PP_Resource</code> corresponding to a file /// reference. + /// /// @param[in] open_flags A bit-mask of the <code>PP_FileOpenFlags</code> - /// values. + /// values. Valid values are: + /// - PP_FILEOPENFLAG_READ + /// - PP_FILEOPENFLAG_WRITE + /// - PP_FILEOPENFLAG_CREATE + /// - PP_FILEOPENFLAG_TRUNCATE + /// - PP_FILEOPENFLAG_EXCLUSIVE + /// See <code>PP_FileOpenFlags</code> in <code>ppb_file_io.h</code> for more + /// details on these flags. + /// /// @param[in] cc A <code>CompletionCallback</code> to be called upon /// completion of Open(). /// @@ -83,9 +92,33 @@ class FileIO : public Resource { PP_Time last_modified_time, const CompletionCallback& cc); - /// Read() reads from an offset in the file. The size of the buffer must be - /// large enough to hold the specified number of bytes to read. This - /// function might perform a partial read. + /// Reads from an offset in the file. + /// + /// The size of the buffer must be large enough to hold the specified number + /// of bytes to read. This function might perform a partial read, meaning + /// that all the requested bytes might not be returned, even if the end of the + /// file has not been reached. + /// + /// This function reads into a buffer that the caller supplies. This buffer + /// must remain valid as long as the FileIO resource is alive. If you use + /// a completion callback factory and it goes out of scope, it will not issue + /// the callback on your class, BUT the callback factory can NOT cancel + /// the request from the browser's perspective. This means that the browser + /// will still try to write to your buffer even if the callback factory is + /// destroyed! + /// + /// So you must ensure that your buffer outlives the FileIO resource. If you + /// have one class and use the FileIO resource exclusively from that class + /// and never make any copies, this will be fine: the resource will be + /// destroyed when your class is. But keep in mind that copying a pp::FileIO + /// object just creates a second reference to the original resource. For + /// example, if you have a function like this: + /// pp::FileIO MyClass::GetFileIO(); + /// where a copy of your FileIO resource could outlive your class, the + /// callback will still be pending when your class goes out of scope, creating + /// the possibility of writing into invalid memory. So it's recommended to + /// keep your FileIO resource and any oubput buffers tightly controlled in + /// the same scope. /// /// <strong>Caveat:</strong> This Read() is potentially unsafe if you're using /// a CompletionCallbackFactory to scope callbacks to the lifetime of your diff --git a/ppapi/examples/url_loader/stream_to_file.cc b/ppapi/examples/url_loader/stream_to_file.cc new file mode 100644 index 0000000..887a9d7 --- /dev/null +++ b/ppapi/examples/url_loader/stream_to_file.cc @@ -0,0 +1,171 @@ +// Copyright (c) 2012 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. + +// This example shows how to use the URLLoader in "stream to file" mode where +// the browser writes incoming data to a file, which you can read out via the +// file I/O APIs. +// +// This example uses PostMessage between the plugin and the url_loader.html +// page in this directory to start the load and to communicate the result. + +#include "ppapi/c/ppb_file_io.h" +#include "ppapi/cpp/file_io.h" +#include "ppapi/cpp/file_ref.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/url_loader.h" +#include "ppapi/cpp/url_request_info.h" +#include "ppapi/cpp/url_response_info.h" +#include "ppapi/utility/completion_callback_factory.h" + +// When compiling natively on Windows, PostMessage can be #define-d to +// something else. +#ifdef PostMessage +#undef PostMessage +#endif + +// Buffer size for reading network data. +const int kBufSize = 1024; + +class MyInstance : public pp::Instance { + public: + explicit MyInstance(PP_Instance instance) + : pp::Instance(instance) { + factory_.Initialize(this); + } + virtual ~MyInstance() { + // Make sure to explicitly close the loader. If somebody else is holding a + // reference to the URLLoader object when this class goes out of scope (so + // the URLLoader outlives "this"), and you have an outstanding read + // request, the URLLoader will write into invalid memory. + loader_.Close(); + } + + // Handler for the page sending us messages. + virtual void HandleMessage(const pp::Var& message_data); + + private: + // Called to initiate the request. + void StartRequest(const std::string& url); + + // Callback for the URLLoader to tell us it finished opening the connection. + void OnOpenComplete(int32_t result); + + // Callback for when the file is completely filled with the download + void OnStreamComplete(int32_t result); + + void OnOpenFileComplete(int32_t result); + void OnReadComplete(int32_t result); + + // Forwards the given string to the page. + void ReportResponse(const std::string& data); + + // Generates completion callbacks scoped to this class. + pp::CompletionCallbackFactory<MyInstance> factory_; + + pp::URLLoader loader_; + pp::URLResponseInfo response_; + pp::FileRef dest_file_; + pp::FileIO file_io_; + + // The buffer used for the current read request. This is filled and then + // copied into content_ to build up the entire document. + char buf_[kBufSize]; + + // All the content loaded so far. + std::string content_; +}; + +void MyInstance::HandleMessage(const pp::Var& message_data) { + if (message_data.is_string() && message_data.AsString() == "go") + StartRequest("./fetched_content.html"); +} + +void MyInstance::StartRequest(const std::string& url) { + content_.clear(); + + pp::URLRequestInfo request(this); + request.SetURL(url); + request.SetMethod("GET"); + request.SetStreamToFile(true); + + loader_ = pp::URLLoader(this); + loader_.Open(request, + factory_.NewCallback(&MyInstance::OnOpenComplete)); +} + +void MyInstance::OnOpenComplete(int32_t result) { + if (result != PP_OK) { + ReportResponse("URL could not be requested"); + return; + } + + loader_.FinishStreamingToFile( + factory_.NewCallback(&MyInstance::OnStreamComplete)); + response_ = loader_.GetResponseInfo(); + dest_file_ = response_.GetBodyAsFileRef(); +} + +void MyInstance::OnStreamComplete(int32_t result) { + if (result == PP_OK) { + file_io_ = pp::FileIO(this); + file_io_.Open(dest_file_, PP_FILEOPENFLAG_READ, + factory_.NewCallback(&MyInstance::OnOpenFileComplete)); + } else { + ReportResponse("Could not stream to file"); + } +} + +void MyInstance::OnOpenFileComplete(int32_t result) { + if (result == PP_OK) { + // Note we only read the first 1024 bytes from the file in this example + // to keep things simple. Please see a file I/O example for more details + // on reading files. + file_io_.Read(0, buf_, kBufSize, + factory_.NewCallback(&MyInstance::OnReadComplete)); + } else { + ReportResponse("Could not open file"); + } +} + +void MyInstance::OnReadComplete(int32_t result) { + if (result >= 0) { + content_.append(buf_, result); + ReportResponse(buf_); + } else { + ReportResponse("Could not read file"); + } + + // Release everything. + loader_ = pp::URLLoader(); + response_ = pp::URLResponseInfo(); + dest_file_ = pp::FileRef(); + file_io_ = pp::FileIO(); +} + +void MyInstance::ReportResponse(const std::string& data) { + PostMessage(pp::Var(data)); +} + +// This object is the global object representing this plugin library as long +// as it is loaded. +class MyModule : public pp::Module { + public: + MyModule() : pp::Module() {} + virtual ~MyModule() {} + + // Override CreateInstance to create your customized Instance object. + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { + +// Factory function for your specialization of the Module object. +Module* CreateModule() { + return new MyModule(); +} + +} // namespace pp diff --git a/ppapi/examples/url_loader/streaming.cc b/ppapi/examples/url_loader/streaming.cc index 18efe68..762a00b 100644 --- a/ppapi/examples/url_loader/streaming.cc +++ b/ppapi/examples/url_loader/streaming.cc @@ -7,9 +7,7 @@ // the plugin and the url_loader.html page in this directory to start the load // and to communicate the result. // -// The other mode is to stream to a file instead. For that mode, call -// URLLoader.FinishSthreamingToFile once the "Open" callback is complete, and -// then call URLResponseInfo.GetBodyAsFileRef once the file stream is complete. +// The other mode is to stream to a file instead. See stream_to_file.cc #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 47769bd..3c3e1b6 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -115,8 +115,6 @@ 'proxy/ppb_udp_socket_private_proxy.h', 'proxy/ppb_url_loader_proxy.cc', 'proxy/ppb_url_loader_proxy.h', - 'proxy/ppb_url_response_info_proxy.cc', - 'proxy/ppb_url_response_info_proxy.h', 'proxy/ppb_var_deprecated_proxy.cc', 'proxy/ppb_var_deprecated_proxy.h', 'proxy/ppb_video_decoder_proxy.cc', @@ -160,6 +158,8 @@ 'proxy/resource_creation_proxy.h', 'proxy/url_request_info_resource.cc', 'proxy/url_request_info_resource.h', + 'proxy/url_response_info_resource.cc', + 'proxy/url_response_info_resource.h', 'proxy/var_serialization_rules.h', 'proxy/video_capture_resource.cc', 'proxy/video_capture_resource.h', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index f2f4f85..3bc3a46 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -103,6 +103,8 @@ 'shared_impl/tracked_callback.h', 'shared_impl/url_request_info_data.cc', 'shared_impl/url_request_info_data.h', + 'shared_impl/url_response_info_data.cc', + 'shared_impl/url_response_info_data.h', 'shared_impl/var.cc', 'shared_impl/var.h', 'shared_impl/var_tracker.cc', diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index d5dcd95..989188a 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi @@ -365,6 +365,16 @@ ], }, { + 'target_name': 'ppapi_example_url_loader_file', + 'dependencies': [ + 'ppapi_example_skeleton', + 'ppapi.gyp:ppapi_cpp', + ], + 'sources': [ + 'examples/url_loader/stream_to_file.cc', + ], + }, + { 'target_name': 'ppapi_example_gles2', 'dependencies': [ 'ppapi_example_skeleton', diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index d0efc1f..6f2ca2b 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -100,7 +100,6 @@ #include "ppapi/proxy/ppb_testing_proxy.h" #include "ppapi/proxy/ppb_udp_socket_private_proxy.h" #include "ppapi/proxy/ppb_url_loader_proxy.h" -#include "ppapi/proxy/ppb_url_response_info_proxy.h" #include "ppapi/proxy/ppb_var_deprecated_proxy.h" #include "ppapi/proxy/ppb_video_decoder_proxy.h" #include "ppapi/proxy/ppb_x509_certificate_private_proxy.h" diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 95384e2e..275a550 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -56,6 +56,7 @@ #include "ppapi/shared_impl/private/ppb_host_resolver_shared.h" #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" #include "ppapi/shared_impl/url_request_info_data.h" +#include "ppapi/shared_impl/url_response_info_data.h" #undef IPC_MESSAGE_EXPORT #define IPC_MESSAGE_EXPORT PPAPI_PROXY_EXPORT @@ -255,6 +256,15 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::URLRequestInfoData::BodyItem) IPC_STRUCT_TRAITS_MEMBER(expected_last_modified_time) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(ppapi::URLResponseInfoData) + IPC_STRUCT_TRAITS_MEMBER(url) + IPC_STRUCT_TRAITS_MEMBER(headers) + IPC_STRUCT_TRAITS_MEMBER(status_code) + IPC_STRUCT_TRAITS_MEMBER(status_text) + IPC_STRUCT_TRAITS_MEMBER(redirect_url) + IPC_STRUCT_TRAITS_MEMBER(body_as_file_ref) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(ppapi::NetworkInfo) IPC_STRUCT_TRAITS_MEMBER(name) IPC_STRUCT_TRAITS_MEMBER(type) @@ -1066,10 +1076,11 @@ IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLLoader_Open, ppapi::URLRequestInfoData /* request_data */) IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBURLLoader_FollowRedirect, ppapi::HostResource /* loader */) -IPC_SYNC_MESSAGE_ROUTED1_1( +IPC_SYNC_MESSAGE_ROUTED1_2( PpapiHostMsg_PPBURLLoader_GetResponseInfo, ppapi::HostResource /* loader */, - ppapi::HostResource /* response_info_out */) + bool /* success */, + ppapi::URLResponseInfoData /* result */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLLoader_ReadResponseBody, ppapi::HostResource /* loader */, int32_t /* bytes_to_read */) @@ -1080,15 +1091,6 @@ IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBURLLoader_Close, IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBURLLoader_GrantUniversalAccess, ppapi::HostResource /* loader */) -// PPB_URLResponseInfo. -IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBURLResponseInfo_GetProperty, - ppapi::HostResource /* response */, - int32_t /* property */, - ppapi::proxy::SerializedVar /* result */) -IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLResponseInfo_GetBodyAsFileRef, - ppapi::HostResource /* response */, - ppapi::PPB_FileRef_CreateInfo /* result */) - // PPB_Var. IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBVar_AddRefObject, int64 /* object_id */, diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc index 1f398ce..91c1bba 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.cc +++ b/ppapi/proxy/ppb_url_loader_proxy.cc @@ -22,7 +22,7 @@ #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/proxy/ppb_url_response_info_proxy.h" +#include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/shared_impl/scoped_pp_resource.h" #include "ppapi/shared_impl/tracked_callback.h" #include "ppapi/thunk/enter.h" @@ -114,6 +114,7 @@ class URLLoader : public Resource, public PPB_URLLoader_API { virtual void GrantUniversalAccess() OVERRIDE; virtual void SetStatusCallback( PP_URLLoaderTrusted_StatusCallback cb) OVERRIDE; + virtual bool GetResponseInfoData(URLResponseInfoData* data) OVERRIDE; // Called when the browser has new up/download progress to report. void UpdateProgress(const PPBURLLoader_UpdateProgress_Params& params); @@ -249,14 +250,24 @@ PP_Bool URLLoader::GetDownloadProgress( PP_Resource URLLoader::GetResponseInfo() { if (!response_info_) { - HostResource response_id; + bool success = false; + URLResponseInfoData data; GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_GetResponseInfo( - API_ID_PPB_URL_LOADER, host_resource(), &response_id)); - if (response_id.is_null()) + API_ID_PPB_URL_LOADER, host_resource(), &success, &data)); + if (!success) return 0; - response_info_ = PPB_URLResponseInfo_Proxy::CreateResponseForResource( - response_id); + // Create a proxy resource for the the file ref host resource if needed. + PP_Resource body_as_file_ref = 0; + if (!data.body_as_file_ref.resource.is_null()) { + body_as_file_ref = + PPB_FileRef_Proxy::DeserializeFileRef(data.body_as_file_ref); + } + + // Assumes ownership of body_as_file_ref. + thunk::EnterResourceCreationNoLock enter(pp_instance()); + response_info_ = enter.functions()->CreateURLResponseInfo( + pp_instance(), data, body_as_file_ref); } // The caller expects to get a ref, and we want to keep holding ours. @@ -319,6 +330,12 @@ void URLLoader::SetStatusCallback( // proxy itself in the host. } +bool URLLoader::GetResponseInfoData(URLResponseInfoData* data) { + // Not implemented in the proxied version, this is for implementing the + // proxy itself in the host. + return false; +} + void URLLoader::UpdateProgress( const PPBURLLoader_UpdateProgress_Params& params) { bytes_sent_ = params.bytes_sent; @@ -484,12 +501,13 @@ void PPB_URLLoader_Proxy::OnMsgFollowRedirect( } void PPB_URLLoader_Proxy::OnMsgGetResponseInfo(const HostResource& loader, - HostResource* result) { + bool* success, + URLResponseInfoData* result) { EnterHostFromHostResource<PPB_URLLoader_API> enter(loader); - if (enter.succeeded()) { - result->SetHostResource(loader.instance(), - enter.object()->GetResponseInfo()); - } + if (enter.succeeded()) + *success = enter.object()->GetResponseInfoData(result); + else + *success = false; } void PPB_URLLoader_Proxy::OnMsgReadResponseBody( diff --git a/ppapi/proxy/ppb_url_loader_proxy.h b/ppapi/proxy/ppb_url_loader_proxy.h index 5e4e759..f4c5bc5 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.h +++ b/ppapi/proxy/ppb_url_loader_proxy.h @@ -21,6 +21,7 @@ namespace ppapi { struct URLRequestInfoData; +struct URLResponseInfoData; namespace proxy { @@ -61,7 +62,8 @@ class PPB_URLLoader_Proxy : public InterfaceProxy { const URLRequestInfoData& data); void OnMsgFollowRedirect(const HostResource& loader); void OnMsgGetResponseInfo(const HostResource& loader, - HostResource* result); + bool* success, + URLResponseInfoData* result); void OnMsgReadResponseBody(const HostResource& loader, int32_t bytes_to_read); void OnMsgFinishStreamingToFile(const HostResource& loader); diff --git a/ppapi/proxy/ppb_url_response_info_proxy.cc b/ppapi/proxy/ppb_url_response_info_proxy.cc deleted file mode 100644 index 1d90386..0000000 --- a/ppapi/proxy/ppb_url_response_info_proxy.cc +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ppapi/proxy/ppb_url_response_info_proxy.h" - -#include "ppapi/c/ppb_url_response_info.h" -#include "ppapi/proxy/enter_proxy.h" -#include "ppapi/proxy/host_dispatcher.h" -#include "ppapi/proxy/plugin_dispatcher.h" -#include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/proxy/ppb_file_ref_proxy.h" -#include "ppapi/proxy/serialized_var.h" -#include "ppapi/shared_impl/resource.h" -#include "ppapi/thunk/ppb_url_response_info_api.h" -#include "ppapi/thunk/thunk.h" - -using ppapi::thunk::PPB_URLResponseInfo_API; - -namespace ppapi { -namespace proxy { - -// URLResponseInfo ------------------------------------------------------------- - -class URLResponseInfo : public Resource, public PPB_URLResponseInfo_API { - public: - URLResponseInfo(const HostResource& resource); - virtual ~URLResponseInfo(); - - // Resource override. - virtual PPB_URLResponseInfo_API* AsPPB_URLResponseInfo_API() OVERRIDE; - - // PPB_URLResponseInfo_API implementation. - virtual PP_Var GetProperty(PP_URLResponseProperty property) OVERRIDE; - virtual PP_Resource GetBodyAsFileRef() OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(URLResponseInfo); -}; - -URLResponseInfo::URLResponseInfo(const HostResource& resource) - : Resource(OBJECT_IS_PROXY, resource) { -} - -URLResponseInfo::~URLResponseInfo() { -} - -PPB_URLResponseInfo_API* URLResponseInfo::AsPPB_URLResponseInfo_API() { - return this; -} - -PP_Var URLResponseInfo::GetProperty(PP_URLResponseProperty property) { - PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this); - ReceiveSerializedVarReturnValue result; - dispatcher->Send(new PpapiHostMsg_PPBURLResponseInfo_GetProperty( - API_ID_PPB_URL_RESPONSE_INFO, host_resource(), property, &result)); - return result.Return(dispatcher); -} - -PP_Resource URLResponseInfo::GetBodyAsFileRef() { - // This could be more efficient by having the host automatically send us the - // 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. - PPB_FileRef_CreateInfo create_info; - PluginDispatcher::GetForResource(this)->Send( - new PpapiHostMsg_PPBURLResponseInfo_GetBodyAsFileRef( - API_ID_PPB_URL_RESPONSE_INFO, host_resource(), &create_info)); - return PPB_FileRef_Proxy::DeserializeFileRef(create_info); -} - -// PPB_URLResponseInfo_Proxy --------------------------------------------------- - -PPB_URLResponseInfo_Proxy::PPB_URLResponseInfo_Proxy(Dispatcher* dispatcher) - : InterfaceProxy(dispatcher) { -} - -PPB_URLResponseInfo_Proxy::~PPB_URLResponseInfo_Proxy() { -} - -// static -PP_Resource PPB_URLResponseInfo_Proxy::CreateResponseForResource( - const HostResource& resource) { - return (new URLResponseInfo(resource))->GetReference(); -} - -bool PPB_URLResponseInfo_Proxy::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PPB_URLResponseInfo_Proxy, msg) -#if !defined(OS_NACL) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLResponseInfo_GetProperty, - OnMsgGetProperty) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLResponseInfo_GetBodyAsFileRef, - OnMsgGetBodyAsFileRef) -#endif - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - // TODO(brettw): handle bad messages. - return handled; -} - -#if !defined(OS_NACL) -void PPB_URLResponseInfo_Proxy::OnMsgGetProperty( - const HostResource& response, - int32_t property, - SerializedVarReturnValue result) { - EnterHostFromHostResource<PPB_URLResponseInfo_API> enter(response); - PP_Var result_var = PP_MakeUndefined(); - if (enter.succeeded()) { - result_var = enter.object()->GetProperty( - static_cast<PP_URLResponseProperty>(property)); - } - result.Return(dispatcher(), result_var); -} - -void PPB_URLResponseInfo_Proxy::OnMsgGetBodyAsFileRef( - const HostResource& response, - PPB_FileRef_CreateInfo* result) { - EnterHostFromHostResource<PPB_URLResponseInfo_API> enter(response); - PP_Resource file_ref = 0; - if (enter.succeeded()) - file_ref = enter.object()->GetBodyAsFileRef(); - - // Use the FileRef proxy to serialize. - PPB_FileRef_Proxy* file_ref_proxy = static_cast<PPB_FileRef_Proxy*>( - dispatcher()->GetInterfaceProxy(API_ID_PPB_FILE_REF)); - file_ref_proxy->SerializeFileRef(file_ref, result); -} -#endif // !defined(OS_NACL) - -} // namespace proxy -} // namespace ppapi diff --git a/ppapi/proxy/ppb_url_response_info_proxy.h b/ppapi/proxy/ppb_url_response_info_proxy.h deleted file mode 100644 index 86c27fb..0000000 --- a/ppapi/proxy/ppb_url_response_info_proxy.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2012 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_PROXY_PPB_URL_RESPONSE_INFO_PROXY_H_ -#define PPAPI_PROXY_PPB_URL_RESPONSE_INFO_PROXY_H_ - -#include "base/basictypes.h" -#include "ppapi/c/pp_instance.h" -#include "ppapi/c/pp_module.h" -#include "ppapi/c/pp_resource.h" -#include "ppapi/proxy/interface_proxy.h" -#include "ppapi/shared_impl/host_resource.h" - -namespace ppapi { - -struct PPB_FileRef_CreateInfo; - -namespace proxy { - -class SerializedVarReturnValue; - -class PPB_URLResponseInfo_Proxy : public InterfaceProxy { - public: - PPB_URLResponseInfo_Proxy(Dispatcher* dispatcher); - virtual ~PPB_URLResponseInfo_Proxy(); - - // URLResponseInfo objects are actually created and returned by the - // URLLoader. This function allows the URLLoader to convert a new - // HostResource representing a response info to a properly tracked - // URLReponseInfo Resource. Returns the plugin resource ID for the - // new resource. - static PP_Resource CreateResponseForResource( - const ppapi::HostResource& resource); - - // InterfaceProxy implementation. - virtual bool OnMessageReceived(const IPC::Message& msg); - - static const ApiID kApiID = API_ID_PPB_URL_RESPONSE_INFO; - - private: - // Message handlers. - void OnMsgGetProperty(const ppapi::HostResource& response, - int32_t property, - SerializedVarReturnValue result); - void OnMsgGetBodyAsFileRef(const ppapi::HostResource& response, - PPB_FileRef_CreateInfo* result); - - DISALLOW_COPY_AND_ASSIGN(PPB_URLResponseInfo_Proxy); -}; - -} // namespace proxy -} // namespace ppapi - -#endif // PPAPI_PROXY_PPB_URL_RESPONSE_INFO_PROXY_H_ diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 2b8836a..bb103c3 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -39,6 +39,7 @@ #include "ppapi/proxy/ppb_x509_certificate_private_proxy.h" #include "ppapi/proxy/printing_resource.h" #include "ppapi/proxy/url_request_info_resource.h" +#include "ppapi/proxy/url_response_info_resource.h" #include "ppapi/proxy/video_capture_resource.h" #include "ppapi/proxy/websocket_resource.h" #include "ppapi/shared_impl/api_id.h" @@ -153,6 +154,15 @@ PP_Resource ResourceCreationProxy::CreateURLRequestInfo( instance, data))->GetReference(); } +PP_Resource ResourceCreationProxy::CreateURLResponseInfo( + PP_Instance instance, + const URLResponseInfoData& data, + PP_Resource file_ref_resource) { + return (new URLResponseInfoResource(GetConnection(), instance, + data, + file_ref_resource))->GetReference(); +} + PP_Resource ResourceCreationProxy::CreateWheelInputEvent( PP_Instance instance, PP_TimeTicks time_stamp, diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index b748b84..612ff2ba 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -79,6 +79,10 @@ class ResourceCreationProxy : public InterfaceProxy, virtual PP_Resource CreateURLRequestInfo( PP_Instance instance, const URLRequestInfoData& data) OVERRIDE; + virtual PP_Resource CreateURLResponseInfo( + PP_Instance instance, + const URLResponseInfoData& data, + PP_Resource file_ref_resource) OVERRIDE; virtual PP_Resource CreateWheelInputEvent( PP_Instance instance, PP_TimeTicks time_stamp, diff --git a/ppapi/proxy/url_response_info_resource.cc b/ppapi/proxy/url_response_info_resource.cc new file mode 100644 index 0000000..91c9990 --- /dev/null +++ b/ppapi/proxy/url_response_info_resource.cc @@ -0,0 +1,82 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/proxy/url_response_info_resource.h" + +#include "ppapi/proxy/ppb_file_ref_proxy.h" +#include "ppapi/shared_impl/var.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/resource_creation_api.h" + +namespace ppapi { +namespace proxy { + +namespace { + +bool IsRedirect(int32_t status) { + return status >= 300 && status <= 399; +} + +} // namespace + +URLResponseInfoResource::URLResponseInfoResource( + Connection connection, + PP_Instance instance, + const URLResponseInfoData& data, + PP_Resource file_ref_resource) + : PluginResource(connection, instance), + data_(data), + body_as_file_ref_(ScopedPPResource::PassRef(), file_ref_resource) { +} + +URLResponseInfoResource::~URLResponseInfoResource() { +} + +thunk::PPB_URLResponseInfo_API* +URLResponseInfoResource::AsPPB_URLResponseInfo_API() { + return this; +} + +PP_Var URLResponseInfoResource::GetProperty(PP_URLResponseProperty property) { + switch (property) { + case PP_URLRESPONSEPROPERTY_URL: + return StringVar::StringToPPVar(data_.url); + case PP_URLRESPONSEPROPERTY_REDIRECTURL: + if (IsRedirect(data_.status_code)) + return StringVar::StringToPPVar(data_.redirect_url); + break; + case PP_URLRESPONSEPROPERTY_REDIRECTMETHOD: + if (IsRedirect(data_.status_code)) + return StringVar::StringToPPVar(data_.status_text); + break; + case PP_URLRESPONSEPROPERTY_STATUSCODE: + return PP_MakeInt32(data_.status_code); + case PP_URLRESPONSEPROPERTY_STATUSLINE: + return StringVar::StringToPPVar(data_.status_text); + case PP_URLRESPONSEPROPERTY_HEADERS: + return StringVar::StringToPPVar(data_.headers); + } + // The default is to return an undefined PP_Var. + return PP_MakeUndefined(); +} + +PP_Resource URLResponseInfoResource::GetBodyAsFileRef() { + if (!body_as_file_ref_.get()) + return 0; + PpapiGlobals::Get()->GetResourceTracker()->AddRefResource( + body_as_file_ref_.get()); + return body_as_file_ref_.get(); +} + +URLResponseInfoData URLResponseInfoResource::GetData() { + // One ref is passed to the caller if there's a file ref. + if (body_as_file_ref_.get()) { + PpapiGlobals::Get()->GetResourceTracker()->AddRefResource( + body_as_file_ref_.get()); + } + return data_; +} + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/url_response_info_resource.h b/ppapi/proxy/url_response_info_resource.h new file mode 100644 index 0000000..d3902d8 --- /dev/null +++ b/ppapi/proxy/url_response_info_resource.h @@ -0,0 +1,53 @@ +// Copyright (c) 2012 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_PROXY_URL_RESPONSE_INFO_RESOURCE_H_ +#define PPAPI_PROXY_URL_RESPONSE_INFO_RESOURCE_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/proxy/ppapi_proxy_export.h" +#include "ppapi/shared_impl/scoped_pp_resource.h" +#include "ppapi/shared_impl/url_response_info_data.h" +#include "ppapi/thunk/ppb_url_response_info_api.h" + +namespace ppapi { +namespace proxy { + +class PPAPI_PROXY_EXPORT URLResponseInfoResource + : public PluginResource, + public NON_EXPORTED_BASE(thunk::PPB_URLResponseInfo_API) { + public: + // The file_ref_resource should be the body_as_file_ref host resource in the + // |data| converted to a resource valid in the current process (if we're + // downloading to a file; it will be 0 if we're not). A reference + // is passed from the caller and is taken over by this object. + URLResponseInfoResource(Connection connection, + PP_Instance instance, + const URLResponseInfoData& data, + PP_Resource file_ref_resource); + virtual ~URLResponseInfoResource(); + + // Resource override. + virtual PPB_URLResponseInfo_API* AsPPB_URLResponseInfo_API() OVERRIDE; + + // PPB_URLResponseInfo_API implementation. + virtual PP_Var GetProperty(PP_URLResponseProperty property) OVERRIDE; + virtual PP_Resource GetBodyAsFileRef() OVERRIDE; + virtual URLResponseInfoData GetData() OVERRIDE; + + private: + URLResponseInfoData data_; + + // Non-zero when the load is being streamed to a file. + ScopedPPResource body_as_file_ref_; + + DISALLOW_COPY_AND_ASSIGN(URLResponseInfoResource); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_URL_RESPONSE_INFO_RESOURCE_H_ diff --git a/ppapi/shared_impl/url_response_info_data.cc b/ppapi/shared_impl/url_response_info_data.cc new file mode 100644 index 0000000..0b4b078 --- /dev/null +++ b/ppapi/shared_impl/url_response_info_data.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2012 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_response_info_data.h" + +namespace ppapi { + +URLResponseInfoData::URLResponseInfoData() : status_code(-1) { +} + +URLResponseInfoData::~URLResponseInfoData() { +} + +} // namespace ppapi diff --git a/ppapi/shared_impl/url_response_info_data.h b/ppapi/shared_impl/url_response_info_data.h new file mode 100644 index 0000000..a40ca50 --- /dev/null +++ b/ppapi/shared_impl/url_response_info_data.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012 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_RESPONSE_INFO_DATA_H_ +#define PPAPI_SHARED_IMPL_URL_RESPONSE_INFO_DATA_H_ + +#include <string> + +#include "ppapi/c/pp_stdint.h" +#include "ppapi/shared_impl/ppb_file_ref_shared.h" +#include "ppapi/shared_impl/ppapi_shared_export.h" + +namespace ppapi { + +struct PPAPI_SHARED_EXPORT URLResponseInfoData { + URLResponseInfoData(); + ~URLResponseInfoData(); + + std::string url; + std::string headers; + int32_t status_code; + std::string status_text; + std::string redirect_url; + + // Nonzero when streaming to a file. + PPB_FileRef_CreateInfo body_as_file_ref; +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_URL_RESPONSE_INFO_DATA_H_ diff --git a/ppapi/thunk/interfaces_ppb_public_stable.h b/ppapi/thunk/interfaces_ppb_public_stable.h index d3a74a6..96f4a5e 100644 --- a/ppapi/thunk/interfaces_ppb_public_stable.h +++ b/ppapi/thunk/interfaces_ppb_public_stable.h @@ -27,7 +27,6 @@ PROXIED_API(PPB_Graphics3D) PROXIED_API(PPB_ImageData) PROXIED_API(PPB_Instance) PROXIED_API(PPB_URLLoader) -PROXIED_API(PPB_URLResponseInfo) // AudioConfig isn't proxied in the normal way, we have only local classes and // serialize it to a struct when we need it on the host side. @@ -77,7 +76,7 @@ PROXIED_IFACE(PPB_Instance, PPB_MOUSELOCK_INTERFACE_1_0, PPB_MouseLock_1_0) PROXIED_IFACE(PPB_URLLoader, PPB_URLLOADER_INTERFACE_1_0, PPB_URLLoader_1_0) PROXIED_IFACE(NoAPIName, PPB_URLREQUESTINFO_INTERFACE_1_0, PPB_URLRequestInfo_1_0) -PROXIED_IFACE(PPB_URLResponseInfo, PPB_URLRESPONSEINFO_INTERFACE_1_0, +PROXIED_IFACE(NoAPIName, PPB_URLRESPONSEINFO_INTERFACE_1_0, PPB_URLResponseInfo_1_0) PROXIED_IFACE(NoAPIName, PPB_WEBSOCKET_INTERFACE_1_0, PPB_WebSocket_1_0) diff --git a/ppapi/thunk/ppb_url_loader_api.h b/ppapi/thunk/ppb_url_loader_api.h index ddcd20e..0fe8e04 100644 --- a/ppapi/thunk/ppb_url_loader_api.h +++ b/ppapi/thunk/ppb_url_loader_api.h @@ -13,6 +13,7 @@ namespace ppapi { class TrackedCallback; struct URLRequestInfoData; +struct URLResponseInfoData; namespace thunk { @@ -47,6 +48,14 @@ class PPB_URLLoader_API { // Trusted API. virtual void GrantUniversalAccess() = 0; virtual void SetStatusCallback(PP_URLLoaderTrusted_StatusCallback cb) = 0; + + // Internal function. This will fill in the given response info data and + // return true on sucesss. If the dowbload was to a file, there will be one + // plugin reference transferred to the caller. On failure, returns false. + // + // If body_as_file_ref is non-zero, this will transfer one plugin reference + // to that object to the caller. + virtual bool GetResponseInfoData(URLResponseInfoData* data) = 0; }; } // namespace thunk diff --git a/ppapi/thunk/ppb_url_response_info_api.h b/ppapi/thunk/ppb_url_response_info_api.h index e518a9a..b23847a 100644 --- a/ppapi/thunk/ppb_url_response_info_api.h +++ b/ppapi/thunk/ppb_url_response_info_api.h @@ -6,6 +6,7 @@ #define PPAPI_THUNK_PPB_URL_RESPONSE_INFO_API_H_ #include "ppapi/c/ppb_url_response_info.h" +#include "ppapi/shared_impl/url_response_info_data.h" namespace ppapi { namespace thunk { @@ -16,6 +17,11 @@ class PPB_URLResponseInfo_API { virtual PP_Var GetProperty(PP_URLResponseProperty property) = 0; virtual PP_Resource GetBodyAsFileRef() = 0; + + // Internal function to get the internal data. This passes one plugin + // reference to the caller for the file ref resource if body_as_file_ref is + // non-null (meaning we're downloading to a file). + virtual URLResponseInfoData GetData() = 0; }; } // namespace thunk diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index 4c20559..cd0505c 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h @@ -29,6 +29,7 @@ struct PP_Size; namespace ppapi { struct URLRequestInfoData; +struct URLResponseInfoData; namespace thunk { @@ -83,6 +84,15 @@ class ResourceCreationAPI { virtual PP_Resource CreateURLRequestInfo( PP_Instance instance, const URLRequestInfoData& data) = 0; + + // Passes a reference to the file_ref_resource, which is a process-local + // resource corresponding to the body_as_file_ref host resource in |data|, + // if there is one. + virtual PP_Resource CreateURLResponseInfo( + PP_Instance instance, + const URLResponseInfoData& data, + PP_Resource file_ref_resource) = 0; + virtual PP_Resource CreateWheelInputEvent( PP_Instance instance, PP_TimeTicks time_stamp, diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 297ee5b..4fb60f6 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -240,8 +240,6 @@ '../plugins/ppapi/ppb_uma_private_impl.h', '../plugins/ppapi/ppb_url_loader_impl.cc', '../plugins/ppapi/ppb_url_loader_impl.h', - '../plugins/ppapi/ppb_url_response_info_impl.cc', - '../plugins/ppapi/ppb_url_response_info_impl.h', '../plugins/ppapi/ppb_var_deprecated_impl.cc', '../plugins/ppapi/ppb_var_deprecated_impl.h', '../plugins/ppapi/ppb_video_decoder_impl.cc', @@ -258,6 +256,8 @@ '../plugins/ppapi/resource_helper.h', '../plugins/ppapi/string.cc', '../plugins/ppapi/string.h', + '../plugins/ppapi/url_response_info_util.cc', + '../plugins/ppapi/url_response_info_util.h', '../plugins/ppapi/url_request_info_util.cc', '../plugins/ppapi/url_request_info_util.h', '../plugins/ppapi/usb_key_code_conversion.h', diff --git a/webkit/plugins/ppapi/ppb_url_loader_impl.cc b/webkit/plugins/ppapi/ppb_url_loader_impl.cc index 8c29f7c..e707f26 100644 --- a/webkit/plugins/ppapi/ppb_url_loader_impl.cc +++ b/webkit/plugins/ppapi/ppb_url_loader_impl.cc @@ -10,6 +10,8 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_url_loader.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" +#include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/url_response_info_data.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_url_request_info_api.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" @@ -30,7 +32,7 @@ #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/resource_helper.h" #include "webkit/plugins/ppapi/url_request_info_util.h" -#include "webkit/plugins/ppapi/ppb_url_response_info_impl.h" +#include "webkit/plugins/ppapi/url_response_info_util.h" using appcache::WebApplicationCacheHostImpl; using ppapi::Resource; @@ -225,9 +227,20 @@ PP_Bool PPB_URLLoader_Impl::GetDownloadProgress( } PP_Resource PPB_URLLoader_Impl::GetResponseInfo() { - if (!response_info_) + ::ppapi::thunk::EnterResourceCreationNoLock enter(pp_instance()); + if (enter.failed() || !response_info_.get()) return 0; - return response_info_->GetReference(); + + // Since we're the "host" the process-local resource for the file ref is + // the same as the host resource. We pass a ref to the file ref. + if (!response_info_->body_as_file_ref.resource.is_null()) { + ::ppapi::PpapiGlobals::Get()->GetResourceTracker()->AddRefResource( + response_info_->body_as_file_ref.resource.host_resource()); + } + return enter.functions()->CreateURLResponseInfo( + pp_instance(), + *response_info_, + response_info_->body_as_file_ref.resource.host_resource()); } int32_t PPB_URLLoader_Impl::ReadResponseBody( @@ -237,7 +250,8 @@ int32_t PPB_URLLoader_Impl::ReadResponseBody( int32_t rv = ValidateCallback(callback); if (rv != PP_OK) return rv; - if (!response_info_ || response_info_->body()) + if (!response_info_.get() || + !response_info_->body_as_file_ref.resource.is_null()) return PP_ERROR_FAILED; if (bytes_to_read <= 0 || !buffer) return PP_ERROR_BADARGUMENT; @@ -264,7 +278,8 @@ int32_t PPB_URLLoader_Impl::FinishStreamingToFile( int32_t rv = ValidateCallback(callback); if (rv != PP_OK) return rv; - if (!response_info_ || !response_info_->body()) + if (!response_info_.get() || + response_info_->body_as_file_ref.resource.is_null()) return PP_ERROR_FAILED; // We may have already reached EOF. @@ -298,6 +313,21 @@ void PPB_URLLoader_Impl::SetStatusCallback( status_callback_ = cb; } +bool PPB_URLLoader_Impl::GetResponseInfoData( + ::ppapi::URLResponseInfoData* data) { + if (!response_info_.get()) + return false; + + *data = *response_info_; + + // We transfer one plugin reference to the FileRef to the caller. + if (!response_info_->body_as_file_ref.resource.is_null()) { + ::ppapi::PpapiGlobals::Get()->GetResourceTracker()->AddRefResource( + response_info_->body_as_file_ref.resource.host_resource()); + } + return true; +} + void PPB_URLLoader_Impl::willSendRequest( WebURLLoader* loader, WebURLRequest& new_request, @@ -479,10 +509,13 @@ size_t PPB_URLLoader_Impl::FillUserBuffer() { } void PPB_URLLoader_Impl::SaveResponse(const WebURLResponse& response) { - scoped_refptr<PPB_URLResponseInfo_Impl> response_info( - new PPB_URLResponseInfo_Impl(pp_instance())); - if (response_info->Initialize(response)) - response_info_ = response_info; + // DataFromWebURLResponse returns a file ref with one reference to it, which + // we take over via our ScopedPPResource. + response_info_.reset(new ::ppapi::URLResponseInfoData( + DataFromWebURLResponse(pp_instance(), response))); + response_info_file_ref_ = ::ppapi::ScopedPPResource( + ::ppapi::ScopedPPResource::PassRef(), + response_info_->body_as_file_ref.resource.host_resource()); } void PPB_URLLoader_Impl::UpdateStatus() { diff --git a/webkit/plugins/ppapi/ppb_url_loader_impl.h b/webkit/plugins/ppapi/ppb_url_loader_impl.h index 20f4f19..aa1acfd 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/scoped_pp_resource.h" #include "ppapi/shared_impl/tracked_callback.h" #include "ppapi/shared_impl/url_request_info_data.h" #include "ppapi/thunk/ppb_url_loader_api.h" @@ -25,8 +26,6 @@ class WebURL; namespace webkit { namespace ppapi { -class PPB_URLResponseInfo_Impl; - class PPB_URLLoader_Impl : public ::ppapi::Resource, public ::ppapi::thunk::PPB_URLLoader_API, public WebKit::WebURLLoaderClient { @@ -64,6 +63,8 @@ class PPB_URLLoader_Impl : public ::ppapi::Resource, virtual void GrantUniversalAccess() OVERRIDE; virtual void SetStatusCallback( PP_URLLoaderTrusted_StatusCallback cb) OVERRIDE; + virtual bool GetResponseInfoData( + ::ppapi::URLResponseInfoData* data) OVERRIDE; // WebKit::WebURLLoaderClient implementation. virtual void willSendRequest(WebKit::WebURLLoader* loader, @@ -86,8 +87,6 @@ class PPB_URLLoader_Impl : public ::ppapi::Resource, virtual void didFail(WebKit::WebURLLoader* loader, const WebKit::WebURLError& error); - PPB_URLResponseInfo_Impl* response_info() const { return response_info_; } - // Returns the number of bytes currently available for synchronous reading // in the loader. int32_t buffer_size() const { return buffer_.size(); } @@ -146,7 +145,6 @@ class PPB_URLLoader_Impl : public ::ppapi::Resource, // load, etc. since there is no loader. scoped_ptr<WebKit::WebURLLoader> loader_; - scoped_refptr<PPB_URLResponseInfo_Impl> response_info_; scoped_refptr< ::ppapi::TrackedCallback> pending_callback_; std::deque<char> buffer_; int64_t bytes_sent_; @@ -163,6 +161,12 @@ class PPB_URLLoader_Impl : public ::ppapi::Resource, PP_URLLoaderTrusted_StatusCallback status_callback_; + // When the response info is received, this stores the data. The + // ScopedResource maintains the reference to the file ref (if any) in the + // data object so we don't forget to dereference it. + scoped_ptr< ::ppapi::URLResponseInfoData > response_info_; + ::ppapi::ScopedPPResource response_info_file_ref_; + DISALLOW_COPY_AND_ASSIGN(PPB_URLLoader_Impl); }; diff --git a/webkit/plugins/ppapi/ppb_url_response_info_impl.cc b/webkit/plugins/ppapi/ppb_url_response_info_impl.cc deleted file mode 100644 index d5c80ce..0000000 --- a/webkit/plugins/ppapi/ppb_url_response_info_impl.cc +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2012 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 "webkit/plugins/ppapi/ppb_url_response_info_impl.h" - -#include "base/logging.h" -#include "ppapi/c/pp_var.h" -#include "ppapi/shared_impl/var.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebHTTPHeaderVisitor.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.h" -#include "webkit/base/file_path_string_conversions.h" -#include "webkit/plugins/ppapi/common.h" -#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" -#include "webkit/plugins/ppapi/ppb_file_ref_impl.h" -#include "webkit/plugins/ppapi/resource_helper.h" - -using ppapi::StringVar; -using ppapi::thunk::PPB_URLResponseInfo_API; -using WebKit::WebHTTPHeaderVisitor; -using WebKit::WebString; -using WebKit::WebURLResponse; - -namespace webkit { -namespace ppapi { - -namespace { - -class HeaderFlattener : public WebHTTPHeaderVisitor { - public: - const std::string& buffer() const { return buffer_; } - - virtual void visitHeader(const WebString& name, const WebString& value) { - if (!buffer_.empty()) - buffer_.append("\n"); - buffer_.append(name.utf8()); - buffer_.append(": "); - buffer_.append(value.utf8()); - } - - private: - std::string buffer_; -}; - -bool IsRedirect(int32_t status) { - return status >= 300 && status <= 399; -} - -} // namespace - -PPB_URLResponseInfo_Impl::PPB_URLResponseInfo_Impl(PP_Instance instance) - : Resource(::ppapi::OBJECT_IS_IMPL, instance), - status_code_(-1) { -} - -PPB_URLResponseInfo_Impl::~PPB_URLResponseInfo_Impl() { -} - -bool PPB_URLResponseInfo_Impl::Initialize(const WebURLResponse& response) { - url_ = response.url().spec(); - status_code_ = response.httpStatusCode(); - status_text_ = response.httpStatusText().utf8(); - if (IsRedirect(status_code_)) { - redirect_url_ = response.httpHeaderField( - WebString::fromUTF8("Location")).utf8(); - } - - HeaderFlattener flattener; - response.visitHTTPHeaderFields(&flattener); - headers_ = flattener.buffer(); - - WebString file_path = response.downloadFilePath(); - if (!file_path.isEmpty()) { - body_ = PPB_FileRef_Impl::CreateExternal( - pp_instance(), - webkit_base::WebStringToFilePath(file_path), - std::string()); - } - return true; -} - -PPB_URLResponseInfo_API* PPB_URLResponseInfo_Impl::AsPPB_URLResponseInfo_API() { - return this; -} - -PP_Var PPB_URLResponseInfo_Impl::GetProperty(PP_URLResponseProperty property) { - switch (property) { - case PP_URLRESPONSEPROPERTY_URL: - return StringVar::StringToPPVar(url_); - case PP_URLRESPONSEPROPERTY_REDIRECTURL: - if (IsRedirect(status_code_)) - return StringVar::StringToPPVar(redirect_url_); - break; - case PP_URLRESPONSEPROPERTY_REDIRECTMETHOD: - if (IsRedirect(status_code_)) - return StringVar::StringToPPVar(status_text_); - break; - case PP_URLRESPONSEPROPERTY_STATUSCODE: - return PP_MakeInt32(status_code_); - case PP_URLRESPONSEPROPERTY_STATUSLINE: - return StringVar::StringToPPVar(status_text_); - case PP_URLRESPONSEPROPERTY_HEADERS: - return StringVar::StringToPPVar(headers_); - } - // The default is to return an undefined PP_Var. - return PP_MakeUndefined(); -} - -PP_Resource PPB_URLResponseInfo_Impl::GetBodyAsFileRef() { - if (!body_.get()) - return 0; - return body_->GetReference(); -} - -} // namespace ppapi -} // namespace webkit diff --git a/webkit/plugins/ppapi/ppb_url_response_info_impl.h b/webkit/plugins/ppapi/ppb_url_response_info_impl.h deleted file mode 100644 index 96399923..0000000 --- a/webkit/plugins/ppapi/ppb_url_response_info_impl.h +++ /dev/null @@ -1,58 +0,0 @@ -// 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 WEBKIT_PLUGINS_PPAPI_PPB_URL_RESPONSE_INFO_IMPL_H_ -#define WEBKIT_PLUGINS_PPAPI_PPB_URL_RESPONSE_INFO_IMPL_H_ - -#include <string> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "ppapi/c/ppb_url_response_info.h" -#include "ppapi/shared_impl/resource.h" -#include "ppapi/thunk/ppb_url_response_info_api.h" - -namespace WebKit { -class WebURLResponse; -} - -namespace webkit { -namespace ppapi { - -class PPB_FileRef_Impl; - -class PPB_URLResponseInfo_Impl - : public ::ppapi::Resource, - public ::ppapi::thunk::PPB_URLResponseInfo_API { - public: - explicit PPB_URLResponseInfo_Impl(PP_Instance instance); - virtual ~PPB_URLResponseInfo_Impl(); - - bool Initialize(const WebKit::WebURLResponse& response); - - // Resource overrides. - virtual PPB_URLResponseInfo_API* AsPPB_URLResponseInfo_API() OVERRIDE; - - // PPB_URLResponseInfo_API implementation. - virtual PP_Var GetProperty(PP_URLResponseProperty property) OVERRIDE; - virtual PP_Resource GetBodyAsFileRef() OVERRIDE; - - PPB_FileRef_Impl* body() { return body_; } - std::string redirect_url() { return redirect_url_; } - - private: - std::string url_; - std::string headers_; - int32_t status_code_; - std::string status_text_; - std::string redirect_url_; - scoped_refptr<PPB_FileRef_Impl> body_; - - DISALLOW_COPY_AND_ASSIGN(PPB_URLResponseInfo_Impl); -}; - -} // namespace ppapi -} // namespace webkit - -#endif // WEBKIT_PLUGINS_PPAPI_PPB_URL_RESPONSE_INFO_IMPL_H_ diff --git a/webkit/plugins/ppapi/url_response_info_util.cc b/webkit/plugins/ppapi/url_response_info_util.cc new file mode 100644 index 0000000..8ef2363 --- /dev/null +++ b/webkit/plugins/ppapi/url_response_info_util.cc @@ -0,0 +1,78 @@ +// Copyright (c) 2012 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 "webkit/plugins/ppapi/url_response_info_util.h" + +#include "base/logging.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebHTTPHeaderVisitor.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.h" +#include "webkit/base/file_path_string_conversions.h" +#include "webkit/plugins/ppapi/ppb_file_ref_impl.h" +#include "webkit/glue/webkit_glue.h" + +using WebKit::WebHTTPHeaderVisitor; +using WebKit::WebString; +using WebKit::WebURLResponse; + +namespace webkit { +namespace ppapi { + +namespace { + +class HeaderFlattener : public WebHTTPHeaderVisitor { + public: + const std::string& buffer() const { return buffer_; } + + virtual void visitHeader(const WebString& name, const WebString& value) { + if (!buffer_.empty()) + buffer_.append("\n"); + buffer_.append(name.utf8()); + buffer_.append(": "); + buffer_.append(value.utf8()); + } + + private: + std::string buffer_; +}; + +bool IsRedirect(int32_t status) { + return status >= 300 && status <= 399; +} + +} // namespace + +::ppapi::URLResponseInfoData DataFromWebURLResponse( + PP_Instance pp_instance, + const WebURLResponse& response) { + ::ppapi::URLResponseInfoData data; + + data.url = response.url().spec(); + data.status_code = response.httpStatusCode(); + data.status_text = response.httpStatusText().utf8(); + if (IsRedirect(data.status_code)) { + data.redirect_url = response.httpHeaderField( + WebString::fromUTF8("Location")).utf8(); + } + + HeaderFlattener flattener; + response.visitHTTPHeaderFields(&flattener); + data.headers = flattener.buffer(); + + WebString file_path = response.downloadFilePath(); + if (!file_path.isEmpty()) { + scoped_refptr<PPB_FileRef_Impl> file_ref( + PPB_FileRef_Impl::CreateExternal( + pp_instance, + webkit_base::WebStringToFilePath(file_path), + std::string())); + data.body_as_file_ref = file_ref->GetCreateInfo(); + file_ref->GetReference(); // The returned data has one ref for the plugin. + } + return data; +} + +} // namespace ppapi +} // namespace webkit diff --git a/webkit/plugins/ppapi/url_response_info_util.h b/webkit/plugins/ppapi/url_response_info_util.h new file mode 100644 index 0000000..ff805db --- /dev/null +++ b/webkit/plugins/ppapi/url_response_info_util.h @@ -0,0 +1,28 @@ +// Copyright (c) 2012 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 WEBKIT_PLUGINS_PPAPI_PPB_URL_RESPONSE_INFO_UTIL_H_ +#define WEBKIT_PLUGINS_PPAPI_PPB_URL_RESPONSE_INFO_UTIL_H_ + +#include "ppapi/c/pp_instance.h" +#include "ppapi/shared_impl/url_response_info_data.h" + +namespace WebKit { +class WebURLResponse; +} + +namespace webkit { +namespace ppapi { + +// The returned object will have one plugin reference to the "body_as_file_ref" +// if it's non-null. It's expected that the result of this function will be +// passed to the plugin. +::ppapi::URLResponseInfoData DataFromWebURLResponse( + PP_Instance pp_instance, + const WebKit::WebURLResponse& response); + +} // namespace ppapi +} // namespace webkit + +#endif // WEBKIT_PLUGINS_PPAPI_PPB_URL_RESPONSE_INFO_UTIL_H_ |