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) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_vector.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/message_loop/message_loop.h" 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/common/common_type_converters.h" 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "mojo/services/network/network_context.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/base/io_buffer.h" 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/base/load_flags.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/upload_data_stream.h" 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/http/http_response_headers.h" 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "net/url_request/redirect_info.h" 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "net/url_request/url_request_context.h" 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace mojo { 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace { 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const uint32_t kMaxReadSize = 64 * 1024; 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Generates an URLResponsePtr from the response state of a net::URLRequest. 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)URLResponsePtr MakeURLResponse(const net::URLRequest* url_request) { 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) URLResponsePtr response(URLResponse::New()); 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response->url = String::From(url_request->url()); 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const net::HttpResponseHeaders* headers = url_request->response_headers(); 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (headers) { 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) response->status_code = headers->response_code(); 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) response->status_line = headers->GetStatusLine(); 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::vector<String> header_lines; 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void* iter = NULL; 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string name, value; 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) while (headers->EnumerateHeaderLines(&iter, &name, &value)) 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) header_lines.push_back(name + ": " + value); 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!header_lines.empty()) 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) response->headers.Swap(&header_lines); 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string mime_type; 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch url_request->GetMimeType(&mime_type); 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response->mime_type = mime_type; 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string charset; 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch url_request->GetCharset(&charset); 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response->charset = charset; 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return response.Pass(); 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 54116680a4aac90f2aa7413d9095a592090648e557Ben MurdochNetworkErrorPtr MakeNetworkError(int error_code) { 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NetworkErrorPtr error = NetworkError::New(); 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error->code = error_code; 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error->description = net::ErrorToString(error_code); 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return error.Pass(); 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Reads the request body upload data from a DataPipe. 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class UploadDataPipeElementReader : public net::UploadElementReader { 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UploadDataPipeElementReader(ScopedDataPipeConsumerHandle pipe) 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : pipe_(pipe.Pass()), num_bytes_(0) {} 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual ~UploadDataPipeElementReader() {} 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // UploadElementReader overrides: 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual int Init(const net::CompletionCallback& callback) OVERRIDE { 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) offset_ = 0; 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ReadDataRaw(pipe_.get(), NULL, &num_bytes_, MOJO_READ_DATA_FLAG_QUERY); 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return net::OK; 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual uint64 GetContentLength() const OVERRIDE { 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return num_bytes_; 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual uint64 BytesRemaining() const OVERRIDE { 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return num_bytes_ - offset_; 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual bool IsInMemory() const OVERRIDE { 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual int Read(net::IOBuffer* buf, 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int buf_length, 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const net::CompletionCallback& callback) OVERRIDE { 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint32_t bytes_read = 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::min(static_cast<uint32_t>(BytesRemaining()), 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) static_cast<uint32_t>(buf_length)); 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (bytes_read > 0) { 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ReadDataRaw(pipe_.get(), buf->data(), &bytes_read, 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_READ_DATA_FLAG_NONE); 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) offset_ += bytes_read; 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return bytes_read; 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedDataPipeConsumerHandle pipe_; 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint32_t num_bytes_; 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint32_t offset_; 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UploadDataPipeElementReader); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace 10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Keeps track of a pending two-phase write on a DataPipeProducerHandle. 10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class URLLoaderImpl::PendingWriteToDataPipe : 11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public base::RefCountedThreadSafe<PendingWriteToDataPipe> { 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) explicit PendingWriteToDataPipe(ScopedDataPipeProducerHandle handle) 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : handle_(handle.Pass()), 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) buffer_(NULL) { 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoResult BeginWrite(uint32_t* num_bytes) { 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MojoResult result = BeginWriteDataRaw(handle_.get(), &buffer_, num_bytes, 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MOJO_WRITE_DATA_FLAG_NONE); 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (*num_bytes > kMaxReadSize) 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *num_bytes = kMaxReadSize; 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return result; 12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ScopedDataPipeProducerHandle Complete(uint32_t num_bytes) { 12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EndWriteDataRaw(handle_.get(), num_bytes); 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) buffer_ = NULL; 12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return handle_.Pass(); 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) char* buffer() { return static_cast<char*>(buffer_); } 13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) friend class base::RefCountedThreadSafe<PendingWriteToDataPipe>; 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ~PendingWriteToDataPipe() { 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (handle_.is_valid()) 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EndWriteDataRaw(handle_.get(), 0); 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ScopedDataPipeProducerHandle handle_; 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void* buffer_; 14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PendingWriteToDataPipe); 14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Takes ownership of a pending two-phase write on a DataPipeProducerHandle, 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// and makes its buffer available as a net::IOBuffer. 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class URLLoaderImpl::DependentIOBuffer : public net::WrappedIOBuffer { 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DependentIOBuffer(PendingWriteToDataPipe* pending_write) 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : net::WrappedIOBuffer(pending_write->buffer()), 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pending_write_(pending_write) { 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual ~DependentIOBuffer() {} 15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<PendingWriteToDataPipe> pending_write_; 15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)URLLoaderImpl::URLLoaderImpl(NetworkContext* context) 16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : context_(context), 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response_body_buffer_size_(0), 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) auto_follow_redirects_(true), 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) weak_ptr_factory_(this) { 16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)URLLoaderImpl::~URLLoaderImpl() { 16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::Start(URLRequestPtr request, 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Callback<void(URLResponsePtr)>& callback) { 17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (url_request_) { 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SendError(net::ERR_UNEXPECTED, callback); 17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!request) { 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SendError(net::ERR_INVALID_ARGUMENT, callback); 18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) url_request_ = context_->url_request_context()->CreateRequest( 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GURL(request->url), 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) net::DEFAULT_PRIORITY, 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this, 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NULL); 188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) url_request_->set_method(request->method); 189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (request->headers) { 190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) net::HttpRequestHeaders headers; 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t i = 0; i < request->headers.size(); ++i) 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) headers.AddHeaderFromString(request->headers[i].To<base::StringPiece>()); 193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) url_request_->SetExtraRequestHeaders(headers); 194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (request->body) { 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedVector<net::UploadElementReader> element_readers; 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (size_t i = 0; i < request->body.size(); ++i) { 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) element_readers.push_back( 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new UploadDataPipeElementReader(request->body[i].Pass())); 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) url_request_->set_upload(make_scoped_ptr( 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new net::UploadDataStream(element_readers.Pass(), 0))); 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (request->bypass_cache) 205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) url_request_->SetLoadFlags(net::LOAD_BYPASS_CACHE); 206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_ = callback; 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response_body_buffer_size_ = request->response_body_buffer_size; 209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) auto_follow_redirects_ = request->auto_follow_redirects; 210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) url_request_->Start(); 21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid URLLoaderImpl::FollowRedirect( 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Callback<void(URLResponsePtr)>& callback) { 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!url_request_) { 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SendError(net::ERR_UNEXPECTED, callback); 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (auto_follow_redirects_) { 222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DLOG(ERROR) << "Spurious call to FollowRedirect"; 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SendError(net::ERR_UNEXPECTED, callback); 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(darin): Verify that it makes sense to call FollowDeferredRedirect. 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch url_request_->FollowDeferredRedirect(); 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid URLLoaderImpl::QueryStatus( 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Callback<void(URLLoaderStatusPtr)>& callback) { 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch URLLoaderStatusPtr status(URLLoaderStatus::New()); 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (url_request_) { 235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status->is_loading = url_request_->is_pending(); 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!url_request_->status().is_success()) 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status->error = MakeNetworkError(url_request_->status().error()); 238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status->is_loading = false; 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(darin): Populate more status fields. 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback.Run(status.Pass()); 24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request, 2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const net::RedirectInfo& redirect_info, 24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool* defer_redirect) { 24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(url_request == url_request_.get()); 24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(url_request->status().is_success()); 25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (auto_follow_redirects_) 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Send the redirect response to the client, allowing them to inspect it and 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // optionally follow the redirect. 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *defer_redirect = true; 257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) URLResponsePtr response = MakeURLResponse(url_request); 2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) response->redirect_method = redirect_info.new_method; 2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) response->redirect_url = String::From(redirect_info.new_url); 26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SendResponse(response.Pass()); 26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) { 26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(url_request == url_request_.get()); 26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!url_request->status().is_success()) { 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SendError(url_request->status().error(), callback_); 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback_ = Callback<void(URLResponsePtr)>(); 27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(darin): Add support for optional MIME sniffing. 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DataPipe data_pipe; 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(darin): Honor given buffer size. 278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch URLResponsePtr response = MakeURLResponse(url_request); 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response->body = data_pipe.consumer_handle.Pass(); 281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response_body_stream_ = data_pipe.producer_handle.Pass(); 282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SendResponse(response.Pass()); 28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Start reading... 28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ReadMore(); 28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request, 29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int bytes_read) { 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(url_request == url_request_.get()); 292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (url_request->status().is_success()) { 29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DidRead(static_cast<uint32_t>(bytes_read), false); 29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pending_write_ = NULL; // This closes the data pipe. 29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid URLLoaderImpl::SendError( 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int error_code, 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Callback<void(URLResponsePtr)>& callback) { 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch URLResponsePtr response(URLResponse::New()); 304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (url_request_) 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response->url = String::From(url_request_->url()); 306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response->error = MakeNetworkError(error_code); 307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback.Run(response.Pass()); 308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 310116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid URLLoaderImpl::SendResponse(URLResponsePtr response) { 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Callback<void(URLResponsePtr)> callback; 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::swap(callback_, callback); 313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback.Run(response.Pass()); 314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 316116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { 317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(darin): Handle a bad |result| value. 318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReadMore(); 319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid URLLoaderImpl::WaitToReadMore() { 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch handle_watcher_.Start(response_body_stream_.get(), 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOJO_HANDLE_SIGNAL_WRITABLE, 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOJO_DEADLINE_INDEFINITE, 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady, 326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr())); 32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::ReadMore() { 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!pending_write_.get()); 33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pending_write_ = new PendingWriteToDataPipe(response_body_stream_.Pass()); 33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uint32_t num_bytes; 335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MojoResult result = pending_write_->BeginWrite(&num_bytes); 336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (result == MOJO_RESULT_SHOULD_WAIT) { 337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The pipe is full. We need to wait for it to have more space. 338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch response_body_stream_ = pending_write_->Complete(num_bytes); 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_write_ = NULL; 340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch WaitToReadMore(); 341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (result != MOJO_RESULT_OK) { 344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The response body stream is in a bad state. Bail. 345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(darin): How should this be communicated to our client? 346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes); 34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::IOBuffer> buf = 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new DependentIOBuffer(pending_write_.get()); 35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int bytes_read; 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url_request_->Read(buf.get(), static_cast<int>(num_bytes), &bytes_read); 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Drop our reference to the buffer. 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) buf = NULL; 35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (url_request_->status().is_io_pending()) { 36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Wait for OnReadCompleted. 36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else if (url_request_->status().is_success() && bytes_read > 0) { 36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DidRead(static_cast<uint32_t>(bytes_read), true); 36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pending_write_->Complete(0); 36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pending_write_ = NULL; // This closes the data pipe. 36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) { 37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(url_request_->status().is_success()); 37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) response_body_stream_ = pending_write_->Complete(num_bytes); 37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) pending_write_ = NULL; 37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (completed_synchronously) { 37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->PostTask( 37746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&URLLoaderImpl::ReadMore, weak_ptr_factory_.GetWeakPtr())); 37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ReadMore(); 38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace mojo 385