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

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: Matt's comments 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') | net/url_request/sdch_dictionary_fetcher.cc » ('J')
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. 195 // Called once the job has exceeded its deadline.
196 void OnTimeout(); 196 void OnTimeout(Error error);
197 197
198 // Called when the URLRequest has completed (either success or failure). 198 // Called when the URLRequest has completed (either success or failure).
199 void OnUrlRequestCompleted(URLRequest* request); 199 void OnUrlRequestCompleted(int net_error);
200 200
201 // Called when the Job has completed. The job may finish in response to a 201 // 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 202 // timeout, an invalid URL, or the URLRequest completing. By the time this
203 // method is called, the response variables have been assigned 203 // method is called, the |response_body_| variable have been assigned.
204 // (result_net_error_ and response_body_). 204 void OnJobCompleted(Error error);
205 void OnJobCompleted(); 205
206 // Cancels a request with a specified error code and calls
207 // OnUrlRequestCompleted().
208 void FailRequest(Error error);
206 209
207 // The requests attached to this job. 210 // The requests attached to this job.
208 RequestList requests_; 211 RequestList requests_;
209 212
210 // The input parameters for starting a URLRequest. 213 // The input parameters for starting a URLRequest.
211 std::unique_ptr<RequestParams> request_params_; 214 std::unique_ptr<RequestParams> request_params_;
212 215
213 // The URLRequest response information. 216 // The URLRequest response information.
214 std::vector<uint8_t> response_body_; 217 std::vector<uint8_t> response_body_;
215 Error result_net_error_;
216 218
217 std::unique_ptr<URLRequest> url_request_; 219 std::unique_ptr<URLRequest> url_request_;
218 scoped_refptr<IOBuffer> read_buffer_; 220 scoped_refptr<IOBuffer> read_buffer_;
219 221
220 // Used to timeout the job when the URLRequest takes too long. This timer is 222 // 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. 223 // also used for notifying a failure to start the URLRequest.
222 base::OneShotTimer timer_; 224 base::OneShotTimer timer_;
223 225
224 // Non-owned pointer to the CertNetFetcherImpl that created this job. 226 // Non-owned pointer to the CertNetFetcherImpl that created this job.
225 CertNetFetcherImpl* parent_; 227 CertNetFetcherImpl* parent_;
226 228
227 DISALLOW_COPY_AND_ASSIGN(Job); 229 DISALLOW_COPY_AND_ASSIGN(Job);
228 }; 230 };
229 231
230 CertNetFetcherImpl::RequestImpl::~RequestImpl() { 232 CertNetFetcherImpl::RequestImpl::~RequestImpl() {
231 if (job_) 233 if (job_)
232 job_->DetachRequest(this); 234 job_->DetachRequest(this);
233 } 235 }
234 236
235 CertNetFetcherImpl::Job::Job(std::unique_ptr<RequestParams> request_params, 237 CertNetFetcherImpl::Job::Job(std::unique_ptr<RequestParams> request_params,
236 CertNetFetcherImpl* parent) 238 CertNetFetcherImpl* parent)
237 : request_params_(std::move(request_params)), 239 : request_params_(std::move(request_params)),
238 result_net_error_(ERR_IO_PENDING),
239 parent_(parent) {} 240 parent_(parent) {}
240 241
241 CertNetFetcherImpl::Job::~Job() { 242 CertNetFetcherImpl::Job::~Job() {
242 Cancel(); 243 Cancel();
243 } 244 }
244 245
245 void CertNetFetcherImpl::Job::Cancel() { 246 void CertNetFetcherImpl::Job::Cancel() {
246 parent_ = nullptr; 247 parent_ = nullptr;
247 248
248 // Notify each request of cancellation and remove it from the list. 249 // Notify each request of cancellation and remove it from the list.
(...skipping 24 matching lines...) Expand all
273 274
274 // If there are no longer any requests attached to the job then 275 // If there are no longer any requests attached to the job then
275 // cancel and delete it. 276 // cancel and delete it.
276 if (requests_.empty() && !parent_->IsCurrentlyCompletingJob(this)) 277 if (requests_.empty() && !parent_->IsCurrentlyCompletingJob(this))
277 delete_this = parent_->RemoveJob(this); 278 delete_this = parent_->RemoveJob(this);
278 } 279 }
279 280
280 void CertNetFetcherImpl::Job::StartURLRequest(URLRequestContext* context) { 281 void CertNetFetcherImpl::Job::StartURLRequest(URLRequestContext* context) {
281 Error error = CanFetchUrl(request_params_->url); 282 Error error = CanFetchUrl(request_params_->url);
282 if (error != OK) { 283 if (error != OK) {
283 result_net_error_ = error;
284 // The CertNetFetcher's API contract is that requests always complete 284 // The CertNetFetcher's API contract is that requests always complete
285 // asynchronously. Use the timer class so the task is easily cancelled. 285 // asynchronously. Use the timer class so the task is easily cancelled.
286 timer_.Start(FROM_HERE, base::TimeDelta(), this, &Job::OnJobCompleted); 286 timer_.Start(
287 FROM_HERE, base::TimeDelta(),
288 base::Bind(&Job::OnJobCompleted, base::Unretained(this), error));
287 return; 289 return;
288 } 290 }
289 291
290 // Start the URLRequest. 292 // Start the URLRequest.
291 read_buffer_ = new IOBuffer(kReadBufferSizeInBytes); 293 read_buffer_ = new IOBuffer(kReadBufferSizeInBytes);
292 url_request_ = 294 url_request_ =
293 context->CreateRequest(request_params_->url, DEFAULT_PRIORITY, this); 295 context->CreateRequest(request_params_->url, DEFAULT_PRIORITY, this);
294 if (request_params_->http_method == HTTP_METHOD_POST) 296 if (request_params_->http_method == HTTP_METHOD_POST)
295 url_request_->set_method("POST"); 297 url_request_->set_method("POST");
296 url_request_->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES | 298 url_request_->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES |
297 LOAD_DO_NOT_SEND_COOKIES); 299 LOAD_DO_NOT_SEND_COOKIES);
298 url_request_->Start(); 300 url_request_->Start();
299 301
300 // Start a timer to limit how long the job runs for. 302 // Start a timer to limit how long the job runs for.
301 if (request_params_->timeout > base::TimeDelta()) 303 if (request_params_->timeout > base::TimeDelta())
302 timer_.Start(FROM_HERE, request_params_->timeout, this, &Job::OnTimeout); 304 timer_.Start(
305 FROM_HERE, request_params_->timeout,
306 base::Bind(&Job::OnTimeout, base::Unretained(this), ERR_TIMED_OUT));
mmenke 2016/09/01 16:57:25 Can get rid of OnTimeout entirely and just use Fai
maksims (do not use this acc) 2016/09/02 12:31:53 Done.
303 } 307 }
304 308
305 void CertNetFetcherImpl::Job::OnReceivedRedirect( 309 void CertNetFetcherImpl::Job::OnReceivedRedirect(
306 URLRequest* request, 310 URLRequest* request,
307 const RedirectInfo& redirect_info, 311 const RedirectInfo& redirect_info,
308 bool* defer_redirect) { 312 bool* defer_redirect) {
309 DCHECK_EQ(url_request_.get(), request); 313 DCHECK_EQ(url_request_.get(), request);
310 314
311 // Ensure that the new URL matches the policy. 315 // Ensure that the new URL matches the policy.
312 Error error = CanFetchUrl(redirect_info.new_url); 316 Error error = CanFetchUrl(redirect_info.new_url);
313 if (error != OK) { 317 if (error != OK) {
314 request->CancelWithError(error); 318 FailRequest(error);
315 OnUrlRequestCompleted(request);
316 return; 319 return;
317 } 320 }
318 } 321 }
319 322
320 void CertNetFetcherImpl::Job::OnResponseStarted(URLRequest* request) { 323 void CertNetFetcherImpl::Job::OnResponseStarted(URLRequest* request,
324 int net_error) {
321 DCHECK_EQ(url_request_.get(), request); 325 DCHECK_EQ(url_request_.get(), request);
326 DCHECK_NE(ERR_IO_PENDING, net_error);
322 327
323 if (!request->status().is_success()) { 328 if (net_error != OK) {
324 OnUrlRequestCompleted(request); 329 OnUrlRequestCompleted(net_error);
325 return; 330 return;
326 } 331 }
327 332
328 if (request->GetResponseCode() != 200) { 333 if (request->GetResponseCode() != 200) {
329 // TODO(eroman): Use a more specific error code. 334 // TODO(eroman): Use a more specific error code.
330 request->CancelWithError(ERR_FAILED); 335 FailRequest(ERR_FAILED);
331 OnUrlRequestCompleted(request);
332 return; 336 return;
333 } 337 }
334 338
335 ReadBody(request); 339 ReadBody(request);
336 } 340 }
337 341
338 void CertNetFetcherImpl::Job::OnReadCompleted(URLRequest* request, 342 void CertNetFetcherImpl::Job::OnReadCompleted(URLRequest* request,
339 int bytes_read) { 343 int bytes_read) {
340 DCHECK_EQ(url_request_.get(), request); 344 DCHECK_EQ(url_request_.get(), request);
345 DCHECK_NE(ERR_IO_PENDING, bytes_read);
341 346
342 // Keep reading the response body. 347 // Keep reading the response body.
343 if (ConsumeBytesRead(request, bytes_read)) 348 if (ConsumeBytesRead(request, bytes_read))
344 ReadBody(request); 349 ReadBody(request);
345 } 350 }
346 351
347 void CertNetFetcherImpl::Job::Stop() { 352 void CertNetFetcherImpl::Job::Stop() {
348 timer_.Stop(); 353 timer_.Stop();
349 url_request_.reset(); 354 url_request_.reset();
350 } 355 }
351 356
352 void CertNetFetcherImpl::Job::ReadBody(URLRequest* request) { 357 void CertNetFetcherImpl::Job::ReadBody(URLRequest* request) {
353 // Read as many bytes as are available synchronously. 358 // Read as many bytes as are available synchronously.
354 int num_bytes; 359 int num_bytes = 0;
355 while ( 360 while (num_bytes >= 0) {
356 request->Read(read_buffer_.get(), kReadBufferSizeInBytes, &num_bytes)) { 361 num_bytes = request->Read(read_buffer_.get(), kReadBufferSizeInBytes);
357 if (!ConsumeBytesRead(request, num_bytes)) 362 if (!ConsumeBytesRead(request, num_bytes))
358 return; 363 return;
359 } 364 }
360 365
361 // Check whether the read failed synchronously. 366 // Check whether the read failed synchronously.
362 if (!request->status().is_io_pending()) 367 if (num_bytes != ERR_IO_PENDING)
363 OnUrlRequestCompleted(request); 368 OnUrlRequestCompleted(num_bytes);
364 return; 369 return;
365 } 370 }
366 371
367 bool CertNetFetcherImpl::Job::ConsumeBytesRead(URLRequest* request, 372 bool CertNetFetcherImpl::Job::ConsumeBytesRead(URLRequest* request,
368 int num_bytes) { 373 int num_bytes) {
369 if (num_bytes <= 0) { 374 if (num_bytes <= 0) {
370 // Error while reading, or EOF. 375 // Error while reading, or EOF.
371 OnUrlRequestCompleted(request); 376 OnUrlRequestCompleted(num_bytes);
372 return false; 377 return false;
373 } 378 }
374 379
375 // Enforce maximum size bound. 380 // Enforce maximum size bound.
376 if (num_bytes + response_body_.size() > request_params_->max_response_bytes) { 381 if (num_bytes + response_body_.size() > request_params_->max_response_bytes) {
377 request->CancelWithError(ERR_FILE_TOO_BIG); 382 FailRequest(ERR_FILE_TOO_BIG);
378 OnUrlRequestCompleted(request);
379 return false; 383 return false;
380 } 384 }
381 385
382 // Append the data to |response_body_|. 386 // Append the data to |response_body_|.
383 response_body_.reserve(num_bytes); 387 response_body_.reserve(num_bytes);
384 response_body_.insert(response_body_.end(), read_buffer_->data(), 388 response_body_.insert(response_body_.end(), read_buffer_->data(),
385 read_buffer_->data() + num_bytes); 389 read_buffer_->data() + num_bytes);
386 return true; 390 return true;
387 } 391 }
388 392
389 void CertNetFetcherImpl::Job::OnTimeout() { 393 void CertNetFetcherImpl::Job::OnTimeout(Error error) {
390 result_net_error_ = ERR_TIMED_OUT; 394 FailRequest(error);
391 url_request_->CancelWithError(result_net_error_);
392 OnJobCompleted();
393 } 395 }
394 396
395 void CertNetFetcherImpl::Job::OnUrlRequestCompleted(URLRequest* request) { 397 void CertNetFetcherImpl::Job::OnUrlRequestCompleted(int net_error) {
396 DCHECK_EQ(request, url_request_.get()); 398 Error result = static_cast<Error>(net_error);
397 399 OnJobCompleted(result);
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 } 400 }
405 401
406 void CertNetFetcherImpl::Job::OnJobCompleted() { 402 void CertNetFetcherImpl::Job::OnJobCompleted(Error error) {
407 // Stop the timer and clear the URLRequest. 403 // Stop the timer and clear the URLRequest.
408 Stop(); 404 Stop();
409 405
410 // Invoking the callbacks is subtle as state may be mutated while iterating 406 // Invoking the callbacks is subtle as state may be mutated while iterating
411 // through the callbacks: 407 // through the callbacks:
412 // 408 //
413 // * The parent CertNetFetcherImpl may be deleted 409 // * The parent CertNetFetcherImpl may be deleted
414 // * Requests in this job may be cancelled 410 // * Requests in this job may be cancelled
415 411
416 std::unique_ptr<Job> delete_this = parent_->RemoveJob(this); 412 std::unique_ptr<Job> delete_this = parent_->RemoveJob(this);
417 parent_->SetCurrentlyCompletingJob(this); 413 parent_->SetCurrentlyCompletingJob(this);
418 414
419 while (!requests_.empty()) { 415 while (!requests_.empty()) {
420 base::LinkNode<RequestImpl>* request = requests_.head(); 416 base::LinkNode<RequestImpl>* request = requests_.head();
421 request->RemoveFromList(); 417 request->RemoveFromList();
422 request->value()->OnJobCompleted(this, result_net_error_, response_body_); 418 request->value()->OnJobCompleted(this, error, response_body_);
423 } 419 }
424 420
425 if (parent_) 421 if (parent_)
426 parent_->ClearCurrentlyCompletingJob(this); 422 parent_->ClearCurrentlyCompletingJob(this);
427 } 423 }
428 424
425 void CertNetFetcherImpl::Job::FailRequest(Error error) {
426 int result = url_request_->CancelWithError(error);
427 OnUrlRequestCompleted(result);
428 }
429
429 CertNetFetcherImpl::CertNetFetcherImpl(URLRequestContext* context) 430 CertNetFetcherImpl::CertNetFetcherImpl(URLRequestContext* context)
430 : currently_completing_job_(nullptr), context_(context) { 431 : currently_completing_job_(nullptr), context_(context) {
431 } 432 }
432 433
433 CertNetFetcherImpl::~CertNetFetcherImpl() { 434 CertNetFetcherImpl::~CertNetFetcherImpl() {
434 base::STLDeleteElements(&jobs_); 435 base::STLDeleteElements(&jobs_);
435 436
436 // The CertNetFetcherImpl was destroyed in a FetchCallback. Detach all 437 // The CertNetFetcherImpl was destroyed in a FetchCallback. Detach all
437 // remaining requests from the job so no further callbacks are called. 438 // remaining requests from the job so no further callbacks are called.
438 if (currently_completing_job_) 439 if (currently_completing_job_)
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 void CertNetFetcherImpl::ClearCurrentlyCompletingJob(Job* job) { 548 void CertNetFetcherImpl::ClearCurrentlyCompletingJob(Job* job) {
548 DCHECK_EQ(currently_completing_job_, job); 549 DCHECK_EQ(currently_completing_job_, job);
549 currently_completing_job_ = nullptr; 550 currently_completing_job_ = nullptr;
550 } 551 }
551 552
552 bool CertNetFetcherImpl::IsCurrentlyCompletingJob(Job* job) { 553 bool CertNetFetcherImpl::IsCurrentlyCompletingJob(Job* job) {
553 return job == currently_completing_job_; 554 return job == currently_completing_job_;
554 } 555 }
555 556
556 } // namespace net 557 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/cert_net/nss_ocsp.cc » ('j') | net/url_request/sdch_dictionary_fetcher.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698