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