1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// HttpRequestHeaders manages the request headers.
// It maintains these in a vector of header key/value pairs, thereby maintaining
// the order of the headers. This means that any lookups are linear time
// operations.
#ifndef NET_HTTP_HTTP_REQUEST_HEADERS_H_
#define NET_HTTP_HTTP_REQUEST_HEADERS_H_
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/values.h"
#include "net/base/net_export.h"
#include "net/filter/source_stream_type.h"
#include "net/log/net_log_capture_mode.h"
#include "url/gurl.h"
namespace net {
class NET_EXPORT HttpRequestHeaders {
public:
struct NET_EXPORT HeaderKeyValuePair {
HeaderKeyValuePair();
HeaderKeyValuePair(std::string_view key, std::string_view value);
HeaderKeyValuePair(std::string_view key, std::string&& value);
// Inline to take advantage of the std::string_view constructor being
// constexpr.
HeaderKeyValuePair(std::string_view key, const char* value)
: HeaderKeyValuePair(key, std::string_view(value)) {}
bool operator==(const HeaderKeyValuePair& other) const = default;
std::string key;
std::string value;
};
typedef std::vector<HeaderKeyValuePair> HeaderVector;
class NET_EXPORT Iterator {
public:
explicit Iterator(const HttpRequestHeaders& headers);
Iterator(const Iterator&) = delete;
Iterator& operator=(const Iterator&) = delete;
~Iterator();
// Advances the iterator to the next header, if any. Returns true if there
// is a next header. Use name() and value() methods to access the resultant
// header name and value.
bool GetNext();
// These two accessors are only valid if GetNext() returned true.
const std::string& name() const { return curr_->key; }
const std::string& value() const { return curr_->value; }
private:
bool started_ = false;
HttpRequestHeaders::HeaderVector::const_iterator curr_;
const HttpRequestHeaders::HeaderVector::const_iterator end_;
};
static const char kConnectMethod[];
static const char kDeleteMethod[];
static const char kGetMethod[];
static const char kHeadMethod[];
static const char kOptionsMethod[];
static const char kPatchMethod[];
static const char kPostMethod[];
static const char kPutMethod[];
static const char kTraceMethod[];
static const char kTrackMethod[];
static const char kAccept[];
static const char kAcceptCharset[];
static const char kAcceptEncoding[];
static const char kAcceptLanguage[];
static const char kAuthorization[];
static const char kCacheControl[];
static const char kConnection[];
static const char kContentType[];
static const char kCookie[];
static const char kContentLength[];
static const char kHost[];
static const char kIfMatch[];
static const char kIfModifiedSince[];
static const char kIfNoneMatch[];
static const char kIfRange[];
static const char kIfUnmodifiedSince[];
static const char kOrigin[];
static const char kPragma[];
static const char kPriority[];
static const char kProxyAuthorization[];
static const char kProxyConnection[];
static const char kRange[];
static const char kReferer[];
static const char kTransferEncoding[];
static const char kUserAgent[];
HttpRequestHeaders();
HttpRequestHeaders(const HttpRequestHeaders& other);
HttpRequestHeaders(HttpRequestHeaders&& other);
~HttpRequestHeaders();
HttpRequestHeaders& operator=(const HttpRequestHeaders& other);
HttpRequestHeaders& operator=(HttpRequestHeaders&& other);
bool IsEmpty() const { return headers_.empty(); }
bool HasHeader(std::string_view key) const {
return FindHeader(key) != headers_.end();
}
// Gets the first header that matches |key|, if one exists. If none exist,
// returns std::nullopt.
std::optional<std::string> GetHeader(std::string_view key) const;
// Clears all the headers.
void Clear();
// Sets the header value pair for |key| and |value|. If |key| already exists,
// then the header value is modified, but the key is untouched, and the order
// in the vector remains the same. When comparing |key|, case is ignored.
// The caller must ensure that |key| passes HttpUtil::IsValidHeaderName() and
// |value| passes HttpUtil::IsValidHeaderValue().
void SetHeader(std::string_view key, std::string_view value);
void SetHeader(std::string_view key, std::string&& value);
// Inline to take advantage of the std::string_view constructor being
// constexpr.
void SetHeader(std::string_view key, const char* value) {
SetHeader(key, std::string_view(value));
}
// Does the same as above but without internal DCHECKs for validations.
void SetHeaderWithoutCheckForTesting(std::string_view key,
std::string_view value);
// Sets the header value pair for |key| and |value|, if |key| does not exist.
// If |key| already exists, the call is a no-op.
// When comparing |key|, case is ignored.
//
// The caller must ensure that |key| passes HttpUtil::IsValidHeaderName() and
// |value| passes HttpUtil::IsValidHeaderValue().
void SetHeaderIfMissing(std::string_view key, std::string_view value);
// Removes the first header that matches (case insensitive) |key|.
void RemoveHeader(std::string_view key);
// Parses the header from a string and calls SetHeader() with it. This string
// should not contain any CRLF. As per RFC7230 Section 3.2, the format is:
//
// header-field = field-name ":" OWS field-value OWS
//
// field-name = token
// field-value = *( field-content / obs-fold )
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
// field-vchar = VCHAR / obs-text
//
// obs-fold = CRLF 1*( SP / HTAB )
// ; obsolete line folding
// ; see Section 3.2.4
//
// AddHeaderFromString() will trim any LWS surrounding the
// field-content.
void AddHeaderFromString(std::string_view header_line);
// Same thing as AddHeaderFromString() except that |headers| is a "\r\n"
// delimited string of header lines. It will split up the string by "\r\n"
// and call AddHeaderFromString() on each.
void AddHeadersFromString(std::string_view headers);
// Calls SetHeader() on each header from |other|, maintaining order.
void MergeFrom(const HttpRequestHeaders& other);
void Swap(HttpRequestHeaders* other) { headers_.swap(other->headers_); }
// Serializes HttpRequestHeaders to a string representation. Joins all the
// header keys and values with ": ", and inserts "\r\n" between each header
// line, and adds the trailing "\r\n".
std::string ToString() const;
// Takes in the request line and returns a Value for use with the NetLog
// containing both the request line and all headers fields.
base::Value::Dict NetLogParams(const std::string& request_line,
NetLogCaptureMode capture_mode) const;
const HeaderVector& GetHeaderVector() const { return headers_; }
// Sets Accept-Encoding header based on `url` and `accepted_stream_types`, if
// it does not exist. "br" is appended only when `enable_brotli` is true.
void SetAcceptEncodingIfMissing(
const GURL& url,
const std::optional<base::flat_set<SourceStreamType>>&
accepted_stream_types,
bool enable_brotli,
bool enable_zstd);
private:
HeaderVector::iterator FindHeader(std::string_view key);
HeaderVector::const_iterator FindHeader(std::string_view key) const;
void SetHeaderInternal(std::string_view key, std::string&& value);
HeaderVector headers_;
};
} // namespace net
#endif // NET_HTTP_HTTP_REQUEST_HEADERS_H_
|