Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(682)

Unified Diff: ppapi/proxy/ppb_url_loader_proxy.cc

Issue 11417145: Provide a safer URLLoader ReadResponseBody API (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c ('k') | ppapi/tests/test_url_loader.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/proxy/ppb_url_loader_proxy.cc
diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc
index 91c1bba3020bd3ebb0ed6d22f0db126c453f29d5..3421ef002d674b06e5059eede3ff04cbcce0d8ce 100644
--- a/ppapi/proxy/ppb_url_loader_proxy.cc
+++ b/ppapi/proxy/ppb_url_loader_proxy.cc
@@ -23,6 +23,7 @@
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppb_file_ref_proxy.h"
+#include "ppapi/shared_impl/array_writer.h"
#include "ppapi/shared_impl/scoped_pp_resource.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/thunk/enter.h"
@@ -78,6 +79,12 @@ InterfaceProxy* CreateURLLoaderProxy(Dispatcher* dispatcher) {
return new PPB_URLLoader_Proxy(dispatcher);
}
+// An adapter to let ReadResponseBody() share the same implementation with
+// ReadResponseBodyToArray().
+void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) {
+ return user_data;
+}
+
} // namespace
// URLLoader -------------------------------------------------------------------
@@ -108,6 +115,10 @@ class URLLoader : public Resource, public PPB_URLLoader_API {
void* buffer,
int32_t bytes_to_read,
scoped_refptr<TrackedCallback> callback) OVERRIDE;
+ virtual int32_t ReadResponseBodyToArray(
+ int32_t max_read_length,
+ PP_ArrayOutput* array_output,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual int32_t FinishStreamingToFile(
scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual void Close() OVERRIDE;
@@ -116,6 +127,10 @@ class URLLoader : public Resource, public PPB_URLLoader_API {
PP_URLLoaderTrusted_StatusCallback cb) OVERRIDE;
virtual bool GetResponseInfoData(URLResponseInfoData* data) OVERRIDE;
+ int32_t ReadResponseBodyInternal(const PP_ArrayOutput& output,
+ int32_t max_read_length,
+ scoped_refptr<TrackedCallback> callback);
+
// Called when the browser has new up/download progress to report.
void UpdateProgress(const PPBURLLoader_UpdateProgress_Params& params);
@@ -130,7 +145,7 @@ class URLLoader : public Resource, public PPB_URLLoader_API {
// buffer, and removes the bytes from the buffer.
//
// The size must be not more than the current size of the buffer.
- void PopBuffer(void* output_buffer, int32_t output_size);
+ void PopBuffer(const PP_ArrayOutput& output_buffer, int32_t output_size);
PluginDispatcher* GetDispatcher() const {
return PluginDispatcher::GetForResource(this);
@@ -149,8 +164,8 @@ class URLLoader : public Resource, public PPB_URLLoader_API {
// When an asynchronous read is pending, this will contain the buffer to put
// the data. The current_callback_ will identify the read callback.
- void* current_read_buffer_;
- int32_t current_read_buffer_size_;
+ PP_ArrayOutput current_array_output_;
+ int32_t current_max_read_length_;
// A buffer of all the data that's been sent to us from the host that we
// have yet to send out to the plugin.
@@ -170,8 +185,7 @@ URLLoader::URLLoader(const HostResource& resource)
total_bytes_to_be_sent_(-1),
bytes_received_(-1),
total_bytes_to_be_received_(-1),
- current_read_buffer_(NULL),
- current_read_buffer_size_(0),
+ current_max_read_length_(0),
response_info_(0) {
}
@@ -278,27 +292,19 @@ PP_Resource URLLoader::GetResponseInfo() {
int32_t URLLoader::ReadResponseBody(void* buffer,
int32_t bytes_to_read,
scoped_refptr<TrackedCallback> callback) {
- if (!buffer || bytes_to_read <= 0)
- return PP_ERROR_BADARGUMENT; // Must specify an output buffer.
- if (TrackedCallback::IsPending(current_callback_))
- return PP_ERROR_INPROGRESS; // Can only have one request pending.
-
- if (buffer_.size()) {
- // Special case: we've already buffered some data that we can synchronously
- // return to the caller. Do so without making IPCs.
- int32_t bytes_to_return =
- std::min(bytes_to_read, static_cast<int32_t>(buffer_.size()));
- PopBuffer(buffer, bytes_to_return);
- return bytes_to_return;
- }
-
- current_callback_ = callback;
- current_read_buffer_ = buffer;
- current_read_buffer_size_ = bytes_to_read;
+ if (!buffer)
+ return PP_ERROR_BADARGUMENT;
+ PP_ArrayOutput output_adapter = { &DummyGetDataBuffer, buffer };
+ return ReadResponseBodyInternal(output_adapter, bytes_to_read, callback);
+}
- GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody(
- API_ID_PPB_URL_LOADER, host_resource(), bytes_to_read));
- return PP_OK_COMPLETIONPENDING;
+int32_t URLLoader::ReadResponseBodyToArray(
+ int32_t max_read_length,
+ PP_ArrayOutput* array_output,
+ scoped_refptr<TrackedCallback> callback) {
+ if (!array_output)
+ return PP_ERROR_BADARGUMENT;
+ return ReadResponseBodyInternal(*array_output, max_read_length, callback);
}
int32_t URLLoader::FinishStreamingToFile(
@@ -345,7 +351,7 @@ void URLLoader::UpdateProgress(
}
void URLLoader::ReadResponseBodyAck(int32 result, const char* data) {
- if (!TrackedCallback::IsPending(current_callback_) || !current_read_buffer_) {
+ if (!TrackedCallback::IsPending(current_callback_)) {
NOTREACHED();
return;
}
@@ -353,10 +359,11 @@ void URLLoader::ReadResponseBodyAck(int32 result, const char* data) {
if (result >= 0) {
DCHECK_EQ(0U, buffer_.size());
- int32_t bytes_to_return = std::min(current_read_buffer_size_, result);
- std::copy(data,
- data + bytes_to_return,
- static_cast<char*>(current_read_buffer_));
+ int32_t bytes_to_return = std::min(current_max_read_length_, result);
+ ArrayWriter output;
+ output.set_pp_array_output(current_array_output_);
+ if (output.is_valid())
+ output.StoreArray(data, bytes_to_return);
if (result > bytes_to_return) {
// Save what remains to be copied when ReadResponseBody is called again.
@@ -375,13 +382,16 @@ void URLLoader::CallbackComplete(int32_t result) {
current_callback_->Run(result);
}
-void URLLoader::PopBuffer(void* output_buffer, int32_t output_size) {
+void URLLoader::PopBuffer(const PP_ArrayOutput& output_buffer,
+ int32_t output_size) {
CHECK(output_size <= static_cast<int32_t>(buffer_.size()));
- std::copy(buffer_.begin(),
- buffer_.begin() + output_size,
- static_cast<char*>(output_buffer));
- buffer_.erase(buffer_.begin(),
- buffer_.begin() + output_size);
+
+ ArrayWriter output;
+ output.set_pp_array_output(output_buffer);
+ if (output.is_valid() && !buffer_.empty()) {
+ output.StoreArray(&buffer_[0], output_size);
+ buffer_.erase(buffer_.begin(), buffer_.begin() + output_size);
+ }
}
// PPB_URLLoader_Proxy ---------------------------------------------------------
@@ -645,5 +655,32 @@ void PPB_URLLoader_Proxy::OnCallback(int32_t result,
}
#endif // !defined(OS_NACL)
+int32_t URLLoader::ReadResponseBodyInternal(
+ const PP_ArrayOutput& output,
+ int32_t max_read_length,
+ scoped_refptr<TrackedCallback> callback) {
+ if (max_read_length <= 0)
+ return PP_ERROR_BADARGUMENT; // Must specify an output buffer.
+ if (TrackedCallback::IsPending(current_callback_))
+ return PP_ERROR_INPROGRESS; // Can only have one request pending.
+
+ if (buffer_.size()) {
+ // Special case: we've already buffered some data that we can synchronously
+ // return to the caller. Do so without making IPCs.
+ int32_t bytes_to_return =
+ std::min(max_read_length, static_cast<int32_t>(buffer_.size()));
+ PopBuffer(output, bytes_to_return);
+ return bytes_to_return;
+ }
+
+ current_callback_ = callback;
+ current_array_output_ = output;
+ current_max_read_length_ = max_read_length;
+
+ GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody(
+ API_ID_PPB_URL_LOADER, host_resource(), max_read_length));
+ return PP_OK_COMPLETIONPENDING;
+}
+
} // namespace proxy
} // namespace ppapi
« no previous file with comments | « ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c ('k') | ppapi/tests/test_url_loader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698