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