Home | History | Annotate | Download | only in url_request
      1 // Copyright (c) 2013 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 "net/url_request/url_fetcher_response_writer.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/location.h"
      9 #include "base/sequenced_task_runner.h"
     10 #include "base/task_runner_util.h"
     11 #include "net/base/file_stream.h"
     12 #include "net/base/io_buffer.h"
     13 #include "net/base/net_errors.h"
     14 
     15 namespace net {
     16 
     17 URLFetcherStringWriter* URLFetcherResponseWriter::AsStringWriter() {
     18   return NULL;
     19 }
     20 
     21 URLFetcherFileWriter* URLFetcherResponseWriter::AsFileWriter() {
     22   return NULL;
     23 }
     24 
     25 URLFetcherStringWriter::URLFetcherStringWriter() {
     26 }
     27 
     28 URLFetcherStringWriter::~URLFetcherStringWriter() {
     29 }
     30 
     31 int URLFetcherStringWriter::Initialize(const CompletionCallback& callback) {
     32   data_.clear();
     33   return OK;
     34 }
     35 
     36 int URLFetcherStringWriter::Write(IOBuffer* buffer,
     37                                   int num_bytes,
     38                                   const CompletionCallback& callback) {
     39   data_.append(buffer->data(), num_bytes);
     40   return num_bytes;
     41 }
     42 
     43 int URLFetcherStringWriter::Finish(const CompletionCallback& callback) {
     44   // Do nothing.
     45   return OK;
     46 }
     47 
     48 URLFetcherStringWriter* URLFetcherStringWriter::AsStringWriter() {
     49   return this;
     50 }
     51 
     52 URLFetcherFileWriter::URLFetcherFileWriter(
     53     scoped_refptr<base::SequencedTaskRunner> file_task_runner,
     54     const base::FilePath& file_path)
     55     : weak_factory_(this),
     56       file_task_runner_(file_task_runner),
     57       file_path_(file_path),
     58       owns_file_(false) {
     59   DCHECK(file_task_runner_.get());
     60 }
     61 
     62 URLFetcherFileWriter::~URLFetcherFileWriter() {
     63   CloseAndDeleteFile();
     64 }
     65 
     66 int URLFetcherFileWriter::Initialize(const CompletionCallback& callback) {
     67   file_stream_.reset(new FileStream(NULL));
     68 
     69   int result = ERR_IO_PENDING;
     70   if (file_path_.empty()) {
     71     base::FilePath* temp_file_path = new base::FilePath;
     72     base::PostTaskAndReplyWithResult(
     73         file_task_runner_.get(),
     74         FROM_HERE,
     75         base::Bind(&base::CreateTemporaryFile, temp_file_path),
     76         base::Bind(&URLFetcherFileWriter::DidCreateTempFile,
     77                    weak_factory_.GetWeakPtr(),
     78                    callback,
     79                    base::Owned(temp_file_path)));
     80   } else {
     81     result = file_stream_->Open(
     82         file_path_,
     83         base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC |
     84         base::PLATFORM_FILE_CREATE_ALWAYS,
     85         base::Bind(&URLFetcherFileWriter::DidOpenFile,
     86                    weak_factory_.GetWeakPtr(),
     87                    callback));
     88     DCHECK_NE(OK, result);
     89   }
     90   return result;
     91 }
     92 
     93 int URLFetcherFileWriter::Write(IOBuffer* buffer,
     94                                 int num_bytes,
     95                                 const CompletionCallback& callback) {
     96   DCHECK(file_stream_);
     97   DCHECK(owns_file_);
     98 
     99   int result = file_stream_->Write(buffer, num_bytes,
    100                                    base::Bind(&URLFetcherFileWriter::DidWrite,
    101                                               weak_factory_.GetWeakPtr(),
    102                                               callback));
    103   if (result < 0 && result != ERR_IO_PENDING)
    104     CloseAndDeleteFile();
    105 
    106   return result;
    107 }
    108 
    109 int URLFetcherFileWriter::Finish(const CompletionCallback& callback) {
    110   int result = file_stream_->Close(base::Bind(
    111       &URLFetcherFileWriter::CloseComplete,
    112       weak_factory_.GetWeakPtr(), callback));
    113   if (result != ERR_IO_PENDING)
    114     file_stream_.reset();
    115   return result;
    116 }
    117 
    118 URLFetcherFileWriter* URLFetcherFileWriter::AsFileWriter() {
    119   return this;
    120 }
    121 
    122 void URLFetcherFileWriter::DisownFile() {
    123   // Disowning is done by the delegate's OnURLFetchComplete method.
    124   // The file should be closed by the time that method is called.
    125   DCHECK(!file_stream_);
    126 
    127   owns_file_ = false;
    128 }
    129 
    130 void URLFetcherFileWriter::DidWrite(const CompletionCallback& callback,
    131                                     int result) {
    132   if (result < 0)
    133     CloseAndDeleteFile();
    134 
    135   callback.Run(result);
    136 }
    137 
    138 void URLFetcherFileWriter::CloseAndDeleteFile() {
    139   if (!owns_file_)
    140     return;
    141 
    142   file_stream_.reset();
    143   DisownFile();
    144   file_task_runner_->PostTask(FROM_HERE,
    145                               base::Bind(base::IgnoreResult(&base::DeleteFile),
    146                                          file_path_,
    147                                          false /* recursive */));
    148 }
    149 
    150 void URLFetcherFileWriter::DidCreateTempFile(const CompletionCallback& callback,
    151                                              base::FilePath* temp_file_path,
    152                                              bool success) {
    153   if (!success) {
    154     callback.Run(ERR_FILE_NOT_FOUND);
    155     return;
    156   }
    157   file_path_ = *temp_file_path;
    158   owns_file_ = true;
    159   const int result = file_stream_->Open(
    160       file_path_,
    161       base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC |
    162       base::PLATFORM_FILE_OPEN,
    163       base::Bind(&URLFetcherFileWriter::DidOpenFile,
    164                  weak_factory_.GetWeakPtr(),
    165                  callback));
    166   if (result != ERR_IO_PENDING)
    167     DidOpenFile(callback, result);
    168 }
    169 
    170 void URLFetcherFileWriter::DidOpenFile(const CompletionCallback& callback,
    171                                        int result) {
    172   if (result == OK)
    173     owns_file_ = true;
    174   else
    175     CloseAndDeleteFile();
    176 
    177   callback.Run(result);
    178 }
    179 
    180 void URLFetcherFileWriter::CloseComplete(const CompletionCallback& callback,
    181                                          int result) {
    182   // Destroy |file_stream_| whether or not the close succeeded.
    183   file_stream_.reset();
    184   callback.Run(result);
    185 }
    186 
    187 }  // namespace net
    188