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