Home | History | Annotate | Download | only in renderer
      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 
     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 
     31 FileDownloader::~FileDownloader() {
     32 }
     33 
     34 void FileDownloader::Load(const blink::WebURLRequest& request) {
     35   url_loader_->loadAsynchronously(request, this);
     36 }
     37 
     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 
     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 
     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 
     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