// 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