• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/nacl/renderer/file_downloader.h"
6 
7 #include <utility>
8 
9 #include "base/functional/callback.h"
10 #include "components/nacl/renderer/nexe_load_manager.h"
11 #include "net/base/net_errors.h"
12 #include "third_party/blink/public/platform/web_url_error.h"
13 #include "third_party/blink/public/platform/web_url_response.h"
14 #include "third_party/blink/public/web/web_associated_url_loader.h"
15 
16 namespace nacl {
17 
FileDownloader(std::unique_ptr<blink::WebAssociatedURLLoader> url_loader,base::File file,StatusCallback status_cb,ProgressCallback progress_cb)18 FileDownloader::FileDownloader(
19     std::unique_ptr<blink::WebAssociatedURLLoader> url_loader,
20     base::File file,
21     StatusCallback status_cb,
22     ProgressCallback progress_cb)
23     : url_loader_(std::move(url_loader)),
24       file_(std::move(file)),
25       status_cb_(std::move(status_cb)),
26       progress_cb_(std::move(progress_cb)),
27       http_status_code_(-1),
28       total_bytes_received_(0),
29       total_bytes_to_be_received_(-1),
30       status_(SUCCESS) {
31   CHECK(!status_cb_.is_null());
32 }
33 
~FileDownloader()34 FileDownloader::~FileDownloader() {
35 }
36 
Load(const blink::WebURLRequest & request)37 void FileDownloader::Load(const blink::WebURLRequest& request) {
38   url_loader_->LoadAsynchronously(request, this);
39 }
40 
DidReceiveResponse(const blink::WebURLResponse & response)41 void FileDownloader::DidReceiveResponse(const blink::WebURLResponse& response) {
42   http_status_code_ = response.HttpStatusCode();
43   if (http_status_code_ != 200)
44     status_ = FAILED;
45 
46   // Set -1 if the content length is unknown. Set before issuing callback.
47   total_bytes_to_be_received_ = response.ExpectedContentLength();
48   if (!progress_cb_.is_null())
49     progress_cb_.Run(total_bytes_received_, total_bytes_to_be_received_);
50 }
51 
DidReceiveData(const char * data,int data_length)52 void FileDownloader::DidReceiveData(const char* data, int data_length) {
53   if (status_ == SUCCESS) {
54     if (file_.Write(total_bytes_received_, data, data_length) == -1) {
55       status_ = FAILED;
56       return;
57     }
58     total_bytes_received_ += data_length;
59     if (!progress_cb_.is_null())
60       progress_cb_.Run(total_bytes_received_, total_bytes_to_be_received_);
61   }
62 }
63 
DidFinishLoading()64 void FileDownloader::DidFinishLoading() {
65   if (status_ == SUCCESS) {
66     // Seek back to the beginning of the file that was just written so it's
67     // easy for consumers to use.
68     if (file_.Seek(base::File::FROM_BEGIN, 0) != 0)
69       status_ = FAILED;
70   }
71   std::move(status_cb_).Run(status_, std::move(file_), http_status_code_);
72   delete this;
73 }
74 
DidFail(const blink::WebURLError & error)75 void FileDownloader::DidFail(const blink::WebURLError& error) {
76   status_ = FAILED;
77   switch (error.reason()) {
78     case net::ERR_ACCESS_DENIED:
79     case net::ERR_NETWORK_ACCESS_DENIED:
80       status_ = ACCESS_DENIED;
81       break;
82   }
83 
84   if (error.is_web_security_violation())
85     status_ = ACCESS_DENIED;
86 
87   // Delete url_loader to prevent didFinishLoading from being called, which
88   // some implementations of blink::URLLoader will do after calling didFail.
89   url_loader_.reset();
90 
91   std::move(status_cb_).Run(status_, std::move(file_), http_status_code_);
92   delete this;
93 }
94 
95 }  // namespace nacl
96