| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/services/network/url_loader_impl.h" | 5 #include "mojo/services/network/url_loader_impl.h" |
| 6 | 6 |
| 7 #include <utility> |
| 7 #include <vector> | 8 #include <vector> |
| 8 | 9 |
| 9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 11 #include "mojo/common/common_type_converters.h" | 12 #include "mojo/common/common_type_converters.h" |
| 12 #include "mojo/common/url_type_converters.h" | 13 #include "mojo/common/url_type_converters.h" |
| 13 #include "mojo/services/network/net_adapters.h" | 14 #include "mojo/services/network/net_adapters.h" |
| 14 #include "mojo/services/network/network_context.h" | 15 #include "mojo/services/network/network_context.h" |
| 15 #include "net/base/elements_upload_data_stream.h" | 16 #include "net/base/elements_upload_data_stream.h" |
| 16 #include "net/base/io_buffer.h" | 17 #include "net/base/io_buffer.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 response->status_line = headers->GetStatusLine(); | 72 response->status_line = headers->GetStatusLine(); |
| 72 | 73 |
| 73 response->headers = Array<HttpHeaderPtr>::New(0); | 74 response->headers = Array<HttpHeaderPtr>::New(0); |
| 74 std::vector<String> header_lines; | 75 std::vector<String> header_lines; |
| 75 void* iter = nullptr; | 76 void* iter = nullptr; |
| 76 std::string name, value; | 77 std::string name, value; |
| 77 while (headers->EnumerateHeaderLines(&iter, &name, &value)) { | 78 while (headers->EnumerateHeaderLines(&iter, &name, &value)) { |
| 78 HttpHeaderPtr header = HttpHeader::New(); | 79 HttpHeaderPtr header = HttpHeader::New(); |
| 79 header->name = name; | 80 header->name = name; |
| 80 header->value = value; | 81 header->value = value; |
| 81 response->headers.push_back(header.Pass()); | 82 response->headers.push_back(std::move(header)); |
| 82 } | 83 } |
| 83 } | 84 } |
| 84 | 85 |
| 85 std::string mime_type; | 86 std::string mime_type; |
| 86 url_request->GetMimeType(&mime_type); | 87 url_request->GetMimeType(&mime_type); |
| 87 response->mime_type = mime_type; | 88 response->mime_type = mime_type; |
| 88 | 89 |
| 89 std::string charset; | 90 std::string charset; |
| 90 url_request->GetCharset(&charset); | 91 url_request->GetCharset(&charset); |
| 91 response->charset = charset; | 92 response->charset = charset; |
| 92 | 93 |
| 93 return response.Pass(); | 94 return response; |
| 94 } | 95 } |
| 95 | 96 |
| 96 // Reads the request body upload data from a DataPipe. | 97 // Reads the request body upload data from a DataPipe. |
| 97 class UploadDataPipeElementReader : public net::UploadElementReader { | 98 class UploadDataPipeElementReader : public net::UploadElementReader { |
| 98 public: | 99 public: |
| 99 UploadDataPipeElementReader(ScopedDataPipeConsumerHandle pipe) | 100 UploadDataPipeElementReader(ScopedDataPipeConsumerHandle pipe) |
| 100 : pipe_(pipe.Pass()), num_bytes_(0) {} | 101 : pipe_(std::move(pipe)), num_bytes_(0) {} |
| 101 ~UploadDataPipeElementReader() override {} | 102 ~UploadDataPipeElementReader() override {} |
| 102 | 103 |
| 103 // UploadElementReader overrides: | 104 // UploadElementReader overrides: |
| 104 int Init(const net::CompletionCallback& callback) override { | 105 int Init(const net::CompletionCallback& callback) override { |
| 105 offset_ = 0; | 106 offset_ = 0; |
| 106 ReadDataRaw(pipe_.get(), nullptr, &num_bytes_, MOJO_READ_DATA_FLAG_QUERY); | 107 ReadDataRaw(pipe_.get(), nullptr, &num_bytes_, MOJO_READ_DATA_FLAG_QUERY); |
| 107 return net::OK; | 108 return net::OK; |
| 108 } | 109 } |
| 109 uint64 GetContentLength() const override { return num_bytes_; } | 110 uint64 GetContentLength() const override { return num_bytes_; } |
| 110 uint64 BytesRemaining() const override { return num_bytes_ - offset_; } | 111 uint64 BytesRemaining() const override { return num_bytes_ - offset_; } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 135 } // namespace | 136 } // namespace |
| 136 | 137 |
| 137 URLLoaderImpl::URLLoaderImpl(NetworkContext* context, | 138 URLLoaderImpl::URLLoaderImpl(NetworkContext* context, |
| 138 InterfaceRequest<URLLoader> request, | 139 InterfaceRequest<URLLoader> request, |
| 139 scoped_ptr<mojo::AppRefCount> app_refcount) | 140 scoped_ptr<mojo::AppRefCount> app_refcount) |
| 140 : context_(context), | 141 : context_(context), |
| 141 response_body_buffer_size_(0), | 142 response_body_buffer_size_(0), |
| 142 response_body_bytes_read_(0), | 143 response_body_bytes_read_(0), |
| 143 auto_follow_redirects_(true), | 144 auto_follow_redirects_(true), |
| 144 connected_(true), | 145 connected_(true), |
| 145 binding_(this, request.Pass()), | 146 binding_(this, std::move(request)), |
| 146 app_refcount_(app_refcount.Pass()), | 147 app_refcount_(std::move(app_refcount)), |
| 147 weak_ptr_factory_(this) { | 148 weak_ptr_factory_(this) { |
| 148 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); | 149 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); |
| 149 context_->RegisterURLLoader(this); | 150 context_->RegisterURLLoader(this); |
| 150 } | 151 } |
| 151 | 152 |
| 152 URLLoaderImpl::~URLLoaderImpl() { | 153 URLLoaderImpl::~URLLoaderImpl() { |
| 153 context_->DeregisterURLLoader(this); | 154 context_->DeregisterURLLoader(this); |
| 154 } | 155 } |
| 155 | 156 |
| 156 void URLLoaderImpl::Cleanup() { | 157 void URLLoaderImpl::Cleanup() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } else { | 190 } else { |
| 190 headers.SetHeader(header, value); | 191 headers.SetHeader(header, value); |
| 191 } | 192 } |
| 192 } | 193 } |
| 193 url_request_->SetExtraRequestHeaders(headers); | 194 url_request_->SetExtraRequestHeaders(headers); |
| 194 } | 195 } |
| 195 if (request->body) { | 196 if (request->body) { |
| 196 std::vector<scoped_ptr<net::UploadElementReader>> element_readers; | 197 std::vector<scoped_ptr<net::UploadElementReader>> element_readers; |
| 197 for (size_t i = 0; i < request->body.size(); ++i) { | 198 for (size_t i = 0; i < request->body.size(); ++i) { |
| 198 element_readers.push_back(make_scoped_ptr( | 199 element_readers.push_back(make_scoped_ptr( |
| 199 new UploadDataPipeElementReader(request->body[i].Pass()))); | 200 new UploadDataPipeElementReader(std::move(request->body[i])))); |
| 200 } | 201 } |
| 201 url_request_->set_upload(make_scoped_ptr<net::UploadDataStream>( | 202 url_request_->set_upload(make_scoped_ptr<net::UploadDataStream>( |
| 202 new net::ElementsUploadDataStream(std::move(element_readers), 0))); | 203 new net::ElementsUploadDataStream(std::move(element_readers), 0))); |
| 203 } | 204 } |
| 204 if (request->bypass_cache) | 205 if (request->bypass_cache) |
| 205 url_request_->SetLoadFlags(net::LOAD_BYPASS_CACHE); | 206 url_request_->SetLoadFlags(net::LOAD_BYPASS_CACHE); |
| 206 | 207 |
| 207 callback_ = callback; | 208 callback_ = callback; |
| 208 response_body_buffer_size_ = request->response_body_buffer_size; | 209 response_body_buffer_size_ = request->response_body_buffer_size; |
| 209 auto_follow_redirects_ = request->auto_follow_redirects; | 210 auto_follow_redirects_ = request->auto_follow_redirects; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 238 if (!url_request_->status().is_success()) | 239 if (!url_request_->status().is_success()) |
| 239 status->error = MakeNetworkError(url_request_->status().error()); | 240 status->error = MakeNetworkError(url_request_->status().error()); |
| 240 if (url_request_->response_info().headers) { | 241 if (url_request_->response_info().headers) { |
| 241 status->content_length = | 242 status->content_length = |
| 242 url_request_->response_info().headers->GetContentLength(); | 243 url_request_->response_info().headers->GetContentLength(); |
| 243 } | 244 } |
| 244 } else { | 245 } else { |
| 245 status->is_loading = false; | 246 status->is_loading = false; |
| 246 } | 247 } |
| 247 // TODO(darin): Populate more status fields. | 248 // TODO(darin): Populate more status fields. |
| 248 callback.Run(status.Pass()); | 249 callback.Run(std::move(status)); |
| 249 } | 250 } |
| 250 | 251 |
| 251 void URLLoaderImpl::OnConnectionError() { | 252 void URLLoaderImpl::OnConnectionError() { |
| 252 connected_ = false; | 253 connected_ = false; |
| 253 DeleteIfNeeded(); | 254 DeleteIfNeeded(); |
| 254 } | 255 } |
| 255 | 256 |
| 256 void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request, | 257 void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request, |
| 257 const net::RedirectInfo& redirect_info, | 258 const net::RedirectInfo& redirect_info, |
| 258 bool* defer_redirect) { | 259 bool* defer_redirect) { |
| 259 DCHECK(url_request == url_request_.get()); | 260 DCHECK(url_request == url_request_.get()); |
| 260 DCHECK(url_request->status().is_success()); | 261 DCHECK(url_request->status().is_success()); |
| 261 | 262 |
| 262 if (auto_follow_redirects_) | 263 if (auto_follow_redirects_) |
| 263 return; | 264 return; |
| 264 | 265 |
| 265 // Send the redirect response to the client, allowing them to inspect it and | 266 // Send the redirect response to the client, allowing them to inspect it and |
| 266 // optionally follow the redirect. | 267 // optionally follow the redirect. |
| 267 *defer_redirect = true; | 268 *defer_redirect = true; |
| 268 | 269 |
| 269 URLResponsePtr response = MakeURLResponse(url_request); | 270 URLResponsePtr response = MakeURLResponse(url_request); |
| 270 response->redirect_method = redirect_info.new_method; | 271 response->redirect_method = redirect_info.new_method; |
| 271 response->redirect_url = String::From(redirect_info.new_url); | 272 response->redirect_url = String::From(redirect_info.new_url); |
| 272 response->redirect_referrer = redirect_info.new_referrer; | 273 response->redirect_referrer = redirect_info.new_referrer; |
| 273 | 274 |
| 274 SendResponse(response.Pass()); | 275 SendResponse(std::move(response)); |
| 275 | 276 |
| 276 DeleteIfNeeded(); | 277 DeleteIfNeeded(); |
| 277 } | 278 } |
| 278 | 279 |
| 279 void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) { | 280 void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) { |
| 280 DCHECK(url_request == url_request_.get()); | 281 DCHECK(url_request == url_request_.get()); |
| 281 | 282 |
| 282 if (!url_request->status().is_success()) { | 283 if (!url_request->status().is_success()) { |
| 283 SendError(url_request->status().error(), callback_); | 284 SendError(url_request->status().error(), callback_); |
| 284 callback_ = Callback<void(URLResponsePtr)>(); | 285 callback_ = Callback<void(URLResponsePtr)>(); |
| 285 DeleteIfNeeded(); | 286 DeleteIfNeeded(); |
| 286 return; | 287 return; |
| 287 } | 288 } |
| 288 | 289 |
| 289 // TODO(darin): Add support for optional MIME sniffing. | 290 // TODO(darin): Add support for optional MIME sniffing. |
| 290 | 291 |
| 291 DataPipe data_pipe; | 292 DataPipe data_pipe; |
| 292 // TODO(darin): Honor given buffer size. | 293 // TODO(darin): Honor given buffer size. |
| 293 | 294 |
| 294 URLResponsePtr response = MakeURLResponse(url_request); | 295 URLResponsePtr response = MakeURLResponse(url_request); |
| 295 response->body = data_pipe.consumer_handle.Pass(); | 296 response->body = std::move(data_pipe.consumer_handle); |
| 296 response_body_stream_ = data_pipe.producer_handle.Pass(); | 297 response_body_stream_ = std::move(data_pipe.producer_handle); |
| 297 ListenForPeerClosed(); | 298 ListenForPeerClosed(); |
| 298 | 299 |
| 299 SendResponse(response.Pass()); | 300 SendResponse(std::move(response)); |
| 300 | 301 |
| 301 // Start reading... | 302 // Start reading... |
| 302 ReadMore(); | 303 ReadMore(); |
| 303 } | 304 } |
| 304 | 305 |
| 305 void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request, | 306 void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request, |
| 306 int bytes_read) { | 307 int bytes_read) { |
| 307 DCHECK(url_request == url_request_.get()); | 308 DCHECK(url_request == url_request_.get()); |
| 308 | 309 |
| 309 if (url_request->status().is_success()) { | 310 if (url_request->status().is_success()) { |
| 310 DidRead(static_cast<uint32_t>(bytes_read), false); | 311 DidRead(static_cast<uint32_t>(bytes_read), false); |
| 311 } else { | 312 } else { |
| 312 handle_watcher_.Stop(); | 313 handle_watcher_.Stop(); |
| 313 pending_write_ = nullptr; // This closes the data pipe. | 314 pending_write_ = nullptr; // This closes the data pipe. |
| 314 DeleteIfNeeded(); | 315 DeleteIfNeeded(); |
| 315 return; | 316 return; |
| 316 } | 317 } |
| 317 } | 318 } |
| 318 | 319 |
| 319 void URLLoaderImpl::SendError( | 320 void URLLoaderImpl::SendError( |
| 320 int error_code, | 321 int error_code, |
| 321 const Callback<void(URLResponsePtr)>& callback) { | 322 const Callback<void(URLResponsePtr)>& callback) { |
| 322 URLResponsePtr response(URLResponse::New()); | 323 URLResponsePtr response(URLResponse::New()); |
| 323 if (url_request_) | 324 if (url_request_) |
| 324 response->url = String::From(url_request_->url()); | 325 response->url = String::From(url_request_->url()); |
| 325 response->error = MakeNetworkError(error_code); | 326 response->error = MakeNetworkError(error_code); |
| 326 callback.Run(response.Pass()); | 327 callback.Run(std::move(response)); |
| 327 } | 328 } |
| 328 | 329 |
| 329 void URLLoaderImpl::SendResponse(URLResponsePtr response) { | 330 void URLLoaderImpl::SendResponse(URLResponsePtr response) { |
| 330 Callback<void(URLResponsePtr)> callback; | 331 Callback<void(URLResponsePtr)> callback; |
| 331 std::swap(callback_, callback); | 332 std::swap(callback_, callback); |
| 332 callback.Run(response.Pass()); | 333 callback.Run(std::move(response)); |
| 333 } | 334 } |
| 334 | 335 |
| 335 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { | 336 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { |
| 336 // TODO(darin): Handle a bad |result| value. | 337 // TODO(darin): Handle a bad |result| value. |
| 337 | 338 |
| 338 // Continue watching the handle in case the peer is closed. | 339 // Continue watching the handle in case the peer is closed. |
| 339 ListenForPeerClosed(); | 340 ListenForPeerClosed(); |
| 340 ReadMore(); | 341 ReadMore(); |
| 341 } | 342 } |
| 342 | 343 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 | 413 |
| 413 void URLLoaderImpl::ListenForPeerClosed() { | 414 void URLLoaderImpl::ListenForPeerClosed() { |
| 414 handle_watcher_.Start(response_body_stream_.get(), | 415 handle_watcher_.Start(response_body_stream_.get(), |
| 415 MOJO_HANDLE_SIGNAL_PEER_CLOSED, | 416 MOJO_HANDLE_SIGNAL_PEER_CLOSED, |
| 416 MOJO_DEADLINE_INDEFINITE, | 417 MOJO_DEADLINE_INDEFINITE, |
| 417 base::Bind(&URLLoaderImpl::OnResponseBodyStreamClosed, | 418 base::Bind(&URLLoaderImpl::OnResponseBodyStreamClosed, |
| 418 base::Unretained(this))); | 419 base::Unretained(this))); |
| 419 } | 420 } |
| 420 | 421 |
| 421 } // namespace mojo | 422 } // namespace mojo |
| OLD | NEW |