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 |