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

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

Issue 649783002: Add mojo <--> net IO adapters. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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"
11 #include "mojo/services/network/network_context.h" 11 #include "mojo/services/network/network_context.h"
12 #include "net/base/io_buffer.h" 12 #include "net/base/io_buffer.h"
13 #include "net/base/load_flags.h" 13 #include "net/base/load_flags.h"
14 #include "net/base/upload_bytes_element_reader.h" 14 #include "net/base/upload_bytes_element_reader.h"
15 #include "net/base/upload_data_stream.h" 15 #include "net/base/upload_data_stream.h"
16 #include "net/http/http_response_headers.h" 16 #include "net/http/http_response_headers.h"
17 #include "net/url_request/redirect_info.h" 17 #include "net/url_request/redirect_info.h"
18 #include "net/url_request/url_request_context.h" 18 #include "net/url_request/url_request_context.h"
19 19
20 namespace mojo { 20 namespace mojo {
21 namespace { 21 namespace {
22 22
23 const uint32_t kMaxReadSize = 64 * 1024;
24
25 // Generates an URLResponsePtr from the response state of a net::URLRequest. 23 // Generates an URLResponsePtr from the response state of a net::URLRequest.
26 URLResponsePtr MakeURLResponse(const net::URLRequest* url_request) { 24 URLResponsePtr MakeURLResponse(const net::URLRequest* url_request) {
27 URLResponsePtr response(URLResponse::New()); 25 URLResponsePtr response(URLResponse::New());
28 response->url = String::From(url_request->url()); 26 response->url = String::From(url_request->url());
29 27
30 const net::HttpResponseHeaders* headers = url_request->response_headers(); 28 const net::HttpResponseHeaders* headers = url_request->response_headers();
31 if (headers) { 29 if (headers) {
32 response->status_code = headers->response_code(); 30 response->status_code = headers->response_code();
33 response->status_line = headers->GetStatusLine(); 31 response->status_line = headers->GetStatusLine();
34 32
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 private: 90 private:
93 ScopedDataPipeConsumerHandle pipe_; 91 ScopedDataPipeConsumerHandle pipe_;
94 uint32_t num_bytes_; 92 uint32_t num_bytes_;
95 uint32_t offset_; 93 uint32_t offset_;
96 94
97 DISALLOW_COPY_AND_ASSIGN(UploadDataPipeElementReader); 95 DISALLOW_COPY_AND_ASSIGN(UploadDataPipeElementReader);
98 }; 96 };
99 97
100 } // namespace 98 } // namespace
101 99
102 // Keeps track of a pending two-phase write on a DataPipeProducerHandle.
103 class URLLoaderImpl::PendingWriteToDataPipe :
104 public base::RefCountedThreadSafe<PendingWriteToDataPipe> {
105 public:
106 explicit PendingWriteToDataPipe(ScopedDataPipeProducerHandle handle)
107 : handle_(handle.Pass()),
108 buffer_(NULL) {
109 }
110
111 MojoResult BeginWrite(uint32_t* num_bytes) {
112 MojoResult result = BeginWriteDataRaw(handle_.get(), &buffer_, num_bytes,
113 MOJO_WRITE_DATA_FLAG_NONE);
114 if (*num_bytes > kMaxReadSize)
115 *num_bytes = kMaxReadSize;
116
117 return result;
118 }
119
120 ScopedDataPipeProducerHandle Complete(uint32_t num_bytes) {
121 EndWriteDataRaw(handle_.get(), num_bytes);
122 buffer_ = NULL;
123 return handle_.Pass();
124 }
125
126 char* buffer() { return static_cast<char*>(buffer_); }
127
128 private:
129 friend class base::RefCountedThreadSafe<PendingWriteToDataPipe>;
130
131 ~PendingWriteToDataPipe() {
132 if (handle_.is_valid())
133 EndWriteDataRaw(handle_.get(), 0);
134 }
135
136 ScopedDataPipeProducerHandle handle_;
137 void* buffer_;
138
139 DISALLOW_COPY_AND_ASSIGN(PendingWriteToDataPipe);
140 };
141
142 // Takes ownership of a pending two-phase write on a DataPipeProducerHandle,
143 // and makes its buffer available as a net::IOBuffer.
144 class URLLoaderImpl::DependentIOBuffer : public net::WrappedIOBuffer {
145 public:
146 DependentIOBuffer(PendingWriteToDataPipe* pending_write)
147 : net::WrappedIOBuffer(pending_write->buffer()),
148 pending_write_(pending_write) {
149 }
150 private:
151 virtual ~DependentIOBuffer() {}
152 scoped_refptr<PendingWriteToDataPipe> pending_write_;
153 };
154
155 URLLoaderImpl::URLLoaderImpl(NetworkContext* context) 100 URLLoaderImpl::URLLoaderImpl(NetworkContext* context)
156 : context_(context), 101 : context_(context),
157 response_body_buffer_size_(0), 102 response_body_buffer_size_(0),
158 auto_follow_redirects_(true), 103 auto_follow_redirects_(true),
159 weak_ptr_factory_(this) { 104 weak_ptr_factory_(this) {
160 } 105 }
161 106
162 URLLoaderImpl::~URLLoaderImpl() { 107 URLLoaderImpl::~URLLoaderImpl() {
163 } 108 }
164 109
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 Callback<void(URLResponsePtr)> callback; 250 Callback<void(URLResponsePtr)> callback;
306 std::swap(callback_, callback); 251 std::swap(callback_, callback);
307 callback.Run(response.Pass()); 252 callback.Run(response.Pass());
308 } 253 }
309 254
310 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { 255 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) {
311 // TODO(darin): Handle a bad |result| value. 256 // TODO(darin): Handle a bad |result| value.
312 ReadMore(); 257 ReadMore();
313 } 258 }
314 259
315 void URLLoaderImpl::WaitToReadMore() {
316 handle_watcher_.Start(response_body_stream_.get(),
317 MOJO_HANDLE_SIGNAL_WRITABLE,
318 MOJO_DEADLINE_INDEFINITE,
319 base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady,
320 weak_ptr_factory_.GetWeakPtr()));
321 }
322
323 void URLLoaderImpl::ReadMore() { 260 void URLLoaderImpl::ReadMore() {
324 DCHECK(!pending_write_.get()); 261 DCHECK(!pending_write_.get());
325 262
326 pending_write_ = new PendingWriteToDataPipe(response_body_stream_.Pass()); 263 uint32_t num_bytes;
264 MojoResult result = NetToMojoPendingBuffer::BeginWrite(
265 &response_body_stream_, &pending_write_, &num_bytes);
327 266
328 uint32_t num_bytes;
329 MojoResult result = pending_write_->BeginWrite(&num_bytes);
330 if (result == MOJO_RESULT_SHOULD_WAIT) { 267 if (result == MOJO_RESULT_SHOULD_WAIT) {
331 // The pipe is full. We need to wait for it to have more space. 268 // The pipe is full. We need to wait for it to have more space.
332 response_body_stream_ = pending_write_->Complete(num_bytes); 269 handle_watcher_.Start(response_body_stream_.get(),
333 pending_write_ = NULL; 270 MOJO_HANDLE_SIGNAL_WRITABLE,
334 WaitToReadMore(); 271 MOJO_DEADLINE_INDEFINITE,
272 base::Bind(&URLLoaderImpl::OnResponseBodyStreamReady,
273 weak_ptr_factory_.GetWeakPtr()));
335 return; 274 return;
336 } 275 } else if (result != MOJO_RESULT_OK) {
337 if (result != MOJO_RESULT_OK) {
338 // The response body stream is in a bad state. Bail. 276 // The response body stream is in a bad state. Bail.
339 // TODO(darin): How should this be communicated to our client? 277 // TODO(darin): How should this be communicated to our client?
340 return; 278 return;
341 } 279 }
342 CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes); 280 CHECK_GT(static_cast<uint32_t>(std::numeric_limits<int>::max()), num_bytes);
343 281
344 scoped_refptr<net::IOBuffer> buf =
345 new DependentIOBuffer(pending_write_.get());
346
347 int bytes_read; 282 int bytes_read;
348 url_request_->Read(buf.get(), static_cast<int>(num_bytes), &bytes_read); 283 url_request_->Read(new NetToMojoIOBuffer(pending_write_.get()),
yzshen1 2014/10/10 21:19:00 This may leak the buffer, because Read() may not a
brettw 2014/10/10 22:36:59 Ooh, good catch!
349 284 static_cast<int>(num_bytes), &bytes_read);
350 // Drop our reference to the buffer.
351 buf = NULL;
352 285
353 if (url_request_->status().is_io_pending()) { 286 if (url_request_->status().is_io_pending()) {
354 // Wait for OnReadCompleted. 287 // Wait for OnReadCompleted.
355 } else if (url_request_->status().is_success() && bytes_read > 0) { 288 } else if (url_request_->status().is_success() && bytes_read > 0) {
356 DidRead(static_cast<uint32_t>(bytes_read), true); 289 DidRead(static_cast<uint32_t>(bytes_read), true);
357 } else { 290 } else {
358 pending_write_->Complete(0); 291 pending_write_->Complete(0);
359 pending_write_ = NULL; // This closes the data pipe. 292 pending_write_ = NULL; // This closes the data pipe.
360 } 293 }
361 } 294 }
362 295
363 void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) { 296 void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) {
364 DCHECK(url_request_->status().is_success()); 297 DCHECK(url_request_->status().is_success());
365 298
366 response_body_stream_ = pending_write_->Complete(num_bytes); 299 response_body_stream_ = pending_write_->Complete(num_bytes);
367 pending_write_ = NULL; 300 pending_write_ = NULL;
368 301
369 if (completed_synchronously) { 302 if (completed_synchronously) {
370 base::MessageLoop::current()->PostTask( 303 base::MessageLoop::current()->PostTask(
371 FROM_HERE, 304 FROM_HERE,
372 base::Bind(&URLLoaderImpl::ReadMore, weak_ptr_factory_.GetWeakPtr())); 305 base::Bind(&URLLoaderImpl::ReadMore, weak_ptr_factory_.GetWeakPtr()));
373 } else { 306 } else {
374 ReadMore(); 307 ReadMore();
375 } 308 }
376 } 309 }
377 310
378 } // namespace mojo 311 } // namespace mojo
OLDNEW
« mojo/services/network/net_adapters.cc ('K') | « mojo/services/network/url_loader_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698