• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 #include "google_apis/drive/request_sender.h"
6 
7 #include "base/bind.h"
8 #include "base/sequenced_task_runner.h"
9 #include "base/stl_util.h"
10 #include "google_apis/drive/auth_service.h"
11 #include "google_apis/drive/base_requests.h"
12 #include "net/url_request/url_request_context_getter.h"
13 
14 namespace google_apis {
15 
RequestSender(AuthServiceInterface * auth_service,net::URLRequestContextGetter * url_request_context_getter,base::SequencedTaskRunner * blocking_task_runner,const std::string & custom_user_agent)16 RequestSender::RequestSender(
17     AuthServiceInterface* auth_service,
18     net::URLRequestContextGetter* url_request_context_getter,
19     base::SequencedTaskRunner* blocking_task_runner,
20     const std::string& custom_user_agent)
21     : auth_service_(auth_service),
22       url_request_context_getter_(url_request_context_getter),
23       blocking_task_runner_(blocking_task_runner),
24       custom_user_agent_(custom_user_agent),
25       weak_ptr_factory_(this) {
26 }
27 
~RequestSender()28 RequestSender::~RequestSender() {
29   DCHECK(thread_checker_.CalledOnValidThread());
30   STLDeleteContainerPointers(in_flight_requests_.begin(),
31                              in_flight_requests_.end());
32 }
33 
StartRequestWithRetry(AuthenticatedRequestInterface * request)34 base::Closure RequestSender::StartRequestWithRetry(
35     AuthenticatedRequestInterface* request) {
36   DCHECK(thread_checker_.CalledOnValidThread());
37 
38   in_flight_requests_.insert(request);
39 
40   // TODO(kinaba): Stop relying on weak pointers. Move lifetime management
41   // of the requests to request sender.
42   base::Closure cancel_closure =
43       base::Bind(&RequestSender::CancelRequest,
44                  weak_ptr_factory_.GetWeakPtr(),
45                  request->GetWeakPtr());
46 
47   if (!auth_service_->HasAccessToken()) {
48     // Fetch OAuth2 access token from the refresh token first.
49     auth_service_->StartAuthentication(
50         base::Bind(&RequestSender::OnAccessTokenFetched,
51                    weak_ptr_factory_.GetWeakPtr(),
52                    request->GetWeakPtr()));
53   } else {
54     request->Start(auth_service_->access_token(),
55                    custom_user_agent_,
56                    base::Bind(&RequestSender::RetryRequest,
57                               weak_ptr_factory_.GetWeakPtr()));
58   }
59 
60   return cancel_closure;
61 }
62 
OnAccessTokenFetched(const base::WeakPtr<AuthenticatedRequestInterface> & request,GDataErrorCode code,const std::string &)63 void RequestSender::OnAccessTokenFetched(
64     const base::WeakPtr<AuthenticatedRequestInterface>& request,
65     GDataErrorCode code,
66     const std::string& /* access_token */) {
67   DCHECK(thread_checker_.CalledOnValidThread());
68 
69   // Do nothing if the request is canceled during authentication.
70   if (!request.get())
71     return;
72 
73   if (code == HTTP_SUCCESS) {
74     DCHECK(auth_service_->HasAccessToken());
75     StartRequestWithRetry(request.get());
76   } else {
77     request->OnAuthFailed(code);
78   }
79 }
80 
RetryRequest(AuthenticatedRequestInterface * request)81 void RequestSender::RetryRequest(AuthenticatedRequestInterface* request) {
82   DCHECK(thread_checker_.CalledOnValidThread());
83 
84   auth_service_->ClearAccessToken();
85   // User authentication might have expired - rerun the request to force
86   // auth token refresh.
87   StartRequestWithRetry(request);
88 }
89 
CancelRequest(const base::WeakPtr<AuthenticatedRequestInterface> & request)90 void RequestSender::CancelRequest(
91     const base::WeakPtr<AuthenticatedRequestInterface>& request) {
92   DCHECK(thread_checker_.CalledOnValidThread());
93 
94   // Do nothing if the request is already finished.
95   if (!request.get())
96     return;
97   request->Cancel();
98 }
99 
RequestFinished(AuthenticatedRequestInterface * request)100 void RequestSender::RequestFinished(AuthenticatedRequestInterface* request) {
101   in_flight_requests_.erase(request);
102   delete request;
103 }
104 
105 }  // namespace google_apis
106