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