summaryrefslogtreecommitdiffstats
path: root/chrome/browser/remoting
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-23 19:44:17 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-23 19:44:17 +0000
commit15e7eba9c74140f4e976c0d152ba738c36f14bb5 (patch)
tree1eed92b43c3dd47bd7f200f5454701d93e46fbf1 /chrome/browser/remoting
parent809e10f57b8bbfb1b780e3963a7466b15aef45bf (diff)
downloadchromium_src-15e7eba9c74140f4e976c0d152ba738c36f14bb5.zip
chromium_src-15e7eba9c74140f4e976c0d152ba738c36f14bb5.tar.gz
chromium_src-15e7eba9c74140f4e976c0d152ba738c36f14bb5.tar.bz2
Move directory code from chrome/service to chrome/browser.
Renamed RemotingDirectoryService to DirectoryAddRequest. It will be used in RemotingSetupFlow to register host. Also added unittests for this code. BUG=67218 TEST=Unittests Review URL: http://codereview.chromium.org/6036001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70082 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/remoting')
-rw-r--r--chrome/browser/remoting/directory_add_request.cc125
-rw-r--r--chrome/browser/remoting/directory_add_request.h75
-rw-r--r--chrome/browser/remoting/directory_add_request_unittest.cc82
3 files changed, 282 insertions, 0 deletions
diff --git a/chrome/browser/remoting/directory_add_request.cc b/chrome/browser/remoting/directory_add_request.cc
new file mode 100644
index 0000000..c7d2645
--- /dev/null
+++ b/chrome/browser/remoting/directory_add_request.cc
@@ -0,0 +1,125 @@
+// Copyright (c) 2010 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 "chrome/common/net/url_request_context_getter.h"
+#include "net/http/http_request_headers.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(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 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
diff --git a/chrome/browser/remoting/directory_add_request.h b/chrome/browser/remoting/directory_add_request.h
new file mode 100644
index 0000000..2ec6ed2
--- /dev/null
+++ b/chrome/browser/remoting/directory_add_request.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_REMOTING_DIRECTORY_ADD_REQUEST_H_
+#define CHROME_BROWSER_REMOTING_DIRECTORY_ADD_REQUEST_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/remoting/chromoting_host_info.h"
+#include "chrome/common/net/url_fetcher.h"
+#include "googleurl/src/gurl.h"
+
+namespace remoting {
+
+// A class implements REST API insert call for the Chromoting directory service.
+class DirectoryAddRequest : public URLFetcher::Delegate {
+ public:
+ enum Result {
+ // Host was added successfully.
+ SUCCESS,
+ // Invalid authentication token.
+ ERROR_AUTH,
+ // Server rejected request because it was invalid (e.g. specified
+ // public key is invalid).
+ ERROR_INVALID_REQUEST,
+ // Host is already registered.
+ ERROR_EXISTS,
+ // Internal server error.
+ ERROR_SERVER,
+ // Timeout expired.
+ ERROR_TIMEOUT_EXPIRED,
+ // Some other error, e.g. network failure.
+ ERROR_OTHER,
+ };
+
+ // Callback called when request is finished. The second parameter
+ // contains error message in case of an error. The error message may
+ // not be localized, and should be used for logging, but not shown
+ // to the user.
+ typedef Callback2<Result, const std::string&>::Type DoneCallback;
+
+ explicit DirectoryAddRequest(URLRequestContextGetter* getter);
+ ~DirectoryAddRequest();
+
+ // Add this computer as a host. Use the token for
+ // authentication. |done_callback| is called when the request is
+ // finished. Request can be cancelled by destroying this object.
+ void AddHost(const remoting::ChromotingHostInfo& host_info,
+ const std::string& auth_token,
+ DoneCallback* done_callback);
+
+ // URLFetcher::Delegate implementation.
+ virtual void OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data);
+
+ private:
+ friend class DirectoryAddRequestTest;
+
+ URLRequestContextGetter* getter_;
+ scoped_ptr<DoneCallback> done_callback_;
+ scoped_ptr<URLFetcher> fetcher_;
+
+ DISALLOW_COPY_AND_ASSIGN(DirectoryAddRequest);
+};
+
+} // namespace remoting
+
+#endif // CHROME_BROWSER_REMOTING_DIRECTORY_ADD_REQUEST_H_
diff --git a/chrome/browser/remoting/directory_add_request_unittest.cc b/chrome/browser/remoting/directory_add_request_unittest.cc
new file mode 100644
index 0000000..6389b3e8
--- /dev/null
+++ b/chrome/browser/remoting/directory_add_request_unittest.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2010 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 "chrome/test/testing_profile.h"
+#include "net/url_request/url_request_status.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace remoting {
+
+namespace {
+class MockDoneCallback {
+ public:
+ MOCK_METHOD2(OnDone,
+ void(DirectoryAddRequest::Result,
+ const std::string& message));
+};
+} // namespace
+
+class DirectoryAddRequestTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ target_.reset(new DirectoryAddRequest(profile_.GetRequestContext()));
+ }
+
+ void TestResult(int response_code, const std::string& data,
+ DirectoryAddRequest::Result expected_result,
+ const std::string& expected_message) {
+ MockDoneCallback callback;
+ EXPECT_CALL(callback, OnDone(expected_result, expected_message))
+ .Times(1);
+
+ target_->done_callback_.reset(
+ NewCallback(&callback, &MockDoneCallback::OnDone));
+
+ GURL url;
+ URLRequestStatus status_ok;
+ ResponseCookies cookies;
+ target_->OnURLFetchComplete(NULL, url, status_ok, response_code,
+ cookies, data);
+ }
+
+ TestingProfile profile_;
+ scoped_ptr<DirectoryAddRequest> target_;
+};
+
+TEST_F(DirectoryAddRequestTest, Success) {
+ TestResult(200, "{\"data\":{\"kind\":\"chromoting#host\","
+ "\"hostId\":\"e64906c9-fdc9-4921-80cb-563cf7f564f3\","
+ "\"hostName\":\"host_name\",\"publicKey\":\"PUBLIC+KEY\"}}",
+ DirectoryAddRequest::SUCCESS, "");
+}
+
+TEST_F(DirectoryAddRequestTest, Duplicate) {
+ TestResult(400, "{\"error\":{\"errors\":[{\"domain\":\"global\","
+ "\"reason\":\"invalid\",\"message\":\"Attempt to register "
+ "a duplicate host.\"}],\"code\":400,\"message\":\"Attempt to "
+ "register a duplicate host.\"}}",
+ DirectoryAddRequest::ERROR_EXISTS,
+ "Attempt to register a duplicate host.");
+}
+
+TEST_F(DirectoryAddRequestTest, InvalidRequest) {
+ TestResult(400, "{\"error\":{\"errors\":[{\"domain\":\"global\","
+ "\"reason\":\"invalid\",\"message\":\"Invalid Value\"}],"
+ "\"code\":400,\"message\":\"Invalid Value\"}}",
+ DirectoryAddRequest::ERROR_INVALID_REQUEST,
+ "Invalid Value");
+}
+
+TEST_F(DirectoryAddRequestTest, InvalidToken) {
+ TestResult(401, "{\"error\":{\"errors\":[{\"domain\":\"global\","
+ "\"reason\":\"invalid\",\"message\":\"Token invalid\","
+ "\"locationType\":\"header\",\"location\":\"Authorization\"}],"
+ "\"code\":401,\"message\":\"Token invalid\"}}",
+ DirectoryAddRequest::ERROR_AUTH,
+ "Token invalid");
+}
+
+} // namespace remoting