1// Copyright (c) 2013 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.
4
5#ifndef PPAPI_PROXY_URL_LOADER_RESOURCE_H_
6#define PPAPI_PROXY_URL_LOADER_RESOURCE_H_
7
8#include <deque>
9
10#include "base/basictypes.h"
11#include "base/compiler_specific.h"
12#include "ppapi/c/trusted/ppb_url_loader_trusted.h"
13#include "ppapi/proxy/plugin_resource.h"
14#include "ppapi/proxy/ppapi_proxy_export.h"
15#include "ppapi/shared_impl/url_request_info_data.h"
16#include "ppapi/thunk/ppb_url_loader_api.h"
17
18namespace ppapi {
19namespace proxy {
20
21class URLResponseInfoResource;
22
23class PPAPI_PROXY_EXPORT URLLoaderResource
24    : public PluginResource,
25      public NON_EXPORTED_BASE(thunk::PPB_URLLoader_API) {
26 public:
27  // Constructor for plugin-initiated loads.
28  URLLoaderResource(Connection connection,
29                    PP_Instance instance);
30
31  // Constructor for renderer-initiated (document) loads. The loader ID is the
32  // pending host ID for the already-created host in the renderer, and the
33  // response data is the response for the already-opened connection.
34  URLLoaderResource(Connection connection,
35                    PP_Instance instance,
36                    int pending_main_document_loader_id,
37                    const URLResponseInfoData& data);
38
39  virtual ~URLLoaderResource();
40
41  // Resource override.
42  thunk::PPB_URLLoader_API* AsPPB_URLLoader_API() OVERRIDE;
43
44  // PPB_URLLoader_API implementation.
45  virtual int32_t Open(PP_Resource request_id,
46                       scoped_refptr<TrackedCallback> callback) OVERRIDE;
47  virtual int32_t Open(const URLRequestInfoData& data,
48                       int requestor_pid,
49                       scoped_refptr<TrackedCallback> callback) OVERRIDE;
50  virtual int32_t FollowRedirect(
51      scoped_refptr<TrackedCallback> callback) OVERRIDE;
52  virtual PP_Bool GetUploadProgress(int64_t* bytes_sent,
53                                    int64_t* total_bytes_to_be_sent) OVERRIDE;
54  virtual PP_Bool GetDownloadProgress(
55      int64_t* bytes_received,
56      int64_t* total_bytes_to_be_received) OVERRIDE;
57  virtual PP_Resource GetResponseInfo() OVERRIDE;
58  virtual int32_t ReadResponseBody(
59      void* buffer,
60      int32_t bytes_to_read,
61      scoped_refptr<TrackedCallback> callback) OVERRIDE;
62  virtual int32_t FinishStreamingToFile(
63      scoped_refptr<TrackedCallback> callback) OVERRIDE;
64  virtual void Close() OVERRIDE;
65  virtual void GrantUniversalAccess() OVERRIDE;
66  virtual void RegisterStatusCallback(
67      PP_URLLoaderTrusted_StatusCallback callback) OVERRIDE;
68
69  // PluginResource implementation.
70  virtual void OnReplyReceived(const ResourceMessageReplyParams& params,
71                               const IPC::Message& msg) OVERRIDE;
72
73 private:
74  enum Mode {
75    // The plugin has not called Open() yet.
76    MODE_WAITING_TO_OPEN,
77
78    // The plugin is waiting for the Open() or FollowRedirect callback.
79    MODE_OPENING,
80
81    // We've started to receive data and may receive more.
82    MODE_STREAMING_DATA,
83
84    // All data has been streamed or there was an error.
85    MODE_LOAD_COMPLETE
86  };
87
88  // IPC message handlers.
89  void OnPluginMsgReceivedResponse(const ResourceMessageReplyParams& params,
90                                   const URLResponseInfoData& data);
91  void OnPluginMsgSendData(const ResourceMessageReplyParams& params,
92                           const IPC::Message& message);
93  void OnPluginMsgFinishedLoading(const ResourceMessageReplyParams& params,
94                                  int32_t result);
95  void OnPluginMsgUpdateProgress(const ResourceMessageReplyParams& params,
96                                 int64_t bytes_sent,
97                                 int64_t total_bytes_to_be_sent,
98                                 int64_t bytes_received,
99                                 int64_t total_bytes_to_be_received);
100
101  // Sends the defers loading message to the renderer to block or unblock the
102  // load.
103  void SetDefersLoading(bool defers_loading);
104
105  int32_t ValidateCallback(scoped_refptr<TrackedCallback> callback);
106
107  // Sets up |callback| as the pending callback. This should only be called once
108  // it is certain that |PP_OK_COMPLETIONPENDING| will be returned.
109  void RegisterCallback(scoped_refptr<TrackedCallback> callback);
110
111  void RunCallback(int32_t result);
112
113  // Saves the given response info to response_info_, handling file refs if
114  // necessary. This does not issue any callbacks.
115  void SaveResponseInfo(const URLResponseInfoData& data);
116
117  size_t FillUserBuffer();
118
119  Mode mode_;
120  URLRequestInfoData request_data_;
121
122  scoped_refptr<TrackedCallback> pending_callback_;
123
124  PP_URLLoaderTrusted_StatusCallback status_callback_;
125
126  std::deque<char> buffer_;
127  int64_t bytes_sent_;
128  int64_t total_bytes_to_be_sent_;
129  int64_t bytes_received_;
130  int64_t total_bytes_to_be_received_;
131  char* user_buffer_;
132  size_t user_buffer_size_;
133  int32_t done_status_;
134  bool is_streaming_to_file_;
135  bool is_asynchronous_load_suspended_;
136
137  // The response info if we've received it.
138  scoped_refptr<URLResponseInfoResource> response_info_;
139
140  DISALLOW_COPY_AND_ASSIGN(URLLoaderResource);
141};
142
143}  // namespace proxy
144}  // namespace ppapi
145
146#endif  // PPAPI_PROXY_URL_LOADER_RESOURCE_H_
147