summaryrefslogtreecommitdiffstats
path: root/google_apis
diff options
context:
space:
mode:
authorfgorski@chromium.org <fgorski@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-01 00:13:05 +0000
committerfgorski@chromium.org <fgorski@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-01 00:13:05 +0000
commit96b720aad18057f9ad42316240748001c20af375 (patch)
treebf23a9ea47949f75a483edbe2884b2adfb0c2d0a /google_apis
parentd19885a56feafa2865d7b4b41c27d88fa68d3a6c (diff)
downloadchromium_src-96b720aad18057f9ad42316240748001c20af375.zip
chromium_src-96b720aad18057f9ad42316240748001c20af375.tar.gz
chromium_src-96b720aad18057f9ad42316240748001c20af375.tar.bz2
[GCM] RegistrationRequest is retrying when sender is invlalid
It turns out that some of the Error="*" responses come as HTTP_OK, and some not. Given that check for HTTP_OK was done before response was parsed, we were missing some of the error conditions, including INVALID_SENDER and retrying assuming UNKNOWN_ERROR. The problem was already partially mitigated by failing after sever attempts, but with this fix we will actually start seeing the INVALID_SENDER response. Semantics of the HTTP_NOT_OK result was updated to distinguish it from UNKNOWN_ERROR in the following way: * if we have HTTP_OK but cannot parse token or error, we return UNKNOWN_ERROR, * if we don't have HTTP_OK an cannot parse error, we return HTTP_NOT_OK. Also updating the string comparisons in GetStatusFromError to use find instead of ==, to make sure that if there is more content in response, we can parse the error. BUG=345408 Review URL: https://codereview.chromium.org/181743004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254282 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'google_apis')
-rw-r--r--google_apis/gcm/engine/registration_request.cc48
-rw-r--r--google_apis/gcm/engine/registration_request_unittest.cc15
2 files changed, 44 insertions, 19 deletions
diff --git a/google_apis/gcm/engine/registration_request.cc b/google_apis/gcm/engine/registration_request.cc
index a6fd036..3acd591 100644
--- a/google_apis/gcm/engine/registration_request.cc
+++ b/google_apis/gcm/engine/registration_request.cc
@@ -54,13 +54,15 @@ void BuildFormEncoding(const std::string& key,
// Gets correct status from the error message.
RegistrationRequest::Status GetStatusFromError(const std::string& error) {
- if (error == kDeviceRegistrationError)
+ // TODO(fgorski): Improve error parsing in case there is nore then just an
+ // Error=ERROR_STRING in response.
+ if (error.find(kDeviceRegistrationError) != std::string::npos)
return RegistrationRequest::DEVICE_REGISTRATION_ERROR;
- if (error == kAuthenticationFailed)
+ if (error.find(kAuthenticationFailed) != std::string::npos)
return RegistrationRequest::AUTHENTICATION_FAILED;
- if (error == kInvalidSender)
+ if (error.find(kInvalidSender) != std::string::npos)
return RegistrationRequest::INVALID_SENDER;
- if (error == kInvalidParameters)
+ if (error.find(kInvalidParameters) != std::string::npos)
return RegistrationRequest::INVALID_PARAMETERS;
return RegistrationRequest::UNKNOWN_ERROR;
}
@@ -189,29 +191,39 @@ RegistrationRequest::Status RegistrationRequest::ParseResponse(
LOG(ERROR) << "URL fetching failed.";
return URL_FETCHING_FAILED;
}
- if (source->GetResponseCode() != net::HTTP_OK) {
- LOG(ERROR) << "URL fetching HTTP response code is not OK. It is "
- << source->GetResponseCode();
- return HTTP_NOT_OK;
- }
+
std::string response;
if (!source->GetResponseAsString(&response)) {
LOG(ERROR) << "Failed to parse registration response as a string.";
return RESPONSE_PARSING_FAILED;
}
- DVLOG(1) << "Parsing registration response: " << response;
- size_t token_pos = response.find(kTokenPrefix);
- if (token_pos != std::string::npos) {
- *token = response.substr(token_pos + arraysize(kTokenPrefix) - 1);
- return SUCCESS;
+ if (source->GetResponseCode() == net::HTTP_OK) {
+ size_t token_pos = response.find(kTokenPrefix);
+ if (token_pos != std::string::npos) {
+ *token = response.substr(token_pos + arraysize(kTokenPrefix) - 1);
+ return SUCCESS;
+ }
}
+ // If we are able to parse a meaningful known error, let's do so. Some errors
+ // will have HTTP_BAD_REQUEST, some will have HTTP_OK response code.
size_t error_pos = response.find(kErrorPrefix);
- if (error_pos == std::string::npos)
- return UNKNOWN_ERROR;
- std::string error = response.substr(error_pos + arraysize(kErrorPrefix) - 1);
- return GetStatusFromError(error);
+ if (error_pos != std::string::npos) {
+ std::string error = response.substr(
+ error_pos + arraysize(kErrorPrefix) - 1);
+ return GetStatusFromError(error);
+ }
+
+ // If we cannot tell what the error is, but at least we know response code was
+ // not OK.
+ if (source->GetResponseCode() != net::HTTP_OK) {
+ DLOG(ERROR) << "URL fetching HTTP response code is not OK. It is "
+ << source->GetResponseCode();
+ return HTTP_NOT_OK;
+ }
+
+ return UNKNOWN_ERROR;
}
void RegistrationRequest::OnURLFetchComplete(const net::URLFetcher* source) {
diff --git a/google_apis/gcm/engine/registration_request_unittest.cc b/google_apis/gcm/engine/registration_request_unittest.cc
index 4764d13..f08c4f4 100644
--- a/google_apis/gcm/engine/registration_request_unittest.cc
+++ b/google_apis/gcm/engine/registration_request_unittest.cc
@@ -293,7 +293,8 @@ TEST_F(RegistrationRequestTest, ResponseAuthenticationError) {
CreateRequest("sender1,sender2");
request_->Start();
- SetResponseStatusAndString(net::HTTP_OK, "Error=AUTHENTICATION_FAILED");
+ SetResponseStatusAndString(net::HTTP_UNAUTHORIZED,
+ "Error=AUTHENTICATION_FAILED");
CompleteFetch();
EXPECT_FALSE(callback_called_);
@@ -331,6 +332,18 @@ TEST_F(RegistrationRequestTest, ResponseInvalidSender) {
EXPECT_EQ(std::string(), registration_id_);
}
+TEST_F(RegistrationRequestTest, ResponseInvalidSenderBadRequest) {
+ CreateRequest("sender1");
+ request_->Start();
+
+ SetResponseStatusAndString(net::HTTP_BAD_REQUEST, "Error=INVALID_SENDER");
+ CompleteFetch();
+
+ EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(RegistrationRequest::INVALID_SENDER, status_);
+ EXPECT_EQ(std::string(), registration_id_);
+}
+
TEST_F(RegistrationRequestTest, RequestNotSuccessful) {
CreateRequest("sender1,sender2");
request_->Start();