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 16 RequestSender::RequestSender( 17 AuthServiceInterface* auth_service, 18 net::URLRequestContextGetter* url_request_context_getter, 19 const scoped_refptr<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 28 RequestSender::~RequestSender() { 29 DCHECK(thread_checker_.CalledOnValidThread()); 30 STLDeleteContainerPointers(in_flight_requests_.begin(), 31 in_flight_requests_.end()); 32 } 33 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 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 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 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 100 void RequestSender::RequestFinished(AuthenticatedRequestInterface* request) { 101 in_flight_requests_.erase(request); 102 delete request; 103 } 104 105 } // namespace google_apis 106