proxygen
proxygen::HTTPHeaders Class Reference

#include <HTTPHeaders.h>

Classes

struct  HTTPHeaderName
 

Public Types

using headers_initializer_list = std::initializer_list< std::pair< HTTPHeaderName, folly::StringPiece >>
 

Public Member Functions

FB_EXPORT HTTPHeaders ()
 
FB_EXPORT ~HTTPHeaders ()
 
FB_EXPORT HTTPHeaders (const HTTPHeaders &)
 
FB_EXPORT HTTPHeadersoperator= (const HTTPHeaders &)
 
FB_EXPORT HTTPHeaders (HTTPHeaders &&) noexcept
 
FB_EXPORT HTTPHeadersoperator= (HTTPHeaders &&)
 
void add (folly::StringPiece name, folly::StringPiece value)
 
template<typename T >
void add (folly::StringPiece name, T &&value)
 
template<typename T >
void add (HTTPHeaderCode code, T &&value)
 
void add (headers_initializer_list l)
 
void rawAdd (const std::string &name, const std::string &value)
 
void addFromCodec (const char *str, size_t len, std::string &&value)
 
void set (folly::StringPiece name, const std::string &value)
 
void set (HTTPHeaderCode code, const std::string &value)
 
void rawSet (const std::string &name, const std::string &value)
 
bool exists (folly::StringPiece name) const
 
bool exists (HTTPHeaderCode code) const
 
bool rawExists (std::string &name) const
 
template<typename T >
std::string combine (const T &header, const std::string &separator=COMBINE_SEPARATOR) const
 
template<typename LAMBDA >
void forEach (LAMBDA func) const
 
template<typename LAMBDA >
void forEachWithCode (LAMBDA func) const
 
template<typename LAMBDA >
bool removeByPredicate (LAMBDA func)
 
template<typename T >
const std::stringgetSingleOrEmpty (const T &nameOrCode) const
 
const std::string rawGet (const std::string &header) const
 
size_t getNumberOfValues (HTTPHeaderCode code) const
 
size_t getNumberOfValues (folly::StringPiece name) const
 
template<typename LAMBDA >
bool forEachValueOfHeader (folly::StringPiece name, LAMBDA func) const
 
template<typename LAMBDA >
bool forEachValueOfHeader (HTTPHeaderCode code, LAMBDA func) const
 
bool remove (folly::StringPiece name)
 
bool remove (HTTPHeaderCode code)
 
void rawRemove (const std::string &name)
 
void removeAll ()
 
void stripPerHopHeaders (HTTPHeaders &strippedHeaders)
 
size_t size () const
 
void copyTo (HTTPHeaders &hdrs) const
 

Static Public Member Functions

static std::bitset< 256 > & perHopHeaderCodes ()
 

Static Public Attributes

static const std::string COMBINE_SEPARATOR = ", "
 

Private Member Functions

bool transferHeaderIfPresent (folly::StringPiece name, HTTPHeaders &dest)
 
void disposeOfHeaderNames ()
 

Private Attributes

folly::fbvector< HTTPHeaderCodecodes_
 
folly::fbvector< const std::string * > headerNames_
 
folly::fbvector< std::stringheaderValues_
 
size_t deletedCount_
 

Static Private Attributes

static const size_t kInitialVectorReserve = 16
 

Detailed Description

A collection of HTTP headers.

This is broken out from HTTPMessage, as it's convenient for other things to be able to use collections of HTTP headers that are easy to work with. The structure is optimized for real-life header collection sizes.

Headers are stored as Name/Value pairs, in the order they are received on the wire. We hash the names of all common HTTP headers (using a static perfect hash function generated using gperf from HTTPCommonHeaders.gperf) into 1-byte hashes (we call them "codes") and only store these. We search them using memchr, which has an x86_64 assembly implementation with complexity O(n/16) ;)

Instead of creating strings with header names, we point to a static array of strings in HTTPCommonHeaders. If the header name is not in our set of common header names (this is considered unlikely, because we intend this set to be very complete), then we create a new string with its name (we own that pointer then). For such headers, we store the code HTTP_HEADER_OTHER.

The code HTTP_HEADER_NONE signifies a header that has been removed.

Most methods which take a header name have two versions: one accepting a string, and one accepting a code. It is recommended to use the latter if possible, as in: headers.add(HTTP_HEADER_LOCATION, location); rather than: headers.add("Location", location);

Definition at line 68 of file HTTPHeaders.h.

Member Typedef Documentation

Definition at line 86 of file HTTPHeaders.h.

Constructor & Destructor Documentation

proxygen::HTTPHeaders::HTTPHeaders ( )

Definition at line 45 of file HTTPHeaders.cpp.

References codes_, headerNames_, headerValues_, kInitialVectorReserve, and folly::fbvector< T, Allocator >::reserve().

45  :
46  deletedCount_(0) {
50 }
void reserve(size_type n)
Definition: FBVector.h:1003
static const size_t kInitialVectorReserve
Definition: HTTPHeaders.h:281
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
proxygen::HTTPHeaders::~HTTPHeaders ( )

Definition at line 157 of file HTTPHeaders.cpp.

References disposeOfHeaderNames().

157  {
159 }
proxygen::HTTPHeaders::HTTPHeaders ( const HTTPHeaders hdrs)

Definition at line 161 of file HTTPHeaders.cpp.

References codes_, headerNames_, proxygen::HTTP_HEADER_OTHER, i, folly::fbvector< T, Allocator >::size(), and string.

161  :
162  codes_(hdrs.codes_),
163  headerNames_(hdrs.headerNames_),
164  headerValues_(hdrs.headerValues_),
165  deletedCount_(hdrs.deletedCount_) {
166  for (size_t i = 0; i < codes_.size(); ++i) {
167  if (codes_[i] == HTTP_HEADER_OTHER) {
168  headerNames_[i] = new string(*hdrs.headerNames_[i]);
169  }
170  }
171 }
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
const char * string
Definition: Conv.cpp:212
size_type size() const noexcept
Definition: FBVector.h:964
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
proxygen::HTTPHeaders::HTTPHeaders ( HTTPHeaders &&  hdrs)
noexcept

Definition at line 173 of file HTTPHeaders.cpp.

173  :
174  codes_(std::move(hdrs.codes_)),
175  headerNames_(std::move(hdrs.headerNames_)),
176  headerValues_(std::move(hdrs.headerValues_)),
177  deletedCount_(hdrs.deletedCount_) {
178  hdrs.removeAll();
179 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273

Member Function Documentation

void proxygen::HTTPHeaders::add ( folly::StringPiece  name,
folly::StringPiece  value 
)

Add the header 'name' with value 'value'; if other instances of this header name exist, they will be retained.

Definition at line 52 of file HTTPHeaders.cpp.

References codes_, folly::Range< Iter >::data(), folly::fbvector< T, Allocator >::emplace_back(), proxygen::HTTPCommonHeaders::getPointerToHeaderName(), proxygen::HTTPCommonHeaders::hash(), headerNames_, headerValues_, proxygen::HTTP_HEADER_OTHER, folly::fbvector< T, Allocator >::push_back(), folly::Range< Iter >::size(), and string.

Referenced by add(), proxygen::HTTPMessage::constructDirectResponse(), TestPriorityMapBuilder::createVirtualStreams(), CurlService::CurlClient::CurlClient(), proxygen::HTTPMessage::ensureHostHeader(), proxygen::getBigGetRequest(), proxygen::compress::SimStreamingCallback::onHeader(), proxygen::HTTPDirectResponseHandler::onHeadersComplete(), CurlService::CurlClient::parseHeaders(), proxygen::SPDYCodec::parseHeaders(), proxygen::HTTP1xCodec::pushHeaderNameAndValue(), rawAdd(), proxygen::HTTPHandlerBase::sendChunkedReplyWithBody(), proxygen::HTTPHandlerBase::sendHeaders(), proxygen::MockHTTPPushHandler::sendPushHeaders(), proxygen::HTTPHandlerBase::sendReplyWithBody(), CurlService::CurlClient::sendRequest(), set(), proxygen::HTTPRequestVerifier::setAuthority(), TEST(), TEST_F(), TEST_P(), and HTTP2CodecTest::testHeaderListSize().

52  {
53  CHECK(name.size());
54  const HTTPHeaderCode code = HTTPCommonHeaders::hash(name.data(), name.size());
55  codes_.push_back(code);
57  ? new std::string(name.data(), name.size())
59  headerValues_.emplace_back(value.data(), value.size());
60 }
constexpr size_type size() const
Definition: Range.h:431
void push_back(const T &value)
Definition: FBVector.h:1156
constexpr Iter data() const
Definition: Range.h:446
static const std::string * getPointerToHeaderName(HTTPHeaderCode code, HTTPCommonHeaderTableType type=TABLE_CAMELCASE)
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
void emplace_back(Args &&...args)
Definition: FBVector.h:1147
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
const char * string
Definition: Conv.cpp:212
static FB_EXPORT HTTPHeaderCode hash(const char *name, size_t len)
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
template<typename T >
void proxygen::HTTPHeaders::add ( folly::StringPiece  name,
T &&  value 
)

Definition at line 297 of file HTTPHeaders.h.

References codes_, folly::Range< Iter >::data(), folly::fbvector< T, Allocator >::emplace_back(), proxygen::HTTPCommonHeaders::getPointerToHeaderName(), proxygen::HTTPCommonHeaders::hash(), headerNames_, headerValues_, proxygen::HTTP_HEADER_OTHER, folly::fbvector< T, Allocator >::push_back(), folly::Range< Iter >::size(), string, and value.

297  {
298  assert(name.size());
299  const HTTPHeaderCode code = HTTPCommonHeaders::hash(name.data(), name.size());
300  codes_.push_back(code);
302  ? new std::string(name.data(), name.size())
304  headerValues_.emplace_back(std::forward<T>(value));
305 }
constexpr size_type size() const
Definition: Range.h:431
void push_back(const T &value)
Definition: FBVector.h:1156
constexpr Iter data() const
Definition: Range.h:446
static const std::string * getPointerToHeaderName(HTTPHeaderCode code, HTTPCommonHeaderTableType type=TABLE_CAMELCASE)
static const char *const value
Definition: Conv.cpp:50
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
void emplace_back(Args &&...args)
Definition: FBVector.h:1147
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
const char * string
Definition: Conv.cpp:212
static FB_EXPORT HTTPHeaderCode hash(const char *name, size_t len)
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
template<typename T >
void proxygen::HTTPHeaders::add ( HTTPHeaderCode  code,
T &&  value 
)

Definition at line 308 of file HTTPHeaders.h.

References codes_, folly::fbvector< T, Allocator >::emplace_back(), proxygen::HTTPCommonHeaders::getPointerToHeaderName(), headerNames_, headerValues_, folly::fbvector< T, Allocator >::push_back(), and value.

308  {
309  codes_.push_back(code);
311  headerValues_.emplace_back(std::forward<T>(value));
312 }
void push_back(const T &value)
Definition: FBVector.h:1156
static const std::string * getPointerToHeaderName(HTTPHeaderCode code, HTTPCommonHeaderTableType type=TABLE_CAMELCASE)
static const char *const value
Definition: Conv.cpp:50
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
void emplace_back(Args &&...args)
Definition: FBVector.h:1147
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
void proxygen::HTTPHeaders::add ( HTTPHeaders::headers_initializer_list  l)

Definition at line 62 of file HTTPHeaders.cpp.

References add(), proxygen::HTTPHeaders::HTTPHeaderName::CODE, and string.

62  {
63  for (auto& p : l) {
64  if (p.first.type_ == HTTPHeaderName::CODE) {
65  add(p.first.code_, std::string(p.second.data(), p.second.size()));
66  }
67  else {
68  add(p.first.name_, std::string(p.second.data(), p.second.size()));
69  }
70  }
71 }
const char * string
Definition: Conv.cpp:212
void add(folly::StringPiece name, folly::StringPiece value)
Definition: HTTPHeaders.cpp:52
void proxygen::HTTPHeaders::addFromCodec ( const char *  str,
size_t  len,
std::string &&  value 
)

Definition at line 77 of file HTTPHeaders.cpp.

References codes_, folly::fbvector< T, Allocator >::emplace_back(), proxygen::HTTPCommonHeaders::getPointerToHeaderName(), proxygen::HTTPCommonHeaders::hash(), headerNames_, headerValues_, proxygen::HTTP_HEADER_OTHER, folly::gen::move, folly::fbvector< T, Allocator >::push_back(), and value.

Referenced by proxygen::HTTP1xCodec::pushHeaderNameAndValue().

77  {
78  const HTTPHeaderCode code = HTTPCommonHeaders::hash(str, len);
79  codes_.push_back(code);
81  ? new string(str, len)
84 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void push_back(const T &value)
Definition: FBVector.h:1156
static const std::string * getPointerToHeaderName(HTTPHeaderCode code, HTTPCommonHeaderTableType type=TABLE_CAMELCASE)
static const char *const value
Definition: Conv.cpp:50
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
void emplace_back(Args &&...args)
Definition: FBVector.h:1147
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
static FB_EXPORT HTTPHeaderCode hash(const char *name, size_t len)
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
template<typename T >
std::string proxygen::HTTPHeaders::combine ( const T header,
const std::string separator = COMBINE_SEPARATOR 
) const

combine all the value for this header into a string

Definition at line 382 of file HTTPHeaders.h.

References forEachValueOfHeader(), string, and value.

Referenced by proxygen::HeaderDecodeInfo::onHeadersComplete(), proxygen::compress::SimStreamingCallback::onHeadersComplete(), rawExists(), and TEST().

383  {
384  std::string combined = "";
385  forEachValueOfHeader(header, [&] (const std::string& value) -> bool {
386  if (combined.empty()) {
387  combined.append(value);
388  } else {
389  combined.append(separator).append(value);
390  }
391  return false;
392  });
393  return combined;
394 }
bool forEachValueOfHeader(folly::StringPiece name, LAMBDA func) const
Definition: HTTPHeaders.h:355
static const char *const value
Definition: Conv.cpp:50
const char * string
Definition: Conv.cpp:212
void proxygen::HTTPHeaders::copyTo ( HTTPHeaders hdrs) const

Copy all headers from this to hdrs.

Definition at line 312 of file HTTPHeaders.cpp.

References codes_, headerNames_, headerValues_, proxygen::HTTP_HEADER_NONE, proxygen::HTTP_HEADER_OTHER, i, folly::fbvector< T, Allocator >::push_back(), and folly::fbvector< T, Allocator >::size().

Referenced by rawRemove().

312  {
313  for (size_t i = 0; i < codes_.size(); ++i) {
314  if (codes_[i] != HTTP_HEADER_NONE) {
315  hdrs.codes_.push_back(codes_[i]);
316  hdrs.headerNames_.push_back((codes_[i] == HTTP_HEADER_OTHER) ?
317  new string(*headerNames_[i]) : headerNames_[i]);
318  hdrs.headerValues_.push_back(headerValues_[i]);
319  }
320  }
321 }
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
size_type size() const noexcept
Definition: FBVector.h:964
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
void proxygen::HTTPHeaders::disposeOfHeaderNames ( )
private

Definition at line 149 of file HTTPHeaders.cpp.

References codes_, headerNames_, proxygen::HTTP_HEADER_OTHER, i, and folly::fbvector< T, Allocator >::size().

Referenced by operator=(), removeAll(), and ~HTTPHeaders().

149  {
150  for (size_t i = 0; i < codes_.size(); ++i) {
151  if (codes_[i] == HTTP_HEADER_OTHER) {
152  delete headerNames_[i];
153  }
154  }
155 }
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
size_type size() const noexcept
Definition: FBVector.h:964
bool proxygen::HTTPHeaders::exists ( folly::StringPiece  name) const

Do we have an instance of the given header?

Definition at line 86 of file HTTPHeaders.cpp.

References folly::Range< Iter >::data(), proxygen::HTTPCommonHeaders::hash(), proxygen::HTTP_HEADER_OTHER, ITERATE_OVER_STRINGS, and folly::Range< Iter >::size().

Referenced by proxygen::RFC2616::bodyImplied(), proxygen::HTTPMessage::constructDirectResponse(), proxygen::HTTPMessage::ensureHostHeader(), proxygen::SPDYCodec::parseHeaders(), rawExists(), rawSet(), proxygen::SPDYCodec::serializeRequestHeaders(), proxygen::SPDYCodec::serializeResponseHeaders(), and TEST_F().

86  {
87  const HTTPHeaderCode code = HTTPCommonHeaders::hash(name.data(),
88  name.size());
89  if (code != HTTP_HEADER_OTHER) {
90  return exists(code);
91  } else {
92  ITERATE_OVER_STRINGS(name, { return true; });
93  return false;
94  }
95 }
bool exists(folly::StringPiece name) const
Definition: HTTPHeaders.cpp:86
constexpr size_type size() const
Definition: Range.h:431
constexpr Iter data() const
Definition: Range.h:446
#define ITERATE_OVER_STRINGS(String, Block)
Definition: HTTPHeaders.h:329
static FB_EXPORT HTTPHeaderCode hash(const char *name, size_t len)
bool proxygen::HTTPHeaders::exists ( HTTPHeaderCode  code) const

Definition at line 97 of file HTTPHeaders.cpp.

References codes_, folly::fbvector< T, Allocator >::data(), and folly::fbvector< T, Allocator >::size().

97  {
98  if (codes_.data() == nullptr) {
99  return false;
100  }
101  return memchr((void*)codes_.data(), code, codes_.size()) != nullptr;
102 }
T * data() noexcept
Definition: FBVector.h:1135
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
size_type size() const noexcept
Definition: FBVector.h:964
template<typename LAMBDA >
void proxygen::HTTPHeaders::forEach ( LAMBDA  func) const
inline

Process the list of all headers, in the order that they were seen: for each header:value pair, the function/functor/lambda-expression given as the second parameter will be executed. It should take two const string & parameters and return void. Example use: hdrs.forEach([&] (const string& header, const string& val) { std::cout << header << ": " << val; });

Definition at line 337 of file HTTPHeaders.h.

References codes_, headerNames_, headerValues_, proxygen::HTTP_HEADER_NONE, i, and folly::fbvector< T, Allocator >::size().

Referenced by proxygen::HTTPArchive::convertToHPACK(), CurlService::CurlClient::CurlClient(), proxygen::HTTPMessage::describe(), proxygen::HTTP2Codec::encodeHeaders(), proxygen::HTTP1xCodec::generateTrailers(), proxygen::HTTPArchive::getSize(), proxygen::HasHTTPHeaderMatcherImpl::MatchAndExplain(), and rawExists().

337  {
338  for (size_t i = 0; i < codes_.size(); ++i) {
339  if (codes_[i] != HTTP_HEADER_NONE) {
340  func(*headerNames_[i], headerValues_[i]);
341  }
342  }
343 }
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
size_type size() const noexcept
Definition: FBVector.h:964
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
template<typename LAMBDA >
bool proxygen::HTTPHeaders::forEachValueOfHeader ( folly::StringPiece  name,
LAMBDA  func 
) const
inline

Process the ordered list of values for the given header name: for each value, the function/functor/lambda-expression given as the second parameter will be executed. It should take one const string & parameter and return bool (false to keep processing, true to stop it). Example use: hdrs.forEachValueOfHeader("someheader", [&] (const string& val) { std::cout << val; return false; }); This method returns true if processing was stopped (by func returning true), and false otherwise.

Definition at line 355 of file HTTPHeaders.h.

References folly::Range< Iter >::data(), proxygen::HTTPCommonHeaders::hash(), headerValues_, proxygen::HTTP_HEADER_OTHER, ITERATE_OVER_STRINGS, and folly::Range< Iter >::size().

Referenced by combine(), proxygen::HTTPMessage::doHeaderTokenCheck(), getNumberOfValues(), getSingleOrEmpty(), proxygen::HTTPMessage::parseCookies(), rawGet(), and stripPerHopHeaders().

356  {
357  const HTTPHeaderCode code = HTTPCommonHeaders::hash(name.data(), name.size());
358  if (code != HTTP_HEADER_OTHER) {
359  return forEachValueOfHeader(code, func);
360  } else {
361  ITERATE_OVER_STRINGS(name, {
362  if (func(headerValues_[pos])) {
363  return true;
364  }
365  });
366  return false;
367  }
368 }
constexpr size_type size() const
Definition: Range.h:431
bool forEachValueOfHeader(folly::StringPiece name, LAMBDA func) const
Definition: HTTPHeaders.h:355
constexpr Iter data() const
Definition: Range.h:446
#define ITERATE_OVER_STRINGS(String, Block)
Definition: HTTPHeaders.h:329
static FB_EXPORT HTTPHeaderCode hash(const char *name, size_t len)
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
template<typename LAMBDA >
bool proxygen::HTTPHeaders::forEachValueOfHeader ( HTTPHeaderCode  code,
LAMBDA  func 
) const
inline

Definition at line 371 of file HTTPHeaders.h.

References headerValues_, and ITERATE_OVER_CODES.

372  {
373  ITERATE_OVER_CODES(code, {
374  if (func(headerValues_[pos])) {
375  return true;
376  }
377  });
378  return false;
379 }
#define ITERATE_OVER_CODES(Code, Block)
Definition: HTTPHeaders.h:315
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
template<typename LAMBDA >
void proxygen::HTTPHeaders::forEachWithCode ( LAMBDA  func) const
inline

Process the list of all headers, in the order that they were seen: for each header:value pair, the function/functor/lambda-expression given as the second parameter will be executed. It should take one HTTPHeaderCode (code) parameter, two const string & parameters and return void. Example use: hdrs.forEachWithCode([&] (HTTPHeaderCode code, const string& header, const string& val) { std::cout << header << "(" << code << "): " << val; });

Definition at line 346 of file HTTPHeaders.h.

References codes_, headerNames_, headerValues_, proxygen::HTTP_HEADER_NONE, i, and folly::fbvector< T, Allocator >::size().

Referenced by proxygen::CodecUtil::appendHeaders(), proxygen::SPDYCodec::encodeHeaders(), proxygen::HTTP1xCodec::generateHeader(), proxygen::compress::prepareMessageForCompression(), and rawExists().

346  {
347  for (size_t i = 0; i < codes_.size(); ++i) {
348  if (codes_[i] != HTTP_HEADER_NONE) {
349  func(codes_[i], *headerNames_[i], headerValues_[i]);
350  }
351  }
352 }
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
size_type size() const noexcept
Definition: FBVector.h:964
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
size_t proxygen::HTTPHeaders::getNumberOfValues ( HTTPHeaderCode  code) const

Get the number of values corresponding to a given header name.

Definition at line 104 of file HTTPHeaders.cpp.

References count, and ITERATE_OVER_CODES.

Referenced by proxygen::HTTP2Codec::onIngressUpgradeMessage(), rawGet(), CurlService::CurlClient::sendRequest(), TEST(), and TEST_F().

104  {
105  size_t count = 0;
106  ITERATE_OVER_CODES(code, {
107  (void)pos;
108  ++count;
109  });
110  return count;
111 }
#define ITERATE_OVER_CODES(Code, Block)
Definition: HTTPHeaders.h:315
int * count
size_t proxygen::HTTPHeaders::getNumberOfValues ( folly::StringPiece  name) const

Definition at line 113 of file HTTPHeaders.cpp.

References count, and forEachValueOfHeader().

113  {
114  size_t count = 0;
115  forEachValueOfHeader(name, [&] (folly::StringPiece /*value*/) -> bool {
116  ++count;
117  return false;
118  });
119  return count;
120 }
bool forEachValueOfHeader(folly::StringPiece name, LAMBDA func) const
Definition: HTTPHeaders.h:355
int * count
template<typename T >
const std::string & proxygen::HTTPHeaders::getSingleOrEmpty ( const T nameOrCode) const

Returns the value of the header if it's found in the message and is the only value under the given name. If either of these is violated, returns empty_string.

Definition at line 420 of file HTTPHeaders.h.

References proxygen::empty_string, forEachValueOfHeader(), string, and value.

Referenced by HTTPDownstreamTest< SPDY3_1CodecPair >::expect101(), PushService::generateUrl(), CurlService::CurlClient::getServerName(), proxygen::HTTP2Codec::onIngressUpgradeMessage(), proxygen::SPDYCodec::parseHeaders(), proxygen::compress::prepareMessageForCompression(), proxygen::CodecUtil::prepareMessageForCompression(), proxygen::HTTPMessage::processMaxForwards(), rawExists(), rawGet(), proxygen::HTTPTransaction::sendHeadersWithOptionalEOM(), proxygen::SPDYCodec::serializeRequestHeaders(), TEST(), and TEST_F().

420  {
421  const std::string* res = nullptr;
422  forEachValueOfHeader(nameOrCode, [&] (const std::string& value) -> bool {
423  if (res != nullptr) {
424  // a second value is found
425  res = nullptr;
426  return true; // stop processing
427  } else {
428  // the first value is found
429  res = &value;
430  return false;
431  }
432  });
433  if (res == nullptr) {
434  return empty_string;
435  } else {
436  return *res;
437  }
438 }
bool forEachValueOfHeader(folly::StringPiece name, LAMBDA func) const
Definition: HTTPHeaders.h:355
static const char *const value
Definition: Conv.cpp:50
const std::string empty_string
Definition: HTTPHeaders.cpp:23
const char * string
Definition: Conv.cpp:212
HTTPHeaders & proxygen::HTTPHeaders::operator= ( const HTTPHeaders hdrs)

Definition at line 181 of file HTTPHeaders.cpp.

References codes_, deletedCount_, disposeOfHeaderNames(), headerNames_, headerValues_, proxygen::HTTP_HEADER_OTHER, i, folly::fbvector< T, Allocator >::size(), and string.

181  {
182  if (this != &hdrs) {
184  codes_ = hdrs.codes_;
185  headerNames_ = hdrs.headerNames_;
186  headerValues_ = hdrs.headerValues_;
187  deletedCount_ = hdrs.deletedCount_;
188  for (size_t i = 0; i < codes_.size(); ++i) {
189  if (codes_[i] == HTTP_HEADER_OTHER) {
190  headerNames_[i] = new string(*hdrs.headerNames_[i]);
191  }
192  }
193  }
194  return *this;
195 }
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
const char * string
Definition: Conv.cpp:212
size_type size() const noexcept
Definition: FBVector.h:964
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
HTTPHeaders & proxygen::HTTPHeaders::operator= ( HTTPHeaders &&  hdrs)

Definition at line 197 of file HTTPHeaders.cpp.

References codes_, deletedCount_, headerNames_, headerValues_, and folly::gen::move.

197  {
198  if (this != &hdrs) {
199  codes_ = std::move(hdrs.codes_);
200  headerNames_ = std::move(hdrs.headerNames_);
201  headerValues_ = std::move(hdrs.headerValues_);
202  deletedCount_ = hdrs.deletedCount_;
203 
204  hdrs.removeAll();
205  }
206 
207  return *this;
208 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
bitset< 256 > & proxygen::HTTPHeaders::perHopHeaderCodes ( )
static

Determines whether header with a given code is a per-hop header, which should be stripped by stripPerHopHeaders().

Definition at line 26 of file HTTPHeaders.cpp.

References proxygen::HTTP_HEADER_CONNECTION, proxygen::HTTP_HEADER_KEEP_ALIVE, proxygen::HTTP_HEADER_PROXY_AUTHENTICATE, proxygen::HTTP_HEADER_PROXY_AUTHORIZATION, proxygen::HTTP_HEADER_PROXY_CONNECTION, proxygen::HTTP_HEADER_TE, proxygen::HTTP_HEADER_TRAILER, proxygen::HTTP_HEADER_TRANSFER_ENCODING, and proxygen::HTTP_HEADER_UPGRADE.

Referenced by rawRemove(), and stripPerHopHeaders().

void proxygen::HTTPHeaders::rawAdd ( const std::string name,
const std::string value 
)

Definition at line 73 of file HTTPHeaders.cpp.

References add().

73  {
74  add(name, value);
75 }
const char * name
Definition: http_parser.c:437
static const char *const value
Definition: Conv.cpp:50
void add(folly::StringPiece name, folly::StringPiece value)
Definition: HTTPHeaders.cpp:52
bool proxygen::HTTPHeaders::rawExists ( std::string name) const
inline

Definition at line 137 of file HTTPHeaders.h.

References combine(), exists(), forEach(), forEachWithCode(), getSingleOrEmpty(), removeByPredicate(), string, and T.

137  {
138  return exists(name);
139  }
bool exists(folly::StringPiece name) const
Definition: HTTPHeaders.cpp:86
const char * name
Definition: http_parser.c:437
const std::string proxygen::HTTPHeaders::rawGet ( const std::string header) const
inline

Definition at line 199 of file HTTPHeaders.h.

References forEachValueOfHeader(), getNumberOfValues(), getSingleOrEmpty(), and name.

199  {
200  return getSingleOrEmpty(header);
201  }
const std::string & getSingleOrEmpty(const T &nameOrCode) const
Definition: HTTPHeaders.h:420
void proxygen::HTTPHeaders::rawRemove ( const std::string name)
inline

Definition at line 232 of file HTTPHeaders.h.

References copyTo(), name, perHopHeaderCodes(), removeAll(), size(), and stripPerHopHeaders().

232  {
233  remove(name);
234  }
const char * name
Definition: http_parser.c:437
void proxygen::HTTPHeaders::rawSet ( const std::string name,
const std::string value 
)
inline

Definition at line 128 of file HTTPHeaders.h.

References exists(), name, and value.

128  {
129  set(name, value);
130  }
const char * name
Definition: http_parser.c:437
static const char *const value
Definition: Conv.cpp:50
bool proxygen::HTTPHeaders::remove ( folly::StringPiece  name)

Remove all instances of the given header, returning true if anything was removed and false if this header didn't exist in our set.

Definition at line 122 of file HTTPHeaders.cpp.

References codes_, folly::Range< Iter >::data(), deletedCount_, proxygen::HTTPCommonHeaders::hash(), headerNames_, proxygen::HTTP_HEADER_NONE, proxygen::HTTP_HEADER_OTHER, ITERATE_OVER_STRINGS, and folly::Range< Iter >::size().

Referenced by TEST().

122  {
123  const HTTPHeaderCode code = HTTPCommonHeaders::hash(name.data(),
124  name.size());
125  if (code != HTTP_HEADER_OTHER) {
126  return remove(code);
127  } else {
128  bool removed = false;
129  ITERATE_OVER_STRINGS(name, {
130  delete headerNames_[pos];
131  codes_[pos] = HTTP_HEADER_NONE;
132  removed = true;
133  ++deletedCount_;
134  });
135  return removed;
136  }
137 }
constexpr size_type size() const
Definition: Range.h:431
constexpr Iter data() const
Definition: Range.h:446
#define ITERATE_OVER_STRINGS(String, Block)
Definition: HTTPHeaders.h:329
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
static FB_EXPORT HTTPHeaderCode hash(const char *name, size_t len)
bool proxygen::HTTPHeaders::remove ( HTTPHeaderCode  code)

Definition at line 139 of file HTTPHeaders.cpp.

References codes_, deletedCount_, proxygen::HTTP_HEADER_NONE, and ITERATE_OVER_CODES.

139  {
140  bool removed = false;
141  ITERATE_OVER_CODES(code, {
142  codes_[pos] = HTTP_HEADER_NONE;
143  removed = true;
144  ++deletedCount_;
145  });
146  return removed;
147 }
#define ITERATE_OVER_CODES(Code, Block)
Definition: HTTPHeaders.h:315
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
void proxygen::HTTPHeaders::removeAll ( )

Remove all headers.

Definition at line 210 of file HTTPHeaders.cpp.

References folly::fbvector< T, Allocator >::clear(), codes_, deletedCount_, disposeOfHeaderNames(), headerNames_, and headerValues_.

Referenced by rawRemove(), and proxygen::HTTPMessage::stripPerHopHeaders().

210  {
212 
213  codes_.clear();
216  deletedCount_ = 0;
217 }
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
void clear() noexcept
Definition: FBVector.h:1188
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
template<typename LAMBDA >
bool proxygen::HTTPHeaders::removeByPredicate ( LAMBDA  func)
inline

Process the list of all headers, in the order that they were seen: for each header:value pair, the function/functor/lambda-expression given as the parameter will be executed to determine whether the header should be removed. Example use:

hdrs.removeByPredicate([&] (HTTPHeaderCode code,
                            const string& header,
                            const string& val) {
  return boost::regex_match(header, "^X-Fb-.*");
});

return true only if one or more headers are removed.

Definition at line 398 of file HTTPHeaders.h.

References codes_, deletedCount_, headerNames_, headerValues_, proxygen::HTTP_HEADER_NONE, proxygen::HTTP_HEADER_OTHER, i, and folly::fbvector< T, Allocator >::size().

Referenced by rawExists().

398  {
399  bool removed = false;
400  for (size_t i = 0; i < codes_.size(); ++i) {
401  if (codes_[i] == HTTP_HEADER_NONE ||
402  !func(codes_[i], *headerNames_[i], headerValues_[i])) {
403  continue;
404  }
405 
406  if (codes_[i] == HTTP_HEADER_OTHER) {
407  delete headerNames_[i];
408  headerNames_[i] = nullptr;
409  }
410 
412  ++deletedCount_;
413  removed = true;
414  }
415 
416  return removed;
417 }
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
size_type size() const noexcept
Definition: FBVector.h:964
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
void proxygen::HTTPHeaders::set ( HTTPHeaderCode  code,
const std::string value 
)
inline

Definition at line 124 of file HTTPHeaders.h.

References add(), and value.

124  {
125  remove(code);
126  add(code, value);
127  }
static const char *const value
Definition: Conv.cpp:50
void add(folly::StringPiece name, folly::StringPiece value)
Definition: HTTPHeaders.cpp:52
void proxygen::HTTPHeaders::stripPerHopHeaders ( HTTPHeaders strippedHeaders)

Remove per-hop-headers and headers named in the Connection header and place the value in strippedHeaders

Definition at line 253 of file HTTPHeaders.cpp.

References codes_, deletedCount_, forEachValueOfHeader(), headerNames_, headerValues_, proxygen::HTTP_HEADER_CONNECTION, proxygen::HTTP_HEADER_NONE, i, proxygen::isLWS(), perHopHeaderCodes(), folly::fbvector< T, Allocator >::push_back(), folly::fbvector< T, Allocator >::size(), and transferHeaderIfPresent().

Referenced by rawRemove(), and proxygen::HTTPMessage::stripPerHopHeaders().

253  {
254  int len;
256  (const string& stdStr) -> bool {
257  // Remove all headers specified in Connection header
258  // look for multiple values separated by commas
259  char const* str = stdStr.c_str();
260 
261  // skip leading whitespace
262  while (isLWS(*str)) str++;
263 
264  while (*str != 0) {
265  char const* pos = strchr(str, ',');
266  if (pos == nullptr) {
267  // last (or only) token, done
268 
269  // count chars in the token
270  len = 0;
271  while (str[len] != 0 && !isLWS(str[len])) len++;
272  if (len > 0) {
273  string hdr(str, len);
274  if (transferHeaderIfPresent(hdr, strippedHeaders)) {
275  VLOG(3) << "Stripped connection-named hop-by-hop header " << hdr;
276  }
277  }
278  break;
279  }
280  len = pos - str;
281  // strip trailing whitespace
282  while (len > 0 && isLWS(str[len - 1])) len--;
283  if (len > 0) {
284  // non-empty token
285  string hdr(str, len);
286  if (transferHeaderIfPresent(hdr, strippedHeaders)) {
287  VLOG(3) << "Stripped connection-named hop-by-hop header " << hdr;
288  }
289  } // else empty token, no-op
290  str = pos + 1;
291 
292  // skip whitespace
293  while (isLWS(*str)) str++;
294  }
295  return false; // continue processing "connection" headers
296  });
297 
298  // Strip hop-by-hop headers
299  auto& perHopHeaders = perHopHeaderCodes();
300  for (size_t i = 0; i < codes_.size(); ++i) {
301  if (perHopHeaders[codes_[i]]) {
302  strippedHeaders.codes_.push_back(codes_[i]);
303  strippedHeaders.headerNames_.push_back(headerNames_[i]);
304  strippedHeaders.headerValues_.push_back(headerValues_[i]);
306  ++deletedCount_;
307  VLOG(5) << "Stripped hop-by-hop header " << *headerNames_[i];
308  }
309  }
310 }
bool isLWS(char c)
Definition: HTTPHeaders.h:31
bool transferHeaderIfPresent(folly::StringPiece name, HTTPHeaders &dest)
static std::bitset< 256 > & perHopHeaderCodes()
Definition: HTTPHeaders.cpp:26
bool forEachValueOfHeader(folly::StringPiece name, LAMBDA func) const
Definition: HTTPHeaders.h:355
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
size_type size() const noexcept
Definition: FBVector.h:964
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273
bool proxygen::HTTPHeaders::transferHeaderIfPresent ( folly::StringPiece  name,
HTTPHeaders dest 
)
private

Moves the named header and values from this group to the destination group. No-op if the header doesn't exist. Returns true if header(s) were moved.

Definition at line 224 of file HTTPHeaders.cpp.

References codes_, folly::Range< Iter >::data(), deletedCount_, proxygen::HTTPCommonHeaders::hash(), headerNames_, headerValues_, proxygen::HTTP_HEADER_NONE, proxygen::HTTP_HEADER_OTHER, ITERATE_OVER_CODES, ITERATE_OVER_STRINGS, folly::fbvector< T, Allocator >::push_back(), and folly::Range< Iter >::size().

Referenced by stripPerHopHeaders().

225  {
226  bool transferred = false;
227  const HTTPHeaderCode code = HTTPCommonHeaders::hash(name.data(),
228  name.size());
229  if (code == HTTP_HEADER_OTHER) {
230  ITERATE_OVER_STRINGS(name, {
231  strippedHeaders.codes_.push_back(HTTP_HEADER_OTHER);
232  // in the next line, ownership of pointer goes to strippedHeaders
233  strippedHeaders.headerNames_.push_back(headerNames_[pos]);
234  strippedHeaders.headerValues_.push_back(headerValues_[pos]);
235  codes_[pos] = HTTP_HEADER_NONE;
236  transferred = true;
237  ++deletedCount_;
238  });
239  } else { // code != HTTP_HEADER_OTHER
240  ITERATE_OVER_CODES(code, {
241  strippedHeaders.codes_.push_back(code);
242  strippedHeaders.headerNames_.push_back(headerNames_[pos]);
243  strippedHeaders.headerValues_.push_back(headerValues_[pos]);
244  codes_[pos] = HTTP_HEADER_NONE;
245  transferred = true;
246  ++deletedCount_;
247  });
248  }
249  return transferred;
250 }
constexpr size_type size() const
Definition: Range.h:431
constexpr Iter data() const
Definition: Range.h:446
#define ITERATE_OVER_CODES(Code, Block)
Definition: HTTPHeaders.h:315
#define ITERATE_OVER_STRINGS(String, Block)
Definition: HTTPHeaders.h:329
folly::fbvector< HTTPHeaderCode > codes_
Definition: HTTPHeaders.h:265
folly::fbvector< const std::string * > headerNames_
Definition: HTTPHeaders.h:271
static FB_EXPORT HTTPHeaderCode hash(const char *name, size_t len)
folly::fbvector< std::string > headerValues_
Definition: HTTPHeaders.h:273

Member Data Documentation

const std::string proxygen::HTTPHeaders::COMBINE_SEPARATOR = ", "
static

Definition at line 92 of file HTTPHeaders.h.

size_t proxygen::HTTPHeaders::deletedCount_
private
folly::fbvector<const std::string *> proxygen::HTTPHeaders::headerNames_
private

Vector storing pointers to header names; we own those pointers which correspond to HTTP_HEADER_OTHER codes.

Definition at line 271 of file HTTPHeaders.h.

Referenced by add(), addFromCodec(), copyTo(), disposeOfHeaderNames(), forEach(), forEachWithCode(), HTTPHeaders(), operator=(), remove(), removeAll(), removeByPredicate(), stripPerHopHeaders(), and transferHeaderIfPresent().

const size_t proxygen::HTTPHeaders::kInitialVectorReserve = 16
staticprivate

The initial capacity of the three vectors, reserved right after construction.

Definition at line 281 of file HTTPHeaders.h.

Referenced by HTTPHeaders().


The documentation for this class was generated from the following files: