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/gcm/engine/registration_request.h" | 5 #include "google_apis/gcm/engine/registration_request.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 27 matching lines...) Expand all Loading... | |
38 const char kDeviceIdKey[] = "device"; | 38 const char kDeviceIdKey[] = "device"; |
39 const char kLoginHeader[] = "AidLogin"; | 39 const char kLoginHeader[] = "AidLogin"; |
40 | 40 |
41 // Response constants. | 41 // Response constants. |
42 const char kErrorPrefix[] = "Error="; | 42 const char kErrorPrefix[] = "Error="; |
43 const char kTokenPrefix[] = "token="; | 43 const char kTokenPrefix[] = "token="; |
44 const char kDeviceRegistrationError[] = "PHONE_REGISTRATION_ERROR"; | 44 const char kDeviceRegistrationError[] = "PHONE_REGISTRATION_ERROR"; |
45 const char kAuthenticationFailed[] = "AUTHENTICATION_FAILED"; | 45 const char kAuthenticationFailed[] = "AUTHENTICATION_FAILED"; |
46 const char kInvalidSender[] = "INVALID_SENDER"; | 46 const char kInvalidSender[] = "INVALID_SENDER"; |
47 const char kInvalidParameters[] = "INVALID_PARAMETERS"; | 47 const char kInvalidParameters[] = "INVALID_PARAMETERS"; |
48 const char kInternalServerError[] = "InternalServerError"; | |
Nicolas Zea
2016/10/20 21:05:23
Is this defined server-side? Seems odd that the fo
johnme
2016/11/01 14:15:40
Yup, this one just happens to be CamelCase for no
| |
49 const char kQuotaExceeded[] = "QUOTA_EXCEEDED"; | |
50 const char kTooManyRegistrations[] = "TOO_MANY_REGISTRATIONS"; | |
48 | 51 |
49 // Gets correct status from the error message. | 52 // Gets correct status from the error message. |
50 RegistrationRequest::Status GetStatusFromError(const std::string& error) { | 53 RegistrationRequest::Status GetStatusFromError(const std::string& error) { |
51 // TODO(fgorski): Improve error parsing in case there is nore then just an | |
52 // Error=ERROR_STRING in response. | |
53 if (error.find(kDeviceRegistrationError) != std::string::npos) | 54 if (error.find(kDeviceRegistrationError) != std::string::npos) |
54 return RegistrationRequest::DEVICE_REGISTRATION_ERROR; | 55 return RegistrationRequest::DEVICE_REGISTRATION_ERROR; |
55 if (error.find(kAuthenticationFailed) != std::string::npos) | 56 if (error.find(kAuthenticationFailed) != std::string::npos) |
56 return RegistrationRequest::AUTHENTICATION_FAILED; | 57 return RegistrationRequest::AUTHENTICATION_FAILED; |
57 if (error.find(kInvalidSender) != std::string::npos) | 58 if (error.find(kInvalidSender) != std::string::npos) |
58 return RegistrationRequest::INVALID_SENDER; | 59 return RegistrationRequest::INVALID_SENDER; |
59 if (error.find(kInvalidParameters) != std::string::npos) | 60 if (error.find(kInvalidParameters) != std::string::npos) |
60 return RegistrationRequest::INVALID_PARAMETERS; | 61 return RegistrationRequest::INVALID_PARAMETERS; |
62 if (error.find(kInternalServerError) != std::string::npos) | |
63 return RegistrationRequest::INTERNAL_SERVER_ERROR; | |
64 if (error.find(kQuotaExceeded) != std::string::npos) | |
65 return RegistrationRequest::QUOTA_EXCEEDED; | |
66 if (error.find(kTooManyRegistrations) != std::string::npos) | |
67 return RegistrationRequest::TOO_MANY_REGISTRATIONS; | |
68 // Should not be reached, unless the server adds new error types. | |
61 return RegistrationRequest::UNKNOWN_ERROR; | 69 return RegistrationRequest::UNKNOWN_ERROR; |
62 } | 70 } |
63 | 71 |
64 // Determines whether to retry based on the status of the last request. | 72 // Determines whether to retry based on the status of the last request. |
65 bool ShouldRetryWithStatus(RegistrationRequest::Status status) { | 73 bool ShouldRetryWithStatus(RegistrationRequest::Status status) { |
66 switch (status) { | 74 switch (status) { |
67 case RegistrationRequest::AUTHENTICATION_FAILED: | 75 case RegistrationRequest::AUTHENTICATION_FAILED: |
68 case RegistrationRequest::DEVICE_REGISTRATION_ERROR: | 76 case RegistrationRequest::DEVICE_REGISTRATION_ERROR: |
69 case RegistrationRequest::UNKNOWN_ERROR: | 77 case RegistrationRequest::UNKNOWN_ERROR: |
70 case RegistrationRequest::URL_FETCHING_FAILED: | 78 case RegistrationRequest::URL_FETCHING_FAILED: |
71 case RegistrationRequest::HTTP_NOT_OK: | 79 case RegistrationRequest::HTTP_NOT_OK: |
72 case RegistrationRequest::NO_RESPONSE_BODY: | 80 case RegistrationRequest::NO_RESPONSE_BODY: |
81 case RegistrationRequest::RESPONSE_PARSING_FAILED: | |
82 case RegistrationRequest::INTERNAL_SERVER_ERROR: | |
73 return true; | 83 return true; |
74 case RegistrationRequest::SUCCESS: | 84 case RegistrationRequest::SUCCESS: |
75 case RegistrationRequest::INVALID_PARAMETERS: | 85 case RegistrationRequest::INVALID_PARAMETERS: |
76 case RegistrationRequest::INVALID_SENDER: | 86 case RegistrationRequest::INVALID_SENDER: |
87 case RegistrationRequest::QUOTA_EXCEEDED: | |
88 case RegistrationRequest::TOO_MANY_REGISTRATIONS: | |
77 case RegistrationRequest::REACHED_MAX_RETRIES: | 89 case RegistrationRequest::REACHED_MAX_RETRIES: |
78 return false; | 90 return false; |
79 case RegistrationRequest::STATUS_COUNT: | 91 case RegistrationRequest::STATUS_COUNT: |
80 NOTREACHED(); | 92 NOTREACHED(); |
81 break; | 93 break; |
82 } | 94 } |
83 return false; | 95 return false; |
84 } | 96 } |
85 | 97 |
86 } // namespace | 98 } // namespace |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 DCHECK(!weak_ptr_factory_.HasWeakPtrs()); | 204 DCHECK(!weak_ptr_factory_.HasWeakPtrs()); |
193 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 205 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
194 FROM_HERE, | 206 FROM_HERE, |
195 base::Bind(&RegistrationRequest::Start, weak_ptr_factory_.GetWeakPtr()), | 207 base::Bind(&RegistrationRequest::Start, weak_ptr_factory_.GetWeakPtr()), |
196 backoff_entry_.GetTimeUntilRelease()); | 208 backoff_entry_.GetTimeUntilRelease()); |
197 } | 209 } |
198 | 210 |
199 RegistrationRequest::Status RegistrationRequest::ParseResponse( | 211 RegistrationRequest::Status RegistrationRequest::ParseResponse( |
200 const net::URLFetcher* source, std::string* token) { | 212 const net::URLFetcher* source, std::string* token) { |
201 if (!source->GetStatus().is_success()) { | 213 if (!source->GetStatus().is_success()) { |
202 LOG(ERROR) << "URL fetching failed."; | 214 DVLOG(1) << "Registration URL fetching failed."; |
203 return URL_FETCHING_FAILED; | 215 return URL_FETCHING_FAILED; |
204 } | 216 } |
205 | 217 |
206 std::string response; | 218 std::string response; |
207 if (!source->GetResponseAsString(&response)) { | 219 if (!source->GetResponseAsString(&response)) { |
208 LOG(ERROR) << "Failed to parse registration response as a string."; | 220 DVLOG(1) << "Failed to get registration response body."; |
209 return NO_RESPONSE_BODY; | 221 return NO_RESPONSE_BODY; |
210 } | 222 } |
211 | 223 |
212 if (source->GetResponseCode() == net::HTTP_OK) { | 224 // If we are able to parse a meaningful known error, let's do so. Note that |
213 size_t token_pos = response.find(kTokenPrefix); | 225 // some errors will have HTTP_OK response code! |
214 if (token_pos != std::string::npos) { | |
215 *token = response.substr(token_pos + arraysize(kTokenPrefix) - 1); | |
216 return SUCCESS; | |
217 } | |
218 } | |
219 | |
220 // If we are able to parse a meaningful known error, let's do so. Some errors | |
221 // will have HTTP_BAD_REQUEST, some will have HTTP_OK response code. | |
222 size_t error_pos = response.find(kErrorPrefix); | 226 size_t error_pos = response.find(kErrorPrefix); |
223 if (error_pos != std::string::npos) { | 227 if (error_pos != std::string::npos) { |
224 std::string error = response.substr( | 228 std::string error = response.substr( |
225 error_pos + arraysize(kErrorPrefix) - 1); | 229 error_pos + arraysize(kErrorPrefix) - 1); |
230 DVLOG(1) << "Registration response error message: " << error; | |
226 return GetStatusFromError(error); | 231 return GetStatusFromError(error); |
227 } | 232 } |
228 | 233 |
229 // If we cannot tell what the error is, but at least we know response code was | 234 // If we cannot tell what the error is, but at least we know response code was |
230 // not OK. | 235 // not OK. |
231 if (source->GetResponseCode() != net::HTTP_OK) { | 236 if (source->GetResponseCode() != net::HTTP_OK) { |
232 DLOG(ERROR) << "URL fetching HTTP response code is not OK. It is " | 237 DVLOG(1) << "Registration HTTP response code not OK: " |
233 << source->GetResponseCode(); | 238 << source->GetResponseCode(); |
234 return HTTP_NOT_OK; | 239 return HTTP_NOT_OK; |
235 } | 240 } |
236 | 241 |
237 return UNKNOWN_ERROR; | 242 size_t token_pos = response.find(kTokenPrefix); |
243 if (token_pos != std::string::npos) { | |
244 *token = response.substr(token_pos + arraysize(kTokenPrefix) - 1); | |
245 return SUCCESS; | |
246 } | |
247 | |
248 return RESPONSE_PARSING_FAILED; | |
238 } | 249 } |
239 | 250 |
240 void RegistrationRequest::OnURLFetchComplete(const net::URLFetcher* source) { | 251 void RegistrationRequest::OnURLFetchComplete(const net::URLFetcher* source) { |
241 std::string token; | 252 std::string token; |
242 Status status = ParseResponse(source, &token); | 253 Status status = ParseResponse(source, &token); |
243 recorder_->RecordRegistrationResponse(request_info_.app_id(), | 254 recorder_->RecordRegistrationResponse(request_info_.app_id(), |
244 source_to_record_, status); | 255 source_to_record_, status); |
245 | 256 |
246 DCHECK(custom_request_handler_.get()); | 257 DCHECK(custom_request_handler_.get()); |
247 custom_request_handler_->ReportUMAs( | 258 custom_request_handler_->ReportUMAs( |
(...skipping 14 matching lines...) Expand all Loading... | |
262 // Only REACHED_MAX_RETRIES is reported because the function will skip | 273 // Only REACHED_MAX_RETRIES is reported because the function will skip |
263 // reporting count and time when status is not SUCCESS. | 274 // reporting count and time when status is not SUCCESS. |
264 DCHECK(custom_request_handler_.get()); | 275 DCHECK(custom_request_handler_.get()); |
265 custom_request_handler_->ReportUMAs(status, 0, base::TimeDelta()); | 276 custom_request_handler_->ReportUMAs(status, 0, base::TimeDelta()); |
266 } | 277 } |
267 | 278 |
268 callback_.Run(status, token); | 279 callback_.Run(status, token); |
269 } | 280 } |
270 | 281 |
271 } // namespace gcm | 282 } // namespace gcm |
OLD | NEW |