1 // Copyright 2015 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/test/host_list_fetcher.h"
8 #include "base/callback_helpers.h"
9 #include "base/json/json_reader.h"
10 #include "base/logging.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/values.h"
13 #include "net/http/http_status_code.h"
14 #include "net/url_request/url_fetcher.h"
15 #include "remoting/base/url_request_context_getter.h"
20 HostListFetcher::HostListFetcher() {
23 HostListFetcher::~HostListFetcher() {
26 void HostListFetcher::RetrieveHostlist(
27 const std::string
& access_token
,
28 const HostlistCallback
& callback
) {
30 VLOG(2) << "HostListFetcher::RetrieveHostlist() called";
32 DCHECK(!access_token
.empty());
33 DCHECK(!callback
.is_null());
34 DCHECK(hostlist_callback_
.is_null());
36 hostlist_callback_
= callback
;
38 request_context_getter_
= new remoting::URLRequestContextGetter(
39 base::ThreadTaskRunnerHandle::Get(), // network_runner
40 base::ThreadTaskRunnerHandle::Get()); // file_runner
42 request_
= net::URLFetcher::Create(
43 GURL(kHostListProdRequestUrl
), net::URLFetcher::GET
, this);
44 request_
->SetRequestContext(request_context_getter_
.get());
45 request_
->AddExtraRequestHeader("Authorization: OAuth " + access_token
);
49 bool HostListFetcher::ProcessResponse(
50 std::vector
<HostInfo
>* hostlist
) {
51 int response_code
= request_
->GetResponseCode();
52 if (response_code
!= net::HTTP_OK
) {
53 LOG(ERROR
) << "Hostlist request failed with error code: " << response_code
;
57 std::string response_string
;
58 if (!request_
->GetResponseAsString(&response_string
)) {
59 LOG(ERROR
) << "Failed to retrieve Hostlist response data";
63 scoped_ptr
<base::Value
> response_value(
64 base::JSONReader::Read(response_string
));
65 if (!response_value
||
66 !response_value
->IsType(base::Value::TYPE_DICTIONARY
)) {
67 LOG(ERROR
) << "Failed to parse response string to JSON";
71 const base::DictionaryValue
* response
;
72 if (!response_value
->GetAsDictionary(&response
)) {
73 LOG(ERROR
) << "Failed to convert parsed JSON to a dictionary object";
77 const base::DictionaryValue
* data
= nullptr;
78 if (!response
->GetDictionary("data", &data
)) {
79 LOG(ERROR
) << "Hostlist response data is empty";
83 const base::ListValue
* hosts
= nullptr;
84 if (!data
->GetList("items", &hosts
)) {
85 LOG(ERROR
) << "Failed to find hosts in Hostlist response data";
89 // Any host_info with malformed data will not be added to the hostlist.
90 base::DictionaryValue
* host_dict
;
91 for (base::Value
* host_info
: *hosts
) {
93 if (host_info
->GetAsDictionary(&host_dict
) &&
94 host
.ParseHostInfo(*host_dict
)) {
95 hostlist
->push_back(host
);
101 void HostListFetcher::OnURLFetchComplete(
102 const net::URLFetcher
* source
) {
104 VLOG(2) << "URL Fetch Completed for: " << source
->GetOriginalURL();
106 std::vector
<HostInfo
> hostlist
;
108 if (!ProcessResponse(&hostlist
)) {
111 base::ResetAndReturn(&hostlist_callback_
).Run(hostlist
);
115 } // namespace remoting