Home | History | Annotate | Download | only in url_request
      1 // Copyright (c) 2012 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_request_simple_job.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/bind.h"
     10 #include "base/compiler_specific.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "net/base/io_buffer.h"
     13 #include "net/base/net_errors.h"
     14 #include "net/http/http_request_headers.h"
     15 #include "net/http/http_util.h"
     16 #include "net/url_request/url_request_status.h"
     17 
     18 namespace net {
     19 
     20 URLRequestSimpleJob::URLRequestSimpleJob(
     21     URLRequest* request, NetworkDelegate* network_delegate)
     22     : URLRangeRequestJob(request, network_delegate),
     23       data_offset_(0),
     24       weak_factory_(this) {}
     25 
     26 void URLRequestSimpleJob::Start() {
     27   // Start reading asynchronously so that all error reporting and data
     28   // callbacks happen as they would for network requests.
     29   base::MessageLoop::current()->PostTask(
     30       FROM_HERE,
     31       base::Bind(&URLRequestSimpleJob::StartAsync, weak_factory_.GetWeakPtr()));
     32 }
     33 
     34 bool URLRequestSimpleJob::GetMimeType(std::string* mime_type) const {
     35   *mime_type = mime_type_;
     36   return true;
     37 }
     38 
     39 bool URLRequestSimpleJob::GetCharset(std::string* charset) {
     40   *charset = charset_;
     41   return true;
     42 }
     43 
     44 URLRequestSimpleJob::~URLRequestSimpleJob() {}
     45 
     46 bool URLRequestSimpleJob::ReadRawData(IOBuffer* buf, int buf_size,
     47                                       int* bytes_read) {
     48   DCHECK(bytes_read);
     49   int remaining = byte_range_.last_byte_position() - data_offset_ + 1;
     50   if (buf_size > remaining)
     51     buf_size = remaining;
     52   memcpy(buf->data(), data_.data() + data_offset_, buf_size);
     53   data_offset_ += buf_size;
     54   *bytes_read = buf_size;
     55   return true;
     56 }
     57 
     58 void URLRequestSimpleJob::StartAsync() {
     59   if (!request_)
     60     return;
     61 
     62   if (ranges().size() > 1) {
     63     NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
     64                                 ERR_REQUEST_RANGE_NOT_SATISFIABLE));
     65     return;
     66   }
     67 
     68   if (!ranges().empty() && range_parse_result() == OK)
     69     byte_range_ = ranges().front();
     70 
     71   int result = GetData(&mime_type_, &charset_, &data_,
     72                        base::Bind(&URLRequestSimpleJob::OnGetDataCompleted,
     73                                   weak_factory_.GetWeakPtr()));
     74   if (result != ERR_IO_PENDING)
     75     OnGetDataCompleted(result);
     76 }
     77 
     78 void URLRequestSimpleJob::OnGetDataCompleted(int result) {
     79   if (result == OK) {
     80     // Notify that the headers are complete
     81     if (!byte_range_.ComputeBounds(data_.size())) {
     82       NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
     83                  ERR_REQUEST_RANGE_NOT_SATISFIABLE));
     84       return;
     85     }
     86 
     87     data_offset_ = byte_range_.first_byte_position();
     88     int remaining_bytes = byte_range_.last_byte_position() -
     89         byte_range_.first_byte_position() + 1;
     90     set_expected_content_size(remaining_bytes);
     91     NotifyHeadersComplete();
     92   } else {
     93     NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result));
     94   }
     95 }
     96 
     97 }  // namespace net
     98