OLD | NEW |
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 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ | 5 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ |
6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ | 6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 | 9 |
10 #include "native_client/src/include/nacl_macros.h" | 10 #include "native_client/src/include/nacl_macros.h" |
11 #include "native_client/src/include/nacl_string.h" | 11 #include "native_client/src/include/nacl_string.h" |
12 #include "native_client/src/public/nacl_file_info.h" | 12 #include "native_client/src/public/nacl_file_info.h" |
13 #include "ppapi/c/private/pp_file_handle.h" | |
14 #include "ppapi/c/private/ppb_file_io_private.h" | |
15 #include "ppapi/c/private/ppb_nacl_private.h" | 13 #include "ppapi/c/private/ppb_nacl_private.h" |
16 #include "ppapi/c/trusted/ppb_url_loader_trusted.h" | |
17 #include "ppapi/cpp/file_io.h" | 14 #include "ppapi/cpp/file_io.h" |
18 #include "ppapi/cpp/instance.h" | 15 #include "ppapi/cpp/instance.h" |
19 #include "ppapi/cpp/url_loader.h" | 16 #include "ppapi/cpp/url_loader.h" |
20 #include "ppapi/cpp/url_response_info.h" | 17 #include "ppapi/cpp/url_response_info.h" |
21 #include "ppapi/native_client/src/trusted/plugin/callback_source.h" | 18 #include "ppapi/native_client/src/trusted/plugin/callback_source.h" |
22 #include "ppapi/utility/completion_callback_factory.h" | 19 #include "ppapi/utility/completion_callback_factory.h" |
23 | 20 |
24 namespace plugin { | 21 namespace plugin { |
25 | 22 |
26 class Plugin; | 23 class Plugin; |
27 | 24 |
28 typedef enum { | 25 typedef enum { |
29 DOWNLOAD_TO_FILE = 0, | 26 DOWNLOAD_TO_BUFFER_AND_STREAM = 0, |
30 DOWNLOAD_TO_BUFFER_AND_STREAM, | |
31 DOWNLOAD_NONE | 27 DOWNLOAD_NONE |
32 } DownloadMode; | 28 } DownloadMode; |
33 | 29 |
34 typedef std::vector<char>* FileStreamData; | 30 typedef std::vector<char>* FileStreamData; |
35 typedef CallbackSource<FileStreamData> StreamCallbackSource; | 31 typedef CallbackSource<FileStreamData> StreamCallbackSource; |
36 typedef pp::CompletionCallbackWithOutput<FileStreamData> StreamCallback; | 32 typedef pp::CompletionCallbackWithOutput<FileStreamData> StreamCallback; |
37 | 33 |
38 // RAII-style wrapper class | |
39 class NaClFileInfoAutoCloser { | |
40 public: | |
41 NaClFileInfoAutoCloser(); | |
42 | |
43 explicit NaClFileInfoAutoCloser(NaClFileInfo* pass_ownership); | |
44 | |
45 ~NaClFileInfoAutoCloser() { | |
46 FreeResources(); | |
47 } | |
48 | |
49 // Frees owned resources | |
50 void FreeResources(); | |
51 | |
52 void TakeOwnership(NaClFileInfo* pass_ownership); | |
53 | |
54 // Return NaClFileInfo for temporary use, retaining ownership. | |
55 const NaClFileInfo& get() { return info_; } | |
56 | |
57 // Returns POSIX descriptor for temporary use, retaining ownership. | |
58 int get_desc() { return info_.desc; } | |
59 | |
60 // Returns ownership to caller | |
61 NaClFileInfo Release(); | |
62 | |
63 private: | |
64 NACL_DISALLOW_COPY_AND_ASSIGN(NaClFileInfoAutoCloser); | |
65 | |
66 NaClFileInfo info_; | |
67 }; | |
68 | |
69 // A class that wraps PPAPI URLLoader and FileIO functionality for downloading | 34 // A class that wraps PPAPI URLLoader and FileIO functionality for downloading |
70 // the url into a file and providing an open file descriptor. | 35 // the url into a file and providing an open file descriptor. |
71 class FileDownloader { | 36 class FileDownloader { |
72 public: | 37 public: |
73 // Ctor initializes |instance_| to NULL, be sure to call Initialize() before | 38 // Ctor initializes |instance_| to NULL, be sure to call Initialize() before |
74 // calling Open(), or Open() will fail. | 39 // calling Open(), or Open() will fail. |
75 FileDownloader() | 40 FileDownloader() |
76 : instance_(NULL), | 41 : instance_(NULL), |
77 file_open_notify_callback_(pp::BlockUntilComplete()), | 42 file_open_notify_callback_(pp::BlockUntilComplete()), |
78 stream_finish_callback_(pp::BlockUntilComplete()), | 43 stream_finish_callback_(pp::BlockUntilComplete()), |
79 file_io_private_interface_(NULL), | |
80 url_loader_trusted_interface_(NULL), | |
81 mode_(DOWNLOAD_NONE), | 44 mode_(DOWNLOAD_NONE), |
82 data_stream_callback_source_(NULL) {} | 45 data_stream_callback_source_(NULL) {} |
83 ~FileDownloader() {} | 46 ~FileDownloader() {} |
84 | 47 |
85 // Initialize() can only be called once during the lifetime of this instance. | 48 // Initialize() can only be called once during the lifetime of this instance. |
86 void Initialize(Plugin* instance); | 49 void Initialize(Plugin* instance); |
87 | 50 |
88 // Issues a GET on |url| to start downloading the response into a file, | 51 // Issues a GET on |url| to start downloading the response into a file, |
89 // and finish streaming it. |callback| will be run after streaming is | 52 // and finish streaming it. |callback| will be run after streaming is |
90 // done or if an error prevents streaming from completing. | 53 // done or if an error prevents streaming from completing. |
91 // Returns true when callback is scheduled to be called on success or failure. | 54 // Returns true when callback is scheduled to be called on success or failure. |
92 // Returns false if callback is NULL, Initialize() has not been called or if | 55 // Returns false if callback is NULL, Initialize() has not been called or if |
93 // the PPB_FileIO_Trusted interface is not available. | 56 // the PPB_FileIO_Trusted interface is not available. |
94 // If |record_progress| is true, then download progress will be recorded, | 57 // If |record_progress| is true, then download progress will be recorded, |
95 // and can be polled through GetDownloadProgress(). | 58 // and can be polled through GetDownloadProgress(). |
96 // If |progress_callback| is not NULL and |record_progress| is true, | 59 // If |progress_callback| is not NULL and |record_progress| is true, |
97 // then the callback will be invoked for every progress update received | 60 // then the callback will be invoked for every progress update received |
98 // by the loader. | 61 // by the loader. |
99 bool Open(const nacl::string& url, | |
100 DownloadMode mode, | |
101 const pp::CompletionCallback& callback, | |
102 bool record_progress, | |
103 PP_URLLoaderTrusted_StatusCallback progress_callback); | |
104 | 62 |
105 // Similar to Open(), but used for streaming the |url| data directly to the | 63 // Similar to Open(), but used for streaming the |url| data directly to the |
106 // caller without writing to a temporary file. The callbacks provided by | 64 // caller without writing to a temporary file. The callbacks provided by |
107 // |stream_callback_source| are expected to copy the data before returning. | 65 // |stream_callback_source| are expected to copy the data before returning. |
108 // |callback| is called once the response headers are received, | 66 // |callback| is called once the response headers are received, |
109 // and streaming must be completed separately via FinishStreaming(). | 67 // and streaming must be completed separately via FinishStreaming(). |
110 bool OpenStream(const nacl::string& url, | 68 bool OpenStream(const nacl::string& url, |
111 const pp::CompletionCallback& callback, | 69 const pp::CompletionCallback& callback, |
112 StreamCallbackSource* stream_callback_source); | 70 StreamCallbackSource* stream_callback_source); |
113 | 71 |
114 // Finish streaming the response body for a URL request started by either | 72 // Finish streaming the response body for a URL request started by either |
115 // Open() or OpenStream(). If DownloadMode is DOWNLOAD_TO_FILE, | 73 // OpenStream(). Runs the given |callback| when streaming is done. |
116 // then the response body is streamed to a file, the file is opened and | |
117 // a file descriptor is made available. Runs the given |callback| when | |
118 // streaming is done. | |
119 void FinishStreaming(const pp::CompletionCallback& callback); | 74 void FinishStreaming(const pp::CompletionCallback& callback); |
120 | 75 |
121 // Returns the url passed to Open(). | 76 // Returns the url passed to Open(). |
122 const nacl::string& url() const { return url_; } | 77 const nacl::string& url() const { return url_; } |
123 | 78 |
124 // Once the GET request has finished, and the contents of the file | 79 // Once the GET request has finished, and the contents of the file |
125 // represented by |url_| are available, |full_url_| is the full URL including | 80 // represented by |url_| are available, |full_url_| is the full URL including |
126 // the scheme, host and full path. | 81 // the scheme, host and full path. |
127 // Returns an empty string before the GET request has finished. | 82 // Returns an empty string before the GET request has finished. |
128 const nacl::string& full_url() const { return full_url_; } | 83 const nacl::string& full_url() const { return full_url_; } |
(...skipping 17 matching lines...) Expand all Loading... |
146 int status_code() const { return status_code_; } | 101 int status_code() const { return status_code_; } |
147 nacl::string GetResponseHeaders() const; | 102 nacl::string GetResponseHeaders() const; |
148 | 103 |
149 void set_request_headers(const nacl::string& extra_request_headers) { | 104 void set_request_headers(const nacl::string& extra_request_headers) { |
150 extra_request_headers_ = extra_request_headers; | 105 extra_request_headers_ = extra_request_headers; |
151 } | 106 } |
152 | 107 |
153 | 108 |
154 private: | 109 private: |
155 NACL_DISALLOW_COPY_AND_ASSIGN(FileDownloader); | 110 NACL_DISALLOW_COPY_AND_ASSIGN(FileDownloader); |
156 // This class loads and opens the file in three steps for DOWNLOAD_TO_FILE: | |
157 // 1) Ask the browser to start streaming |url_| as a file. | |
158 // 2) Ask the browser to finish streaming if headers indicate success. | |
159 // 3) Ask the browser to open the file, so we can get the file descriptor. | |
160 // For DOWNLOAD_TO_BUFFER_AND_STREAM, the process is very similar: | 111 // For DOWNLOAD_TO_BUFFER_AND_STREAM, the process is very similar: |
161 // 1) Ask the browser to start streaming |url_| to an internal buffer. | 112 // 1) Ask the browser to start streaming |url_| to an internal buffer. |
162 // 2) Ask the browser to finish streaming to |temp_buffer_| on success. | 113 // 2) Ask the browser to finish streaming to |temp_buffer_| on success. |
163 // 3) Wait for streaming to finish, passing the data directly to the user. | 114 // 3) Wait for streaming to finish, passing the data directly to the user. |
164 // Each step is done asynchronously using callbacks. We create callbacks | 115 // Each step is done asynchronously using callbacks. We create callbacks |
165 // through a factory to take advantage of ref-counting. | 116 // through a factory to take advantage of ref-counting. |
166 // The public Open*() functions start step 1), and the public FinishStreaming | 117 // The public Open*() functions start step 1), and the public FinishStreaming |
167 // function proceeds to step 2) and 3). | 118 // function proceeds to step 2) and 3). |
168 bool InitialResponseIsValid(); | 119 bool InitialResponseIsValid(); |
169 void URLLoadStartNotify(int32_t pp_error); | 120 void URLLoadStartNotify(int32_t pp_error); |
170 void URLLoadFinishNotify(int32_t pp_error); | |
171 void URLReadBodyNotify(int32_t pp_error); | 121 void URLReadBodyNotify(int32_t pp_error); |
172 void StreamFinishNotify(int32_t pp_error); | |
173 void GotFileHandleNotify(int32_t pp_error, PP_FileHandle handle); | |
174 | 122 |
175 Plugin* instance_; | 123 Plugin* instance_; |
176 nacl::string url_; | 124 nacl::string url_; |
177 nacl::string full_url_; | 125 nacl::string full_url_; |
178 | 126 |
179 nacl::string extra_request_headers_; | 127 nacl::string extra_request_headers_; |
180 pp::URLResponseInfo url_response_; | 128 pp::URLResponseInfo url_response_; |
181 pp::CompletionCallback file_open_notify_callback_; | 129 pp::CompletionCallback file_open_notify_callback_; |
182 pp::CompletionCallback stream_finish_callback_; | 130 pp::CompletionCallback stream_finish_callback_; |
183 pp::FileIO file_reader_; | |
184 const PPB_FileIO_Private* file_io_private_interface_; | |
185 const PPB_URLLoaderTrusted* url_loader_trusted_interface_; | |
186 pp::URLLoader url_loader_; | 131 pp::URLLoader url_loader_; |
187 pp::CompletionCallbackFactory<FileDownloader> callback_factory_; | 132 pp::CompletionCallbackFactory<FileDownloader> callback_factory_; |
188 int32_t status_code_; | 133 int32_t status_code_; |
189 DownloadMode mode_; | 134 DownloadMode mode_; |
190 static const uint32_t kTempBufferSize = 16384; | 135 static const uint32_t kTempBufferSize = 16384; |
191 std::vector<char> temp_buffer_; | 136 std::vector<char> temp_buffer_; |
192 StreamCallbackSource* data_stream_callback_source_; | 137 StreamCallbackSource* data_stream_callback_source_; |
193 NaClFileInfoAutoCloser file_info_; | |
194 }; | 138 }; |
195 } // namespace plugin; | 139 } // namespace plugin; |
196 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ | 140 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ |
OLD | NEW |