• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "chrome/browser/remoting/directory_add_request.h"
6 
7 #include <vector>
8 
9 #include "base/json/json_reader.h"
10 #include "base/json/json_writer.h"
11 #include "base/values.h"
12 #include "chrome/common/net/http_return.h"
13 #include "net/http/http_request_headers.h"
14 #include "net/url_request/url_request_context_getter.h"
15 #include "net/url_request/url_request_status.h"
16 
17 namespace remoting {
18 
19 static const char kRemotingDirectoryUrl[] =
20     "https://www.googleapis.com/chromoting/v1/@me/hosts";
21 
DirectoryAddRequest(net::URLRequestContextGetter * getter)22 DirectoryAddRequest::DirectoryAddRequest(net::URLRequestContextGetter* getter)
23     : getter_(getter) {
24 }
25 
~DirectoryAddRequest()26 DirectoryAddRequest::~DirectoryAddRequest() {
27   DCHECK(!fetcher_.get()) << "URLFetcher not destroyed.";
28 }
29 
AddHost(const remoting::ChromotingHostInfo & host_info,const std::string & auth_token,DoneCallback * done_callback)30 void DirectoryAddRequest::AddHost(const remoting::ChromotingHostInfo& host_info,
31                                   const std::string& auth_token,
32                                   DoneCallback* done_callback) {
33   DCHECK(done_callback);
34   done_callback_.reset(done_callback);
35 
36   // Prepare the parameters for the request.
37   DictionaryValue data;
38   data.SetString("hostId", host_info.host_id);
39   data.SetString("hostName", host_info.hostname);
40   data.SetString("publicKey", host_info.public_key);
41 
42   // Generate the final json query.
43   DictionaryValue args;
44   args.Set("data", data.DeepCopy());
45   std::string request_content;
46   base::JSONWriter::Write(&args, false, &request_content);
47 
48   // Prepare the HTTP header for authentication.
49   net::HttpRequestHeaders headers;
50   headers.SetHeader("Authorization", "GoogleLogin auth=" + auth_token);
51   fetcher_.reset(
52       new URLFetcher(GURL(kRemotingDirectoryUrl), URLFetcher::POST, this));
53   fetcher_->set_request_context(getter_);
54   fetcher_->set_upload_data("application/json", request_content);
55   fetcher_->set_extra_request_headers(headers.ToString());
56 
57   // And then start the request.
58   fetcher_->Start();
59 }
60 
OnURLFetchComplete(const URLFetcher * source,const GURL & url,const net::URLRequestStatus & status,int response_code,const ResponseCookies & cookies,const std::string & data)61 void DirectoryAddRequest::OnURLFetchComplete(
62     const URLFetcher* source,
63     const GURL& url,
64     const net::URLRequestStatus& status,
65     int response_code,
66     const ResponseCookies& cookies,
67     const std::string& data) {
68   DCHECK_EQ(source, fetcher_.get());
69 
70   // Destroy the fetcher after the response has been received.
71   fetcher_.reset();
72 
73   Result result;
74   std::string error_message;
75 
76   if (status.is_success()) {
77     DictionaryValue* response = NULL;
78     scoped_ptr<Value> response_json(base::JSONReader::Read(data, true));
79     if (response_json != NULL &&
80         response_json->IsType(Value::TYPE_DICTIONARY)) {
81       response = static_cast<DictionaryValue*>(response_json.get());
82       response->GetString("error.message", &error_message);
83     }
84 
85     switch (response_code) {
86       case RC_REQUEST_OK:
87         result = SUCCESS;
88         break;
89 
90       case RC_BAD_REQUEST:
91         // TODO(sergeyu): Implement duplicate error detection that doesn't
92         // depend on error message.
93         if (error_message.find("duplicate") != std::string::npos) {
94           result = ERROR_EXISTS;
95         } else {
96           result = ERROR_INVALID_REQUEST;
97         }
98         break;
99 
100       case RC_UNAUTHORIZED:
101         result = ERROR_AUTH;
102         break;
103 
104       case RC_INTERNAL_SERVER_ERROR:
105         result = ERROR_SERVER;
106         break;
107 
108       default:
109         result = ERROR_OTHER;
110     }
111   } else {
112     result = ERROR_OTHER;
113   }
114 
115   if (result != SUCCESS) {
116     LOG(WARNING) << "Received error when trying to register Chromoting host. "
117                  << "status.is_success(): " << status.is_success()
118                  << "  response_code: " << response_code
119                  << "  error_message: " << error_message;
120   }
121 
122   done_callback_->Run(result, error_message);
123 }
124 
125 }  // namespace remoting
126