15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_simple_job.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_request_headers.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestSimpleJob::URLRequestSimpleJob(
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequest* request, NetworkDelegate* network_delegate)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : URLRangeRequestJob(request, network_delegate),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_offset_(0),
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestSimpleJob::Start() {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start reading asynchronously so that all error reporting and data
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callbacks happen as they would for network requests.
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&URLRequestSimpleJob::StartAsync, weak_factory_.GetWeakPtr()));
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestSimpleJob::GetMimeType(std::string* mime_type) const {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *mime_type = mime_type_;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestSimpleJob::GetCharset(std::string* charset) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *charset = charset_;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestSimpleJob::~URLRequestSimpleJob() {}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestSimpleJob::ReadRawData(IOBuffer* buf, int buf_size,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int* bytes_read) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bytes_read);
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int remaining = byte_range_.last_byte_position() - data_offset_ + 1;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (buf_size > remaining)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf_size = remaining;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buf->data(), data_.data() + data_offset_, buf_size);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_offset_ += buf_size;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *bytes_read = buf_size;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestSimpleJob::StartAsync() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request_)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ranges().size() > 1) {
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                ERR_REQUEST_RANGE_NOT_SATISFIABLE));
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ranges().empty() && range_parse_result() == OK)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    byte_range_ = ranges().front();
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = GetData(&mime_type_, &charset_, &data_,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::Bind(&URLRequestSimpleJob::OnGetDataCompleted,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  weak_factory_.GetWeakPtr()));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result != ERR_IO_PENDING)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnGetDataCompleted(result);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestSimpleJob::OnGetDataCompleted(int result) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == OK) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Notify that the headers are complete
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!byte_range_.ComputeBounds(data_.size())) {
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 ERR_REQUEST_RANGE_NOT_SATISFIABLE));
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    data_offset_ = byte_range_.first_byte_position();
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int remaining_bytes = byte_range_.last_byte_position() -
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        byte_range_.first_byte_position() + 1;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    set_expected_content_size(remaining_bytes);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyHeadersComplete();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, result));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
98