| Index: mojo/services/network/url_loader_impl.cc
|
| diff --git a/mojo/services/network/url_loader_impl.cc b/mojo/services/network/url_loader_impl.cc
|
| index 3f263780407b907f7d25da682dcc69719f91e0f0..ccaf4e51c7a156def0bdaf8fcf829801303d55d1 100644
|
| --- a/mojo/services/network/url_loader_impl.cc
|
| +++ b/mojo/services/network/url_loader_impl.cc
|
| @@ -31,7 +31,7 @@ URLResponsePtr MakeURLResponse(const net::URLRequest* url_request) {
|
| response->status_line = headers->GetStatusLine();
|
|
|
| std::vector<String> header_lines;
|
| - void* iter = NULL;
|
| + void* iter = nullptr;
|
| std::string name, value;
|
| while (headers->EnumerateHeaderLines(&iter, &name, &value))
|
| header_lines.push_back(name + ": " + value);
|
| @@ -60,7 +60,7 @@ class UploadDataPipeElementReader : public net::UploadElementReader {
|
| // UploadElementReader overrides:
|
| int Init(const net::CompletionCallback& callback) override {
|
| offset_ = 0;
|
| - ReadDataRaw(pipe_.get(), NULL, &num_bytes_, MOJO_READ_DATA_FLAG_QUERY);
|
| + ReadDataRaw(pipe_.get(), nullptr, &num_bytes_, MOJO_READ_DATA_FLAG_QUERY);
|
| return net::OK;
|
| }
|
| uint64 GetContentLength() const override { return num_bytes_; }
|
| @@ -91,11 +91,15 @@ class UploadDataPipeElementReader : public net::UploadElementReader {
|
|
|
| } // namespace
|
|
|
| -URLLoaderImpl::URLLoaderImpl(NetworkContext* context)
|
| +URLLoaderImpl::URLLoaderImpl(NetworkContext* context,
|
| + InterfaceRequest<URLLoader> request)
|
| : context_(context),
|
| response_body_buffer_size_(0),
|
| auto_follow_redirects_(true),
|
| + connected_(true),
|
| + binding_(this, request.Pass()),
|
| weak_ptr_factory_(this) {
|
| + binding_.set_error_handler(this);
|
| }
|
|
|
| URLLoaderImpl::~URLLoaderImpl() {
|
| @@ -114,10 +118,7 @@ void URLLoaderImpl::Start(URLRequestPtr request,
|
| }
|
|
|
| url_request_ = context_->url_request_context()->CreateRequest(
|
| - GURL(request->url),
|
| - net::DEFAULT_PRIORITY,
|
| - this,
|
| - NULL);
|
| + GURL(request->url), net::DEFAULT_PRIORITY, this, nullptr);
|
| url_request_->set_method(request->method);
|
| if (request->headers) {
|
| net::HttpRequestHeaders headers;
|
| @@ -175,6 +176,11 @@ void URLLoaderImpl::QueryStatus(
|
| callback.Run(status.Pass());
|
| }
|
|
|
| +void URLLoaderImpl::OnConnectionError() {
|
| + connected_ = false;
|
| + DeleteIfNeeded();
|
| +}
|
| +
|
| void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request,
|
| const net::RedirectInfo& redirect_info,
|
| bool* defer_redirect) {
|
| @@ -193,6 +199,8 @@ void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request,
|
| response->redirect_url = String::From(redirect_info.new_url);
|
|
|
| SendResponse(response.Pass());
|
| +
|
| + DeleteIfNeeded();
|
| }
|
|
|
| void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) {
|
| @@ -201,6 +209,7 @@ void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) {
|
| if (!url_request->status().is_success()) {
|
| SendError(url_request->status().error(), callback_);
|
| callback_ = Callback<void(URLResponsePtr)>();
|
| + DeleteIfNeeded();
|
| return;
|
| }
|
|
|
| @@ -212,6 +221,7 @@ void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) {
|
| URLResponsePtr response = MakeURLResponse(url_request);
|
| response->body = data_pipe.consumer_handle.Pass();
|
| response_body_stream_ = data_pipe.producer_handle.Pass();
|
| + ListenForPeerClosed();
|
|
|
| SendResponse(response.Pass());
|
|
|
| @@ -226,7 +236,10 @@ void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request,
|
| if (url_request->status().is_success()) {
|
| DidRead(static_cast<uint32_t>(bytes_read), false);
|
| } else {
|
| - pending_write_ = NULL; // This closes the data pipe.
|
| + handle_watcher_.Stop();
|
| + pending_write_ = nullptr; // This closes the data pipe.
|
| + DeleteIfNeeded();
|
| + return;
|
| }
|
| }
|
|
|
| @@ -248,9 +261,18 @@ void URLLoaderImpl::SendResponse(URLResponsePtr response) {
|
|
|
| void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) {
|
| // TODO(darin): Handle a bad |result| value.
|
| +
|
| + // Continue watching the handle in case the peer is closed.
|
| + ListenForPeerClosed();
|
| ReadMore();
|
| }
|
|
|
| +void URLLoaderImpl::OnResponseBodyStreamClosed(MojoResult result) {
|
| + response_body_stream_.reset();
|
| + pending_write_ = nullptr;
|
| + DeleteIfNeeded();
|
| +}
|
| +
|
| void URLLoaderImpl::ReadMore() {
|
| DCHECK(!pending_write_.get());
|
|
|
| @@ -261,14 +283,16 @@ void URLLoaderImpl::ReadMore() {
|
| if (result == MOJO_RESULT_SHOULD_WAIT) {
|
| // The pipe is full. We need to wait for it to have more space.
|
| handle_watcher_.Start(response_body_stream_.get(),
|
| - MOJO_HANDLE_SIGNAL_WRITABLE,
|
| - MOJO_DEADLINE_INDEFINITE,
|
| + MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE,
|
| base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady,
|
| - weak_ptr_factory_.GetWeakPtr()));
|
| + base::Unretained(this)));
|
| return;
|
| } else if (result != MOJO_RESULT_OK) {
|
| // The response body stream is in a bad state. Bail.
|
| // TODO(darin): How should this be communicated to our client?
|
| + handle_watcher_.Stop();
|
| + response_body_stream_.reset();
|
| + DeleteIfNeeded();
|
| return;
|
| }
|
| CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes);
|
| @@ -282,8 +306,11 @@ void URLLoaderImpl::ReadMore() {
|
| } else if (url_request_->status().is_success() && bytes_read > 0) {
|
| DidRead(static_cast<uint32_t>(bytes_read), true);
|
| } else {
|
| + handle_watcher_.Stop();
|
| pending_write_->Complete(0);
|
| - pending_write_ = NULL; // This closes the data pipe.
|
| + pending_write_ = nullptr; // This closes the data pipe.
|
| + DeleteIfNeeded();
|
| + return;
|
| }
|
| }
|
|
|
| @@ -291,7 +318,7 @@ void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) {
|
| DCHECK(url_request_->status().is_success());
|
|
|
| response_body_stream_ = pending_write_->Complete(num_bytes);
|
| - pending_write_ = NULL;
|
| + pending_write_ = nullptr;
|
|
|
| if (completed_synchronously) {
|
| base::MessageLoop::current()->PostTask(
|
| @@ -302,4 +329,18 @@ void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) {
|
| }
|
| }
|
|
|
| +void URLLoaderImpl::DeleteIfNeeded() {
|
| + bool has_data_pipe = pending_write_.get() || response_body_stream_.is_valid();
|
| + if (!connected_ && !has_data_pipe)
|
| + delete this;
|
| +}
|
| +
|
| +void URLLoaderImpl::ListenForPeerClosed() {
|
| + handle_watcher_.Start(response_body_stream_.get(),
|
| + MOJO_HANDLE_SIGNAL_PEER_CLOSED,
|
| + MOJO_DEADLINE_INDEFINITE,
|
| + base::Bind(&URLLoaderImpl::OnResponseBodyStreamClosed,
|
| + base::Unretained(this)));
|
| +}
|
| +
|
| } // namespace mojo
|
|
|