- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / google_apis / request_sender.cc
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 #include "net/url_request/url_request_context_getter.h"
12
13 namespace google_apis {
14
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) {
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