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 |