1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_headers.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <string_view>
8*6777b538SAndroid Build Coastguard Worker #include <utility>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_macros.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/strings/escape.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
19*6777b538SAndroid Build Coastguard Worker #include "net/base/url_util.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/http/http_log_util.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/http/http_util.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_capture_mode.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_values.h"
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker namespace net {
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker namespace {
28*6777b538SAndroid Build Coastguard Worker
SupportsStreamType(const std::optional<base::flat_set<SourceStream::SourceType>> & accepted_stream_types,SourceStream::SourceType type)29*6777b538SAndroid Build Coastguard Worker bool SupportsStreamType(
30*6777b538SAndroid Build Coastguard Worker const std::optional<base::flat_set<SourceStream::SourceType>>&
31*6777b538SAndroid Build Coastguard Worker accepted_stream_types,
32*6777b538SAndroid Build Coastguard Worker SourceStream::SourceType type) {
33*6777b538SAndroid Build Coastguard Worker if (!accepted_stream_types)
34*6777b538SAndroid Build Coastguard Worker return true;
35*6777b538SAndroid Build Coastguard Worker return accepted_stream_types->contains(type);
36*6777b538SAndroid Build Coastguard Worker }
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker } // namespace
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kConnectMethod[] = "CONNECT";
41*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kDeleteMethod[] = "DELETE";
42*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kGetMethod[] = "GET";
43*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kHeadMethod[] = "HEAD";
44*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kOptionsMethod[] = "OPTIONS";
45*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kPatchMethod[] = "PATCH";
46*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kPostMethod[] = "POST";
47*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kPutMethod[] = "PUT";
48*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kTraceMethod[] = "TRACE";
49*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kTrackMethod[] = "TRACK";
50*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kAccept[] = "Accept";
51*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kAcceptCharset[] = "Accept-Charset";
52*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kAcceptEncoding[] = "Accept-Encoding";
53*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kAcceptLanguage[] = "Accept-Language";
54*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kAuthorization[] = "Authorization";
55*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kCacheControl[] = "Cache-Control";
56*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kConnection[] = "Connection";
57*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kContentLength[] = "Content-Length";
58*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kContentType[] = "Content-Type";
59*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kCookie[] = "Cookie";
60*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kHost[] = "Host";
61*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kIfMatch[] = "If-Match";
62*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kIfModifiedSince[] = "If-Modified-Since";
63*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kIfNoneMatch[] = "If-None-Match";
64*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kIfRange[] = "If-Range";
65*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kIfUnmodifiedSince[] = "If-Unmodified-Since";
66*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kOrigin[] = "Origin";
67*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kPragma[] = "Pragma";
68*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kPriority[] = "Priority";
69*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kProxyAuthorization[] = "Proxy-Authorization";
70*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kProxyConnection[] = "Proxy-Connection";
71*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kRange[] = "Range";
72*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kReferer[] = "Referer";
73*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kTransferEncoding[] = "Transfer-Encoding";
74*6777b538SAndroid Build Coastguard Worker const char HttpRequestHeaders::kUserAgent[] = "User-Agent";
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::HeaderKeyValuePair::HeaderKeyValuePair() = default;
77*6777b538SAndroid Build Coastguard Worker
HeaderKeyValuePair(std::string_view key,std::string_view value)78*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::HeaderKeyValuePair::HeaderKeyValuePair(
79*6777b538SAndroid Build Coastguard Worker std::string_view key,
80*6777b538SAndroid Build Coastguard Worker std::string_view value)
81*6777b538SAndroid Build Coastguard Worker : HeaderKeyValuePair(key, std::string(value)) {}
82*6777b538SAndroid Build Coastguard Worker
HeaderKeyValuePair(std::string_view key,std::string && value)83*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::HeaderKeyValuePair::HeaderKeyValuePair(std::string_view key,
84*6777b538SAndroid Build Coastguard Worker std::string&& value)
85*6777b538SAndroid Build Coastguard Worker : key(key), value(std::move(value)) {}
86*6777b538SAndroid Build Coastguard Worker
Iterator(const HttpRequestHeaders & headers)87*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::Iterator::Iterator(const HttpRequestHeaders& headers)
88*6777b538SAndroid Build Coastguard Worker : curr_(headers.headers_.begin()), end_(headers.headers_.end()) {}
89*6777b538SAndroid Build Coastguard Worker
90*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::Iterator::~Iterator() = default;
91*6777b538SAndroid Build Coastguard Worker
GetNext()92*6777b538SAndroid Build Coastguard Worker bool HttpRequestHeaders::Iterator::GetNext() {
93*6777b538SAndroid Build Coastguard Worker if (!started_) {
94*6777b538SAndroid Build Coastguard Worker started_ = true;
95*6777b538SAndroid Build Coastguard Worker return curr_ != end_;
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker
98*6777b538SAndroid Build Coastguard Worker if (curr_ == end_)
99*6777b538SAndroid Build Coastguard Worker return false;
100*6777b538SAndroid Build Coastguard Worker
101*6777b538SAndroid Build Coastguard Worker ++curr_;
102*6777b538SAndroid Build Coastguard Worker return curr_ != end_;
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::HttpRequestHeaders() = default;
106*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::HttpRequestHeaders(const HttpRequestHeaders& other) =
107*6777b538SAndroid Build Coastguard Worker default;
108*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::HttpRequestHeaders(HttpRequestHeaders&& other) = default;
109*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::~HttpRequestHeaders() = default;
110*6777b538SAndroid Build Coastguard Worker
111*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders& HttpRequestHeaders::operator=(
112*6777b538SAndroid Build Coastguard Worker const HttpRequestHeaders& other) = default;
113*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders& HttpRequestHeaders::operator=(HttpRequestHeaders&& other) =
114*6777b538SAndroid Build Coastguard Worker default;
115*6777b538SAndroid Build Coastguard Worker
GetHeader(std::string_view key,std::string * out) const116*6777b538SAndroid Build Coastguard Worker bool HttpRequestHeaders::GetHeader(std::string_view key,
117*6777b538SAndroid Build Coastguard Worker std::string* out) const {
118*6777b538SAndroid Build Coastguard Worker auto it = FindHeader(key);
119*6777b538SAndroid Build Coastguard Worker if (it == headers_.end())
120*6777b538SAndroid Build Coastguard Worker return false;
121*6777b538SAndroid Build Coastguard Worker out->assign(it->value);
122*6777b538SAndroid Build Coastguard Worker return true;
123*6777b538SAndroid Build Coastguard Worker }
124*6777b538SAndroid Build Coastguard Worker
Clear()125*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::Clear() {
126*6777b538SAndroid Build Coastguard Worker headers_.clear();
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker
SetHeader(std::string_view key,std::string_view value)129*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::SetHeader(std::string_view key,
130*6777b538SAndroid Build Coastguard Worker std::string_view value) {
131*6777b538SAndroid Build Coastguard Worker SetHeader(key, std::string(value));
132*6777b538SAndroid Build Coastguard Worker }
133*6777b538SAndroid Build Coastguard Worker
SetHeader(std::string_view key,std::string && value)134*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::SetHeader(std::string_view key, std::string&& value) {
135*6777b538SAndroid Build Coastguard Worker // Invalid header names or values could mean clients can attach
136*6777b538SAndroid Build Coastguard Worker // browser-internal headers.
137*6777b538SAndroid Build Coastguard Worker CHECK(HttpUtil::IsValidHeaderName(key)) << key;
138*6777b538SAndroid Build Coastguard Worker CHECK(HttpUtil::IsValidHeaderValue(value)) << key << " has invalid value.";
139*6777b538SAndroid Build Coastguard Worker
140*6777b538SAndroid Build Coastguard Worker SetHeaderInternal(key, std::move(value));
141*6777b538SAndroid Build Coastguard Worker }
142*6777b538SAndroid Build Coastguard Worker
SetHeaderWithoutCheckForTesting(std::string_view key,std::string_view value)143*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::SetHeaderWithoutCheckForTesting(
144*6777b538SAndroid Build Coastguard Worker std::string_view key,
145*6777b538SAndroid Build Coastguard Worker std::string_view value) {
146*6777b538SAndroid Build Coastguard Worker SetHeaderInternal(key, std::string(value));
147*6777b538SAndroid Build Coastguard Worker }
148*6777b538SAndroid Build Coastguard Worker
SetHeaderIfMissing(std::string_view key,std::string_view value)149*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::SetHeaderIfMissing(std::string_view key,
150*6777b538SAndroid Build Coastguard Worker std::string_view value) {
151*6777b538SAndroid Build Coastguard Worker // Invalid header names or values could mean clients can attach
152*6777b538SAndroid Build Coastguard Worker // browser-internal headers.
153*6777b538SAndroid Build Coastguard Worker CHECK(HttpUtil::IsValidHeaderName(key));
154*6777b538SAndroid Build Coastguard Worker CHECK(HttpUtil::IsValidHeaderValue(value));
155*6777b538SAndroid Build Coastguard Worker auto it = FindHeader(key);
156*6777b538SAndroid Build Coastguard Worker if (it == headers_.end())
157*6777b538SAndroid Build Coastguard Worker headers_.push_back(HeaderKeyValuePair(key, value));
158*6777b538SAndroid Build Coastguard Worker }
159*6777b538SAndroid Build Coastguard Worker
RemoveHeader(std::string_view key)160*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::RemoveHeader(std::string_view key) {
161*6777b538SAndroid Build Coastguard Worker auto it = FindHeader(key);
162*6777b538SAndroid Build Coastguard Worker if (it != headers_.end())
163*6777b538SAndroid Build Coastguard Worker headers_.erase(it);
164*6777b538SAndroid Build Coastguard Worker }
165*6777b538SAndroid Build Coastguard Worker
AddHeaderFromString(std::string_view header_line)166*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::AddHeaderFromString(std::string_view header_line) {
167*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(std::string::npos, header_line.find("\r\n"))
168*6777b538SAndroid Build Coastguard Worker << "\"" << header_line << "\" contains CRLF.";
169*6777b538SAndroid Build Coastguard Worker
170*6777b538SAndroid Build Coastguard Worker const std::string::size_type key_end_index = header_line.find(":");
171*6777b538SAndroid Build Coastguard Worker if (key_end_index == std::string::npos) {
172*6777b538SAndroid Build Coastguard Worker LOG(DFATAL) << "\"" << header_line << "\" is missing colon delimiter.";
173*6777b538SAndroid Build Coastguard Worker return;
174*6777b538SAndroid Build Coastguard Worker }
175*6777b538SAndroid Build Coastguard Worker
176*6777b538SAndroid Build Coastguard Worker if (key_end_index == 0) {
177*6777b538SAndroid Build Coastguard Worker LOG(DFATAL) << "\"" << header_line << "\" is missing header key.";
178*6777b538SAndroid Build Coastguard Worker return;
179*6777b538SAndroid Build Coastguard Worker }
180*6777b538SAndroid Build Coastguard Worker
181*6777b538SAndroid Build Coastguard Worker const std::string_view header_key(header_line.data(), key_end_index);
182*6777b538SAndroid Build Coastguard Worker if (!HttpUtil::IsValidHeaderName(header_key)) {
183*6777b538SAndroid Build Coastguard Worker LOG(DFATAL) << "\"" << header_line << "\" has invalid header key.";
184*6777b538SAndroid Build Coastguard Worker return;
185*6777b538SAndroid Build Coastguard Worker }
186*6777b538SAndroid Build Coastguard Worker
187*6777b538SAndroid Build Coastguard Worker const std::string::size_type value_index = key_end_index + 1;
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Worker if (value_index < header_line.size()) {
190*6777b538SAndroid Build Coastguard Worker std::string_view header_value(header_line.data() + value_index,
191*6777b538SAndroid Build Coastguard Worker header_line.size() - value_index);
192*6777b538SAndroid Build Coastguard Worker header_value = HttpUtil::TrimLWS(header_value);
193*6777b538SAndroid Build Coastguard Worker if (!HttpUtil::IsValidHeaderValue(header_value)) {
194*6777b538SAndroid Build Coastguard Worker LOG(DFATAL) << "\"" << header_line << "\" has invalid header value.";
195*6777b538SAndroid Build Coastguard Worker return;
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker SetHeader(header_key, header_value);
198*6777b538SAndroid Build Coastguard Worker } else if (value_index == header_line.size()) {
199*6777b538SAndroid Build Coastguard Worker SetHeader(header_key, "");
200*6777b538SAndroid Build Coastguard Worker } else {
201*6777b538SAndroid Build Coastguard Worker NOTREACHED();
202*6777b538SAndroid Build Coastguard Worker }
203*6777b538SAndroid Build Coastguard Worker }
204*6777b538SAndroid Build Coastguard Worker
AddHeadersFromString(std::string_view headers)205*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::AddHeadersFromString(std::string_view headers) {
206*6777b538SAndroid Build Coastguard Worker for (std::string_view header : base::SplitStringPieceUsingSubstr(
207*6777b538SAndroid Build Coastguard Worker headers, "\r\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
208*6777b538SAndroid Build Coastguard Worker AddHeaderFromString(header);
209*6777b538SAndroid Build Coastguard Worker }
210*6777b538SAndroid Build Coastguard Worker }
211*6777b538SAndroid Build Coastguard Worker
MergeFrom(const HttpRequestHeaders & other)212*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::MergeFrom(const HttpRequestHeaders& other) {
213*6777b538SAndroid Build Coastguard Worker for (const auto& header : other.headers_) {
214*6777b538SAndroid Build Coastguard Worker SetHeader(header.key, header.value);
215*6777b538SAndroid Build Coastguard Worker }
216*6777b538SAndroid Build Coastguard Worker }
217*6777b538SAndroid Build Coastguard Worker
ToString() const218*6777b538SAndroid Build Coastguard Worker std::string HttpRequestHeaders::ToString() const {
219*6777b538SAndroid Build Coastguard Worker std::string output;
220*6777b538SAndroid Build Coastguard Worker for (const auto& header : headers_) {
221*6777b538SAndroid Build Coastguard Worker base::StringAppendF(&output, "%s: %s\r\n", header.key.c_str(),
222*6777b538SAndroid Build Coastguard Worker header.value.c_str());
223*6777b538SAndroid Build Coastguard Worker }
224*6777b538SAndroid Build Coastguard Worker output.append("\r\n");
225*6777b538SAndroid Build Coastguard Worker return output;
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker
NetLogParams(const std::string & request_line,NetLogCaptureMode capture_mode) const228*6777b538SAndroid Build Coastguard Worker base::Value::Dict HttpRequestHeaders::NetLogParams(
229*6777b538SAndroid Build Coastguard Worker const std::string& request_line,
230*6777b538SAndroid Build Coastguard Worker NetLogCaptureMode capture_mode) const {
231*6777b538SAndroid Build Coastguard Worker base::Value::Dict dict;
232*6777b538SAndroid Build Coastguard Worker dict.Set("line", NetLogStringValue(request_line));
233*6777b538SAndroid Build Coastguard Worker base::Value::List headers;
234*6777b538SAndroid Build Coastguard Worker for (const auto& header : headers_) {
235*6777b538SAndroid Build Coastguard Worker std::string log_value =
236*6777b538SAndroid Build Coastguard Worker ElideHeaderValueForNetLog(capture_mode, header.key, header.value);
237*6777b538SAndroid Build Coastguard Worker headers.Append(
238*6777b538SAndroid Build Coastguard Worker NetLogStringValue(base::StrCat({header.key, ": ", log_value})));
239*6777b538SAndroid Build Coastguard Worker }
240*6777b538SAndroid Build Coastguard Worker dict.Set("headers", std::move(headers));
241*6777b538SAndroid Build Coastguard Worker return dict;
242*6777b538SAndroid Build Coastguard Worker }
243*6777b538SAndroid Build Coastguard Worker
SetAcceptEncodingIfMissing(const GURL & url,const std::optional<base::flat_set<SourceStream::SourceType>> & accepted_stream_types,bool enable_brotli,bool enable_zstd)244*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::SetAcceptEncodingIfMissing(
245*6777b538SAndroid Build Coastguard Worker const GURL& url,
246*6777b538SAndroid Build Coastguard Worker const std::optional<base::flat_set<SourceStream::SourceType>>&
247*6777b538SAndroid Build Coastguard Worker accepted_stream_types,
248*6777b538SAndroid Build Coastguard Worker bool enable_brotli,
249*6777b538SAndroid Build Coastguard Worker bool enable_zstd) {
250*6777b538SAndroid Build Coastguard Worker if (HasHeader(kAcceptEncoding))
251*6777b538SAndroid Build Coastguard Worker return;
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Worker // If a range is specifically requested, set the "Accepted Encoding" header to
254*6777b538SAndroid Build Coastguard Worker // "identity".
255*6777b538SAndroid Build Coastguard Worker if (HasHeader(kRange)) {
256*6777b538SAndroid Build Coastguard Worker SetHeader(kAcceptEncoding, "identity");
257*6777b538SAndroid Build Coastguard Worker return;
258*6777b538SAndroid Build Coastguard Worker }
259*6777b538SAndroid Build Coastguard Worker
260*6777b538SAndroid Build Coastguard Worker // Supply Accept-Encoding headers first so that it is more likely that they
261*6777b538SAndroid Build Coastguard Worker // will be in the first transmitted packet. This can sometimes make it easier
262*6777b538SAndroid Build Coastguard Worker // to filter and analyze the streams to assure that a proxy has not damaged
263*6777b538SAndroid Build Coastguard Worker // these headers. Some proxies deliberately corrupt Accept-Encoding headers.
264*6777b538SAndroid Build Coastguard Worker std::vector<std::string> advertised_encoding_names;
265*6777b538SAndroid Build Coastguard Worker if (SupportsStreamType(accepted_stream_types,
266*6777b538SAndroid Build Coastguard Worker SourceStream::SourceType::TYPE_GZIP)) {
267*6777b538SAndroid Build Coastguard Worker advertised_encoding_names.push_back("gzip");
268*6777b538SAndroid Build Coastguard Worker }
269*6777b538SAndroid Build Coastguard Worker if (SupportsStreamType(accepted_stream_types,
270*6777b538SAndroid Build Coastguard Worker SourceStream::SourceType::TYPE_DEFLATE)) {
271*6777b538SAndroid Build Coastguard Worker advertised_encoding_names.push_back("deflate");
272*6777b538SAndroid Build Coastguard Worker }
273*6777b538SAndroid Build Coastguard Worker
274*6777b538SAndroid Build Coastguard Worker const bool can_use_advanced_encodings =
275*6777b538SAndroid Build Coastguard Worker (url.SchemeIsCryptographic() || IsLocalhost(url));
276*6777b538SAndroid Build Coastguard Worker
277*6777b538SAndroid Build Coastguard Worker // Advertise "br" encoding only if transferred data is opaque to proxy.
278*6777b538SAndroid Build Coastguard Worker if (enable_brotli &&
279*6777b538SAndroid Build Coastguard Worker SupportsStreamType(accepted_stream_types,
280*6777b538SAndroid Build Coastguard Worker SourceStream::SourceType::TYPE_BROTLI) &&
281*6777b538SAndroid Build Coastguard Worker can_use_advanced_encodings) {
282*6777b538SAndroid Build Coastguard Worker advertised_encoding_names.push_back("br");
283*6777b538SAndroid Build Coastguard Worker }
284*6777b538SAndroid Build Coastguard Worker // Advertise "zstd" encoding only if transferred data is opaque to proxy.
285*6777b538SAndroid Build Coastguard Worker if (enable_zstd &&
286*6777b538SAndroid Build Coastguard Worker SupportsStreamType(accepted_stream_types,
287*6777b538SAndroid Build Coastguard Worker SourceStream::SourceType::TYPE_ZSTD) &&
288*6777b538SAndroid Build Coastguard Worker can_use_advanced_encodings) {
289*6777b538SAndroid Build Coastguard Worker advertised_encoding_names.push_back("zstd");
290*6777b538SAndroid Build Coastguard Worker }
291*6777b538SAndroid Build Coastguard Worker if (!advertised_encoding_names.empty()) {
292*6777b538SAndroid Build Coastguard Worker // Tell the server what compression formats are supported.
293*6777b538SAndroid Build Coastguard Worker SetHeader(
294*6777b538SAndroid Build Coastguard Worker kAcceptEncoding,
295*6777b538SAndroid Build Coastguard Worker base::JoinString(base::make_span(advertised_encoding_names), ", "));
296*6777b538SAndroid Build Coastguard Worker }
297*6777b538SAndroid Build Coastguard Worker }
298*6777b538SAndroid Build Coastguard Worker
FindHeader(std::string_view key)299*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::HeaderVector::iterator HttpRequestHeaders::FindHeader(
300*6777b538SAndroid Build Coastguard Worker std::string_view key) {
301*6777b538SAndroid Build Coastguard Worker for (auto it = headers_.begin(); it != headers_.end(); ++it) {
302*6777b538SAndroid Build Coastguard Worker if (base::EqualsCaseInsensitiveASCII(key, it->key))
303*6777b538SAndroid Build Coastguard Worker return it;
304*6777b538SAndroid Build Coastguard Worker }
305*6777b538SAndroid Build Coastguard Worker
306*6777b538SAndroid Build Coastguard Worker return headers_.end();
307*6777b538SAndroid Build Coastguard Worker }
308*6777b538SAndroid Build Coastguard Worker
FindHeader(std::string_view key) const309*6777b538SAndroid Build Coastguard Worker HttpRequestHeaders::HeaderVector::const_iterator HttpRequestHeaders::FindHeader(
310*6777b538SAndroid Build Coastguard Worker std::string_view key) const {
311*6777b538SAndroid Build Coastguard Worker for (auto it = headers_.begin(); it != headers_.end(); ++it) {
312*6777b538SAndroid Build Coastguard Worker if (base::EqualsCaseInsensitiveASCII(key, it->key))
313*6777b538SAndroid Build Coastguard Worker return it;
314*6777b538SAndroid Build Coastguard Worker }
315*6777b538SAndroid Build Coastguard Worker
316*6777b538SAndroid Build Coastguard Worker return headers_.end();
317*6777b538SAndroid Build Coastguard Worker }
318*6777b538SAndroid Build Coastguard Worker
SetHeaderInternal(std::string_view key,std::string && value)319*6777b538SAndroid Build Coastguard Worker void HttpRequestHeaders::SetHeaderInternal(std::string_view key,
320*6777b538SAndroid Build Coastguard Worker std::string&& value) {
321*6777b538SAndroid Build Coastguard Worker auto it = FindHeader(key);
322*6777b538SAndroid Build Coastguard Worker if (it != headers_.end())
323*6777b538SAndroid Build Coastguard Worker it->value = std::move(value);
324*6777b538SAndroid Build Coastguard Worker else
325*6777b538SAndroid Build Coastguard Worker headers_.emplace_back(key, std::move(value));
326*6777b538SAndroid Build Coastguard Worker }
327*6777b538SAndroid Build Coastguard Worker
328*6777b538SAndroid Build Coastguard Worker } // namespace net
329