Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: mojo/services/network/url_loader_impl.cc

Issue 858093002: Update the network service from the Mojo repo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/memory/scoped_vector.h" 7 #include "base/memory/scoped_vector.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "mojo/common/common_type_converters.h" 9 #include "mojo/common/common_type_converters.h"
10 #include "mojo/services/network/net_adapters.h" 10 #include "mojo/services/network/net_adapters.h"
(...skipping 13 matching lines...) Expand all
24 URLResponsePtr MakeURLResponse(const net::URLRequest* url_request) { 24 URLResponsePtr MakeURLResponse(const net::URLRequest* url_request) {
25 URLResponsePtr response(URLResponse::New()); 25 URLResponsePtr response(URLResponse::New());
26 response->url = String::From(url_request->url()); 26 response->url = String::From(url_request->url());
27 27
28 const net::HttpResponseHeaders* headers = url_request->response_headers(); 28 const net::HttpResponseHeaders* headers = url_request->response_headers();
29 if (headers) { 29 if (headers) {
30 response->status_code = headers->response_code(); 30 response->status_code = headers->response_code();
31 response->status_line = headers->GetStatusLine(); 31 response->status_line = headers->GetStatusLine();
32 32
33 std::vector<String> header_lines; 33 std::vector<String> header_lines;
34 void* iter = NULL; 34 void* iter = nullptr;
35 std::string name, value; 35 std::string name, value;
36 while (headers->EnumerateHeaderLines(&iter, &name, &value)) 36 while (headers->EnumerateHeaderLines(&iter, &name, &value))
37 header_lines.push_back(name + ": " + value); 37 header_lines.push_back(name + ": " + value);
38 if (!header_lines.empty()) 38 if (!header_lines.empty())
39 response->headers.Swap(&header_lines); 39 response->headers.Swap(&header_lines);
40 } 40 }
41 41
42 std::string mime_type; 42 std::string mime_type;
43 url_request->GetMimeType(&mime_type); 43 url_request->GetMimeType(&mime_type);
44 response->mime_type = mime_type; 44 response->mime_type = mime_type;
45 45
46 std::string charset; 46 std::string charset;
47 url_request->GetCharset(&charset); 47 url_request->GetCharset(&charset);
48 response->charset = charset; 48 response->charset = charset;
49 49
50 return response.Pass(); 50 return response.Pass();
51 } 51 }
52 52
53 // Reads the request body upload data from a DataPipe. 53 // Reads the request body upload data from a DataPipe.
54 class UploadDataPipeElementReader : public net::UploadElementReader { 54 class UploadDataPipeElementReader : public net::UploadElementReader {
55 public: 55 public:
56 UploadDataPipeElementReader(ScopedDataPipeConsumerHandle pipe) 56 UploadDataPipeElementReader(ScopedDataPipeConsumerHandle pipe)
57 : pipe_(pipe.Pass()), num_bytes_(0) {} 57 : pipe_(pipe.Pass()), num_bytes_(0) {}
58 ~UploadDataPipeElementReader() override {} 58 ~UploadDataPipeElementReader() override {}
59 59
60 // UploadElementReader overrides: 60 // UploadElementReader overrides:
61 int Init(const net::CompletionCallback& callback) override { 61 int Init(const net::CompletionCallback& callback) override {
62 offset_ = 0; 62 offset_ = 0;
63 ReadDataRaw(pipe_.get(), NULL, &num_bytes_, MOJO_READ_DATA_FLAG_QUERY); 63 ReadDataRaw(pipe_.get(), nullptr, &num_bytes_, MOJO_READ_DATA_FLAG_QUERY);
64 return net::OK; 64 return net::OK;
65 } 65 }
66 uint64 GetContentLength() const override { return num_bytes_; } 66 uint64 GetContentLength() const override { return num_bytes_; }
67 uint64 BytesRemaining() const override { return num_bytes_ - offset_; } 67 uint64 BytesRemaining() const override { return num_bytes_ - offset_; }
68 bool IsInMemory() const override { return false; } 68 bool IsInMemory() const override { return false; }
69 int Read(net::IOBuffer* buf, 69 int Read(net::IOBuffer* buf,
70 int buf_length, 70 int buf_length,
71 const net::CompletionCallback& callback) override { 71 const net::CompletionCallback& callback) override {
72 uint32_t bytes_read = 72 uint32_t bytes_read =
73 std::min(static_cast<uint32_t>(BytesRemaining()), 73 std::min(static_cast<uint32_t>(BytesRemaining()),
(...skipping 10 matching lines...) Expand all
84 private: 84 private:
85 ScopedDataPipeConsumerHandle pipe_; 85 ScopedDataPipeConsumerHandle pipe_;
86 uint32_t num_bytes_; 86 uint32_t num_bytes_;
87 uint32_t offset_; 87 uint32_t offset_;
88 88
89 DISALLOW_COPY_AND_ASSIGN(UploadDataPipeElementReader); 89 DISALLOW_COPY_AND_ASSIGN(UploadDataPipeElementReader);
90 }; 90 };
91 91
92 } // namespace 92 } // namespace
93 93
94 URLLoaderImpl::URLLoaderImpl(NetworkContext* context) 94 URLLoaderImpl::URLLoaderImpl(NetworkContext* context,
95 InterfaceRequest<URLLoader> request)
95 : context_(context), 96 : context_(context),
96 response_body_buffer_size_(0), 97 response_body_buffer_size_(0),
97 auto_follow_redirects_(true), 98 auto_follow_redirects_(true),
99 connected_(true),
100 binding_(this, request.Pass()),
98 weak_ptr_factory_(this) { 101 weak_ptr_factory_(this) {
102 binding_.set_error_handler(this);
99 } 103 }
100 104
101 URLLoaderImpl::~URLLoaderImpl() { 105 URLLoaderImpl::~URLLoaderImpl() {
102 } 106 }
103 107
104 void URLLoaderImpl::Start(URLRequestPtr request, 108 void URLLoaderImpl::Start(URLRequestPtr request,
105 const Callback<void(URLResponsePtr)>& callback) { 109 const Callback<void(URLResponsePtr)>& callback) {
106 if (url_request_) { 110 if (url_request_) {
107 SendError(net::ERR_UNEXPECTED, callback); 111 SendError(net::ERR_UNEXPECTED, callback);
108 return; 112 return;
109 } 113 }
110 114
111 if (!request) { 115 if (!request) {
112 SendError(net::ERR_INVALID_ARGUMENT, callback); 116 SendError(net::ERR_INVALID_ARGUMENT, callback);
113 return; 117 return;
114 } 118 }
115 119
116 url_request_ = context_->url_request_context()->CreateRequest( 120 url_request_ = context_->url_request_context()->CreateRequest(
117 GURL(request->url), 121 GURL(request->url), net::DEFAULT_PRIORITY, this, nullptr);
118 net::DEFAULT_PRIORITY,
119 this,
120 NULL);
121 url_request_->set_method(request->method); 122 url_request_->set_method(request->method);
122 if (request->headers) { 123 if (request->headers) {
123 net::HttpRequestHeaders headers; 124 net::HttpRequestHeaders headers;
124 for (size_t i = 0; i < request->headers.size(); ++i) 125 for (size_t i = 0; i < request->headers.size(); ++i)
125 headers.AddHeaderFromString(request->headers[i].To<base::StringPiece>()); 126 headers.AddHeaderFromString(request->headers[i].To<base::StringPiece>());
126 url_request_->SetExtraRequestHeaders(headers); 127 url_request_->SetExtraRequestHeaders(headers);
127 } 128 }
128 if (request->body) { 129 if (request->body) {
129 ScopedVector<net::UploadElementReader> element_readers; 130 ScopedVector<net::UploadElementReader> element_readers;
130 for (size_t i = 0; i < request->body.size(); ++i) { 131 for (size_t i = 0; i < request->body.size(); ++i) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 status->is_loading = url_request_->is_pending(); 169 status->is_loading = url_request_->is_pending();
169 if (!url_request_->status().is_success()) 170 if (!url_request_->status().is_success())
170 status->error = MakeNetworkError(url_request_->status().error()); 171 status->error = MakeNetworkError(url_request_->status().error());
171 } else { 172 } else {
172 status->is_loading = false; 173 status->is_loading = false;
173 } 174 }
174 // TODO(darin): Populate more status fields. 175 // TODO(darin): Populate more status fields.
175 callback.Run(status.Pass()); 176 callback.Run(status.Pass());
176 } 177 }
177 178
179 void URLLoaderImpl::OnConnectionError() {
180 connected_ = false;
181 DeleteIfNeeded();
182 }
183
178 void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request, 184 void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request,
179 const net::RedirectInfo& redirect_info, 185 const net::RedirectInfo& redirect_info,
180 bool* defer_redirect) { 186 bool* defer_redirect) {
181 DCHECK(url_request == url_request_.get()); 187 DCHECK(url_request == url_request_.get());
182 DCHECK(url_request->status().is_success()); 188 DCHECK(url_request->status().is_success());
183 189
184 if (auto_follow_redirects_) 190 if (auto_follow_redirects_)
185 return; 191 return;
186 192
187 // Send the redirect response to the client, allowing them to inspect it and 193 // Send the redirect response to the client, allowing them to inspect it and
188 // optionally follow the redirect. 194 // optionally follow the redirect.
189 *defer_redirect = true; 195 *defer_redirect = true;
190 196
191 URLResponsePtr response = MakeURLResponse(url_request); 197 URLResponsePtr response = MakeURLResponse(url_request);
192 response->redirect_method = redirect_info.new_method; 198 response->redirect_method = redirect_info.new_method;
193 response->redirect_url = String::From(redirect_info.new_url); 199 response->redirect_url = String::From(redirect_info.new_url);
194 200
195 SendResponse(response.Pass()); 201 SendResponse(response.Pass());
202
203 DeleteIfNeeded();
196 } 204 }
197 205
198 void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) { 206 void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) {
199 DCHECK(url_request == url_request_.get()); 207 DCHECK(url_request == url_request_.get());
200 208
201 if (!url_request->status().is_success()) { 209 if (!url_request->status().is_success()) {
202 SendError(url_request->status().error(), callback_); 210 SendError(url_request->status().error(), callback_);
203 callback_ = Callback<void(URLResponsePtr)>(); 211 callback_ = Callback<void(URLResponsePtr)>();
212 DeleteIfNeeded();
204 return; 213 return;
205 } 214 }
206 215
207 // TODO(darin): Add support for optional MIME sniffing. 216 // TODO(darin): Add support for optional MIME sniffing.
208 217
209 DataPipe data_pipe; 218 DataPipe data_pipe;
210 // TODO(darin): Honor given buffer size. 219 // TODO(darin): Honor given buffer size.
211 220
212 URLResponsePtr response = MakeURLResponse(url_request); 221 URLResponsePtr response = MakeURLResponse(url_request);
213 response->body = data_pipe.consumer_handle.Pass(); 222 response->body = data_pipe.consumer_handle.Pass();
214 response_body_stream_ = data_pipe.producer_handle.Pass(); 223 response_body_stream_ = data_pipe.producer_handle.Pass();
224 ListenForPeerClosed();
215 225
216 SendResponse(response.Pass()); 226 SendResponse(response.Pass());
217 227
218 // Start reading... 228 // Start reading...
219 ReadMore(); 229 ReadMore();
220 } 230 }
221 231
222 void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request, 232 void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request,
223 int bytes_read) { 233 int bytes_read) {
224 DCHECK(url_request == url_request_.get()); 234 DCHECK(url_request == url_request_.get());
225 235
226 if (url_request->status().is_success()) { 236 if (url_request->status().is_success()) {
227 DidRead(static_cast<uint32_t>(bytes_read), false); 237 DidRead(static_cast<uint32_t>(bytes_read), false);
228 } else { 238 } else {
229 pending_write_ = NULL; // This closes the data pipe. 239 handle_watcher_.Stop();
240 pending_write_ = nullptr; // This closes the data pipe.
241 DeleteIfNeeded();
242 return;
230 } 243 }
231 } 244 }
232 245
233 void URLLoaderImpl::SendError( 246 void URLLoaderImpl::SendError(
234 int error_code, 247 int error_code,
235 const Callback<void(URLResponsePtr)>& callback) { 248 const Callback<void(URLResponsePtr)>& callback) {
236 URLResponsePtr response(URLResponse::New()); 249 URLResponsePtr response(URLResponse::New());
237 if (url_request_) 250 if (url_request_)
238 response->url = String::From(url_request_->url()); 251 response->url = String::From(url_request_->url());
239 response->error = MakeNetworkError(error_code); 252 response->error = MakeNetworkError(error_code);
240 callback.Run(response.Pass()); 253 callback.Run(response.Pass());
241 } 254 }
242 255
243 void URLLoaderImpl::SendResponse(URLResponsePtr response) { 256 void URLLoaderImpl::SendResponse(URLResponsePtr response) {
244 Callback<void(URLResponsePtr)> callback; 257 Callback<void(URLResponsePtr)> callback;
245 std::swap(callback_, callback); 258 std::swap(callback_, callback);
246 callback.Run(response.Pass()); 259 callback.Run(response.Pass());
247 } 260 }
248 261
249 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { 262 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) {
250 // TODO(darin): Handle a bad |result| value. 263 // TODO(darin): Handle a bad |result| value.
264
265 // Continue watching the handle in case the peer is closed.
266 ListenForPeerClosed();
251 ReadMore(); 267 ReadMore();
252 } 268 }
253 269
270 void URLLoaderImpl::OnResponseBodyStreamClosed(MojoResult result) {
271 response_body_stream_.reset();
272 pending_write_ = nullptr;
273 DeleteIfNeeded();
274 }
275
254 void URLLoaderImpl::ReadMore() { 276 void URLLoaderImpl::ReadMore() {
255 DCHECK(!pending_write_.get()); 277 DCHECK(!pending_write_.get());
256 278
257 uint32_t num_bytes; 279 uint32_t num_bytes;
258 MojoResult result = NetToMojoPendingBuffer::BeginWrite( 280 MojoResult result = NetToMojoPendingBuffer::BeginWrite(
259 &response_body_stream_, &pending_write_, &num_bytes); 281 &response_body_stream_, &pending_write_, &num_bytes);
260 282
261 if (result == MOJO_RESULT_SHOULD_WAIT) { 283 if (result == MOJO_RESULT_SHOULD_WAIT) {
262 // The pipe is full. We need to wait for it to have more space. 284 // The pipe is full. We need to wait for it to have more space.
263 handle_watcher_.Start(response_body_stream_.get(), 285 handle_watcher_.Start(response_body_stream_.get(),
264 MOJO_HANDLE_SIGNAL_WRITABLE, 286 MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE,
265 MOJO_DEADLINE_INDEFINITE,
266 base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady, 287 base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady,
267 weak_ptr_factory_.GetWeakPtr())); 288 base::Unretained(this)));
268 return; 289 return;
269 } else if (result != MOJO_RESULT_OK) { 290 } else if (result != MOJO_RESULT_OK) {
270 // The response body stream is in a bad state. Bail. 291 // The response body stream is in a bad state. Bail.
271 // TODO(darin): How should this be communicated to our client? 292 // TODO(darin): How should this be communicated to our client?
293 handle_watcher_.Stop();
294 response_body_stream_.reset();
295 DeleteIfNeeded();
272 return; 296 return;
273 } 297 }
274 CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes); 298 CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes);
275 299
276 scoped_refptr<net::IOBuffer> buf(new NetToMojoIOBuffer(pending_write_.get())); 300 scoped_refptr<net::IOBuffer> buf(new NetToMojoIOBuffer(pending_write_.get()));
277 301
278 int bytes_read; 302 int bytes_read;
279 url_request_->Read(buf.get(), static_cast<int>(num_bytes), &bytes_read); 303 url_request_->Read(buf.get(), static_cast<int>(num_bytes), &bytes_read);
280 if (url_request_->status().is_io_pending()) { 304 if (url_request_->status().is_io_pending()) {
281 // Wait for OnReadCompleted. 305 // Wait for OnReadCompleted.
282 } else if (url_request_->status().is_success() && bytes_read > 0) { 306 } else if (url_request_->status().is_success() && bytes_read > 0) {
283 DidRead(static_cast<uint32_t>(bytes_read), true); 307 DidRead(static_cast<uint32_t>(bytes_read), true);
284 } else { 308 } else {
309 handle_watcher_.Stop();
285 pending_write_->Complete(0); 310 pending_write_->Complete(0);
286 pending_write_ = NULL; // This closes the data pipe. 311 pending_write_ = nullptr; // This closes the data pipe.
312 DeleteIfNeeded();
313 return;
287 } 314 }
288 } 315 }
289 316
290 void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) { 317 void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) {
291 DCHECK(url_request_->status().is_success()); 318 DCHECK(url_request_->status().is_success());
292 319
293 response_body_stream_ = pending_write_->Complete(num_bytes); 320 response_body_stream_ = pending_write_->Complete(num_bytes);
294 pending_write_ = NULL; 321 pending_write_ = nullptr;
295 322
296 if (completed_synchronously) { 323 if (completed_synchronously) {
297 base::MessageLoop::current()->PostTask( 324 base::MessageLoop::current()->PostTask(
298 FROM_HERE, 325 FROM_HERE,
299 base::Bind(&URLLoaderImpl::ReadMore, weak_ptr_factory_.GetWeakPtr())); 326 base::Bind(&URLLoaderImpl::ReadMore, weak_ptr_factory_.GetWeakPtr()));
300 } else { 327 } else {
301 ReadMore(); 328 ReadMore();
302 } 329 }
303 } 330 }
304 331
332 void URLLoaderImpl::DeleteIfNeeded() {
333 bool has_data_pipe = pending_write_.get() || response_body_stream_.is_valid();
334 if (!connected_ && !has_data_pipe)
335 delete this;
336 }
337
338 void URLLoaderImpl::ListenForPeerClosed() {
339 handle_watcher_.Start(response_body_stream_.get(),
340 MOJO_HANDLE_SIGNAL_PEER_CLOSED,
341 MOJO_DEADLINE_INDEFINITE,
342 base::Bind(&URLLoaderImpl::OnResponseBodyStreamClosed,
343 base::Unretained(this)));
344 }
345
305 } // namespace mojo 346 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/network/url_loader_impl.h ('k') | mojo/services/network/url_loader_impl_apptest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698