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

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

Issue 373373002: Mojo: Refactor URLLoader interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixes per review Created 6 years, 5 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 | Annotate | Revision Log
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/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "mojo/common/common_type_converters.h" 8 #include "mojo/common/common_type_converters.h"
9 #include "mojo/services/network/network_context.h" 9 #include "mojo/services/network/network_context.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
(...skipping 28 matching lines...) Expand all
39 url_request->GetMimeType(&mime_type); 39 url_request->GetMimeType(&mime_type);
40 response->mime_type = mime_type; 40 response->mime_type = mime_type;
41 41
42 std::string charset; 42 std::string charset;
43 url_request->GetCharset(&charset); 43 url_request->GetCharset(&charset);
44 response->charset = charset; 44 response->charset = charset;
45 45
46 return response.Pass(); 46 return response.Pass();
47 } 47 }
48 48
49 NetworkErrorPtr MakeNetworkError(int error_code) {
50 NetworkErrorPtr error = NetworkError::New();
51 error->code = error_code;
52 error->description = net::ErrorToString(error_code);
53 return error.Pass();
54 }
55
49 } // namespace 56 } // namespace
50 57
51 // Keeps track of a pending two-phase write on a DataPipeProducerHandle. 58 // Keeps track of a pending two-phase write on a DataPipeProducerHandle.
52 class URLLoaderImpl::PendingWriteToDataPipe : 59 class URLLoaderImpl::PendingWriteToDataPipe :
53 public base::RefCountedThreadSafe<PendingWriteToDataPipe> { 60 public base::RefCountedThreadSafe<PendingWriteToDataPipe> {
54 public: 61 public:
55 explicit PendingWriteToDataPipe(ScopedDataPipeProducerHandle handle) 62 explicit PendingWriteToDataPipe(ScopedDataPipeProducerHandle handle)
56 : handle_(handle.Pass()), 63 : handle_(handle.Pass()),
57 buffer_(NULL) { 64 buffer_(NULL) {
58 } 65 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 : net::WrappedIOBuffer(pending_write->buffer()), 103 : net::WrappedIOBuffer(pending_write->buffer()),
97 pending_write_(pending_write) { 104 pending_write_(pending_write) {
98 } 105 }
99 private: 106 private:
100 virtual ~DependentIOBuffer() {} 107 virtual ~DependentIOBuffer() {}
101 scoped_refptr<PendingWriteToDataPipe> pending_write_; 108 scoped_refptr<PendingWriteToDataPipe> pending_write_;
102 }; 109 };
103 110
104 URLLoaderImpl::URLLoaderImpl(NetworkContext* context) 111 URLLoaderImpl::URLLoaderImpl(NetworkContext* context)
105 : context_(context), 112 : context_(context),
113 response_body_buffer_size_(0),
106 auto_follow_redirects_(true), 114 auto_follow_redirects_(true),
107 weak_ptr_factory_(this) { 115 weak_ptr_factory_(this) {
108 } 116 }
109 117
110 URLLoaderImpl::~URLLoaderImpl() { 118 URLLoaderImpl::~URLLoaderImpl() {
111 } 119 }
112 120
113 void URLLoaderImpl::OnConnectionError() { 121 void URLLoaderImpl::OnConnectionError() {
114 delete this; 122 delete this;
115 } 123 }
116 124
117 void URLLoaderImpl::Start(URLRequestPtr request, 125 void URLLoaderImpl::Start(URLRequestPtr request,
118 ScopedDataPipeProducerHandle response_body_stream) { 126 const Callback<void(URLResponsePtr)>& callback) {
119 // Do not allow starting another request.
120 if (url_request_) { 127 if (url_request_) {
121 SendError(net::ERR_UNEXPECTED); 128 SendError(net::ERR_UNEXPECTED, callback);
122 url_request_.reset();
123 response_body_stream_.reset();
124 return; 129 return;
125 } 130 }
126 131
127 if (!request) { 132 if (!request) {
128 SendError(net::ERR_INVALID_ARGUMENT); 133 SendError(net::ERR_INVALID_ARGUMENT, callback);
129 return; 134 return;
130 } 135 }
131 136
132 response_body_stream_ = response_body_stream.Pass();
133
134 GURL url(request->url);
135 url_request_.reset( 137 url_request_.reset(
136 new net::URLRequest(url, 138 new net::URLRequest(GURL(request->url),
137 net::DEFAULT_PRIORITY, 139 net::DEFAULT_PRIORITY,
138 this, 140 this,
139 context_->url_request_context())); 141 context_->url_request_context()));
140 url_request_->set_method(request->method); 142 url_request_->set_method(request->method);
141 if (request->headers) { 143 if (request->headers) {
142 net::HttpRequestHeaders headers; 144 net::HttpRequestHeaders headers;
143 for (size_t i = 0; i < request->headers.size(); ++i) 145 for (size_t i = 0; i < request->headers.size(); ++i)
144 headers.AddHeaderFromString(request->headers[i].To<base::StringPiece>()); 146 headers.AddHeaderFromString(request->headers[i].To<base::StringPiece>());
145 url_request_->SetExtraRequestHeaders(headers); 147 url_request_->SetExtraRequestHeaders(headers);
146 } 148 }
147 if (request->bypass_cache) 149 if (request->bypass_cache)
148 url_request_->SetLoadFlags(net::LOAD_BYPASS_CACHE); 150 url_request_->SetLoadFlags(net::LOAD_BYPASS_CACHE);
149 // TODO(darin): Handle request body. 151 // TODO(darin): Handle request body.
150 152
153 callback_ = callback;
154 response_body_buffer_size_ = request->response_body_buffer_size;
151 auto_follow_redirects_ = request->auto_follow_redirects; 155 auto_follow_redirects_ = request->auto_follow_redirects;
152 156
153 url_request_->Start(); 157 url_request_->Start();
154 } 158 }
155 159
156 void URLLoaderImpl::FollowRedirect() { 160 void URLLoaderImpl::FollowRedirect(
161 const Callback<void(URLResponsePtr)>& callback) {
162 if (!url_request_) {
163 SendError(net::ERR_UNEXPECTED, callback);
164 return;
165 }
166
157 if (auto_follow_redirects_) { 167 if (auto_follow_redirects_) {
158 DLOG(ERROR) << "Spurious call to FollowRedirect"; 168 DLOG(ERROR) << "Spurious call to FollowRedirect";
169 SendError(net::ERR_UNEXPECTED, callback);
170 return;
171 }
172
173 // TODO(darin): Verify that it makes sense to call FollowDeferredRedirect.
174 url_request_->FollowDeferredRedirect();
175 }
176
177 void URLLoaderImpl::QueryStatus(
178 const Callback<void(URLLoaderStatusPtr)>& callback) {
179 URLLoaderStatusPtr status(URLLoaderStatus::New());
180 if (url_request_) {
181 status->is_loading = url_request_->is_pending();
182 if (!url_request_->status().is_success())
183 status->error = MakeNetworkError(url_request_->status().error());
159 } else { 184 } else {
160 if (url_request_) 185 status->is_loading = false;
161 url_request_->FollowDeferredRedirect();
162 } 186 }
187 // TODO(darin): Populate more status fields.
188 callback.Run(status.Pass());
163 } 189 }
164 190
165 void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request, 191 void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* url_request,
166 const GURL& new_url, 192 const GURL& new_url,
167 bool* defer_redirect) { 193 bool* defer_redirect) {
168 DCHECK(url_request == url_request_.get()); 194 DCHECK(url_request == url_request_.get());
169 DCHECK(url_request->status().is_success()); 195 DCHECK(url_request->status().is_success());
170 196
197 if (auto_follow_redirects_)
198 return;
199
200 // Send the redirect response to the client, allowing them to inspect it and
201 // optionally follow the redirect.
202 *defer_redirect = true;
203
171 URLResponsePtr response = MakeURLResponse(url_request); 204 URLResponsePtr response = MakeURLResponse(url_request);
172 std::string redirect_method = 205 response->redirect_method =
173 net::URLRequest::ComputeMethodForRedirect(url_request->method(), 206 net::URLRequest::ComputeMethodForRedirect(url_request->method(),
174 response->status_code); 207 response->status_code);
175 client()->OnReceivedRedirect( 208 response->redirect_url = new_url.spec();
176 response.Pass(), new_url.spec(), redirect_method);
177 209
178 *defer_redirect = !auto_follow_redirects_; 210 SendResponse(response.Pass());
179 } 211 }
180 212
181 void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) { 213 void URLLoaderImpl::OnResponseStarted(net::URLRequest* url_request) {
182 DCHECK(url_request == url_request_.get()); 214 DCHECK(url_request == url_request_.get());
183 215
184 if (!url_request->status().is_success()) { 216 if (!url_request->status().is_success()) {
185 SendError(url_request->status().error()); 217 SendError(url_request->status().error(), callback_);
218 callback_ = Callback<void(URLResponsePtr)>();
186 return; 219 return;
187 } 220 }
188 221
189 // TODO(darin): Add support for optional MIME sniffing. 222 // TODO(darin): Add support for optional MIME sniffing.
190 223
191 client()->OnReceivedResponse(MakeURLResponse(url_request)); 224 DataPipe data_pipe;
225 // TODO(darin): Honor given buffer size.
226
227 URLResponsePtr response = MakeURLResponse(url_request);
228 response->body = data_pipe.consumer_handle.Pass();
229 response_body_stream_ = data_pipe.producer_handle.Pass();
230
231 SendResponse(response.Pass());
192 232
193 // Start reading... 233 // Start reading...
194 ReadMore(); 234 ReadMore();
195 } 235 }
196 236
197 void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request, 237 void URLLoaderImpl::OnReadCompleted(net::URLRequest* url_request,
198 int bytes_read) { 238 int bytes_read) {
239 DCHECK(url_request == url_request_.get());
240
199 if (url_request->status().is_success()) { 241 if (url_request->status().is_success()) {
200 DidRead(static_cast<uint32_t>(bytes_read), false); 242 DidRead(static_cast<uint32_t>(bytes_read), false);
201 } else { 243 } else {
202 pending_write_ = NULL; // This closes the data pipe. 244 pending_write_ = NULL; // This closes the data pipe.
203 // TODO(darin): Perhaps we should communicate this error to our client.
204 } 245 }
205 } 246 }
206 247
207 void URLLoaderImpl::SendError(int error_code) { 248 void URLLoaderImpl::SendError(
208 NetworkErrorPtr error(NetworkError::New()); 249 int error_code,
209 error->code = error_code; 250 const Callback<void(URLResponsePtr)>& callback) {
210 error->description = net::ErrorToString(error_code); 251 URLResponsePtr response(URLResponse::New());
211 client()->OnReceivedError(error.Pass()); 252 if (url_request_)
253 response->url = url_request_->url().spec();
254 response->error = MakeNetworkError(error_code);
255 callback.Run(response.Pass());
256 }
257
258 void URLLoaderImpl::SendResponse(URLResponsePtr response) {
259 Callback<void(URLResponsePtr)> callback;
260 std::swap(callback_, callback);
261 callback.Run(response.Pass());
212 } 262 }
213 263
214 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) { 264 void URLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) {
215 // TODO(darin): Handle a bad |result| value. 265 // TODO(darin): Handle a bad |result| value.
216 ReadMore(); 266 ReadMore();
217 } 267 }
218 268
219 void URLLoaderImpl::WaitToReadMore() { 269 void URLLoaderImpl::WaitToReadMore() {
220 handle_watcher_.Start(response_body_stream_.get(), 270 handle_watcher_.Start(response_body_stream_.get(),
221 MOJO_HANDLE_SIGNAL_WRITABLE, 271 MOJO_HANDLE_SIGNAL_WRITABLE,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 // Drop our reference to the buffer. 303 // Drop our reference to the buffer.
254 buf = NULL; 304 buf = NULL;
255 305
256 if (url_request_->status().is_io_pending()) { 306 if (url_request_->status().is_io_pending()) {
257 // Wait for OnReadCompleted. 307 // Wait for OnReadCompleted.
258 } else if (url_request_->status().is_success() && bytes_read > 0) { 308 } else if (url_request_->status().is_success() && bytes_read > 0) {
259 DidRead(static_cast<uint32_t>(bytes_read), true); 309 DidRead(static_cast<uint32_t>(bytes_read), true);
260 } else { 310 } else {
261 pending_write_->Complete(0); 311 pending_write_->Complete(0);
262 pending_write_ = NULL; // This closes the data pipe. 312 pending_write_ = NULL; // This closes the data pipe.
263 if (bytes_read == 0) {
264 client()->OnReceivedEndOfResponseBody();
265 } else {
266 DCHECK(!url_request_->status().is_success());
267 SendError(url_request_->status().error());
268 }
269 } 313 }
270 } 314 }
271 315
272 void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) { 316 void URLLoaderImpl::DidRead(uint32_t num_bytes, bool completed_synchronously) {
273 DCHECK(url_request_->status().is_success()); 317 DCHECK(url_request_->status().is_success());
274 318
275 response_body_stream_ = pending_write_->Complete(num_bytes); 319 response_body_stream_ = pending_write_->Complete(num_bytes);
276 pending_write_ = NULL; 320 pending_write_ = NULL;
277 321
278 if (completed_synchronously) { 322 if (completed_synchronously) {
279 base::MessageLoop::current()->PostTask( 323 base::MessageLoop::current()->PostTask(
280 FROM_HERE, 324 FROM_HERE,
281 base::Bind(&URLLoaderImpl::ReadMore, weak_ptr_factory_.GetWeakPtr())); 325 base::Bind(&URLLoaderImpl::ReadMore, weak_ptr_factory_.GetWeakPtr()));
282 } else { 326 } else {
283 ReadMore(); 327 ReadMore();
284 } 328 }
285 } 329 }
286 330
287 } // namespace mojo 331 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/network/url_loader_impl.h ('k') | mojo/services/public/interfaces/navigation/navigation.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698