• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
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 "base/callback.h"
8 #include "components/nacl/renderer/nexe_load_manager.h"
9 #include "net/base/net_errors.h"
10 #include "third_party/WebKit/public/platform/WebURLError.h"
11 #include "third_party/WebKit/public/platform/WebURLLoader.h"
12 #include "third_party/WebKit/public/platform/WebURLResponse.h"
13 
14 namespace nacl {
15 
FileDownloader(scoped_ptr<blink::WebURLLoader> url_loader,base::File file,StatusCallback status_cb,ProgressCallback progress_cb)16 FileDownloader::FileDownloader(scoped_ptr<blink::WebURLLoader> url_loader,
17                                base::File file,
18                                StatusCallback status_cb,
19                                ProgressCallback progress_cb)
20     : url_loader_(url_loader.Pass()),
21       file_(file.Pass()),
22       status_cb_(status_cb),
23       progress_cb_(progress_cb),
24       http_status_code_(-1),
25       total_bytes_received_(0),
26       total_bytes_to_be_received_(-1),
27       status_(SUCCESS) {
28   CHECK(!status_cb.is_null());
29 }
30 
~FileDownloader()31 FileDownloader::~FileDownloader() {
32 }
33 
Load(const blink::WebURLRequest & request)34 void FileDownloader::Load(const blink::WebURLRequest& request) {
35   url_loader_->loadAsynchronously(request, this);
36 }
37 
didReceiveResponse(blink::WebURLLoader * loader,const blink::WebURLResponse & response)38 void FileDownloader::didReceiveResponse(
39     blink::WebURLLoader* loader,
40     const blink::WebURLResponse& response) {
41   http_status_code_ = response.httpStatusCode();
42   if (http_status_code_ != 200)
43     status_ = FAILED;
44 
45   // Set -1 if the content length is unknown. Set before issuing callback.
46   total_bytes_to_be_received_ = response.expectedContentLength();
47   if (!progress_cb_.is_null())
48     progress_cb_.Run(total_bytes_received_, total_bytes_to_be_received_);
49 }
50 
didReceiveData(blink::WebURLLoader * loader,const char * data,int data_length,int encoded_data_length)51 void FileDownloader::didReceiveData(
52     blink::WebURLLoader* loader,
53     const char* data,
54     int data_length,
55     int encoded_data_length) {
56   if (status_ == SUCCESS) {
57     if (file_.Write(total_bytes_received_, data, data_length) == -1) {
58       status_ = FAILED;
59       return;
60     }
61     total_bytes_received_ += data_length;
62     if (!progress_cb_.is_null())
63       progress_cb_.Run(total_bytes_received_, total_bytes_to_be_received_);
64   }
65 }
66 
didFinishLoading(blink::WebURLLoader * loader,double finish_time,int64_t total_encoded_data_length)67 void FileDownloader::didFinishLoading(
68     blink::WebURLLoader* loader,
69     double finish_time,
70     int64_t total_encoded_data_length) {
71   if (status_ == SUCCESS) {
72     // Seek back to the beginning of the file that was just written so it's
73     // easy for consumers to use.
74     if (file_.Seek(base::File::FROM_BEGIN, 0) != 0)
75       status_ = FAILED;
76   }
77   status_cb_.Run(status_, file_.Pass(), http_status_code_);
78   delete this;
79 }
80 
didFail(blink::WebURLLoader * loader,const blink::WebURLError & error)81 void FileDownloader::didFail(
82     blink::WebURLLoader* loader,
83     const blink::WebURLError& error) {
84   status_ = FAILED;
85   if (error.domain.equals(blink::WebString::fromUTF8(net::kErrorDomain))) {
86     switch (error.reason) {
87       case net::ERR_ACCESS_DENIED:
88       case net::ERR_NETWORK_ACCESS_DENIED:
89         status_ = ACCESS_DENIED;
90         break;
91     }
92   } else {
93     // It's a WebKit error.
94     status_ = ACCESS_DENIED;
95   }
96 }
97 
98 }  // namespace nacl
99