Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(583)

Side by Side Diff: ppapi/native_client/src/trusted/plugin/file_downloader.cc

Issue 16569002: Use HTTP response headers for PNaCl caching instead of bitcode hash. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: use RunAndClear Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "native_client/src/trusted/plugin/file_downloader.h" 5 #include "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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE)); 48 pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE));
49 url_loader_trusted_interface_ = static_cast<const PPB_URLLoaderTrusted*>( 49 url_loader_trusted_interface_ = static_cast<const PPB_URLLoaderTrusted*>(
50 pp::Module::Get()->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE)); 50 pp::Module::Get()->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE));
51 temp_buffer_.resize(kTempBufferSize); 51 temp_buffer_.resize(kTempBufferSize);
52 } 52 }
53 53
54 bool FileDownloader::OpenStream( 54 bool FileDownloader::OpenStream(
55 const nacl::string& url, 55 const nacl::string& url,
56 const pp::CompletionCallback& callback, 56 const pp::CompletionCallback& callback,
57 StreamCallbackSource* stream_callback_source) { 57 StreamCallbackSource* stream_callback_source) {
58 open_and_stream_ = false;
58 data_stream_callback_source_ = stream_callback_source; 59 data_stream_callback_source_ = stream_callback_source;
59 return Open(url, DOWNLOAD_STREAM, callback, true, NULL); 60 return Open(url, DOWNLOAD_STREAM, callback, true, NULL);
60 } 61 }
61 62
62 bool FileDownloader::Open( 63 bool FileDownloader::Open(
63 const nacl::string& url, 64 const nacl::string& url,
64 DownloadMode mode, 65 DownloadMode mode,
65 const pp::CompletionCallback& callback, 66 const pp::CompletionCallback& callback,
66 bool record_progress, 67 bool record_progress,
67 PP_URLLoaderTrusted_StatusCallback progress_callback) { 68 PP_URLLoaderTrusted_StatusCallback progress_callback) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 int64_t now = NaClGetTimeOfDayMicroseconds(); 212 int64_t now = NaClGetTimeOfDayMicroseconds();
212 // If Open() wasn't called or we somehow return an earlier time now, just 213 // If Open() wasn't called or we somehow return an earlier time now, just
213 // return the 0 rather than worse nonsense values. 214 // return the 0 rather than worse nonsense values.
214 if (open_time_ < 0 || now < open_time_) 215 if (open_time_ < 0 || now < open_time_)
215 return 0; 216 return 0;
216 return (now - open_time_) / NACL_MICROS_PER_MILLI; 217 return (now - open_time_) / NACL_MICROS_PER_MILLI;
217 } 218 }
218 219
219 bool FileDownloader::InitialResponseIsValid(int32_t pp_error) { 220 bool FileDownloader::InitialResponseIsValid(int32_t pp_error) {
220 if (pp_error != PP_OK) { // Url loading failed. 221 if (pp_error != PP_OK) { // Url loading failed.
221 file_open_notify_callback_.Run(pp_error); 222 file_open_notify_callback_.RunAndClear(pp_error);
222 return false; 223 return false;
223 } 224 }
224 225
225 // Process the response, validating the headers to confirm successful loading. 226 // Process the response, validating the headers to confirm successful loading.
226 pp::URLResponseInfo url_response(url_loader_.GetResponseInfo()); 227 url_response_ = url_loader_.GetResponseInfo();
227 if (url_response.is_null()) { 228 if (url_response_.is_null()) {
228 PLUGIN_PRINTF(( 229 PLUGIN_PRINTF((
229 "FileDownloader::InitialResponseIsValid (url_response=NULL)\n")); 230 "FileDownloader::InitialResponseIsValid (url_response_=NULL)\n"));
230 file_open_notify_callback_.Run(PP_ERROR_FAILED); 231 file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED);
231 return false; 232 return false;
232 } 233 }
233 // Note that URLs in the chrome-extension scheme produce different error 234
234 // codes than other schemes. This is because chrome-extension URLs are 235 pp::Var full_url = url_response_.GetURL();
235 // really a special kind of file scheme, and therefore do not produce HTTP
236 // status codes.
237 pp::Var full_url = url_response.GetURL();
238 if (!full_url.is_string()) { 236 if (!full_url.is_string()) {
239 PLUGIN_PRINTF(( 237 PLUGIN_PRINTF((
240 "FileDownloader::InitialResponseIsValid (url is not a string)\n")); 238 "FileDownloader::InitialResponseIsValid (url is not a string)\n"));
241 file_open_notify_callback_.Run(PP_ERROR_FAILED); 239 file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED);
242 return false; 240 return false;
243 } 241 }
242 url_ = full_url.AsString();
243
244 // Note that URLs in the data-URI scheme produce different error
245 // codes than other schemes. This is because data-URI are really a
246 // special kind of file scheme, and therefore do not produce HTTP
247 // status codes.
244 bool status_ok = false; 248 bool status_ok = false;
245 status_code_ = url_response.GetStatusCode(); 249 status_code_ = url_response_.GetStatusCode();
246 switch (url_scheme_) { 250 switch (url_scheme_) {
247 case SCHEME_CHROME_EXTENSION: 251 case SCHEME_CHROME_EXTENSION:
248 PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (chrome-extension " 252 PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (chrome-extension "
249 "response status_code=%"NACL_PRId32")\n", status_code_)); 253 "response status_code=%"NACL_PRId32")\n", status_code_));
250 status_ok = (status_code_ == kExtensionUrlRequestStatusOk); 254 status_ok = (status_code_ == kExtensionUrlRequestStatusOk);
251 break; 255 break;
252 case SCHEME_DATA: 256 case SCHEME_DATA:
253 PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (data URI " 257 PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (data URI "
254 "response status_code=%"NACL_PRId32")\n", status_code_)); 258 "response status_code=%"NACL_PRId32")\n", status_code_));
255 status_ok = (status_code_ == kDataUriRequestStatusOk); 259 status_ok = (status_code_ == kDataUriRequestStatusOk);
256 break; 260 break;
257 case SCHEME_OTHER: 261 case SCHEME_OTHER:
258 PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (HTTP response " 262 PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (HTTP response "
259 "status_code=%"NACL_PRId32")\n", status_code_)); 263 "status_code=%"NACL_PRId32")\n", status_code_));
260 status_ok = (status_code_ == NACL_HTTP_STATUS_OK); 264 status_ok = (status_code_ == NACL_HTTP_STATUS_OK);
261 break; 265 break;
262 } 266 }
263 267
264 if (!status_ok) { 268 if (!status_ok) {
265 file_open_notify_callback_.Run(PP_ERROR_FAILED); 269 file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED);
266 return false; 270 return false;
267 } 271 }
268 272
269 return true; 273 return true;
270 } 274 }
271 275
272 void FileDownloader::URLLoadStartNotify(int32_t pp_error) { 276 void FileDownloader::URLLoadStartNotify(int32_t pp_error) {
273 PLUGIN_PRINTF(("FileDownloader::URLLoadStartNotify (pp_error=%" 277 PLUGIN_PRINTF(("FileDownloader::URLLoadStartNotify (pp_error=%"
274 NACL_PRId32")\n", pp_error)); 278 NACL_PRId32")\n", pp_error));
275 279
276 if (!InitialResponseIsValid(pp_error)) 280 if (!InitialResponseIsValid(pp_error)) {
281 // InitialResponseIsValid() calls file_open_notify_callback_ on errors.
277 return; 282 return;
283 }
284
285 if (open_and_stream_)
286 return FinishStreaming(file_open_notify_callback_);
287
288 file_open_notify_callback_.RunAndClear(pp_error);
289 }
290
291 void FileDownloader::URLBufferStartNotify(int32_t pp_error) {
292 PLUGIN_PRINTF(("FileDownloader::URLBufferStartNotify (pp_error=%"
293 NACL_PRId32")\n", pp_error));
294
295 if (!InitialResponseIsValid(pp_error)) {
296 // InitialResponseIsValid() calls file_open_notify_callback_ on errors.
297 return;
298 }
299
300 if (open_and_stream_)
301 return FinishStreaming(file_open_notify_callback_);
302
303 file_open_notify_callback_.RunAndClear(pp_error);
304 }
305
306 void FileDownloader::FinishStreaming(
307 const pp::CompletionCallback& callback) {
308 stream_finish_callback_ = callback;
309
278 // Finish streaming the body providing an optional callback. 310 // Finish streaming the body providing an optional callback.
279 pp::CompletionCallback onload_callback = 311 if (streaming_to_file()) {
280 callback_factory_.NewOptionalCallback( 312 pp::CompletionCallback onload_callback =
281 &FileDownloader::URLLoadFinishNotify); 313 callback_factory_.NewOptionalCallback(
282 pp_error = url_loader_.FinishStreamingToFile(onload_callback); 314 &FileDownloader::URLLoadFinishNotify);
283 bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING); 315 int32_t pp_error = url_loader_.FinishStreamingToFile(onload_callback);
284 PLUGIN_PRINTF(("FileDownloader::URLLoadStartNotify (async_notify_ok=%d)\n", 316 bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING);
285 async_notify_ok)); 317 PLUGIN_PRINTF(("FileDownloader::FinishStreaming (async_notify_ok=%d)\n",
286 if (!async_notify_ok) { 318 async_notify_ok));
287 // Call manually to free allocated memory and report errors. This calls 319 if (!async_notify_ok) {
288 // |file_open_notify_callback_| with |pp_error| as the parameter. 320 // Call manually to free allocated memory and report errors. This calls
289 onload_callback.Run(pp_error); 321 // |stream_finish_callback_| with |pp_error| as the parameter.
322 onload_callback.RunAndClear(pp_error);
323 }
324 } else {
325 pp::CompletionCallback onread_callback =
326 callback_factory_.NewOptionalCallback(
327 &FileDownloader::URLReadBodyNotify);
328 int32_t temp_size = static_cast<int32_t>(temp_buffer_.size());
329 int32_t pp_error = url_loader_.ReadResponseBody(&temp_buffer_[0],
330 temp_size,
331 onread_callback);
332 bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING);
333 PLUGIN_PRINTF((
334 "FileDownloader::FinishStreaming (async_notify_ok=%d)\n",
335 async_notify_ok));
336 if (!async_notify_ok) {
337 onread_callback.RunAndClear(pp_error);
338 }
290 } 339 }
291 } 340 }
292 341
293 void FileDownloader::URLLoadFinishNotify(int32_t pp_error) { 342 void FileDownloader::URLLoadFinishNotify(int32_t pp_error) {
294 PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (pp_error=%" 343 PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (pp_error=%"
295 NACL_PRId32")\n", pp_error)); 344 NACL_PRId32")\n", pp_error));
296 if (pp_error != PP_OK) { // Streaming failed. 345 if (pp_error != PP_OK) { // Streaming failed.
297 file_open_notify_callback_.Run(pp_error); 346 stream_finish_callback_.RunAndClear(pp_error);
298 return; 347 return;
299 } 348 }
300 349
301 pp::URLResponseInfo url_response(url_loader_.GetResponseInfo()); 350 // Validate response again on load (though it should be the same
302 // Validated on load. 351 // as it was during InitialResponseIsValid?).
303 CHECK(url_response.GetStatusCode() == NACL_HTTP_STATUS_OK || 352 url_response_ = url_loader_.GetResponseInfo();
304 url_response.GetStatusCode() == kExtensionUrlRequestStatusOk); 353 CHECK(url_response_.GetStatusCode() == NACL_HTTP_STATUS_OK ||
354 url_response_.GetStatusCode() == kExtensionUrlRequestStatusOk);
305 355
306 // Record the full url from the response. 356 // Record the full url from the response.
307 pp::Var full_url = url_response.GetURL(); 357 pp::Var full_url = url_response_.GetURL();
308 PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (full_url=%s)\n", 358 PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (full_url=%s)\n",
309 full_url.DebugString().c_str())); 359 full_url.DebugString().c_str()));
310 if (!full_url.is_string()) { 360 if (!full_url.is_string()) {
311 file_open_notify_callback_.Run(PP_ERROR_FAILED); 361 stream_finish_callback_.RunAndClear(PP_ERROR_FAILED);
312 return; 362 return;
313 } 363 }
314 url_ = full_url.AsString(); 364 url_ = full_url.AsString();
315 365
316 // The file is now fully downloaded. 366 // The file is now fully downloaded.
317 pp::FileRef file(url_response.GetBodyAsFileRef()); 367 pp::FileRef file(url_response_.GetBodyAsFileRef());
318 if (file.is_null()) { 368 if (file.is_null()) {
319 PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (file=NULL)\n")); 369 PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (file=NULL)\n"));
320 file_open_notify_callback_.Run(PP_ERROR_FAILED); 370 stream_finish_callback_.RunAndClear(PP_ERROR_FAILED);
321 return; 371 return;
322 } 372 }
323 373
324 // Open the file providing an optional callback. 374 // Open the file providing an optional callback.
325 pp::CompletionCallback onopen_callback = 375 pp::CompletionCallback onopen_callback =
326 callback_factory_.NewOptionalCallback(&FileDownloader::FileOpenNotify); 376 callback_factory_.NewOptionalCallback(
377 &FileDownloader::StreamFinishNotify);
327 pp_error = file_reader_.Open(file, PP_FILEOPENFLAG_READ, onopen_callback); 378 pp_error = file_reader_.Open(file, PP_FILEOPENFLAG_READ, onopen_callback);
328 bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING); 379 bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING);
329 PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (async_notify_ok=%d)\n", 380 PLUGIN_PRINTF(("FileDownloader::URLLoadFinishNotify (async_notify_ok=%d)\n",
330 async_notify_ok)); 381 async_notify_ok));
331 if (!async_notify_ok) { 382 if (!async_notify_ok) {
332 // Call manually to free allocated memory and report errors. This calls 383 // Call manually to free allocated memory and report errors. This calls
333 // |file_open_notify_callback_| with |pp_error| as the parameter. 384 // |stream_finish_callback_| with |pp_error| as the parameter.
334 onopen_callback.Run(pp_error); 385 onopen_callback.RunAndClear(pp_error);
335 } 386 }
336 } 387 }
337 388
338 void FileDownloader::URLBufferStartNotify(int32_t pp_error) {
339 PLUGIN_PRINTF(("FileDownloader::URLBufferStartNotify (pp_error=%"
340 NACL_PRId32")\n", pp_error));
341
342 if (!InitialResponseIsValid(pp_error))
343 return;
344 // Finish streaming the body asynchronously providing a callback.
345 pp::CompletionCallback onread_callback =
346 callback_factory_.NewOptionalCallback(&FileDownloader::URLReadBodyNotify);
347
348 int32_t temp_size = static_cast<int32_t>(temp_buffer_.size());
349 pp_error = url_loader_.ReadResponseBody(&temp_buffer_[0],
350 temp_size,
351 onread_callback);
352 bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING);
353 PLUGIN_PRINTF(("FileDownloader::URLBufferStartNotify (async_notify_ok=%d)\n",
354 async_notify_ok));
355 if (!async_notify_ok) {
356 onread_callback.Run(pp_error);
357 }
358 }
359
360 void FileDownloader::URLReadBodyNotify(int32_t pp_error) { 389 void FileDownloader::URLReadBodyNotify(int32_t pp_error) {
361 PLUGIN_PRINTF(("FileDownloader::URLReadBodyNotify (pp_error=%" 390 PLUGIN_PRINTF(("FileDownloader::URLReadBodyNotify (pp_error=%"
362 NACL_PRId32")\n", pp_error)); 391 NACL_PRId32")\n", pp_error));
363 if (pp_error < PP_OK) { 392 if (pp_error < PP_OK) {
364 file_open_notify_callback_.Run(pp_error); 393 stream_finish_callback_.RunAndClear(pp_error);
365 } else if (pp_error == PP_OK) { 394 } else if (pp_error == PP_OK) {
366 if (streaming_to_user()) { 395 if (streaming_to_user()) {
367 data_stream_callback_source_->GetCallback().Run(PP_OK); 396 data_stream_callback_source_->GetCallback().RunAndClear(PP_OK);
368 } 397 }
369 FileOpenNotify(PP_OK); 398 StreamFinishNotify(PP_OK);
370 } else { 399 } else {
371 if (streaming_to_buffer()) { 400 if (streaming_to_buffer()) {
372 buffer_.insert(buffer_.end(), &temp_buffer_[0], &temp_buffer_[pp_error]); 401 buffer_.insert(buffer_.end(), &temp_buffer_[0], &temp_buffer_[pp_error]);
373 } else if (streaming_to_user()) { 402 } else if (streaming_to_user()) {
374 PLUGIN_PRINTF(("Running data_stream_callback, temp_buffer_=%p\n", 403 PLUGIN_PRINTF(("Running data_stream_callback, temp_buffer_=%p\n",
375 &temp_buffer_[0])); 404 &temp_buffer_[0]));
376 StreamCallback cb = data_stream_callback_source_->GetCallback(); 405 StreamCallback cb = data_stream_callback_source_->GetCallback();
377 *(cb.output()) = &temp_buffer_; 406 *(cb.output()) = &temp_buffer_;
378 cb.Run(pp_error); 407 cb.RunAndClear(pp_error);
379 } 408 }
380 pp::CompletionCallback onread_callback = 409 pp::CompletionCallback onread_callback =
381 callback_factory_.NewOptionalCallback( 410 callback_factory_.NewOptionalCallback(
382 &FileDownloader::URLReadBodyNotify); 411 &FileDownloader::URLReadBodyNotify);
383 int32_t temp_size = static_cast<int32_t>(temp_buffer_.size()); 412 int32_t temp_size = static_cast<int32_t>(temp_buffer_.size());
384 pp_error = url_loader_.ReadResponseBody(&temp_buffer_[0], 413 pp_error = url_loader_.ReadResponseBody(&temp_buffer_[0],
385 temp_size, 414 temp_size,
386 onread_callback); 415 onread_callback);
387 bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING); 416 bool async_notify_ok = (pp_error == PP_OK_COMPLETIONPENDING);
388 if (!async_notify_ok) { 417 if (!async_notify_ok) {
389 onread_callback.Run(pp_error); 418 onread_callback.RunAndClear(pp_error);
390 } 419 }
391 } 420 }
392 } 421 }
393 422
394 bool FileDownloader::GetDownloadProgress( 423 bool FileDownloader::GetDownloadProgress(
395 int64_t* bytes_received, 424 int64_t* bytes_received,
396 int64_t* total_bytes_to_be_received) const { 425 int64_t* total_bytes_to_be_received) const {
397 return url_loader_.GetDownloadProgress(bytes_received, 426 return url_loader_.GetDownloadProgress(bytes_received,
398 total_bytes_to_be_received); 427 total_bytes_to_be_received);
399 } 428 }
400 429
401 void FileDownloader::FileOpenNotify(int32_t pp_error) { 430 nacl::string FileDownloader::GetResponseHeaders() const {
402 PLUGIN_PRINTF(("FileDownloader::FileOpenNotify (pp_error=%"NACL_PRId32")\n", 431 pp::Var headers = url_response_.GetHeaders();
403 pp_error)); 432 if (!headers.is_string()) {
404 file_open_notify_callback_.Run(pp_error); 433 PLUGIN_PRINTF((
434 "FileDownloader::GetResponseHeaders (headers are not a string)\n"));
435 return nacl::string();
436 }
437 return headers.AsString();
438 }
439
440 void FileDownloader::StreamFinishNotify(int32_t pp_error) {
441 PLUGIN_PRINTF((
442 "FileDownloader::StreamFinishNotify (pp_error=%"NACL_PRId32")\n",
443 pp_error));
444 stream_finish_callback_.RunAndClear(pp_error);
405 } 445 }
406 446
407 bool FileDownloader::streaming_to_file() const { 447 bool FileDownloader::streaming_to_file() const {
408 return mode_ == DOWNLOAD_TO_FILE; 448 return mode_ == DOWNLOAD_TO_FILE;
409 } 449 }
410 450
411 bool FileDownloader::streaming_to_buffer() const { 451 bool FileDownloader::streaming_to_buffer() const {
412 return mode_ == DOWNLOAD_TO_BUFFER; 452 return mode_ == DOWNLOAD_TO_BUFFER;
413 } 453 }
414 454
415 bool FileDownloader::streaming_to_user() const { 455 bool FileDownloader::streaming_to_user() const {
416 return mode_ == DOWNLOAD_STREAM; 456 return mode_ == DOWNLOAD_STREAM;
417 } 457 }
418 458
419 bool FileDownloader::not_streaming() const { 459 bool FileDownloader::not_streaming() const {
420 return mode_ == DOWNLOAD_NONE; 460 return mode_ == DOWNLOAD_NONE;
421 } 461 }
422 462
423 } // namespace plugin 463 } // namespace plugin
OLDNEW
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/file_downloader.h ('k') | ppapi/native_client/src/trusted/plugin/json_manifest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698