| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "sync/test/accounts_client/test_accounts_client.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/json/json_reader.h" | |
| 12 #include "base/json/json_writer.h" | |
| 13 #include "base/message_loop/message_loop.h" | |
| 14 #include "base/run_loop.h" | |
| 15 #include "base/strings/stringprintf.h" | |
| 16 #include "base/time/time.h" | |
| 17 #include "base/values.h" | |
| 18 #include "net/base/url_util.h" | |
| 19 #include "net/http/http_status_code.h" | |
| 20 #include "net/url_request/url_fetcher.h" | |
| 21 #include "net/url_request/url_fetcher_delegate.h" | |
| 22 #include "net/url_request/url_request.h" | |
| 23 #include "net/url_request/url_request_context_getter.h" | |
| 24 #include "sync/test/accounts_client/url_request_context_getter.h" | |
| 25 | |
| 26 using std::string; | |
| 27 using std::vector; | |
| 28 | |
| 29 static const int kMaxSessionLifetimeSeconds = 30 * 60; | |
| 30 static const string kClaimPath = "claim"; | |
| 31 static const string kReleasePath = "release"; | |
| 32 static const base::TimeDelta kRequestTimeout = base::TimeDelta::FromSeconds(10); | |
| 33 | |
| 34 AccountSession::AccountSession() {} | |
| 35 AccountSession::~AccountSession() {} | |
| 36 | |
| 37 class AccountsRequestDelegate : public net::URLFetcherDelegate { | |
| 38 public: | |
| 39 AccountsRequestDelegate(base::RunLoop* run_loop) : response_(""), | |
| 40 success_(false), run_loop_(run_loop) {} | |
| 41 | |
| 42 void OnURLFetchComplete(const net::URLFetcher* source) override { | |
| 43 string url = source->GetURL().spec(); | |
| 44 source->GetResponseAsString(&response_); | |
| 45 | |
| 46 if (!source->GetStatus().is_success()) { | |
| 47 int error = source->GetStatus().error(); | |
| 48 DVLOG(0) << "The request failed with error code " << error << "." | |
| 49 << "\nRequested URL: " << url << "."; | |
| 50 } else if (source->GetResponseCode() != net::HTTP_OK) { | |
| 51 DVLOG(0) << "The request failed with response code " | |
| 52 << source->GetResponseCode() << "." | |
| 53 << "\nRequested URL: " << url | |
| 54 << "\nResponse body: \"" << response_ << "\""; | |
| 55 } else { | |
| 56 success_ = true; | |
| 57 } | |
| 58 | |
| 59 run_loop_->Quit(); | |
| 60 } | |
| 61 | |
| 62 string response() const { return response_; } | |
| 63 bool success() const { return success_; } | |
| 64 | |
| 65 private: | |
| 66 string response_; | |
| 67 bool success_; | |
| 68 base::RunLoop* run_loop_; | |
| 69 }; | |
| 70 | |
| 71 TestAccountsClient::TestAccountsClient(const string& server, | |
| 72 const string& account_space, | |
| 73 const vector<string>& usernames) | |
| 74 : server_(server), account_space_(account_space), usernames_(usernames) { | |
| 75 } | |
| 76 | |
| 77 TestAccountsClient::~TestAccountsClient() {} | |
| 78 | |
| 79 bool TestAccountsClient::ClaimAccount(AccountSession* session) { | |
| 80 GURL url = CreateGURLWithPath(kClaimPath); | |
| 81 url = net::AppendQueryParameter(url, "account_space", account_space_); | |
| 82 string max_lifetime_seconds = base::StringPrintf("%d", | |
| 83 kMaxSessionLifetimeSeconds); | |
| 84 url = net::AppendQueryParameter(url, "max_lifetime_seconds", | |
| 85 max_lifetime_seconds); | |
| 86 | |
| 87 // TODO(pvalenzuela): Select N random usernames instead of all usernames. | |
| 88 for (vector<string>::iterator it = usernames_.begin(); | |
| 89 it != usernames_.end(); ++it) { | |
| 90 url = net::AppendQueryParameter(url, "username", *it); | |
| 91 } | |
| 92 | |
| 93 string response; | |
| 94 if (!SendRequest(url, &response)) { | |
| 95 return false; | |
| 96 } | |
| 97 | |
| 98 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); | |
| 99 base::DictionaryValue* dict_value; | |
| 100 if (value != NULL && value->GetAsDictionary(&dict_value) && | |
| 101 dict_value != NULL) { | |
| 102 dict_value->GetString("username", &session->username); | |
| 103 dict_value->GetString("account_space", &session->account_space); | |
| 104 dict_value->GetString("session_id", &session->session_id); | |
| 105 dict_value->GetString("expiration_time", &session->expiration_time); | |
| 106 } else { | |
| 107 return false; | |
| 108 } | |
| 109 | |
| 110 return true; | |
| 111 } | |
| 112 | |
| 113 void TestAccountsClient::ReleaseAccount(const AccountSession& session) { | |
| 114 // The expiration_time field is ignored since it isn't passed as part of the | |
| 115 // release request. | |
| 116 if (session.username.empty() || session.account_space.empty() || | |
| 117 account_space_.compare(session.account_space) != 0 || | |
| 118 session.session_id.empty()) { | |
| 119 return; | |
| 120 } | |
| 121 | |
| 122 GURL url = CreateGURLWithPath(kReleasePath); | |
| 123 url = net::AppendQueryParameter(url, "account_space", session.account_space); | |
| 124 url = net::AppendQueryParameter(url, "username", session.username); | |
| 125 url = net::AppendQueryParameter(url, "session_id", session.session_id); | |
| 126 | |
| 127 // This operation is best effort, so don't send any errors back to the caller. | |
| 128 string response; | |
| 129 SendRequest(url, &response); | |
| 130 } | |
| 131 | |
| 132 GURL TestAccountsClient::CreateGURLWithPath(const string& path) { | |
| 133 return GURL(base::StringPrintf("%s/%s", server_.c_str(), path.c_str())); | |
| 134 } | |
| 135 | |
| 136 | |
| 137 bool TestAccountsClient::SendRequest(const GURL& url, string* response) { | |
| 138 base::MessageLoop* loop = base::MessageLoop::current(); | |
| 139 scoped_refptr<URLRequestContextGetter> context_getter( | |
| 140 new URLRequestContextGetter(loop->message_loop_proxy())); | |
| 141 | |
| 142 base::RunLoop run_loop; | |
| 143 | |
| 144 AccountsRequestDelegate delegate(&run_loop); | |
| 145 scoped_ptr<net::URLFetcher> fetcher = | |
| 146 net::URLFetcher::Create(url, net::URLFetcher::POST, &delegate); | |
| 147 fetcher->SetRequestContext(context_getter.get()); | |
| 148 fetcher->SetUploadData("application/json", ""); | |
| 149 fetcher->Start(); | |
| 150 | |
| 151 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
| 152 run_loop.QuitClosure(), | |
| 153 kRequestTimeout); | |
| 154 run_loop.Run(); | |
| 155 | |
| 156 if (delegate.success()) { | |
| 157 *response = delegate.response(); | |
| 158 } | |
| 159 | |
| 160 return delegate.success(); | |
| 161 } | |
| OLD | NEW |