Home | History | Annotate | Download | only in drive
      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