Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: chrome/browser/extensions/api/dial/device_description_fetcher.cc

Issue 2756483007: [Device Discovery] Move files from browser/extensions/api/dial to browser/media/router/discovery/di… (Closed)
Patch Set: resolve code review comments from Devlin Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2017 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/extensions/api/dial/device_description_fetcher.h"
6
7 #include "base/strings/string_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "chrome/browser/extensions/api/dial/dial_device_data.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "net/base/load_flags.h"
13 #include "net/http/http_response_headers.h"
14 #include "net/http/http_status_code.h"
15 #include "net/http/http_util.h"
16 #include "net/url_request/url_fetcher.h"
17 #include "net/url_request/url_request_context_getter.h"
18
19 using content::BrowserThread;
20
21 constexpr char kApplicationUrlHeaderName[] = "Application-URL";
22 constexpr int kMaxRetries = 3;
23 // DIAL devices are unlikely to expose uPnP functions other than DIAL, so 256kb
24 // should be more than sufficient.
25 constexpr int kMaxDescriptionSizeBytes = 262144;
26
27 namespace extensions {
28 namespace api {
29 namespace dial {
30
31 DeviceDescriptionFetcher::DeviceDescriptionFetcher(
32 const GURL& device_description_url,
33 net::URLRequestContextGetter* request_context,
34 base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb,
35 base::OnceCallback<void(const std::string&)> error_cb)
36 : device_description_url_(device_description_url),
37 request_context_(request_context),
38 success_cb_(std::move(success_cb)),
39 error_cb_(std::move(error_cb)) {
40 DCHECK(request_context_);
41 DCHECK(device_description_url_.is_valid());
42 }
43
44 DeviceDescriptionFetcher::~DeviceDescriptionFetcher() {
45 DCHECK(thread_checker_.CalledOnValidThread());
46 }
47
48 void DeviceDescriptionFetcher::Start() {
49 DCHECK(thread_checker_.CalledOnValidThread());
50 DCHECK(!fetcher_);
51
52 // DIAL returns device descriptions via GET request.
53 fetcher_ =
54 net::URLFetcher::Create(kURLFetcherIDForTest, device_description_url_,
55 net::URLFetcher::GET, this);
56
57 // net::LOAD_BYPASS_PROXY: Proxies almost certainly hurt more cases than they
58 // help.
59 // net::LOAD_DISABLE_CACHE: The request should not touch the cache.
60 // net::LOAD_DO_NOT_{SAVE,SEND}_COOKIES: The request should not touch cookies.
61 // net::LOAD_DO_NOT_SEND_AUTH_DATA: The request should not send auth data.
62 fetcher_->SetLoadFlags(net::LOAD_BYPASS_PROXY | net::LOAD_DISABLE_CACHE |
63 net::LOAD_DO_NOT_SAVE_COOKIES |
64 net::LOAD_DO_NOT_SEND_COOKIES |
65 net::LOAD_DO_NOT_SEND_AUTH_DATA);
66
67 // Section 5.4 of the DIAL spec prohibits redirects.
68 fetcher_->SetStopOnRedirect(true);
69
70 // Allow the fetcher to retry on 5XX responses and ERR_NETWORK_CHANGED.
71 fetcher_->SetMaxRetriesOn5xx(kMaxRetries);
72 fetcher_->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries);
73
74 fetcher_->SetRequestContext(request_context_.get());
75 fetcher_->Start();
76 }
77
78 void DeviceDescriptionFetcher::OnURLFetchComplete(
79 const net::URLFetcher* source) {
80 DCHECK_EQ(fetcher_.get(), source);
81
82 if (source->GetResponseCode() != net::HTTP_OK) {
83 ReportError(
84 base::StringPrintf("HTTP %d: Unable to fetch device description",
85 source->GetResponseCode()));
86 return;
87 }
88
89 const net::HttpResponseHeaders* headers = source->GetResponseHeaders();
90
91 // NOTE: The uPnP spec requires devices to set a Content-Type: header of
92 // text/xml; charset="utf-8" (sec 2.11). However Chromecast (and possibly
93 // other devices) do not comply, so specifically not checking this header.
94 std::string app_url_header;
95 if (!headers->GetNormalizedHeader(kApplicationUrlHeaderName,
96 &app_url_header) ||
97 app_url_header.empty()) {
98 ReportError("Missing or empty Application-URL:");
99 return;
100 }
101
102 // Section 5.4 of the DIAL spec implies that the Application URL should not
103 // have path, query or fragment...unsure if that can be enforced.
104 GURL app_url(app_url_header);
105 if (!app_url.is_valid() || !app_url.SchemeIs("http") ||
106 !app_url.HostIsIPAddress() ||
107 app_url.host() != device_description_url_.host()) {
108 ReportError(base::StringPrintf("Invalid Application-URL: %s",
109 app_url_header.c_str()));
110 return;
111 }
112
113 if (source->GetReceivedResponseContentLength() > kMaxDescriptionSizeBytes) {
114 ReportError("Response too large");
115 return;
116 }
117
118 std::string device_description;
119 if (!source->GetResponseAsString(&device_description) ||
120 device_description.empty()) {
121 ReportError("Missing or empty response");
122 return;
123 }
124
125 if (!base::IsStringUTF8(device_description)) {
126 ReportError("Invalid response encoding");
127 return;
128 }
129
130 std::move(success_cb_)
131 .Run(DialDeviceDescriptionData(std::move(device_description), app_url));
132 }
133
134 void DeviceDescriptionFetcher::OnURLFetchDownloadProgress(
135 const net::URLFetcher* source,
136 int64_t current,
137 int64_t total,
138 int64_t current_network_bytes) {}
139
140 void DeviceDescriptionFetcher::OnURLFetchUploadProgress(
141 const net::URLFetcher* source,
142 int64_t current,
143 int64_t total) {}
144
145 void DeviceDescriptionFetcher::ReportError(const std::string& message) {
146 std::move(error_cb_).Run(message);
147 }
148
149 } // namespace dial
150 } // namespace api
151 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698