Chromium Code Reviews| 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(const std::string& email, |
| 28 const std::string& token) { | |
| 29 // Do nothing. We get access token by requesting it for every message. | |
| 16 } | 30 } |
| 17 | 31 |
| 18 void GCMNetworkChannel::UpdateCredentials(const std::string& email, | 32 void GCMNetworkChannel::OnRegisterComplete(const std::string& registration_id, |
|
rlarocque
2014/01/16 18:52:48
nit: either put this parameter on the next line, o
pavely
2014/01/17 00:44:39
Done.
| |
| 19 const std::string& token) { | 33 gcm::GCMClient::Result result) { |
| 34 if (result == gcm::GCMClient::SUCCESS) { | |
| 35 DCHECK(!registration_id.empty()); | |
| 36 DVLOG(2) << "Got registration_id"; | |
| 37 registration_id_ = registration_id; | |
| 38 if (!encoded_message_.empty()) | |
| 39 RequestAccessToken(); | |
| 40 } else { | |
| 41 DVLOG(2) << "Register failed"; | |
| 42 // TODO(pavely): Don't know what to do if registration fails. Let's not do | |
| 43 // anything for now. | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 void GCMNetworkChannel::SendEncodedMessage(const std::string& encoded_message) { | |
| 48 DCHECK(!encoded_message.empty()); | |
| 49 DVLOG(2) << "SendEncodedMessage"; | |
| 50 encoded_message_ = encoded_message; | |
| 51 | |
| 52 if (!registration_id_.empty()) { | |
| 53 RequestAccessToken(); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 void GCMNetworkChannel::RequestAccessToken() { | |
| 58 delegate_->RequestToken(base::Bind(&GCMNetworkChannel::OnGetTokenComplete, | |
| 59 weak_factory_.GetWeakPtr())); | |
|
rlarocque
2014/01/16 18:52:48
another indentation nit: I think the second line s
pavely
2014/01/17 00:44:39
Done.
| |
| 60 } | |
| 61 | |
| 62 void GCMNetworkChannel::OnGetTokenComplete( | |
| 63 const GoogleServiceAuthError& error, const std::string& token) { | |
| 64 if (encoded_message_.empty()) { | |
| 65 // Nothing to do. | |
| 66 return; | |
| 67 } | |
| 68 | |
| 69 if (!(error == GoogleServiceAuthError::AuthErrorNone())) { | |
| 70 // Requesting access token failed. Persistent errors will be reported by | |
| 71 // token service. Just drop this request, cacheinvalidations will retry | |
| 72 // sending message and at that time we'll retry requesting access token. | |
| 73 DVLOG(1) << "RequestAccessToken failed: " << error.ToString(); | |
| 74 return; | |
| 75 } | |
| 76 DCHECK(!token.empty()); | |
| 77 // Save access token in case POST fails and we need to invalidate it. | |
| 78 access_token_ = token; | |
| 79 | |
| 80 DVLOG(2) << "Got access token, sending message"; | |
| 81 | |
| 82 fetcher_.reset(net::URLFetcher::Create(BuildUrl(), net::URLFetcher::POST, | |
| 83 this)); | |
|
rlarocque
2014/01/16 18:52:48
more nits: I recommend indenting the 'this' parame
pavely
2014/01/17 00:44:39
Done.
| |
| 84 fetcher_->SetRequestContext(request_context_getter_); | |
| 85 std::string auth_header; | |
|
rlarocque
2014/01/16 18:52:48
I think it's slightly better to declare and initia
pavely
2014/01/17 00:44:39
Done.
| |
| 86 auth_header = "Authorization: Bearer " + access_token_; | |
| 87 fetcher_->AddExtraRequestHeader(auth_header); | |
| 88 fetcher_->SetUploadData("application/x-protobuffer", encoded_message_); | |
| 89 fetcher_->Start(); | |
| 90 // Clear message to prevent accidentally resending it in the future. | |
| 91 encoded_message_.clear(); | |
| 92 } | |
| 93 | |
| 94 void GCMNetworkChannel::OnURLFetchComplete(const net::URLFetcher* source) { | |
| 95 DCHECK_EQ(fetcher_, source); | |
| 96 // Free fetcher at the end of function. | |
| 97 scoped_ptr<net::URLFetcher> fetcher = fetcher_.Pass(); | |
| 98 | |
| 99 net::URLRequestStatus status = fetcher->GetStatus(); | |
| 100 if (!status.is_success()) { | |
| 101 DVLOG(1) << "URLFetcher failure"; | |
| 102 return; | |
| 103 } | |
| 104 | |
| 105 if (fetcher->GetResponseCode() == net::HTTP_UNAUTHORIZED) { | |
| 106 DVLOG(1) << "URLFetcher failure: HTTP_UNAUTHORIZED"; | |
| 107 delegate_->InvalidateToken(access_token_); | |
| 108 return; | |
| 109 } | |
| 110 DVLOG(2) << "URLFetcher success"; | |
| 111 } | |
| 112 | |
| 113 GURL GCMNetworkChannel::BuildUrl() { | |
| 114 DCHECK(!registration_id_.empty()); | |
| 115 // Prepare NetworkEndpointId using registration_id | |
| 116 // Serialize NetworkEndpointId into byte array and base64 encode. | |
| 117 // Format url using encoded NetworkEndpointId. | |
| 118 // TODO(pavely): implement all of the above. | |
| 119 return GURL("http://invalid.url.com"); | |
| 20 } | 120 } |
| 21 | 121 |
| 22 } // namespace syncer | 122 } // namespace syncer |
| OLD | NEW |