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

Side by Side Diff: webkit/plugins/ppapi/ppb_url_loader_impl.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 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 unified diff | Download patch
« no previous file with comments | « webkit/plugins/ppapi/ppb_url_loader_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/plugins/ppapi/ppb_url_loader_impl.h" 5 #include "webkit/plugins/ppapi/ppb_url_loader_impl.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "net/base/net_errors.h" 8 #include "net/base/net_errors.h"
9 #include "ppapi/c/pp_completion_callback.h" 9 #include "ppapi/c/pp_completion_callback.h"
10 #include "ppapi/c/pp_errors.h" 10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/c/ppb_url_loader.h" 11 #include "ppapi/c/ppb_url_loader.h"
12 #include "ppapi/c/trusted/ppb_url_loader_trusted.h" 12 #include "ppapi/c/trusted/ppb_url_loader_trusted.h"
13 #include "ppapi/shared_impl/array_writer.h"
13 #include "ppapi/shared_impl/ppapi_globals.h" 14 #include "ppapi/shared_impl/ppapi_globals.h"
14 #include "ppapi/shared_impl/url_response_info_data.h" 15 #include "ppapi/shared_impl/url_response_info_data.h"
15 #include "ppapi/thunk/enter.h" 16 #include "ppapi/thunk/enter.h"
16 #include "ppapi/thunk/ppb_url_request_info_api.h" 17 #include "ppapi/thunk/ppb_url_request_info_api.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebKitPlatfo rmSupport.h" 22 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebKitPlatfo rmSupport.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" 23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 60
60 namespace { 61 namespace {
61 62
62 WebFrame* GetFrameForResource(const Resource* resource) { 63 WebFrame* GetFrameForResource(const Resource* resource) {
63 PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(resource); 64 PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(resource);
64 if (!plugin_instance) 65 if (!plugin_instance)
65 return NULL; 66 return NULL;
66 return plugin_instance->container()->element().document().frame(); 67 return plugin_instance->container()->element().document().frame();
67 } 68 }
68 69
70 // An adapter to let ReadResponseBody() share the same implementation with
71 // ReadResponseBodyToArray().
72 void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) {
73 return user_data;
74 }
75
69 } // namespace 76 } // namespace
70 77
71 PPB_URLLoader_Impl::PPB_URLLoader_Impl(PP_Instance instance, 78 PPB_URLLoader_Impl::PPB_URLLoader_Impl(PP_Instance instance,
72 bool main_document_loader) 79 bool main_document_loader)
73 : Resource(::ppapi::OBJECT_IS_IMPL, instance), 80 : Resource(::ppapi::OBJECT_IS_IMPL, instance),
74 main_document_loader_(main_document_loader), 81 main_document_loader_(main_document_loader),
75 pending_callback_(), 82 pending_callback_(),
76 bytes_sent_(0), 83 bytes_sent_(0),
77 total_bytes_to_be_sent_(-1), 84 total_bytes_to_be_sent_(-1),
78 bytes_received_(0), 85 bytes_received_(0),
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 return enter.functions()->CreateURLResponseInfo( 247 return enter.functions()->CreateURLResponseInfo(
241 pp_instance(), 248 pp_instance(),
242 *response_info_, 249 *response_info_,
243 response_info_->body_as_file_ref.resource.host_resource()); 250 response_info_->body_as_file_ref.resource.host_resource());
244 } 251 }
245 252
246 int32_t PPB_URLLoader_Impl::ReadResponseBody( 253 int32_t PPB_URLLoader_Impl::ReadResponseBody(
247 void* buffer, 254 void* buffer,
248 int32_t bytes_to_read, 255 int32_t bytes_to_read,
249 scoped_refptr<TrackedCallback> callback) { 256 scoped_refptr<TrackedCallback> callback) {
257 if (!buffer)
258 return PP_ERROR_BADARGUMENT;
259 PP_ArrayOutput output_adapter = { &DummyGetDataBuffer, buffer };
260 return ReadResponseBodyInternal(bytes_to_read, output_adapter, callback);
261 }
262
263 int32_t PPB_URLLoader_Impl::ReadResponseBodyInternal(
264 int32_t max_read_length,
265 const PP_ArrayOutput& array_output,
266 scoped_refptr<TrackedCallback> callback) {
250 int32_t rv = ValidateCallback(callback); 267 int32_t rv = ValidateCallback(callback);
251 if (rv != PP_OK) 268 if (rv != PP_OK)
252 return rv; 269 return rv;
253 if (!response_info_.get() || 270 if (!response_info_.get() ||
254 !response_info_->body_as_file_ref.resource.is_null()) 271 !response_info_->body_as_file_ref.resource.is_null())
255 return PP_ERROR_FAILED; 272 return PP_ERROR_FAILED;
256 if (bytes_to_read <= 0 || !buffer) 273 if (max_read_length <= 0)
257 return PP_ERROR_BADARGUMENT; 274 return PP_ERROR_BADARGUMENT;
258 275
259 user_buffer_ = static_cast<char*>(buffer); 276 user_buffer_.reset(new PP_ArrayOutput(array_output));
260 user_buffer_size_ = bytes_to_read; 277 user_buffer_size_ = max_read_length;
261 278
262 if (!buffer_.empty()) 279 if (!buffer_.empty())
263 return FillUserBuffer(); 280 return FillUserBuffer();
264 281
265 // We may have already reached EOF. 282 // We may have already reached EOF.
266 if (done_status_ != PP_OK_COMPLETIONPENDING) { 283 if (done_status_ != PP_OK_COMPLETIONPENDING) {
267 user_buffer_ = NULL; 284 user_buffer_.reset(NULL);
268 user_buffer_size_ = 0; 285 user_buffer_size_ = 0;
269 return done_status_; 286 return done_status_;
270 } 287 }
271 288
272 RegisterCallback(callback); 289 RegisterCallback(callback);
273 return PP_OK_COMPLETIONPENDING; 290 return PP_OK_COMPLETIONPENDING;
274 } 291 }
275 292
293 int32_t PPB_URLLoader_Impl::ReadResponseBodyToArray(
294 int32_t max_read_length,
295 PP_ArrayOutput* array_output,
296 scoped_refptr<TrackedCallback> callback) {
297 if (!array_output)
298 return PP_ERROR_BADARGUMENT;
299 return ReadResponseBodyInternal(max_read_length, *array_output, callback);
300 }
301
276 int32_t PPB_URLLoader_Impl::FinishStreamingToFile( 302 int32_t PPB_URLLoader_Impl::FinishStreamingToFile(
277 scoped_refptr<TrackedCallback> callback) { 303 scoped_refptr<TrackedCallback> callback) {
278 int32_t rv = ValidateCallback(callback); 304 int32_t rv = ValidateCallback(callback);
279 if (rv != PP_OK) 305 if (rv != PP_OK)
280 return rv; 306 return rv;
281 if (!response_info_.get() || 307 if (!response_info_.get() ||
282 response_info_->body_as_file_ref.resource.is_null()) 308 response_info_->body_as_file_ref.resource.is_null())
283 return PP_ERROR_FAILED; 309 return PP_ERROR_FAILED;
284 310
285 // We may have already reached EOF. 311 // We may have already reached EOF.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 loader_->setDefersLoading(defers_loading); 456 loader_->setDefersLoading(defers_loading);
431 is_asynchronous_load_suspended_ = defers_loading; 457 is_asynchronous_load_suspended_ = defers_loading;
432 } 458 }
433 459
434 // TODO(brettw) bug 96770: We need a way to set the defers loading flag on 460 // TODO(brettw) bug 96770: We need a way to set the defers loading flag on
435 // main document loads (when the loader_ is null). 461 // main document loads (when the loader_ is null).
436 } 462 }
437 463
438 void PPB_URLLoader_Impl::FinishLoading(int32_t done_status) { 464 void PPB_URLLoader_Impl::FinishLoading(int32_t done_status) {
439 done_status_ = done_status; 465 done_status_ = done_status;
440 user_buffer_ = NULL; 466 user_buffer_.reset(NULL);
441 user_buffer_size_ = 0; 467 user_buffer_size_ = 0;
442 // If the client hasn't called any function that takes a callback since 468 // If the client hasn't called any function that takes a callback since
443 // the initial call to Open, or called ReadResponseBody and got a 469 // the initial call to Open, or called ReadResponseBody and got a
444 // synchronous return, then the callback will be NULL. 470 // synchronous return, then the callback will be NULL.
445 if (TrackedCallback::IsPending(pending_callback_)) 471 if (TrackedCallback::IsPending(pending_callback_))
446 RunCallback(done_status_); 472 RunCallback(done_status_);
447 } 473 }
448 474
449 int32_t PPB_URLLoader_Impl::ValidateCallback( 475 int32_t PPB_URLLoader_Impl::ValidateCallback(
450 scoped_refptr<TrackedCallback> callback) { 476 scoped_refptr<TrackedCallback> callback) {
(...skipping 23 matching lines...) Expand all
474 return; 500 return;
475 } 501 }
476 502
477 // If |user_buffer_| was set as part of registering a callback, the paths 503 // If |user_buffer_| was set as part of registering a callback, the paths
478 // which trigger that callack must have cleared it since the callback is now 504 // which trigger that callack must have cleared it since the callback is now
479 // free to delete it. 505 // free to delete it.
480 DCHECK(!user_buffer_); 506 DCHECK(!user_buffer_);
481 507
482 // As a second line of defense, clear the |user_buffer_| in case the 508 // As a second line of defense, clear the |user_buffer_| in case the
483 // callbacks get called in an unexpected order. 509 // callbacks get called in an unexpected order.
484 user_buffer_ = NULL; 510 user_buffer_.reset(NULL);
485 user_buffer_size_ = 0; 511 user_buffer_size_ = 0;
486 pending_callback_->Run(result); 512 pending_callback_->Run(result);
487 } 513 }
488 514
489 size_t PPB_URLLoader_Impl::FillUserBuffer() { 515 size_t PPB_URLLoader_Impl::FillUserBuffer() {
490 DCHECK(user_buffer_); 516 DCHECK(user_buffer_.get());
491 DCHECK(user_buffer_size_); 517 DCHECK(user_buffer_size_);
492 518
493 size_t bytes_to_copy = std::min(buffer_.size(), user_buffer_size_); 519 size_t bytes_to_copy = std::min(buffer_.size(), user_buffer_size_);
494 std::copy(buffer_.begin(), buffer_.begin() + bytes_to_copy, user_buffer_); 520 ::ppapi::ArrayWriter output;
495 buffer_.erase(buffer_.begin(), buffer_.begin() + bytes_to_copy); 521 output.set_pp_array_output(*user_buffer_);
522 if (output.is_valid() && !buffer_.empty()) {
523 output.StoreArray(&buffer_[0], bytes_to_copy);
524 buffer_.erase(buffer_.begin(), buffer_.begin() + bytes_to_copy);
525 }
496 526
497 // If the buffer is getting too empty, resume asynchronous loading. 527 // If the buffer is getting too empty, resume asynchronous loading.
498 if (is_asynchronous_load_suspended_ && 528 if (is_asynchronous_load_suspended_ &&
499 buffer_.size() <= static_cast<size_t>( 529 buffer_.size() <= static_cast<size_t>(
500 request_data_.prefetch_buffer_lower_threshold)) { 530 request_data_.prefetch_buffer_lower_threshold)) {
501 DVLOG(1) << "Resuming async load - buffer size: " << buffer_.size(); 531 DVLOG(1) << "Resuming async load - buffer size: " << buffer_.size();
502 SetDefersLoading(false); 532 SetDefersLoading(false);
503 } 533 }
504 534
505 // Reset for next time. 535 // Reset for next time.
506 user_buffer_ = NULL; 536 user_buffer_.reset(NULL);
507 user_buffer_size_ = 0; 537 user_buffer_size_ = 0;
508 return bytes_to_copy; 538 return bytes_to_copy;
509 } 539 }
510 540
511 void PPB_URLLoader_Impl::SaveResponse(const WebURLResponse& response) { 541 void PPB_URLLoader_Impl::SaveResponse(const WebURLResponse& response) {
512 // DataFromWebURLResponse returns a file ref with one reference to it, which 542 // DataFromWebURLResponse returns a file ref with one reference to it, which
513 // we take over via our ScopedPPResource. 543 // we take over via our ScopedPPResource.
514 response_info_.reset(new ::ppapi::URLResponseInfoData( 544 response_info_.reset(new ::ppapi::URLResponseInfoData(
515 DataFromWebURLResponse(pp_instance(), response))); 545 DataFromWebURLResponse(pp_instance(), response)));
516 response_info_file_ref_ = ::ppapi::ScopedPPResource( 546 response_info_file_ref_ = ::ppapi::ScopedPPResource(
(...skipping 21 matching lines...) Expand all
538 bool PPB_URLLoader_Impl::RecordDownloadProgress() const { 568 bool PPB_URLLoader_Impl::RecordDownloadProgress() const {
539 return request_data_.record_download_progress; 569 return request_data_.record_download_progress;
540 } 570 }
541 571
542 bool PPB_URLLoader_Impl::RecordUploadProgress() const { 572 bool PPB_URLLoader_Impl::RecordUploadProgress() const {
543 return request_data_.record_upload_progress; 573 return request_data_.record_upload_progress;
544 } 574 }
545 575
546 } // namespace ppapi 576 } // namespace ppapi
547 } // namespace webkit 577 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/ppb_url_loader_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698