url_loader_impl.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "mojo/services/network/url_loader_impl.h"
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "mojo/services/network/network_context.h"
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/base/io_buffer.h"
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/http/http_response_headers.h"
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace mojo {
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace {
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const uint32_t kMaxReadSize = 64 * 1024;
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Generates an URLResponsePtr from the response state of a net::URLRequest.
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)URLResponsePtr MakeURLResponse(const net::URLRequest* url_request) {
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  URLResponsePtr response(URLResponse::New());
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  response->url = url_request->url().spec();
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const net::HttpResponseHeaders* headers = url_request->response_headers();
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (headers) {
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    response->status_code = headers->response_code();
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    response->status_line = headers->GetStatusLine();
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    std::vector<String> header_lines;
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    void* iter = NULL;
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    std::string name, value;
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    while (headers->EnumerateHeaderLines(&iter, &name, &value))
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      header_lines.push_back(name + ": " + value);
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!header_lines.empty())
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      response->headers.Swap(&header_lines);
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return response.Pass();
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Keeps track of a pending two-phase write on a DataPipeProducerHandle.
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class URLLoaderImpl::PendingWriteToDataPipe :
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    public base::RefCountedThreadSafe<PendingWriteToDataPipe> {
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  explicit PendingWriteToDataPipe(ScopedDataPipeProducerHandle handle)
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : handle_(handle.Pass()),
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        buffer_(NULL) {
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool BeginWrite(uint32_t* num_bytes) {
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MojoResult result = BeginWriteDataRaw(handle_.get(), &buffer_, num_bytes,
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          MOJO_WRITE_DATA_FLAG_NONE);
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (*num_bytes > kMaxReadSize)
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      *num_bytes = kMaxReadSize;
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return result == MOJO_RESULT_OK;
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ScopedDataPipeProducerHandle Complete(uint32_t num_bytes) {
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EndWriteDataRaw(handle_.get(), num_bytes);
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    buffer_ = NULL;
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return handle_.Pass();
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  char* buffer() { return static_cast<char*>(buffer_); }
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  friend class base::RefCountedThreadSafe<PendingWriteToDataPipe>;
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ~PendingWriteToDataPipe() {
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (handle_.is_valid())
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      EndWriteDataRaw(handle_.get(), 0);
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ScopedDataPipeProducerHandle handle_;
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void* buffer_;
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PendingWriteToDataPipe);
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Takes ownership of a pending two-phase write on a DataPipeProducerHandle,
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// and makes its buffer available as a net::IOBuffer.
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class URLLoaderImpl::DependentIOBuffer : public net::WrappedIOBuffer {
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DependentIOBuffer(PendingWriteToDataPipe* pending_write)
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : net::WrappedIOBuffer(pending_write->buffer()),
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        pending_write_(pending_write) {
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~DependentIOBuffer() {}
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<PendingWriteToDataPipe> pending_write_;
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)URLLoaderImpl::URLLoaderImpl(NetworkContext* context)
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : context_(context),
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      weak_ptr_factory_(this) {
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)URLLoaderImpl::~URLLoaderImpl() {
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::OnConnectionError() {
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  delete this;
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::Start(URLRequestPtr request,
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          ScopedDataPipeProducerHandle response_body_stream) {
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Do not allow starting another request.
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (url_request_) {
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendError(net::ERR_UNEXPECTED);
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    url_request_.reset();
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    response_body_stream_.reset();
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!request) {
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendError(net::ERR_INVALID_ARGUMENT);
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  response_body_stream_ = response_body_stream.Pass();
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GURL url(request->url);
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  url_request_.reset(
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new net::URLRequest(url,
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          net::DEFAULT_PRIORITY,
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          this,
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          context_->url_request_context()));
12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  url_request_->Start();
12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::FollowRedirect() {
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NOTIMPLEMENTED();
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request,
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                       const GURL& new_url,
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                       bool* defer_redirect) {
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(url_request == url_request_.get());
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(url_request->status().is_success());
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  URLResponsePtr response = MakeURLResponse(url_request);
14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string redirect_method =
14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      net::URLRequest::ComputeMethodForRedirect(url_request->method(),
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                response->status_code);
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client()->OnReceivedRedirect(
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      response.Pass(), new_url.spec(), redirect_method);
14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  *defer_redirect = false;
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) {
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(url_request == url_request_.get());
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!url_request->status().is_success()) {
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SendError(url_request->status().error());
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client()->OnReceivedResponse(MakeURLResponse(url_request));
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Start reading...
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ReadMore();
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request,
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    int bytes_read) {
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (url_request->status().is_success()) {
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DidRead(static_cast<uint32_t>(bytes_read), false);
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else {
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    pending_write_ = NULL;  // This closes the data pipe.
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // TODO(darin): Perhaps we should communicate this error to our client.
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::SendError(int error_code) {
17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NetworkErrorPtr error(NetworkError::New());
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  error->code = error_code;
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  error->description = net::ErrorToString(error_code);
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client()->OnReceivedError(error.Pass());
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::ReadMore() {
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!pending_write_);
18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  pending_write_ = new PendingWriteToDataPipe(response_body_stream_.Pass());
18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  uint32_t num_bytes;
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!pending_write_->BeginWrite(&num_bytes))
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    CHECK(false);  // Oops!
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (num_bytes > static_cast<uint32_t>(std::numeric_limits<int>::max()))
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    CHECK(false);  // Oops!
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf = new DependentIOBuffer(pending_write_);
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int bytes_read;
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  url_request_->Read(buf, static_cast<int>(num_bytes), &bytes_read);
19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Drop our reference to the buffer.
19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  buf = NULL;
20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (url_request_->status().is_io_pending()) {
20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // Wait for OnReadCompleted.
20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else if (url_request_->status().is_success() && bytes_read > 0) {
20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DidRead(static_cast<uint32_t>(bytes_read), true);
20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else {
20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    pending_write_->Complete(0);
20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    pending_write_ = NULL;  // This closes the data pipe.
20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (bytes_read == 0) {
20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      client()->OnReceivedEndOfResponseBody();
21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    } else {
21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      DCHECK(!url_request_->status().is_success());
21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      SendError(url_request_->status().error());
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) {
21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(url_request_->status().is_success());
21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  response_body_stream_ = pending_write_->Complete(num_bytes);
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  pending_write_ = NULL;
22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (completed_synchronously) {
22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        FROM_HERE,
22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(&URLLoaderImpl::ReadMore, weak_ptr_factory_.GetWeakPtr()));
22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else {
22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ReadMore();
22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace mojo
233