request_sender.cc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "google_apis/common/request_sender.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/task/sequenced_task_runner.h"
  8. #include "google_apis/common/auth_service.h"
  9. #include "google_apis/common/base_requests.h"
  10. namespace google_apis {
  11. RequestSender::RequestSender(
  12. std::unique_ptr<AuthServiceInterface> auth_service,
  13. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
  14. const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
  15. const std::string& custom_user_agent,
  16. const net::NetworkTrafficAnnotationTag& traffic_annotation)
  17. : auth_service_(std::move(auth_service)),
  18. url_loader_factory_(url_loader_factory),
  19. blocking_task_runner_(blocking_task_runner),
  20. custom_user_agent_(custom_user_agent),
  21. traffic_annotation_(traffic_annotation) {}
  22. RequestSender::~RequestSender() {
  23. DCHECK(thread_checker_.CalledOnValidThread());
  24. }
  25. base::RepeatingClosure RequestSender::StartRequestWithAuthRetry(
  26. std::unique_ptr<AuthenticatedRequestInterface> request) {
  27. DCHECK(thread_checker_.CalledOnValidThread());
  28. AuthenticatedRequestInterface* request_ptr = request.get();
  29. in_flight_requests_.insert(std::move(request));
  30. return StartRequestWithAuthRetryInternal(request_ptr);
  31. }
  32. base::RepeatingClosure RequestSender::StartRequestWithAuthRetryInternal(
  33. AuthenticatedRequestInterface* request) {
  34. // TODO(kinaba): Stop relying on weak pointers. Move lifetime management
  35. // of the requests to request sender.
  36. base::RepeatingClosure cancel_closure = base::BindRepeating(
  37. &RequestSender::CancelRequest, weak_ptr_factory_.GetWeakPtr(),
  38. request->GetWeakPtr());
  39. if (!auth_service_->HasAccessToken()) {
  40. // Fetch OAuth2 access token from the refresh token first.
  41. auth_service_->StartAuthentication(
  42. base::BindOnce(&RequestSender::OnAccessTokenFetched,
  43. weak_ptr_factory_.GetWeakPtr(), request->GetWeakPtr()));
  44. } else {
  45. request->Start(auth_service_->access_token(), custom_user_agent_,
  46. base::BindRepeating(&RequestSender::RetryRequest,
  47. weak_ptr_factory_.GetWeakPtr()));
  48. }
  49. return cancel_closure;
  50. }
  51. void RequestSender::OnAccessTokenFetched(
  52. const base::WeakPtr<AuthenticatedRequestInterface>& request,
  53. ApiErrorCode code,
  54. const std::string& /* access_token */) {
  55. DCHECK(thread_checker_.CalledOnValidThread());
  56. // Do nothing if the request is canceled during authentication.
  57. if (!request.get())
  58. return;
  59. if (code == HTTP_SUCCESS) {
  60. DCHECK(auth_service_->HasAccessToken());
  61. StartRequestWithAuthRetryInternal(request.get());
  62. } else {
  63. request->OnAuthFailed(code);
  64. }
  65. }
  66. void RequestSender::RetryRequest(AuthenticatedRequestInterface* request) {
  67. DCHECK(thread_checker_.CalledOnValidThread());
  68. auth_service_->ClearAccessToken();
  69. // User authentication might have expired - rerun the request to force
  70. // auth token refresh.
  71. StartRequestWithAuthRetryInternal(request);
  72. }
  73. void RequestSender::CancelRequest(
  74. const base::WeakPtr<AuthenticatedRequestInterface>& request) {
  75. DCHECK(thread_checker_.CalledOnValidThread());
  76. // Do nothing if the request is already finished.
  77. if (!request.get())
  78. return;
  79. request->Cancel();
  80. }
  81. void RequestSender::RequestFinished(AuthenticatedRequestInterface* request) {
  82. auto it = in_flight_requests_.find(request);
  83. if (it == in_flight_requests_.end()) {
  84. // Various BatchUpload tests in DriveApiRequestsTest will commit requests
  85. // using this RequestSender without actually starting them on it. In that
  86. // case, there's nothing to be done, so just return.
  87. return;
  88. }
  89. in_flight_requests_.erase(it);
  90. }
  91. } // namespace google_apis