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