OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "google_apis/gaia/google_service_auth_error.h" | |
6 #include "net/http/http_status_code.h" | |
7 #include "net/url_request/url_fetcher.h" | |
8 #include "net/url_request/url_request_status.h" | |
5 #include "sync/notifier/gcm_network_channel.h" | 9 #include "sync/notifier/gcm_network_channel.h" |
10 #include "sync/notifier/gcm_network_channel_delegate.h" | |
6 | 11 |
7 namespace syncer { | 12 namespace syncer { |
8 | 13 |
9 GCMNetworkChannel::GCMNetworkChannel() { | 14 GCMNetworkChannel::GCMNetworkChannel( |
15 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | |
16 scoped_ptr<GCMNetworkChannelDelegate> delegate) | |
17 : request_context_getter_(request_context_getter), | |
18 delegate_(delegate.Pass()), | |
19 weak_factory_(this) { | |
20 delegate_->Register(base::Bind(&GCMNetworkChannel::OnRegisterComplete, | |
21 weak_factory_.GetWeakPtr())); | |
10 } | 22 } |
11 | 23 |
12 GCMNetworkChannel::~GCMNetworkChannel() { | 24 GCMNetworkChannel::~GCMNetworkChannel() { |
13 } | 25 } |
14 | 26 |
15 void GCMNetworkChannel::SendEncodedMessage(const std::string& encoded_message) { | 27 void GCMNetworkChannel::UpdateCredentials( |
28 const std::string& email, | |
29 const std::string& token) { | |
30 // Do nothing. We get access token by requesting it for every message. | |
16 } | 31 } |
17 | 32 |
18 void GCMNetworkChannel::UpdateCredentials(const std::string& email, | 33 void GCMNetworkChannel::OnRegisterComplete( |
34 const std::string& registration_id, | |
35 gcm::GCMClient::Result result) { | |
36 DCHECK(CalledOnValidThread()); | |
37 if (result == gcm::GCMClient::SUCCESS) { | |
38 DCHECK(!registration_id.empty()); | |
39 DVLOG(2) << "Got registration_id"; | |
40 registration_id_ = registration_id; | |
41 if (!encoded_message_.empty()) | |
42 RequestAccessToken(); | |
43 } else { | |
44 DVLOG(2) << "Register failed"; | |
45 // TODO(pavely): Don't know what to do if registration fails. Let's not do | |
tim (not reviewing)
2014/01/17 19:33:42
Consider filing a bug to associate with this (and
pavely
2014/01/17 22:52:26
Done.
| |
46 // anything for now. | |
47 } | |
48 } | |
49 | |
50 void GCMNetworkChannel::SendEncodedMessage(const std::string& encoded_message) { | |
51 DCHECK(CalledOnValidThread()); | |
52 DCHECK(!encoded_message.empty()); | |
53 DVLOG(2) << "SendEncodedMessage"; | |
54 encoded_message_ = encoded_message; | |
55 | |
56 if (!registration_id_.empty()) { | |
57 RequestAccessToken(); | |
58 } | |
59 } | |
60 | |
61 void GCMNetworkChannel::RequestAccessToken() { | |
62 DCHECK(CalledOnValidThread()); | |
63 delegate_->RequestToken(base::Bind(&GCMNetworkChannel::OnGetTokenComplete, | |
64 weak_factory_.GetWeakPtr())); | |
65 } | |
66 | |
67 void GCMNetworkChannel::OnGetTokenComplete( | |
68 const GoogleServiceAuthError& error, | |
19 const std::string& token) { | 69 const std::string& token) { |
70 DCHECK(CalledOnValidThread()); | |
71 if (encoded_message_.empty()) { | |
72 // Nothing to do. | |
73 return; | |
74 } | |
75 | |
76 if (!(error == GoogleServiceAuthError::AuthErrorNone())) { | |
tim (not reviewing)
2014/01/17 19:33:42
nit - if (error != GSAE::AuthErrorNone())
pavely
2014/01/17 22:52:26
(error != GSAE::AuthErrorNone()) doesn't compile.
| |
77 // Requesting access token failed. Persistent errors will be reported by | |
78 // token service. Just drop this request, cacheinvalidations will retry | |
79 // sending message and at that time we'll retry requesting access token. | |
80 DVLOG(1) << "RequestAccessToken failed: " << error.ToString(); | |
81 return; | |
82 } | |
83 DCHECK(!token.empty()); | |
84 // Save access token in case POST fails and we need to invalidate it. | |
85 access_token_ = token; | |
86 | |
87 DVLOG(2) << "Got access token, sending message"; | |
88 | |
89 fetcher_.reset(net::URLFetcher::Create(BuildUrl(), net::URLFetcher::POST, | |
90 this)); | |
91 fetcher_->SetRequestContext(request_context_getter_); | |
92 const std::string auth_header("Authorization: Bearer " + access_token_); | |
93 fetcher_->AddExtraRequestHeader(auth_header); | |
94 fetcher_->SetUploadData("application/x-protobuffer", encoded_message_); | |
95 fetcher_->Start(); | |
96 // Clear message to prevent accidentally resending it in the future. | |
97 encoded_message_.clear(); | |
98 } | |
99 | |
100 void GCMNetworkChannel::OnURLFetchComplete(const net::URLFetcher* source) { | |
101 DCHECK(CalledOnValidThread()); | |
102 DCHECK_EQ(fetcher_, source); | |
103 // Free fetcher at the end of function. | |
104 scoped_ptr<net::URLFetcher> fetcher = fetcher_.Pass(); | |
105 | |
106 net::URLRequestStatus status = fetcher->GetStatus(); | |
107 if (!status.is_success()) { | |
108 DVLOG(1) << "URLFetcher failure"; | |
109 return; | |
110 } | |
111 | |
112 if (fetcher->GetResponseCode() == net::HTTP_UNAUTHORIZED) { | |
113 DVLOG(1) << "URLFetcher failure: HTTP_UNAUTHORIZED"; | |
114 delegate_->InvalidateToken(access_token_); | |
115 return; | |
116 } | |
117 DVLOG(2) << "URLFetcher success"; | |
118 } | |
119 | |
120 GURL GCMNetworkChannel::BuildUrl() { | |
121 DCHECK(!registration_id_.empty()); | |
122 // Prepare NetworkEndpointId using registration_id | |
123 // Serialize NetworkEndpointId into byte array and base64 encode. | |
124 // Format url using encoded NetworkEndpointId. | |
125 // TODO(pavely): implement all of the above. | |
126 return GURL("http://invalid.url.com"); | |
20 } | 127 } |
21 | 128 |
22 } // namespace syncer | 129 } // namespace syncer |
OLD | NEW |