Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / host / setup / service_client.cc
blobba42825c76cdc5930c68e02d7e5604a0feeda52e
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.
5 #include "remoting/host/setup/service_client.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/values.h"
11 #include "net/http/http_status_code.h"
12 #include "net/url_request/url_fetcher.h"
13 #include "net/url_request/url_fetcher_delegate.h"
14 #include "net/url_request/url_request_context_getter.h"
15 #include "url/gurl.h"
17 namespace remoting {
19 class ServiceClient::Core
20 : public base::RefCountedThreadSafe<ServiceClient::Core>,
21 public net::URLFetcherDelegate {
22 public:
23 Core(const std::string& chromoting_hosts_url,
24 net::URLRequestContextGetter* request_context_getter)
25 : request_context_getter_(request_context_getter),
26 delegate_(nullptr),
27 pending_request_type_(PENDING_REQUEST_NONE),
28 chromoting_hosts_url_(chromoting_hosts_url) {
31 void RegisterHost(const std::string& host_id,
32 const std::string& host_name,
33 const std::string& public_key,
34 const std::string& host_client_id,
35 const std::string& oauth_access_token,
36 ServiceClient::Delegate* delegate);
38 void UnregisterHost(const std::string& host_id,
39 const std::string& oauth_access_token,
40 ServiceClient::Delegate* delegate);
42 // net::URLFetcherDelegate implementation.
43 void OnURLFetchComplete(const net::URLFetcher* source) override;
45 private:
46 friend class base::RefCountedThreadSafe<Core>;
47 ~Core() override {}
49 enum PendingRequestType {
50 PENDING_REQUEST_NONE,
51 PENDING_REQUEST_REGISTER_HOST,
52 PENDING_REQUEST_UNREGISTER_HOST
55 void MakeChromotingRequest(net::URLFetcher::RequestType request_type,
56 const std::string& post_body,
57 const std::string& url_suffix,
58 const std::string& oauth_access_token,
59 ServiceClient::Delegate* delegate);
60 void HandleResponse(const net::URLFetcher* source);
62 scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
63 ServiceClient::Delegate* delegate_;
64 scoped_ptr<net::URLFetcher> request_;
65 PendingRequestType pending_request_type_;
66 std::string chromoting_hosts_url_;
69 void ServiceClient::Core::RegisterHost(
70 const std::string& host_id,
71 const std::string& host_name,
72 const std::string& public_key,
73 const std::string& host_client_id,
74 const std::string& oauth_access_token,
75 Delegate* delegate) {
76 DCHECK(pending_request_type_ == PENDING_REQUEST_NONE);
77 pending_request_type_ = PENDING_REQUEST_REGISTER_HOST;
78 base::DictionaryValue post_body;
79 post_body.SetString("data.hostId", host_id);
80 post_body.SetString("data.hostName", host_name);
81 post_body.SetString("data.publicKey", public_key);
82 std::string url_suffix;
83 if (!host_client_id.empty())
84 url_suffix = "?hostClientId=" + host_client_id;
85 std::string post_body_str;
86 base::JSONWriter::Write(post_body, &post_body_str);
87 MakeChromotingRequest(net::URLFetcher::POST,
88 url_suffix,
89 post_body_str,
90 oauth_access_token,
91 delegate);
94 void ServiceClient::Core::UnregisterHost(
95 const std::string& host_id,
96 const std::string& oauth_access_token,
97 Delegate* delegate) {
98 DCHECK(pending_request_type_ == PENDING_REQUEST_NONE);
99 pending_request_type_ = PENDING_REQUEST_UNREGISTER_HOST;
100 MakeChromotingRequest(net::URLFetcher::DELETE_REQUEST,
101 host_id,
102 std::string(),
103 oauth_access_token,
104 delegate);
107 void ServiceClient::Core::MakeChromotingRequest(
108 net::URLFetcher::RequestType request_type,
109 const std::string& url_suffix,
110 const std::string& request_body,
111 const std::string& oauth_access_token,
112 ServiceClient::Delegate* delegate) {
113 delegate_ = delegate;
114 request_ = net::URLFetcher::Create(
115 0, GURL(chromoting_hosts_url_ + url_suffix), request_type, this);
116 request_->SetRequestContext(request_context_getter_.get());
117 request_->SetUploadData("application/json; charset=UTF-8", request_body);
118 request_->AddExtraRequestHeader("Authorization: OAuth " + oauth_access_token);
119 request_->Start();
122 // URLFetcher::Delegate implementation.
123 void ServiceClient::Core::OnURLFetchComplete(
124 const net::URLFetcher* source) {
125 HandleResponse(source);
126 request_.reset();
129 void ServiceClient::Core::HandleResponse(const net::URLFetcher* source) {
130 DCHECK(pending_request_type_ != PENDING_REQUEST_NONE);
131 PendingRequestType old_type = pending_request_type_;
132 pending_request_type_ = PENDING_REQUEST_NONE;
133 if (source->GetResponseCode() == net::HTTP_BAD_REQUEST) {
134 delegate_->OnOAuthError();
135 return;
138 // Treat codes 2xx as successful; for example, HTTP_NO_CONTENT (204) can be
139 // returned from a DELETE_REQUEST.
140 if (source->GetResponseCode() / 100 == 2) {
141 switch (old_type) {
142 case PENDING_REQUEST_NONE:
143 break;
144 case PENDING_REQUEST_REGISTER_HOST:
146 std::string data;
147 source->GetResponseAsString(&data);
148 scoped_ptr<base::Value> message_value = base::JSONReader::Read(data);
149 base::DictionaryValue *dict;
150 std::string code;
151 if (message_value.get() &&
152 message_value->IsType(base::Value::TYPE_DICTIONARY) &&
153 message_value->GetAsDictionary(&dict) &&
154 dict->GetString("data.authorizationCode", &code)) {
155 delegate_->OnHostRegistered(code);
156 } else {
157 delegate_->OnHostRegistered(std::string());
160 break;
161 case PENDING_REQUEST_UNREGISTER_HOST:
162 delegate_->OnHostUnregistered();
163 break;
165 return;
167 delegate_->OnNetworkError(source->GetResponseCode());
170 ServiceClient::ServiceClient(const std::string& chromoting_hosts_url,
171 net::URLRequestContextGetter* context_getter) {
172 core_ = new Core(chromoting_hosts_url, context_getter);
175 ServiceClient::~ServiceClient() {
178 void ServiceClient::RegisterHost(
179 const std::string& host_id,
180 const std::string& host_name,
181 const std::string& public_key,
182 const std::string& host_client_id,
183 const std::string& oauth_access_token,
184 Delegate* delegate) {
185 return core_->RegisterHost(host_id, host_name, public_key, host_client_id,
186 oauth_access_token, delegate);
189 void ServiceClient::UnregisterHost(
190 const std::string& host_id,
191 const std::string& oauth_access_token,
192 Delegate* delegate) {
193 return core_->UnregisterHost(host_id, oauth_access_token, delegate);
196 } // namespace gaia