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.
5 #include "chrome/browser/google_apis/request_sender.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 #include "net/url_request/url_request_context_getter.h"
13 namespace google_apis {
15 RequestSender::RequestSender(
16 AuthServiceInterface* auth_service,
17 net::URLRequestContextGetter* url_request_context_getter,
18 base::TaskRunner* blocking_task_runner,
19 const std::string& custom_user_agent)
20 : auth_service_(auth_service),
21 url_request_context_getter_(url_request_context_getter),
22 blocking_task_runner_(blocking_task_runner),
23 custom_user_agent_(custom_user_agent),
24 weak_ptr_factory_(this) {
27 RequestSender::~RequestSender() {
28 DCHECK(thread_checker_.CalledOnValidThread());
29 STLDeleteContainerPointers(in_flight_requests_.begin(),
30 in_flight_requests_.end());
33 base::Closure RequestSender::StartRequestWithRetry(
34 AuthenticatedRequestInterface* request) {
35 DCHECK(thread_checker_.CalledOnValidThread());
37 in_flight_requests_.insert(request);
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());
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()));
53 request->Start(auth_service_->access_token(),
55 base::Bind(&RequestSender::RetryRequest,
56 weak_ptr_factory_.GetWeakPtr()));
59 return cancel_closure;
62 void RequestSender::OnAccessTokenFetched(
63 const base::WeakPtr<AuthenticatedRequestInterface>& request,
65 const std::string& /* access_token */) {
66 DCHECK(thread_checker_.CalledOnValidThread());
68 // Do nothing if the request is canceled during authentication.
72 if (code == HTTP_SUCCESS) {
73 DCHECK(auth_service_->HasAccessToken());
74 StartRequestWithRetry(request.get());
76 request->OnAuthFailed(code);
80 void RequestSender::RetryRequest(AuthenticatedRequestInterface* request) {
81 DCHECK(thread_checker_.CalledOnValidThread());
83 auth_service_->ClearAccessToken();
84 // User authentication might have expired - rerun the request to force
85 // auth token refresh.
86 StartRequestWithRetry(request);
89 void RequestSender::CancelRequest(
90 const base::WeakPtr<AuthenticatedRequestInterface>& request) {
91 DCHECK(thread_checker_.CalledOnValidThread());
93 // Do nothing if the request is already finished.
99 void RequestSender::RequestFinished(AuthenticatedRequestInterface* request) {
100 in_flight_requests_.erase(request);
104 } // namespace google_apis