diff options
author | maksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 00:33:56 +0000 |
---|---|---|
committer | maksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 00:33:56 +0000 |
commit | f7338e611f77821ed272c8c245db873d84d1ad27 (patch) | |
tree | 772fbced29e84a8ee0d19c921020772771649211 /cloud_print | |
parent | 2bec828dfe5a003391903726e1718b18d3d7559d (diff) | |
download | chromium_src-f7338e611f77821ed272c8c245db873d84d1ad27.zip chromium_src-f7338e611f77821ed272c8c245db873d84d1ad27.tar.gz chromium_src-f7338e611f77821ed272c8c245db873d84d1ad27.tar.bz2 |
GCP2.0 Device: Instant AccessToken update on AuthFailed.
Also, registration timeout implemented.
BUG=
Review URL: https://chromiumcodereview.appspot.com/22184007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217880 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print')
-rw-r--r-- | cloud_print/gcp20/prototype/cloud_print_request.cc | 7 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/cloud_print_requester.cc | 15 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/cloud_print_requester.h | 4 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/printer.cc | 129 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/printer.h | 26 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/privet_http_server.cc | 4 | ||||
-rw-r--r-- | cloud_print/gcp20/prototype/privet_http_server.h | 1 |
7 files changed, 133 insertions, 53 deletions
diff --git a/cloud_print/gcp20/prototype/cloud_print_request.cc b/cloud_print/gcp20/prototype/cloud_print_request.cc index 2d36dcc..d8baec2 100644 --- a/cloud_print/gcp20/prototype/cloud_print_request.cc +++ b/cloud_print/gcp20/prototype/cloud_print_request.cc @@ -60,7 +60,6 @@ scoped_ptr<CloudPrintRequest> CloudPrintRequest::CreatePost( void CloudPrintRequest::Run( const std::string& access_token, scoped_refptr<net::URLRequestContextGetter> context_getter) { - if (!access_token.empty()) fetcher_->AddExtraRequestHeader(base::StringPrintf( "Authorization: Bearer \"%s\"", access_token.c_str())); @@ -106,13 +105,13 @@ void CloudPrintRequest::OnURLFetchComplete(const URLFetcher* source) { // this call. } else { - // TODO(maksymb): Add |server_http_code| and |server_api| info for errors. + // TODO(maksymb): Add Privet |server_http_code| and |server_api| support in + // case of server errors. + NOTIMPLEMENTED() << "HTTP code: " << http_code; delegate_->OnFetchError("dummy", -1, http_code); // After this object can // be deleted. // Do *NOT* access members // after this call. - - NOTIMPLEMENTED() << "HTTP code: " << http_code; } } diff --git a/cloud_print/gcp20/prototype/cloud_print_requester.cc b/cloud_print/gcp20/prototype/cloud_print_requester.cc index 1154d62..1910b7f 100644 --- a/cloud_print/gcp20/prototype/cloud_print_requester.cc +++ b/cloud_print/gcp20/prototype/cloud_print_requester.cc @@ -168,10 +168,15 @@ void CloudPrintRequester::OnFetchError(const std::string& server_api, VLOG(3) << "Function: " << __FUNCTION__; EraseRequest(); current_print_job_.reset(); - delegate_->OnServerError("Fetch error"); - // TODO(maksymb): |server_api| and other - NOTIMPLEMENTED(); + if (server_http_code == net::HTTP_FORBIDDEN) { + delegate_->OnAuthError(); + } else { + delegate_->OnServerError("Fetch error"); + } + + // TODO(maksymb): Add Privet |server_http_code| and |server_api| support in + // case of server errors. } void CloudPrintRequester::OnFetchTimeoutReached() { @@ -186,8 +191,8 @@ void CloudPrintRequester::OnGetTokensResponse(const std::string& refresh_token, int expires_in_seconds) { VLOG(3) << "Function: " << __FUNCTION__; gaia_.reset(); - delegate_->OnGetAuthCodeResponseParsed(refresh_token, - access_token, expires_in_seconds); + delegate_->OnRegistrationFinished(refresh_token, + access_token, expires_in_seconds); } void CloudPrintRequester::OnRefreshTokenResponse( diff --git a/cloud_print/gcp20/prototype/cloud_print_requester.h b/cloud_print/gcp20/prototype/cloud_print_requester.h index f9c2487..8e1e46c 100644 --- a/cloud_print/gcp20/prototype/cloud_print_requester.h +++ b/cloud_print/gcp20/prototype/cloud_print_requester.h @@ -39,9 +39,9 @@ class CloudPrintRequester : public base::SupportsWeakPtr<CloudPrintRequester>, const std::string& complete_invite_url, const std::string& device_id) = 0; - // Invoked when server respond for registration-getAuthCode query and + // Invoked when server responded for registration-getAuthCode query and // response is successfully parsed. - virtual void OnGetAuthCodeResponseParsed( + virtual void OnRegistrationFinished( const std::string& refresh_token, const std::string& access_token, int access_token_expires_in_seconds) = 0; diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc index 4583aa7..02813ab 100644 --- a/cloud_print/gcp20/prototype/printer.cc +++ b/cloud_print/gcp20/prototype/printer.cc @@ -39,9 +39,9 @@ const char kPrinterDescription[] = "Printer emulator"; const char kUserConfirmationTitle[] = "Confirm registration: type 'y' if you " "agree and any other to discard\n"; -const int64 kUserConfirmationTimeout = 30; // in seconds - -const uint32 kReconnectTimeout = 5; // in seconds +const int kUserConfirmationTimeout = 30; // in seconds +const int kRegistrationTimeout = 60; // in seconds +const int kReconnectTimeout = 5; // in seconds const double kTimeToNextAccessTokenUpdate = 0.8; // relatively to living time. @@ -184,9 +184,8 @@ void Printer::Stop() { void Printer::OnAuthError() { LOG(ERROR) << "Auth error occurred"; - access_token_update_ = base::Time::Now(); - ChangeState(OFFLINE); - // TODO(maksymb): Implement *instant* updating of access_token. + access_token_update_ = base::Time(); + FallOffline(true); } std::string Printer::GetAccessToken() { @@ -195,6 +194,15 @@ std::string Printer::GetAccessToken() { PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart( const std::string& user) { + CheckRegistrationExpiration(); + + RegistrationInfo::ConfirmationState conf_state = reg_info_.confirmation_state; + if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_ERROR || + conf_state == RegistrationInfo::CONFIRMATION_TIMEOUT || + conf_state == RegistrationInfo::CONFIRMATION_DISCARDED) { + reg_info_ = RegistrationInfo(); + } + PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); if (status != PrivetHttpServer::REG_ERROR_OK) return status; @@ -202,6 +210,8 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart( if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED) return PrivetHttpServer::REG_ERROR_INVALID_ACTION; + UpdateRegistrationExpiration(); + reg_info_ = RegistrationInfo(); reg_info_.user = user; reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_STARTED; @@ -242,6 +252,8 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken( if (reg_info_.confirmation_state != RegistrationInfo::CONFIRMATION_CONFIRMED) return ConfirmationToRegistrationError(reg_info_.confirmation_state); + UpdateRegistrationExpiration(); + // If reply wasn't received yet, reply with |pending_user_action| error. if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_STARTED) return PrivetHttpServer::REG_ERROR_PENDING_USER_ACTION; @@ -268,6 +280,8 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationComplete( return PrivetHttpServer::REG_ERROR_INVALID_ACTION; } + UpdateRegistrationExpiration(); + if (reg_info_.confirmation_state != RegistrationInfo::CONFIRMATION_CONFIRMED) return ConfirmationToRegistrationError(reg_info_.confirmation_state); @@ -289,6 +303,8 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationCancel( if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED) return PrivetHttpServer::REG_ERROR_INVALID_ACTION; + InvalidateRegistrationExpiration(); + reg_info_ = RegistrationInfo(); requester_.reset(new CloudPrintRequester(GetTaskRunner(), this)); @@ -296,13 +312,15 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationCancel( } void Printer::GetRegistrationServerError(std::string* description) { - DCHECK_EQ(reg_info_.state, RegistrationInfo::DEV_REG_REGISTRATION_ERROR) << - "Method shouldn't be called when not needed."; + DCHECK_EQ(reg_info_.state, RegistrationInfo::DEV_REG_REGISTRATION_ERROR) + << "Method shouldn't be called when not needed."; *description = reg_info_.error_description; } void Printer::CreateInfo(PrivetHttpServer::DeviceInfo* info) { + CheckRegistrationExpiration(); + // TODO(maksymb): Replace "text" with constants. *info = PrivetHttpServer::DeviceInfo(); @@ -345,9 +363,11 @@ void Printer::OnRegistrationStartResponseParsed( reg_info_.complete_invite_url = complete_invite_url; } -void Printer::OnGetAuthCodeResponseParsed(const std::string& refresh_token, - const std::string& access_token, - int access_token_expires_in_seconds) { +void Printer::OnRegistrationFinished(const std::string& refresh_token, + const std::string& access_token, + int access_token_expires_in_seconds) { + InvalidateRegistrationExpiration(); + reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; reg_info_.refresh_token = refresh_token; RememberAccessToken(access_token, access_token_expires_in_seconds); @@ -380,20 +400,19 @@ void Printer::OnRegistrationError(const std::string& description) { LOG(ERROR) << "server_error: " << description; // TODO(maksymb): Implement waiting after error and timeout of registration. - reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_ERROR; - reg_info_.error_description = description; + SetRegistrationError(description); } void Printer::OnNetworkError() { VLOG(3) << "Function: " << __FUNCTION__; - ChangeState(OFFLINE); + FallOffline(false); } void Printer::OnServerError(const std::string& description) { VLOG(3) << "Function: " << __FUNCTION__; LOG(ERROR) << "Server error: " << description; - ChangeState(OFFLINE); + FallOffline(false); } void Printer::OnPrintJobsAvailable(const std::vector<Job>& jobs) { @@ -439,7 +458,7 @@ void Printer::OnXmppAuthError() { } void Printer::OnXmppNetworkError() { - ChangeState(OFFLINE); + FallOffline(false); } void Printer::OnXmppNewPrintJob(const std::string& device_id) { @@ -542,9 +561,18 @@ void Printer::RememberAccessToken(const std::string& access_token, SaveToFile(); } +void Printer::SetRegistrationError(const std::string& description) { + DCHECK(!IsRegistered()); + reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_ERROR; + reg_info_.error_description = description; +} + PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors( - const std::string& user) const { + const std::string& user) { + CheckRegistrationExpiration(); DCHECK(!IsRegistered()); + if (connection_state_ != ONLINE) + return PrivetHttpServer::REG_ERROR_OFFLINE; if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED && user != reg_info_.user) { @@ -554,10 +582,14 @@ PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors( if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_ERROR) return PrivetHttpServer::REG_ERROR_SERVER_ERROR; + DCHECK(connection_state_ == ONLINE); + return PrivetHttpServer::REG_ERROR_OK; } void Printer::WaitUserConfirmation(base::Time valid_until) { + // TODO(maksymb): Move to separate class. + if (base::Time::Now() > valid_until) { reg_info_.confirmation_state = RegistrationInfo::CONFIRMATION_TIMEOUT; LOG(INFO) << "Confirmation timeout reached."; @@ -723,9 +755,28 @@ void Printer::PostOnIdle() { base::Bind(&Printer::OnIdle, AsWeakPtr())); } +void Printer::CheckRegistrationExpiration() { + if (!registration_expiration_.is_null() && + registration_expiration_ < base::Time::Now()) { + reg_info_ = RegistrationInfo(); + InvalidateRegistrationExpiration(); + if (connection_state_ != ONLINE) + TryConnect(); + } +} + +void Printer::UpdateRegistrationExpiration() { + registration_expiration_ = + base::Time::Now() + base::TimeDelta::FromSeconds(kRegistrationTimeout); +} + +void Printer::InvalidateRegistrationExpiration() { + registration_expiration_ = base::Time(); +} + PrivetHttpServer::RegistrationErrorStatus - Printer::ConfirmationToRegistrationError( - RegistrationInfo::ConfirmationState state) { +Printer::ConfirmationToRegistrationError( + RegistrationInfo::ConfirmationState state) { switch (state) { case RegistrationInfo::CONFIRMATION_PENDING: return PrivetHttpServer::REG_ERROR_PENDING_USER_ACTION; @@ -759,6 +810,23 @@ std::string Printer::ConnectionStateToString(ConnectionState state) const { } } +void Printer::FallOffline(bool instant_reconnect) { + bool changed = ChangeState(OFFLINE); + DCHECK(changed) << "Falling offline from offline is now allowed"; + + if (!IsRegistered()) + SetRegistrationError("Cannot access server during registration process"); + + if (instant_reconnect) { + TryConnect(); + } else { + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&Printer::TryConnect, AsWeakPtr()), + base::TimeDelta::FromSeconds(kReconnectTimeout)); + } +} + bool Printer::ChangeState(ConnectionState new_state) { if (connection_state_ == new_state) return false; @@ -771,26 +839,9 @@ bool Printer::ChangeState(ConnectionState new_state) { dns_server_.UpdateMetadata(CreateTxt()); - switch (connection_state_) { - case CONNECTING: - break; - - case ONLINE: - break; - - case OFFLINE: - requester_.reset(); - xmpp_listener_.reset(); - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&Printer::TryConnect, AsWeakPtr()), - base::TimeDelta::FromSeconds(kReconnectTimeout)); - - case NOT_CONFIGURED: - break; - - default: - NOTREACHED(); + if (connection_state_ == OFFLINE) { + requester_.reset(); + xmpp_listener_.reset(); } return true; diff --git a/cloud_print/gcp20/prototype/printer.h b/cloud_print/gcp20/prototype/printer.h index fab9189..b4ee260 100644 --- a/cloud_print/gcp20/prototype/printer.h +++ b/cloud_print/gcp20/prototype/printer.h @@ -115,7 +115,7 @@ class Printer : public base::SupportsWeakPtr<Printer>, const std::string& registration_token, const std::string& complete_invite_url, const std::string& device_id) OVERRIDE; - virtual void OnGetAuthCodeResponseParsed( + virtual void OnRegistrationFinished( const std::string& refresh_token, const std::string& access_token, int access_token_expires_in_seconds) OVERRIDE; @@ -165,11 +165,14 @@ class Printer : public base::SupportsWeakPtr<Printer>, void RememberAccessToken(const std::string& access_token, int expires_in_seconds); + // Sets registration state to error and adds description. + void SetRegistrationError(const std::string& description); + // Checks if register call is called correctly (|user| is correct, // error is no set etc). Returns |false| if error status is put into |status|. // Otherwise no error was occurred. PrivetHttpServer::RegistrationErrorStatus CheckCommonRegErrors( - const std::string& user) const; + const std::string& user); // Checks if confirmation was received. void WaitUserConfirmation(base::Time valid_until); @@ -187,13 +190,27 @@ class Printer : public base::SupportsWeakPtr<Printer>, // Adds |OnIdle| method to the MessageLoop. void PostOnIdle(); + // Registration timeout. + void CheckRegistrationExpiration(); + + // Delays expiration after user action. + void UpdateRegistrationExpiration(); + + // Deletes registration expiration at all. + void InvalidateRegistrationExpiration(); + // Converts errors. PrivetHttpServer::RegistrationErrorStatus ConfirmationToRegistrationError( RegistrationInfo::ConfirmationState state); std::string ConnectionStateToString(ConnectionState state) const; - // Changes state and update info in DNS server. + // Changes state to OFFLINE and posts TryReconnect. + // For registration reconnect is instant every time. + void FallOffline(bool instant_reconnect); + + // Changes state and update info in DNS server. Returns |true| if state + // was changed (otherwise state was the same). bool ChangeState(ConnectionState new_state); RegistrationInfo reg_info_; @@ -224,6 +241,9 @@ class Printer : public base::SupportsWeakPtr<Printer>, // Uses for calculating uptime. base::Time starttime_; + // Uses to validate registration timeout. + base::Time registration_expiration_; + // Used for preventing two and more OnIdle posted in message loop. bool on_idle_posted_; diff --git a/cloud_print/gcp20/prototype/privet_http_server.cc b/cloud_print/gcp20/prototype/privet_http_server.cc index 0a21059..45e633d 100644 --- a/cloud_print/gcp20/prototype/privet_http_server.cc +++ b/cloud_print/gcp20/prototype/privet_http_server.cc @@ -315,6 +315,10 @@ void PrivetHttpServer::ProcessRegistrationStatus( case REG_ERROR_INVALID_ACTION: *current_response = CreateError("invalid_action"); break; + case REG_ERROR_OFFLINE: + *current_response = CreateError("offline"); + break; + case REG_ERROR_SERVER_ERROR: { std::string description; delegate_->GetRegistrationServerError(&description); diff --git a/cloud_print/gcp20/prototype/privet_http_server.h b/cloud_print/gcp20/prototype/privet_http_server.h index fc80d90..b551976 100644 --- a/cloud_print/gcp20/prototype/privet_http_server.h +++ b/cloud_print/gcp20/prototype/privet_http_server.h @@ -29,6 +29,7 @@ class PrivetHttpServer: public net::HttpServer::Delegate { REG_ERROR_USER_CANCEL, REG_ERROR_CONFIRMATION_TIMEOUT, REG_ERROR_INVALID_ACTION, + REG_ERROR_OFFLINE, REG_ERROR_SERVER_ERROR }; |