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