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

Side by Side Diff: net/cert_net/cert_net_fetcher_impl.cc

Issue 2265873002: Adjust callers and networking delegates in net/ to modified APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@URLRequestRead
Patch Set: rebased on top of URLRequest::Read CL Created 4 years, 3 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
« no previous file with comments | « no previous file | net/cert_net/nss_ocsp.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "net/cert_net/cert_net_fetcher_impl.h" 5 #include "net/cert_net/cert_net_fetcher_impl.h"
6 6
7 #include <tuple> 7 #include <tuple>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 void StartURLRequest(URLRequestContext* context); 171 void StartURLRequest(URLRequestContext* context);
172 172
173 private: 173 private:
174 // The pointers in RequestList are not owned by the Job. 174 // The pointers in RequestList are not owned by the Job.
175 using RequestList = base::LinkedList<RequestImpl>; 175 using RequestList = base::LinkedList<RequestImpl>;
176 176
177 // Implementation of URLRequest::Delegate 177 // Implementation of URLRequest::Delegate
178 void OnReceivedRedirect(URLRequest* request, 178 void OnReceivedRedirect(URLRequest* request,
179 const RedirectInfo& redirect_info, 179 const RedirectInfo& redirect_info,
180 bool* defer_redirect) override; 180 bool* defer_redirect) override;
181 void OnResponseStarted(URLRequest* request) override; 181 void OnResponseStarted(URLRequest* request, int net_error) override;
182 void OnReadCompleted(URLRequest* request, int bytes_read) override; 182 void OnReadCompleted(URLRequest* request, int bytes_read) override;
183 183
184 // Clears the URLRequest and timer. Helper for doing work common to 184 // Clears the URLRequest and timer. Helper for doing work common to
185 // cancellation and job completion. 185 // cancellation and job completion.
186 void Stop(); 186 void Stop();
187 187
188 // Reads as much data as available from |request|. 188 // Reads as much data as available from |request|.
189 void ReadBody(URLRequest* request); 189 void ReadBody(URLRequest* request);
190 190
191 // Helper to copy the partial bytes read from the read IOBuffer to an 191 // Helper to copy the partial bytes read from the read IOBuffer to an
192 // aggregated buffer. 192 // aggregated buffer.
193 bool ConsumeBytesRead(URLRequest* request, int num_bytes); 193 bool ConsumeBytesRead(URLRequest* request, int num_bytes);
194 194
195 // Called once the job has exceeded its deadline.
196 void OnTimeout();
197
198 // Called when the URLRequest has completed (either success or failure). 195 // Called when the URLRequest has completed (either success or failure).
199 void OnUrlRequestCompleted(URLRequest* request); 196 void OnUrlRequestCompleted(int net_error);
200 197
201 // Called when the Job has completed. The job may finish in response to a 198 // Called when the Job has completed. The job may finish in response to a
202 // timeout, an invalid URL, or the URLRequest completing. By the time this 199 // timeout, an invalid URL, or the URLRequest completing. By the time this
203 // method is called, the response variables have been assigned 200 // method is called, the |response_body_| variable have been assigned.
204 // (result_net_error_ and response_body_). 201 void OnJobCompleted(Error error);
205 void OnJobCompleted(); 202
203 // Cancels a request with a specified error code and calls
204 // OnUrlRequestCompleted().
205 void FailRequest(Error error);
206 206
207 // The requests attached to this job. 207 // The requests attached to this job.
208 RequestList requests_; 208 RequestList requests_;
209 209
210 // The input parameters for starting a URLRequest. 210 // The input parameters for starting a URLRequest.
211 std::unique_ptr<RequestParams> request_params_; 211 std::unique_ptr<RequestParams> request_params_;
212 212
213 // The URLRequest response information. 213 // The URLRequest response information.
214 std::vector<uint8_t> response_body_; 214 std::vector<uint8_t> response_body_;
215 Error result_net_error_;
216 215
217 std::unique_ptr<URLRequest> url_request_; 216 std::unique_ptr<URLRequest> url_request_;
218 scoped_refptr<IOBuffer> read_buffer_; 217 scoped_refptr<IOBuffer> read_buffer_;
219 218
220 // Used to timeout the job when the URLRequest takes too long. This timer is 219 // Used to timeout the job when the URLRequest takes too long. This timer is
221 // also used for notifying a failure to start the URLRequest. 220 // also used for notifying a failure to start the URLRequest.
222 base::OneShotTimer timer_; 221 base::OneShotTimer timer_;
223 222
224 // Non-owned pointer to the CertNetFetcherImpl that created this job. 223 // Non-owned pointer to the CertNetFetcherImpl that created this job.
225 CertNetFetcherImpl* parent_; 224 CertNetFetcherImpl* parent_;
226 225
227 DISALLOW_COPY_AND_ASSIGN(Job); 226 DISALLOW_COPY_AND_ASSIGN(Job);
228 }; 227 };
229 228
230 CertNetFetcherImpl::RequestImpl::~RequestImpl() { 229 CertNetFetcherImpl::RequestImpl::~RequestImpl() {
231 if (job_) 230 if (job_)
232 job_->DetachRequest(this); 231 job_->DetachRequest(this);
233 } 232 }
234 233
235 CertNetFetcherImpl::Job::Job(std::unique_ptr<RequestParams> request_params, 234 CertNetFetcherImpl::Job::Job(std::unique_ptr<RequestParams> request_params,
236 CertNetFetcherImpl* parent) 235 CertNetFetcherImpl* parent)
237 : request_params_(std::move(request_params)), 236 : request_params_(std::move(request_params)),
238 result_net_error_(ERR_IO_PENDING),
239 parent_(parent) {} 237 parent_(parent) {}
240 238
241 CertNetFetcherImpl::Job::~Job() { 239 CertNetFetcherImpl::Job::~Job() {
242 Cancel(); 240 Cancel();
243 } 241 }
244 242
245 void CertNetFetcherImpl::Job::Cancel() { 243 void CertNetFetcherImpl::Job::Cancel() {
246 parent_ = nullptr; 244 parent_ = nullptr;
247 245
248 // Notify each request of cancellation and remove it from the list. 246 // Notify each request of cancellation and remove it from the list.
(...skipping 24 matching lines...) Expand all
273 271
274 // If there are no longer any requests attached to the job then 272 // If there are no longer any requests attached to the job then
275 // cancel and delete it. 273 // cancel and delete it.
276 if (requests_.empty() && !parent_->IsCurrentlyCompletingJob(this)) 274 if (requests_.empty() && !parent_->IsCurrentlyCompletingJob(this))
277 delete_this = parent_->RemoveJob(this); 275 delete_this = parent_->RemoveJob(this);
278 } 276 }
279 277
280 void CertNetFetcherImpl::Job::StartURLRequest(URLRequestContext* context) { 278 void CertNetFetcherImpl::Job::StartURLRequest(URLRequestContext* context) {
281 Error error = CanFetchUrl(request_params_->url); 279 Error error = CanFetchUrl(request_params_->url);
282 if (error != OK) { 280 if (error != OK) {
283 result_net_error_ = error;
284 // The CertNetFetcher's API contract is that requests always complete 281 // The CertNetFetcher's API contract is that requests always complete
285 // asynchronously. Use the timer class so the task is easily cancelled. 282 // asynchronously. Use the timer class so the task is easily cancelled.
286 timer_.Start(FROM_HERE, base::TimeDelta(), this, &Job::OnJobCompleted); 283 timer_.Start(
284 FROM_HERE, base::TimeDelta(),
285 base::Bind(&Job::OnJobCompleted, base::Unretained(this), error));
287 return; 286 return;
288 } 287 }
289 288
290 // Start the URLRequest. 289 // Start the URLRequest.
291 read_buffer_ = new IOBuffer(kReadBufferSizeInBytes); 290 read_buffer_ = new IOBuffer(kReadBufferSizeInBytes);
292 url_request_ = 291 url_request_ =
293 context->CreateRequest(request_params_->url, DEFAULT_PRIORITY, this); 292 context->CreateRequest(request_params_->url, DEFAULT_PRIORITY, this);
294 if (request_params_->http_method == HTTP_METHOD_POST) 293 if (request_params_->http_method == HTTP_METHOD_POST)
295 url_request_->set_method("POST"); 294 url_request_->set_method("POST");
296 url_request_->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES | 295 url_request_->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES |
297 LOAD_DO_NOT_SEND_COOKIES); 296 LOAD_DO_NOT_SEND_COOKIES);
298 url_request_->Start(); 297 url_request_->Start();
299 298
300 // Start a timer to limit how long the job runs for. 299 // Start a timer to limit how long the job runs for.
301 if (request_params_->timeout > base::TimeDelta()) 300 if (request_params_->timeout > base::TimeDelta())
302 timer_.Start(FROM_HERE, request_params_->timeout, this, &Job::OnTimeout); 301 timer_.Start(
302 FROM_HERE, request_params_->timeout,
303 base::Bind(&Job::FailRequest, base::Unretained(this), ERR_TIMED_OUT));
303 } 304 }
304 305
305 void CertNetFetcherImpl::Job::OnReceivedRedirect( 306 void CertNetFetcherImpl::Job::OnReceivedRedirect(
306 URLRequest* request, 307 URLRequest* request,
307 const RedirectInfo& redirect_info, 308 const RedirectInfo& redirect_info,
308 bool* defer_redirect) { 309 bool* defer_redirect) {
309 DCHECK_EQ(url_request_.get(), request); 310 DCHECK_EQ(url_request_.get(), request);
310 311
311 // Ensure that the new URL matches the policy. 312 // Ensure that the new URL matches the policy.
312 Error error = CanFetchUrl(redirect_info.new_url); 313 Error error = CanFetchUrl(redirect_info.new_url);
313 if (error != OK) { 314 if (error != OK) {
314 request->CancelWithError(error); 315 FailRequest(error);
315 OnUrlRequestCompleted(request);
316 return; 316 return;
317 } 317 }
318 } 318 }
319 319
320 void CertNetFetcherImpl::Job::OnResponseStarted(URLRequest* request) { 320 void CertNetFetcherImpl::Job::OnResponseStarted(URLRequest* request,
321 int net_error) {
321 DCHECK_EQ(url_request_.get(), request); 322 DCHECK_EQ(url_request_.get(), request);
323 DCHECK_NE(ERR_IO_PENDING, net_error);
322 324
323 if (!request->status().is_success()) { 325 if (net_error != OK) {
324 OnUrlRequestCompleted(request); 326 OnUrlRequestCompleted(net_error);
325 return; 327 return;
326 } 328 }
327 329
328 if (request->GetResponseCode() != 200) { 330 if (request->GetResponseCode() != 200) {
329 // TODO(eroman): Use a more specific error code. 331 // TODO(eroman): Use a more specific error code.
330 request->CancelWithError(ERR_FAILED); 332 FailRequest(ERR_FAILED);
331 OnUrlRequestCompleted(request);
332 return; 333 return;
333 } 334 }
334 335
335 ReadBody(request); 336 ReadBody(request);
336 } 337 }
337 338
338 void CertNetFetcherImpl::Job::OnReadCompleted(URLRequest* request, 339 void CertNetFetcherImpl::Job::OnReadCompleted(URLRequest* request,
339 int bytes_read) { 340 int bytes_read) {
340 DCHECK_EQ(url_request_.get(), request); 341 DCHECK_EQ(url_request_.get(), request);
342 DCHECK_NE(ERR_IO_PENDING, bytes_read);
341 343
342 // Keep reading the response body. 344 // Keep reading the response body.
343 if (ConsumeBytesRead(request, bytes_read)) 345 if (ConsumeBytesRead(request, bytes_read))
344 ReadBody(request); 346 ReadBody(request);
345 } 347 }
346 348
347 void CertNetFetcherImpl::Job::Stop() { 349 void CertNetFetcherImpl::Job::Stop() {
348 timer_.Stop(); 350 timer_.Stop();
349 url_request_.reset(); 351 url_request_.reset();
350 } 352 }
351 353
352 void CertNetFetcherImpl::Job::ReadBody(URLRequest* request) { 354 void CertNetFetcherImpl::Job::ReadBody(URLRequest* request) {
353 // Read as many bytes as are available synchronously. 355 // Read as many bytes as are available synchronously.
354 int num_bytes; 356 int num_bytes = 0;
355 while ( 357 while (num_bytes >= 0) {
356 request->Read(read_buffer_.get(), kReadBufferSizeInBytes, &num_bytes)) { 358 num_bytes = request->Read(read_buffer_.get(), kReadBufferSizeInBytes);
357 if (!ConsumeBytesRead(request, num_bytes)) 359 if (!ConsumeBytesRead(request, num_bytes))
358 return; 360 return;
359 } 361 }
360 362
361 // Check whether the read failed synchronously. 363 // Check whether the read failed synchronously.
362 if (!request->status().is_io_pending()) 364 if (num_bytes != ERR_IO_PENDING)
363 OnUrlRequestCompleted(request); 365 OnUrlRequestCompleted(num_bytes);
364 return; 366 return;
365 } 367 }
366 368
367 bool CertNetFetcherImpl::Job::ConsumeBytesRead(URLRequest* request, 369 bool CertNetFetcherImpl::Job::ConsumeBytesRead(URLRequest* request,
368 int num_bytes) { 370 int num_bytes) {
369 if (num_bytes <= 0) { 371 if (num_bytes <= 0) {
370 // Error while reading, or EOF. 372 // Error while reading, or EOF.
371 OnUrlRequestCompleted(request); 373 OnUrlRequestCompleted(num_bytes);
372 return false; 374 return false;
373 } 375 }
374 376
375 // Enforce maximum size bound. 377 // Enforce maximum size bound.
376 if (num_bytes + response_body_.size() > request_params_->max_response_bytes) { 378 if (num_bytes + response_body_.size() > request_params_->max_response_bytes) {
377 request->CancelWithError(ERR_FILE_TOO_BIG); 379 FailRequest(ERR_FILE_TOO_BIG);
378 OnUrlRequestCompleted(request);
379 return false; 380 return false;
380 } 381 }
381 382
382 // Append the data to |response_body_|. 383 // Append the data to |response_body_|.
383 response_body_.reserve(num_bytes); 384 response_body_.reserve(num_bytes);
384 response_body_.insert(response_body_.end(), read_buffer_->data(), 385 response_body_.insert(response_body_.end(), read_buffer_->data(),
385 read_buffer_->data() + num_bytes); 386 read_buffer_->data() + num_bytes);
386 return true; 387 return true;
387 } 388 }
388 389
389 void CertNetFetcherImpl::Job::OnTimeout() { 390 void CertNetFetcherImpl::Job::OnUrlRequestCompleted(int net_error) {
390 result_net_error_ = ERR_TIMED_OUT; 391 Error result = static_cast<Error>(net_error);
391 url_request_->CancelWithError(result_net_error_); 392 OnJobCompleted(result);
392 OnJobCompleted();
393 } 393 }
394 394
395 void CertNetFetcherImpl::Job::OnUrlRequestCompleted(URLRequest* request) { 395 void CertNetFetcherImpl::Job::OnJobCompleted(Error error) {
396 DCHECK_EQ(request, url_request_.get());
397
398 if (request->status().is_success())
399 result_net_error_ = OK;
400 else
401 result_net_error_ = static_cast<Error>(request->status().error());
402
403 OnJobCompleted();
404 }
405
406 void CertNetFetcherImpl::Job::OnJobCompleted() {
407 // Stop the timer and clear the URLRequest. 396 // Stop the timer and clear the URLRequest.
408 Stop(); 397 Stop();
409 398
410 // Invoking the callbacks is subtle as state may be mutated while iterating 399 // Invoking the callbacks is subtle as state may be mutated while iterating
411 // through the callbacks: 400 // through the callbacks:
412 // 401 //
413 // * The parent CertNetFetcherImpl may be deleted 402 // * The parent CertNetFetcherImpl may be deleted
414 // * Requests in this job may be cancelled 403 // * Requests in this job may be cancelled
415 404
416 std::unique_ptr<Job> delete_this = parent_->RemoveJob(this); 405 std::unique_ptr<Job> delete_this = parent_->RemoveJob(this);
417 parent_->SetCurrentlyCompletingJob(this); 406 parent_->SetCurrentlyCompletingJob(this);
418 407
419 while (!requests_.empty()) { 408 while (!requests_.empty()) {
420 base::LinkNode<RequestImpl>* request = requests_.head(); 409 base::LinkNode<RequestImpl>* request = requests_.head();
421 request->RemoveFromList(); 410 request->RemoveFromList();
422 request->value()->OnJobCompleted(this, result_net_error_, response_body_); 411 request->value()->OnJobCompleted(this, error, response_body_);
423 } 412 }
424 413
425 if (parent_) 414 if (parent_)
426 parent_->ClearCurrentlyCompletingJob(this); 415 parent_->ClearCurrentlyCompletingJob(this);
427 } 416 }
428 417
418 void CertNetFetcherImpl::Job::FailRequest(Error error) {
419 int result = url_request_->CancelWithError(error);
420 OnUrlRequestCompleted(result);
421 }
422
429 CertNetFetcherImpl::CertNetFetcherImpl(URLRequestContext* context) 423 CertNetFetcherImpl::CertNetFetcherImpl(URLRequestContext* context)
430 : currently_completing_job_(nullptr), context_(context) { 424 : currently_completing_job_(nullptr), context_(context) {
431 } 425 }
432 426
433 CertNetFetcherImpl::~CertNetFetcherImpl() { 427 CertNetFetcherImpl::~CertNetFetcherImpl() {
434 base::STLDeleteElements(&jobs_); 428 base::STLDeleteElements(&jobs_);
435 429
436 // The CertNetFetcherImpl was destroyed in a FetchCallback. Detach all 430 // The CertNetFetcherImpl was destroyed in a FetchCallback. Detach all
437 // remaining requests from the job so no further callbacks are called. 431 // remaining requests from the job so no further callbacks are called.
438 if (currently_completing_job_) 432 if (currently_completing_job_)
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 void CertNetFetcherImpl::ClearCurrentlyCompletingJob(Job* job) { 541 void CertNetFetcherImpl::ClearCurrentlyCompletingJob(Job* job) {
548 DCHECK_EQ(currently_completing_job_, job); 542 DCHECK_EQ(currently_completing_job_, job);
549 currently_completing_job_ = nullptr; 543 currently_completing_job_ = nullptr;
550 } 544 }
551 545
552 bool CertNetFetcherImpl::IsCurrentlyCompletingJob(Job* job) { 546 bool CertNetFetcherImpl::IsCurrentlyCompletingJob(Job* job) {
553 return job == currently_completing_job_; 547 return job == currently_completing_job_;
554 } 548 }
555 549
556 } // namespace net 550 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/cert_net/nss_ocsp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698