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 #include "ppapi/native_client/src/trusted/plugin/file_downloader.h" | 5 #include "ppapi/native_client/src/trusted/plugin/file_downloader.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <string.h> | 8 #include <string.h> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 url_loader_trusted_interface_ = static_cast<const PPB_URLLoaderTrusted*>( | 101 url_loader_trusted_interface_ = static_cast<const PPB_URLLoaderTrusted*>( |
102 pp::Module::Get()->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE)); | 102 pp::Module::Get()->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE)); |
103 temp_buffer_.resize(kTempBufferSize); | 103 temp_buffer_.resize(kTempBufferSize); |
104 file_info_.FreeResources(); | 104 file_info_.FreeResources(); |
105 } | 105 } |
106 | 106 |
107 bool FileDownloader::OpenStream( | 107 bool FileDownloader::OpenStream( |
108 const nacl::string& url, | 108 const nacl::string& url, |
109 const pp::CompletionCallback& callback, | 109 const pp::CompletionCallback& callback, |
110 StreamCallbackSource* stream_callback_source) { | 110 StreamCallbackSource* stream_callback_source) { |
111 open_and_stream_ = false; | |
112 data_stream_callback_source_ = stream_callback_source; | 111 data_stream_callback_source_ = stream_callback_source; |
113 return Open(url, DOWNLOAD_STREAM, callback, true, NULL); | 112 return Open(url, DOWNLOAD_STREAM, callback, true, NULL); |
114 } | 113 } |
115 | 114 |
116 bool FileDownloader::Open( | 115 bool FileDownloader::Open( |
117 const nacl::string& url, | 116 const nacl::string& url, |
118 DownloadMode mode, | 117 DownloadMode mode, |
119 const pp::CompletionCallback& callback, | 118 const pp::CompletionCallback& callback, |
120 bool record_progress, | 119 bool record_progress, |
121 PP_URLLoaderTrusted_StatusCallback progress_callback) { | 120 PP_URLLoaderTrusted_StatusCallback progress_callback) { |
(...skipping 17 matching lines...) Expand all Loading... |
139 // Note that "SetAllowCrossOriginRequests" (currently) has the side effect of | 138 // Note that "SetAllowCrossOriginRequests" (currently) has the side effect of |
140 // preventing credentials from being sent on same-origin requests. We | 139 // preventing credentials from being sent on same-origin requests. We |
141 // therefore avoid setting this flag unless we know for sure it is a | 140 // therefore avoid setting this flag unless we know for sure it is a |
142 // cross-origin request, resulting in behavior similar to XMLHttpRequest. | 141 // cross-origin request, resulting in behavior similar to XMLHttpRequest. |
143 if (!instance_->DocumentCanRequest(url)) | 142 if (!instance_->DocumentCanRequest(url)) |
144 url_request.SetAllowCrossOriginRequests(true); | 143 url_request.SetAllowCrossOriginRequests(true); |
145 | 144 |
146 if (!extra_request_headers_.empty()) | 145 if (!extra_request_headers_.empty()) |
147 url_request.SetHeaders(extra_request_headers_); | 146 url_request.SetHeaders(extra_request_headers_); |
148 | 147 |
149 do { | 148 // Reset the url loader and file reader. |
150 // Reset the url loader and file reader. | 149 // Note that we have the only reference to the underlying objects, so |
151 // Note that we have the only reference to the underlying objects, so | 150 // this will implicitly close any pending IO and destroy them. |
152 // this will implicitly close any pending IO and destroy them. | 151 url_loader_ = pp::URLLoader(instance_); |
153 url_loader_ = pp::URLLoader(instance_); | 152 url_scheme_ = instance_->GetUrlScheme(url); |
154 url_scheme_ = instance_->GetUrlScheme(url); | 153 bool grant_universal_access = false; |
155 bool grant_universal_access = false; | 154 if (url_scheme_ == SCHEME_DATA) { |
156 if (url_scheme_ == SCHEME_DATA) { | 155 // TODO(elijahtaylor) Remove this when data URIs can be read without |
157 // TODO(elijahtaylor) Remove this when data URIs can be read without | 156 // universal access. |
158 // universal access. | 157 // https://bugs.webkit.org/show_bug.cgi?id=17352 |
159 // https://bugs.webkit.org/show_bug.cgi?id=17352 | 158 if (streaming_to_buffer()) { |
160 if (streaming_to_buffer()) { | 159 grant_universal_access = true; |
161 grant_universal_access = true; | 160 } else { |
162 } else { | 161 // Open is to invoke a callback on success or failure. Schedule |
163 // Open is to invoke a callback on success or failure. Schedule | 162 // it asynchronously to follow PPAPI's convention and avoid reentrancy. |
164 // it asynchronously to follow PPAPI's convention and avoid reentrancy. | 163 pp::Core* core = pp::Module::Get()->core(); |
165 pp::Core* core = pp::Module::Get()->core(); | 164 core->CallOnMainThread(0, callback, PP_ERROR_NOACCESS); |
166 core->CallOnMainThread(0, callback, PP_ERROR_NOACCESS); | 165 PLUGIN_PRINTF(("FileDownloader::Open (pp_error=PP_ERROR_NOACCESS)\n")); |
167 PLUGIN_PRINTF(("FileDownloader::Open (pp_error=PP_ERROR_NOACCESS)\n")); | 166 return true; |
168 return true; | |
169 } | |
170 } | 167 } |
| 168 } |
171 | 169 |
172 url_request.SetRecordDownloadProgress(record_progress); | 170 url_request.SetRecordDownloadProgress(record_progress); |
173 | 171 |
174 if (url_loader_trusted_interface_ != NULL) { | 172 if (url_loader_trusted_interface_ != NULL) { |
175 if (grant_universal_access) { | 173 if (grant_universal_access) { |
176 // TODO(sehr,jvoung): See if we can remove this -- currently | 174 // TODO(sehr,jvoung): See if we can remove this -- currently |
177 // only used for data URIs. | 175 // only used for data URIs. |
178 url_loader_trusted_interface_->GrantUniversalAccess( | 176 url_loader_trusted_interface_->GrantUniversalAccess( |
179 url_loader_.pp_resource()); | 177 url_loader_.pp_resource()); |
180 } | |
181 if (progress_callback != NULL) { | |
182 url_loader_trusted_interface_->RegisterStatusCallback( | |
183 url_loader_.pp_resource(), progress_callback); | |
184 } | |
185 } | 178 } |
| 179 if (progress_callback != NULL) { |
| 180 url_loader_trusted_interface_->RegisterStatusCallback( |
| 181 url_loader_.pp_resource(), progress_callback); |
| 182 } |
| 183 } |
186 | 184 |
187 // Prepare the url request. | 185 // Prepare the url request. |
188 url_request.SetURL(url_); | 186 url_request.SetURL(url_); |
189 | 187 |
190 if (streaming_to_file()) { | 188 if (streaming_to_file()) { |
191 file_reader_ = pp::FileIO(instance_); | 189 file_reader_ = pp::FileIO(instance_); |
192 url_request.SetStreamToFile(true); | 190 url_request.SetStreamToFile(true); |
193 } | 191 } |
194 } while (0); | |
195 | 192 |
196 // Request asynchronous download of the url providing an on-load callback. | 193 // Request asynchronous download of the url providing an on-load callback. |
197 // As long as this step is guaranteed to be asynchronous, we can call | 194 // As long as this step is guaranteed to be asynchronous, we can call |
198 // synchronously all other internal callbacks that eventually result in the | 195 // synchronously all other internal callbacks that eventually result in the |
199 // invocation of the user callback. The user code will not be reentered. | 196 // invocation of the user callback. The user code will not be reentered. |
200 pp::CompletionCallback onload_callback = | 197 pp::CompletionCallback onload_callback = |
201 callback_factory_.NewCallback(&FileDownloader::URLLoadStartNotify); | 198 callback_factory_.NewCallback(&FileDownloader::URLLoadStartNotify); |
202 int32_t pp_error = url_loader_.Open(url_request, onload_callback); | 199 int32_t pp_error = url_loader_.Open(url_request, onload_callback); |
203 PLUGIN_PRINTF(("FileDownloader::Open (pp_error=%" NACL_PRId32 ")\n", | 200 PLUGIN_PRINTF(("FileDownloader::Open (pp_error=%" NACL_PRId32 ")\n", |
204 pp_error)); | 201 pp_error)); |
205 CHECK(pp_error == PP_OK_COMPLETIONPENDING); | 202 CHECK(pp_error == PP_OK_COMPLETIONPENDING); |
206 return true; | 203 return true; |
207 } | 204 } |
208 | 205 |
209 void FileDownloader::OpenFast(const nacl::string& url, | 206 void FileDownloader::OpenFast(const nacl::string& url, |
210 PP_FileHandle file_handle, | 207 PP_FileHandle file_handle, |
211 uint64_t file_token_lo, uint64_t file_token_hi) { | 208 uint64_t file_token_lo, uint64_t file_token_hi) { |
212 PLUGIN_PRINTF(("FileDownloader::OpenFast (url=%s)\n", url.c_str())); | 209 PLUGIN_PRINTF(("FileDownloader::OpenFast (url=%s)\n", url.c_str())); |
213 | 210 |
214 file_info_.FreeResources(); | 211 file_info_.FreeResources(); |
215 CHECK(instance_ != NULL); | 212 CHECK(instance_ != NULL); |
216 open_time_ = NaClGetTimeOfDayMicroseconds(); | 213 open_time_ = NaClGetTimeOfDayMicroseconds(); |
217 status_code_ = NACL_HTTP_STATUS_OK; | 214 status_code_ = NACL_HTTP_STATUS_OK; |
218 url_ = url; | 215 url_ = url; |
219 mode_ = DOWNLOAD_NONE; | 216 mode_ = DOWNLOAD_NONE; |
220 if (not_streaming() && file_handle != PP_kInvalidFileHandle) { | 217 if (file_handle != PP_kInvalidFileHandle) { |
221 NaClFileInfo tmp_info = NoFileInfo(); | 218 NaClFileInfo tmp_info = NoFileInfo(); |
222 tmp_info.desc = ConvertFileDescriptor(file_handle); | 219 tmp_info.desc = ConvertFileDescriptor(file_handle); |
223 tmp_info.file_token.lo = file_token_lo; | 220 tmp_info.file_token.lo = file_token_lo; |
224 tmp_info.file_token.hi = file_token_hi; | 221 tmp_info.file_token.hi = file_token_hi; |
225 file_info_.TakeOwnership(&tmp_info); | 222 file_info_.TakeOwnership(&tmp_info); |
226 } | 223 } |
227 } | 224 } |
228 | 225 |
229 NaClFileInfo FileDownloader::GetFileInfo() { | 226 NaClFileInfo FileDownloader::GetFileInfo() { |
230 NaClFileInfo info_to_return = NoFileInfo(); | 227 NaClFileInfo info_to_return = NoFileInfo(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 if (pp_error != PP_OK) { | 293 if (pp_error != PP_OK) { |
297 file_open_notify_callback_.RunAndClear(pp_error); | 294 file_open_notify_callback_.RunAndClear(pp_error); |
298 return; | 295 return; |
299 } | 296 } |
300 | 297 |
301 if (!InitialResponseIsValid()) { | 298 if (!InitialResponseIsValid()) { |
302 file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED); | 299 file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED); |
303 return; | 300 return; |
304 } | 301 } |
305 | 302 |
306 if (open_and_stream_) { | 303 if (!streaming_to_user()) { |
307 FinishStreaming(file_open_notify_callback_); | 304 FinishStreaming(file_open_notify_callback_); |
308 return; | 305 return; |
309 } | 306 } |
310 | 307 |
311 file_open_notify_callback_.RunAndClear(PP_OK); | 308 file_open_notify_callback_.RunAndClear(PP_OK); |
312 } | 309 } |
313 | 310 |
314 void FileDownloader::FinishStreaming( | 311 void FileDownloader::FinishStreaming( |
315 const pp::CompletionCallback& callback) { | 312 const pp::CompletionCallback& callback) { |
316 stream_finish_callback_ = callback; | 313 stream_finish_callback_ = callback; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 } | 466 } |
470 | 467 |
471 bool FileDownloader::streaming_to_buffer() const { | 468 bool FileDownloader::streaming_to_buffer() const { |
472 return mode_ == DOWNLOAD_TO_BUFFER; | 469 return mode_ == DOWNLOAD_TO_BUFFER; |
473 } | 470 } |
474 | 471 |
475 bool FileDownloader::streaming_to_user() const { | 472 bool FileDownloader::streaming_to_user() const { |
476 return mode_ == DOWNLOAD_STREAM; | 473 return mode_ == DOWNLOAD_STREAM; |
477 } | 474 } |
478 | 475 |
479 bool FileDownloader::not_streaming() const { | |
480 return mode_ == DOWNLOAD_NONE; | |
481 } | |
482 | |
483 void FileDownloader::GotFileHandleNotify(int32_t pp_error, | 476 void FileDownloader::GotFileHandleNotify(int32_t pp_error, |
484 PP_FileHandle handle) { | 477 PP_FileHandle handle) { |
485 PLUGIN_PRINTF(( | 478 PLUGIN_PRINTF(( |
486 "FileDownloader::GotFileHandleNotify (pp_error=%" NACL_PRId32 ")\n", | 479 "FileDownloader::GotFileHandleNotify (pp_error=%" NACL_PRId32 ")\n", |
487 pp_error)); | 480 pp_error)); |
488 if (pp_error == PP_OK) { | 481 if (pp_error == PP_OK) { |
489 NaClFileInfo tmp_info = NoFileInfo(); | 482 NaClFileInfo tmp_info = NoFileInfo(); |
490 tmp_info.desc = ConvertFileDescriptor(handle); | 483 tmp_info.desc = ConvertFileDescriptor(handle); |
491 file_info_.TakeOwnership(&tmp_info); | 484 file_info_.TakeOwnership(&tmp_info); |
492 } | 485 } |
493 | 486 |
494 stream_finish_callback_.RunAndClear(pp_error); | 487 stream_finish_callback_.RunAndClear(pp_error); |
495 } | 488 } |
496 | 489 |
497 } // namespace plugin | 490 } // namespace plugin |
OLD | NEW |