// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/remoting/directory_add_request.h"
#include <vector>
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/values.h"
#include "chrome/common/net/http_return.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"
namespace remoting {
static const char kRemotingDirectoryUrl[] =
"https://www.googleapis.com/chromoting/v1/@me/hosts";
DirectoryAddRequest::DirectoryAddRequest(net::URLRequestContextGetter* getter)
: getter_(getter) {
}
DirectoryAddRequest::~DirectoryAddRequest() {
DCHECK(!fetcher_.get()) << "URLFetcher not destroyed.";
}
void DirectoryAddRequest::AddHost(const remoting::ChromotingHostInfo& host_info,
const std::string& auth_token,
DoneCallback* done_callback) {
DCHECK(done_callback);
done_callback_.reset(done_callback);
// Prepare the parameters for the request.
DictionaryValue data;
data.SetString("hostId", host_info.host_id);
data.SetString("hostName", host_info.hostname);
data.SetString("publicKey", host_info.public_key);
// Generate the final json query.
DictionaryValue args;
args.Set("data", data.DeepCopy());
std::string request_content;
base::JSONWriter::Write(&args, false, &request_content);
// Prepare the HTTP header for authentication.
net::HttpRequestHeaders headers;
headers.SetHeader("Authorization", "GoogleLogin auth=" + auth_token);
fetcher_.reset(
new URLFetcher(GURL(kRemotingDirectoryUrl), URLFetcher::POST, this));
fetcher_->set_request_context(getter_);
fetcher_->set_upload_data("application/json", request_content);
fetcher_->set_extra_request_headers(headers.ToString());
// And then start the request.
fetcher_->Start();
}
void DirectoryAddRequest::OnURLFetchComplete(
const URLFetcher* source,
const GURL& url,
const net::URLRequestStatus& status,
int response_code,
const ResponseCookies& cookies,
const std::string& data) {
DCHECK_EQ(source, fetcher_.get());
// Destroy the fetcher after the response has been received.
fetcher_.reset();
Result result;
std::string error_message;
if (status.is_success()) {
DictionaryValue* response = NULL;
scoped_ptr<Value> response_json(base::JSONReader::Read(data, true));
if (response_json != NULL &&
response_json->IsType(Value::TYPE_DICTIONARY)) {
response = static_cast<DictionaryValue*>(response_json.get());
response->GetString("error.message", &error_message);
}
switch (response_code) {
case RC_REQUEST_OK:
result = SUCCESS;
break;
case RC_BAD_REQUEST:
// TODO(sergeyu): Implement duplicate error detection that doesn't
// depend on error message.
if (error_message.find("duplicate") != std::string::npos) {
result = ERROR_EXISTS;
} else {
result = ERROR_INVALID_REQUEST;
}
break;
case RC_UNAUTHORIZED:
result = ERROR_AUTH;
break;
case RC_INTERNAL_SERVER_ERROR:
result = ERROR_SERVER;
break;
default:
result = ERROR_OTHER;
}
} else {
result = ERROR_OTHER;
}
if (result != SUCCESS) {
LOG(WARNING) << "Received error when trying to register Chromoting host. "
<< "status.is_success(): " << status.is_success()
<< " response_code: " << response_code
<< " error_message: " << error_message;
}
done_callback_->Run(result, error_message);
}
} // namespace remoting