Refactor android test results logging.
[chromium-blink-merge.git] / ppapi / proxy / ppb_url_loader_proxy.cc
blob91c1bba3020bd3ebb0ed6d22f0db126c453f29d5
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
3 // found in the LICENSE file.
5 #include "ppapi/proxy/ppb_url_loader_proxy.h"
7 #include <algorithm>
8 #include <deque>
9 #include <vector>
11 #include "base/bind.h"
12 #include "base/logging.h"
13 #include "build/build_config.h"
14 #include "ppapi/c/pp_completion_callback.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/c/pp_resource.h"
17 #include "ppapi/c/ppb_url_loader.h"
18 #include "ppapi/c/private/ppb_proxy_private.h"
19 #include "ppapi/c/trusted/ppb_url_loader_trusted.h"
20 #include "ppapi/proxy/enter_proxy.h"
21 #include "ppapi/proxy/host_dispatcher.h"
22 #include "ppapi/proxy/plugin_dispatcher.h"
23 #include "ppapi/proxy/plugin_resource_tracker.h"
24 #include "ppapi/proxy/ppapi_messages.h"
25 #include "ppapi/proxy/ppb_file_ref_proxy.h"
26 #include "ppapi/shared_impl/scoped_pp_resource.h"
27 #include "ppapi/shared_impl/tracked_callback.h"
28 #include "ppapi/thunk/enter.h"
29 #include "ppapi/thunk/ppb_url_loader_api.h"
30 #include "ppapi/thunk/ppb_url_request_info_api.h"
31 #include "ppapi/thunk/resource_creation_api.h"
32 #include "ppapi/thunk/thunk.h"
34 #if defined(OS_LINUX)
35 #include <sys/shm.h>
36 #endif
38 using ppapi::thunk::EnterResourceNoLock;
39 using ppapi::thunk::PPB_URLLoader_API;
40 using ppapi::thunk::ResourceCreationAPI;
42 namespace ppapi {
43 namespace proxy {
45 namespace {
47 // The maximum size we'll read into the plugin without being explicitly
48 // asked for a larger buffer.
49 const int32_t kMaxReadBufferSize = 16777216; // 16MB
51 #if !defined(OS_NACL)
52 // Called in the renderer when the byte counts have changed. We send a message
53 // to the plugin to synchronize its counts so it can respond to status polls
54 // from the plugin.
55 void UpdateResourceLoadStatus(PP_Instance pp_instance,
56 PP_Resource pp_resource,
57 int64 bytes_sent,
58 int64 total_bytes_to_be_sent,
59 int64 bytes_received,
60 int64 total_bytes_to_be_received) {
61 Dispatcher* dispatcher = HostDispatcher::GetForInstance(pp_instance);
62 if (!dispatcher)
63 return;
65 PPBURLLoader_UpdateProgress_Params params;
66 params.instance = pp_instance;
67 params.resource.SetHostResource(pp_instance, pp_resource);
68 params.bytes_sent = bytes_sent;
69 params.total_bytes_to_be_sent = total_bytes_to_be_sent;
70 params.bytes_received = bytes_received;
71 params.total_bytes_to_be_received = total_bytes_to_be_received;
72 dispatcher->Send(new PpapiMsg_PPBURLLoader_UpdateProgress(
73 API_ID_PPB_URL_LOADER, params));
75 #endif // !defined(OS_NACL)
77 InterfaceProxy* CreateURLLoaderProxy(Dispatcher* dispatcher) {
78 return new PPB_URLLoader_Proxy(dispatcher);
81 } // namespace
83 // URLLoader -------------------------------------------------------------------
85 class URLLoader : public Resource, public PPB_URLLoader_API {
86 public:
87 URLLoader(const HostResource& resource);
88 virtual ~URLLoader();
90 // Resource overrides.
91 virtual PPB_URLLoader_API* AsPPB_URLLoader_API() OVERRIDE;
93 // PPB_URLLoader_API implementation.
94 virtual int32_t Open(PP_Resource request_id,
95 scoped_refptr<TrackedCallback> callback) OVERRIDE;
96 virtual int32_t Open(const URLRequestInfoData& data,
97 int requestor_pid,
98 scoped_refptr<TrackedCallback> callback) OVERRIDE;
99 virtual int32_t FollowRedirect(
100 scoped_refptr<TrackedCallback> callback) OVERRIDE;
101 virtual PP_Bool GetUploadProgress(int64_t* bytes_sent,
102 int64_t* total_bytes_to_be_sent) OVERRIDE;
103 virtual PP_Bool GetDownloadProgress(
104 int64_t* bytes_received,
105 int64_t* total_bytes_to_be_received) OVERRIDE;
106 virtual PP_Resource GetResponseInfo() OVERRIDE;
107 virtual int32_t ReadResponseBody(
108 void* buffer,
109 int32_t bytes_to_read,
110 scoped_refptr<TrackedCallback> callback) OVERRIDE;
111 virtual int32_t FinishStreamingToFile(
112 scoped_refptr<TrackedCallback> callback) OVERRIDE;
113 virtual void Close() OVERRIDE;
114 virtual void GrantUniversalAccess() OVERRIDE;
115 virtual void SetStatusCallback(
116 PP_URLLoaderTrusted_StatusCallback cb) OVERRIDE;
117 virtual bool GetResponseInfoData(URLResponseInfoData* data) OVERRIDE;
119 // Called when the browser has new up/download progress to report.
120 void UpdateProgress(const PPBURLLoader_UpdateProgress_Params& params);
122 // Called when the browser responds to our ReadResponseBody request.
123 void ReadResponseBodyAck(int32_t result, const char* data);
125 // Called when any callback other than the read callback has been executed.
126 void CallbackComplete(int32_t result);
128 private:
129 // Reads the give bytes out of the buffer_, placing them in the given output
130 // buffer, and removes the bytes from the buffer.
132 // The size must be not more than the current size of the buffer.
133 void PopBuffer(void* output_buffer, int32_t output_size);
135 PluginDispatcher* GetDispatcher() const {
136 return PluginDispatcher::GetForResource(this);
139 // Initialized to -1. Will be set to nonnegative values by the UpdateProgress
140 // message when the values are known.
141 int64_t bytes_sent_;
142 int64_t total_bytes_to_be_sent_;
143 int64_t bytes_received_;
144 int64_t total_bytes_to_be_received_;
146 // Current completion callback for the current phase of loading. We have only
147 // one thing (open, follow redirect, read, etc.) outstanding at once.
148 scoped_refptr<TrackedCallback> current_callback_;
150 // When an asynchronous read is pending, this will contain the buffer to put
151 // the data. The current_callback_ will identify the read callback.
152 void* current_read_buffer_;
153 int32_t current_read_buffer_size_;
155 // A buffer of all the data that's been sent to us from the host that we
156 // have yet to send out to the plugin.
157 std::deque<char> buffer_;
159 // Cached copy of the response info. When nonzero, we're holding a reference
160 // to this resource.
161 PP_Resource response_info_;
163 private:
164 DISALLOW_COPY_AND_ASSIGN(URLLoader);
167 URLLoader::URLLoader(const HostResource& resource)
168 : Resource(OBJECT_IS_PROXY, resource),
169 bytes_sent_(-1),
170 total_bytes_to_be_sent_(-1),
171 bytes_received_(-1),
172 total_bytes_to_be_received_(-1),
173 current_read_buffer_(NULL),
174 current_read_buffer_size_(0),
175 response_info_(0) {
178 URLLoader::~URLLoader() {
179 if (response_info_)
180 PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(response_info_);
183 PPB_URLLoader_API* URLLoader::AsPPB_URLLoader_API() {
184 return this;
187 int32_t URLLoader::Open(PP_Resource request_id,
188 scoped_refptr<TrackedCallback> callback) {
189 EnterResourceNoLock<thunk::PPB_URLRequestInfo_API> enter(request_id, true);
190 if (enter.failed()) {
191 Log(PP_LOGLEVEL_ERROR, "PPB_URLLoader.Open: The URL you're requesting is "
192 " on a different security origin than your plugin. To request "
193 " cross-origin resources, see "
194 " PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS.");
195 return PP_ERROR_BADRESOURCE;
197 return Open(enter.object()->GetData(), 0, callback);
200 int32_t URLLoader::Open(const URLRequestInfoData& data,
201 int requestor_pid,
202 scoped_refptr<TrackedCallback> callback) {
203 DCHECK_EQ(0, requestor_pid); // Used in-process only.
205 if (TrackedCallback::IsPending(current_callback_))
206 return PP_ERROR_INPROGRESS;
208 current_callback_ = callback;
210 GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_Open(
211 API_ID_PPB_URL_LOADER, host_resource(), data));
212 return PP_OK_COMPLETIONPENDING;
215 int32_t URLLoader::FollowRedirect(scoped_refptr<TrackedCallback> callback) {
216 if (TrackedCallback::IsPending(current_callback_))
217 return PP_ERROR_INPROGRESS;
219 current_callback_ = callback;
221 GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_FollowRedirect(
222 API_ID_PPB_URL_LOADER, host_resource()));
223 return PP_OK_COMPLETIONPENDING;
226 PP_Bool URLLoader::GetUploadProgress(int64_t* bytes_sent,
227 int64_t* total_bytes_to_be_sent) {
228 if (bytes_sent_ == -1) {
229 *bytes_sent = 0;
230 *total_bytes_to_be_sent = 0;
231 return PP_FALSE;
233 *bytes_sent = bytes_sent_;
234 *total_bytes_to_be_sent = total_bytes_to_be_sent_;
235 return PP_TRUE;
238 PP_Bool URLLoader::GetDownloadProgress(
239 int64_t* bytes_received,
240 int64_t* total_bytes_to_be_received) {
241 if (bytes_received_ == -1) {
242 *bytes_received = 0;
243 *total_bytes_to_be_received = 0;
244 return PP_FALSE;
246 *bytes_received = bytes_received_;
247 *total_bytes_to_be_received = total_bytes_to_be_received_;
248 return PP_TRUE;
251 PP_Resource URLLoader::GetResponseInfo() {
252 if (!response_info_) {
253 bool success = false;
254 URLResponseInfoData data;
255 GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_GetResponseInfo(
256 API_ID_PPB_URL_LOADER, host_resource(), &success, &data));
257 if (!success)
258 return 0;
260 // Create a proxy resource for the the file ref host resource if needed.
261 PP_Resource body_as_file_ref = 0;
262 if (!data.body_as_file_ref.resource.is_null()) {
263 body_as_file_ref =
264 PPB_FileRef_Proxy::DeserializeFileRef(data.body_as_file_ref);
267 // Assumes ownership of body_as_file_ref.
268 thunk::EnterResourceCreationNoLock enter(pp_instance());
269 response_info_ = enter.functions()->CreateURLResponseInfo(
270 pp_instance(), data, body_as_file_ref);
273 // The caller expects to get a ref, and we want to keep holding ours.
274 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(response_info_);
275 return response_info_;
278 int32_t URLLoader::ReadResponseBody(void* buffer,
279 int32_t bytes_to_read,
280 scoped_refptr<TrackedCallback> callback) {
281 if (!buffer || bytes_to_read <= 0)
282 return PP_ERROR_BADARGUMENT; // Must specify an output buffer.
283 if (TrackedCallback::IsPending(current_callback_))
284 return PP_ERROR_INPROGRESS; // Can only have one request pending.
286 if (buffer_.size()) {
287 // Special case: we've already buffered some data that we can synchronously
288 // return to the caller. Do so without making IPCs.
289 int32_t bytes_to_return =
290 std::min(bytes_to_read, static_cast<int32_t>(buffer_.size()));
291 PopBuffer(buffer, bytes_to_return);
292 return bytes_to_return;
295 current_callback_ = callback;
296 current_read_buffer_ = buffer;
297 current_read_buffer_size_ = bytes_to_read;
299 GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody(
300 API_ID_PPB_URL_LOADER, host_resource(), bytes_to_read));
301 return PP_OK_COMPLETIONPENDING;
304 int32_t URLLoader::FinishStreamingToFile(
305 scoped_refptr<TrackedCallback> callback) {
306 if (TrackedCallback::IsPending(current_callback_))
307 return PP_ERROR_INPROGRESS;
309 current_callback_ = callback;
311 GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_FinishStreamingToFile(
312 API_ID_PPB_URL_LOADER, host_resource()));
313 return PP_OK_COMPLETIONPENDING;
316 void URLLoader::Close() {
317 GetDispatcher()->Send(new PpapiHostMsg_PPBURLLoader_Close(
318 API_ID_PPB_URL_LOADER, host_resource()));
321 void URLLoader::GrantUniversalAccess() {
322 GetDispatcher()->Send(
323 new PpapiHostMsg_PPBURLLoader_GrantUniversalAccess(
324 API_ID_PPB_URL_LOADER, host_resource()));
327 void URLLoader::SetStatusCallback(
328 PP_URLLoaderTrusted_StatusCallback cb) {
329 // Not implemented in the proxied version, this is for implementing the
330 // proxy itself in the host.
333 bool URLLoader::GetResponseInfoData(URLResponseInfoData* data) {
334 // Not implemented in the proxied version, this is for implementing the
335 // proxy itself in the host.
336 return false;
339 void URLLoader::UpdateProgress(
340 const PPBURLLoader_UpdateProgress_Params& params) {
341 bytes_sent_ = params.bytes_sent;
342 total_bytes_to_be_sent_ = params.total_bytes_to_be_sent;
343 bytes_received_ = params.bytes_received;
344 total_bytes_to_be_received_ = params.total_bytes_to_be_received;
347 void URLLoader::ReadResponseBodyAck(int32 result, const char* data) {
348 if (!TrackedCallback::IsPending(current_callback_) || !current_read_buffer_) {
349 NOTREACHED();
350 return;
353 if (result >= 0) {
354 DCHECK_EQ(0U, buffer_.size());
356 int32_t bytes_to_return = std::min(current_read_buffer_size_, result);
357 std::copy(data,
358 data + bytes_to_return,
359 static_cast<char*>(current_read_buffer_));
361 if (result > bytes_to_return) {
362 // Save what remains to be copied when ReadResponseBody is called again.
363 buffer_.insert(buffer_.end(),
364 data + bytes_to_return,
365 data + result);
368 result = bytes_to_return;
371 current_callback_->Run(result);
374 void URLLoader::CallbackComplete(int32_t result) {
375 current_callback_->Run(result);
378 void URLLoader::PopBuffer(void* output_buffer, int32_t output_size) {
379 CHECK(output_size <= static_cast<int32_t>(buffer_.size()));
380 std::copy(buffer_.begin(),
381 buffer_.begin() + output_size,
382 static_cast<char*>(output_buffer));
383 buffer_.erase(buffer_.begin(),
384 buffer_.begin() + output_size);
387 // PPB_URLLoader_Proxy ---------------------------------------------------------
389 PPB_URLLoader_Proxy::PPB_URLLoader_Proxy(Dispatcher* dispatcher)
390 : InterfaceProxy(dispatcher),
391 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
394 PPB_URLLoader_Proxy::~PPB_URLLoader_Proxy() {
397 // static
398 PP_Resource PPB_URLLoader_Proxy::TrackPluginResource(
399 const HostResource& url_loader_resource) {
400 return (new URLLoader(url_loader_resource))->GetReference();
403 // static
404 const InterfaceProxy::Info* PPB_URLLoader_Proxy::GetTrustedInfo() {
405 static const Info info = {
406 thunk::GetPPB_URLLoaderTrusted_0_3_Thunk(),
407 PPB_URLLOADERTRUSTED_INTERFACE_0_3,
408 API_ID_NONE, // URL_LOADER is the canonical one.
409 false,
410 &CreateURLLoaderProxy
412 return &info;
415 // static
416 PP_Resource PPB_URLLoader_Proxy::CreateProxyResource(PP_Instance pp_instance) {
417 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(pp_instance);
418 if (!dispatcher)
419 return 0;
421 HostResource result;
422 dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Create(
423 API_ID_PPB_URL_LOADER, pp_instance, &result));
424 if (result.is_null())
425 return 0;
426 return PPB_URLLoader_Proxy::TrackPluginResource(result);
429 bool PPB_URLLoader_Proxy::OnMessageReceived(const IPC::Message& msg) {
430 bool handled = true;
431 IPC_BEGIN_MESSAGE_MAP(PPB_URLLoader_Proxy, msg)
432 #if !defined(OS_NACL)
433 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_Create,
434 OnMsgCreate)
435 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_Open,
436 OnMsgOpen)
437 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_FollowRedirect,
438 OnMsgFollowRedirect)
439 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_GetResponseInfo,
440 OnMsgGetResponseInfo)
441 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_ReadResponseBody,
442 OnMsgReadResponseBody)
443 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_FinishStreamingToFile,
444 OnMsgFinishStreamingToFile)
445 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_Close,
446 OnMsgClose)
447 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_GrantUniversalAccess,
448 OnMsgGrantUniversalAccess)
449 #endif // !defined(OS_NACL)
451 IPC_MESSAGE_HANDLER(PpapiMsg_PPBURLLoader_UpdateProgress,
452 OnMsgUpdateProgress)
453 IPC_MESSAGE_HANDLER(PpapiMsg_PPBURLLoader_ReadResponseBody_Ack,
454 OnMsgReadResponseBodyAck)
455 IPC_MESSAGE_HANDLER(PpapiMsg_PPBURLLoader_CallbackComplete,
456 OnMsgCallbackComplete)
457 IPC_MESSAGE_UNHANDLED(handled = false)
458 IPC_END_MESSAGE_MAP()
459 // TODO(brettw) handle bad messages!
460 return handled;
463 #if !defined(OS_NACL)
464 void PPB_URLLoader_Proxy::PrepareURLLoaderForSendingToPlugin(
465 PP_Resource resource) {
466 // So the plugin can query load status, we need to register our status
467 // callback before sending any URLLoader to the plugin.
468 EnterResourceNoLock<PPB_URLLoader_API> enter(resource, false);
469 if (enter.succeeded())
470 enter.object()->SetStatusCallback(&UpdateResourceLoadStatus);
471 else
472 NOTREACHED(); // Only called internally, resource should be valid.
475 void PPB_URLLoader_Proxy::OnMsgCreate(PP_Instance instance,
476 HostResource* result) {
477 thunk::EnterResourceCreation enter(instance);
478 if (enter.succeeded()) {
479 result->SetHostResource(instance,
480 enter.functions()->CreateURLLoader(instance));
481 PrepareURLLoaderForSendingToPlugin(result->host_resource());
485 void PPB_URLLoader_Proxy::OnMsgOpen(const HostResource& loader,
486 const URLRequestInfoData& data) {
487 int peer_pid = dispatcher()->channel()->peer_pid();
489 EnterHostFromHostResourceForceCallback<PPB_URLLoader_API> enter(
490 loader, callback_factory_, &PPB_URLLoader_Proxy::OnCallback, loader);
491 enter.SetResult(enter.object()->Open(data, peer_pid, enter.callback()));
492 // TODO(brettw) bug 73236 register for the status callbacks.
495 void PPB_URLLoader_Proxy::OnMsgFollowRedirect(
496 const HostResource& loader) {
497 EnterHostFromHostResourceForceCallback<PPB_URLLoader_API> enter(
498 loader, callback_factory_, &PPB_URLLoader_Proxy::OnCallback, loader);
499 if (enter.succeeded())
500 enter.SetResult(enter.object()->FollowRedirect(enter.callback()));
503 void PPB_URLLoader_Proxy::OnMsgGetResponseInfo(const HostResource& loader,
504 bool* success,
505 URLResponseInfoData* result) {
506 EnterHostFromHostResource<PPB_URLLoader_API> enter(loader);
507 if (enter.succeeded())
508 *success = enter.object()->GetResponseInfoData(result);
509 else
510 *success = false;
513 void PPB_URLLoader_Proxy::OnMsgReadResponseBody(
514 const HostResource& loader,
515 int32_t bytes_to_read) {
516 // The plugin could be sending us malicious messages, don't accept negative
517 // sizes.
518 if (bytes_to_read < 0) {
519 // TODO(brettw) kill plugin.
520 bytes_to_read = 0;
523 // Read more than requested if there are bytes available for synchronous
524 // reading. This prevents us from getting too far behind due to IPC message
525 // latency. Any extra data will get buffered in the plugin.
526 int32_t synchronously_available_bytes =
527 static_cast<HostDispatcher*>(dispatcher())->ppb_proxy()->
528 GetURLLoaderBufferedBytes(loader.host_resource());
529 if (bytes_to_read < kMaxReadBufferSize) {
530 // Grow the amount to read so we read ahead synchronously, if possible.
531 bytes_to_read =
532 std::max(bytes_to_read,
533 std::min(synchronously_available_bytes, kMaxReadBufferSize));
536 // This heap object will get deleted by the callback handler.
537 // TODO(brettw) this will be leaked if the plugin closes the resource!
538 // (Also including the plugin unloading and having the resource implicitly
539 // destroyed. Depending on the cleanup ordering, we may not need the weak
540 // pointer here.)
541 IPC::Message* message =
542 new PpapiMsg_PPBURLLoader_ReadResponseBody_Ack(API_ID_PPB_URL_LOADER);
543 IPC::ParamTraits<HostResource>::Write(message, loader);
545 char* ptr = message->BeginWriteData(bytes_to_read);
546 if (!ptr) {
547 // TODO(brettw) have a way to check for out-of-memory.
550 EnterHostFromHostResourceForceCallback<PPB_URLLoader_API> enter(
551 loader, callback_factory_, &PPB_URLLoader_Proxy::OnReadCallback, message);
552 if (enter.succeeded()) {
553 enter.SetResult(enter.object()->ReadResponseBody(ptr, bytes_to_read,
554 enter.callback()));
558 void PPB_URLLoader_Proxy::OnMsgFinishStreamingToFile(
559 const HostResource& loader) {
560 EnterHostFromHostResourceForceCallback<PPB_URLLoader_API> enter(
561 loader, callback_factory_, &PPB_URLLoader_Proxy::OnCallback, loader);
562 if (enter.succeeded())
563 enter.SetResult(enter.object()->FinishStreamingToFile(enter.callback()));;
566 void PPB_URLLoader_Proxy::OnMsgClose(const HostResource& loader) {
567 EnterHostFromHostResource<PPB_URLLoader_API> enter(loader);
568 if (enter.succeeded())
569 enter.object()->Close();
572 void PPB_URLLoader_Proxy::OnMsgGrantUniversalAccess(
573 const HostResource& loader) {
574 EnterHostFromHostResource<PPB_URLLoader_API> enter(loader);
575 if (enter.succeeded())
576 enter.object()->GrantUniversalAccess();
578 #endif // !defined(OS_NACL)
580 // Called in the Plugin.
581 void PPB_URLLoader_Proxy::OnMsgUpdateProgress(
582 const PPBURLLoader_UpdateProgress_Params& params) {
583 EnterPluginFromHostResource<PPB_URLLoader_API> enter(params.resource);
584 if (enter.succeeded())
585 static_cast<URLLoader*>(enter.object())->UpdateProgress(params);
588 // Called in the Plugin.
589 void PPB_URLLoader_Proxy::OnMsgReadResponseBodyAck(
590 const IPC::Message& message) {
591 PickleIterator iter(message);
593 HostResource host_resource;
594 if (!IPC::ParamTraits<HostResource>::Read(&message, &iter, &host_resource)) {
595 NOTREACHED() << "Expecting HostResource";
596 return;
599 const char* data;
600 int data_len;
601 if (!iter.ReadData(&data, &data_len)) {
602 NOTREACHED() << "Expecting data";
603 return;
606 int result;
607 if (!iter.ReadInt(&result)) {
608 NOTREACHED() << "Expecting result";
609 return;
612 DCHECK(result < 0 || result == data_len);
614 EnterPluginFromHostResource<PPB_URLLoader_API> enter(host_resource);
615 if (enter.succeeded())
616 static_cast<URLLoader*>(enter.object())->ReadResponseBodyAck(result, data);
619 // Called in the plugin.
620 void PPB_URLLoader_Proxy::OnMsgCallbackComplete(
621 const HostResource& host_resource,
622 int32_t result) {
623 EnterPluginFromHostResource<PPB_URLLoader_API> enter(host_resource);
624 if (enter.succeeded())
625 static_cast<URLLoader*>(enter.object())->CallbackComplete(result);
628 #if !defined(OS_NACL)
629 void PPB_URLLoader_Proxy::OnReadCallback(int32_t result,
630 IPC::Message* message) {
631 int32_t bytes_read = 0;
632 if (result > 0)
633 bytes_read = result; // Positive results indicate bytes read.
635 message->TrimWriteData(bytes_read);
636 message->WriteInt(result);
638 dispatcher()->Send(message);
641 void PPB_URLLoader_Proxy::OnCallback(int32_t result,
642 const HostResource& resource) {
643 dispatcher()->Send(new PpapiMsg_PPBURLLoader_CallbackComplete(
644 API_ID_PPB_URL_LOADER, resource, result));
646 #endif // !defined(OS_NACL)
648 } // namespace proxy
649 } // namespace ppapi