proxygen
proxygen::HTTP1xCodec Class Reference

#include <HTTP1xCodec.h>

Inheritance diagram for proxygen::HTTP1xCodec:
proxygen::HTTPCodec

Public Member Functions

 HTTP1xCodec (TransportDirection direction, bool forceUpstream1_1=false)
 
 ~HTTP1xCodec () override
 
CodecProtocol getProtocol () const override
 
const std::stringgetUserAgent () const override
 
TransportDirection getTransportDirection () const override
 
StreamID createStream () override
 
void setCallback (Callback *callback) override
 
bool isBusy () const override
 
void setParserPaused (bool paused) override
 
size_t onIngress (const folly::IOBuf &buf) override
 
void onIngressEOF () override
 
bool isReusable () const override
 
bool isWaitingToDrain () const override
 
bool closeOnEgressComplete () const override
 
bool supportsParallelRequests () const override
 
bool supportsPushTransactions () const override
 
void generateHeader (folly::IOBufQueue &writeBuf, StreamID txn, const HTTPMessage &msg, bool eom=false, HTTPHeaderSize *size=nullptr) override
 
size_t generateBody (folly::IOBufQueue &writeBuf, StreamID txn, std::unique_ptr< folly::IOBuf > chain, folly::Optional< uint8_t > padding, bool eom) override
 
size_t generateChunkHeader (folly::IOBufQueue &writeBuf, StreamID txn, size_t length) override
 
size_t generateChunkTerminator (folly::IOBufQueue &writeBuf, StreamID txn) override
 
size_t generateTrailers (folly::IOBufQueue &writeBuf, StreamID txn, const HTTPHeaders &trailers) override
 
size_t generateEOM (folly::IOBufQueue &writeBuf, StreamID txn) override
 
size_t generateRstStream (folly::IOBufQueue &writeBuf, StreamID txn, ErrorCode statusCode) override
 
size_t generateGoaway (folly::IOBufQueue &writeBuf, StreamID lastStream, ErrorCode statusCode, std::unique_ptr< folly::IOBuf > debugData=nullptr) override
 
void setAllowedUpgradeProtocols (std::list< std::string > protocols)
 
const std::stringgetAllowedUpgradeProtocols ()
 
- Public Member Functions inherited from proxygen::HTTPCodec
virtual ~HTTPCodec ()
 
virtual HPACKTableInfo getHPACKTableInfo () const
 
virtual bool supportsStreamFlowControl () const
 
virtual bool supportsSessionFlowControl () const
 
virtual bool onIngressUpgradeMessage (const HTTPMessage &)
 
virtual bool supportsExTransactions () const
 
virtual size_t generateConnectionPreface (folly::IOBufQueue &)
 
virtual void generatePushPromise (folly::IOBufQueue &, StreamID, const HTTPMessage &, StreamID, bool, HTTPHeaderSize *)
 
virtual void generateExHeader (folly::IOBufQueue &, StreamID, const HTTPMessage &, const HTTPCodec::ExAttributes &, bool, HTTPHeaderSize *)
 
virtual size_t generatePingRequest (folly::IOBufQueue &)
 
virtual size_t generatePingReply (folly::IOBufQueue &, uint64_t)
 
virtual size_t generateSettings (folly::IOBufQueue &)
 
virtual size_t generateSettingsAck (folly::IOBufQueue &)
 
virtual size_t generateWindowUpdate (folly::IOBufQueue &, StreamID, uint32_t)
 
virtual size_t generatePriority (folly::IOBufQueue &, StreamID, const HTTPMessage::HTTPPriority &)
 
virtual size_t generateCertificateRequest (folly::IOBufQueue &, uint16_t, std::unique_ptr< folly::IOBuf >)
 
virtual size_t generateCertificate (folly::IOBufQueue &, uint16_t, std::unique_ptr< folly::IOBuf >)
 
virtual HTTPSettingsgetEgressSettings ()
 
virtual const HTTPSettingsgetIngressSettings () const
 
virtual void enableDoubleGoawayDrain ()
 
virtual void setHeaderCodecStats (HeaderCodec::Stats *)
 
virtual StreamID getLastIncomingStreamID () const
 
virtual uint32_t getDefaultWindowSize () const
 
virtual size_t addPriorityNodes (PriorityQueue &, folly::IOBufQueue &, uint8_t)
 
virtual StreamID mapPriorityToDependency (uint8_t) const
 
virtual int8_t mapDependencyToPriority (StreamID) const
 

Static Public Member Functions

static bool supportsNextProtocol (const std::string &npn)
 

Private Types

enum  HeaderParseState : uint8_t {
  HeaderParseState::kParsingHeaderIdle, HeaderParseState::kParsingHeaderStart, HeaderParseState::kParsingHeaderName, HeaderParseState::kParsingHeaderValue,
  HeaderParseState::kParsingHeadersComplete, HeaderParseState::kParsingTrailerName, HeaderParseState::kParsingTrailerValue
}
 
enum  KeepaliveRequested : uint8_t { KeepaliveRequested::UNSET, KeepaliveRequested::ENABLED, KeepaliveRequested::DISABLED }
 

Private Member Functions

std::string generateWebsocketKey () const
 
std::string generateWebsocketAccept (const std::string &acceptKey) const
 
void addDateHeader (folly::IOBufQueue &writeBuf, size_t &len)
 
bool isParsingHeaders () const
 
bool isParsingHeaderOrTrailerName () const
 
void onParserError (const char *what=nullptr)
 
void pushHeaderNameAndValue (HTTPHeaders &hdrs)
 
void serializeWebsocketHeader (folly::IOBufQueue &writeBuf, size_t &len, bool upstream)
 
int onMessageBegin ()
 
int onURL (const char *buf, size_t len)
 
int onReason (const char *buf, size_t len)
 
int onHeaderField (const char *buf, size_t len)
 
int onHeaderValue (const char *buf, size_t len)
 
int onHeadersComplete (size_t len)
 
int onBody (const char *buf, size_t len)
 
int onChunkHeader (size_t len)
 
int onChunkComplete ()
 
int onMessageComplete ()
 

Static Private Member Functions

static int onMessageBeginCB (http_parser *parser)
 
static int onPathCB (http_parser *parser, const char *buf, size_t len)
 
static int onQueryStringCB (http_parser *parser, const char *buf, size_t len)
 
static int onUrlCB (http_parser *parser, const char *buf, size_t len)
 
static int onReasonCB (http_parser *parser, const char *buf, size_t len)
 
static int onHeaderFieldCB (http_parser *parser, const char *buf, size_t len)
 
static int onHeaderValueCB (http_parser *parser, const char *buf, size_t len)
 
static int onHeadersCompleteCB (http_parser *parser, const char *buf, size_t len)
 
static int onBodyCB (http_parser *parser, const char *buf, size_t len)
 
static int onChunkHeaderCB (http_parser *parser)
 
static int onChunkCompleteCB (http_parser *parser)
 
static int onMessageCompleteCB (http_parser *parser)
 
static const http_parser_settingsgetParserSettings ()
 

Private Attributes

std::string websockAcceptKey_
 
HTTPCodec::Callbackcallback_
 
StreamID ingressTxnID_
 
StreamID egressTxnID_
 
http_parser parser_
 
const folly::IOBufcurrentIngressBuf_
 
std::unique_ptr< HTTPMessagemsg_
 
std::unique_ptr< HTTPMessageupgradeRequest_
 
std::unique_ptr< HTTPHeaderstrailers_
 
std::string currentHeaderName_
 
folly::StringPiece currentHeaderNameStringPiece_
 
std::string currentHeaderValue_
 
std::string url_
 
std::string userAgent_
 
std::string reason_
 
std::string upgradeHeader_
 
std::string allowedNativeUpgrades_
 
HTTPHeaderSize headerSize_
 
HeaderParseState headerParseState_
 
TransportDirection transportDirection_
 
KeepaliveRequested keepaliveRequested_
 
std::pair< CodecProtocol, std::stringupgradeResult_
 
bool forceUpstream1_1_:1
 
bool parserActive_:1
 
bool pendingEOF_:1
 
bool parserPaused_:1
 
bool parserError_:1
 
bool requestPending_:1
 
bool responsePending_:1
 
bool egressChunked_:1
 
bool inChunk_:1
 
bool lastChunkWritten_:1
 
bool keepalive_:1
 
bool disableKeepalivePending_:1
 
bool connectRequest_:1
 
bool headRequest_:1
 
bool expectNoResponseBody_:1
 
bool mayChunkEgress_:1
 
bool is1xxResponse_:1
 
bool inRecvLastChunk_:1
 
bool ingressUpgrade_:1
 
bool ingressUpgradeComplete_:1
 
bool egressUpgrade_:1
 
bool nativeUpgrade_:1
 
bool headersComplete_:1
 

Additional Inherited Members

- Public Types inherited from proxygen::HTTPCodec
using StreamID = uint64_t
 
- Static Public Attributes inherited from proxygen::HTTPCodec
static const folly::Optional< StreamIDNoStream
 
static const folly::Optional< uint8_tNoPadding = folly::none
 
static const StreamID MAX_STREAM_ID = 1u << 31
 
static const folly::Optional< ExAttributesNoExAttributes
 

Detailed Description

Definition at line 21 of file HTTP1xCodec.h.

Member Enumeration Documentation

Simple state model used to track the parsing of HTTP headers

Enumerator
kParsingHeaderIdle 
kParsingHeaderStart 
kParsingHeaderName 
kParsingHeaderValue 
kParsingHeadersComplete 
kParsingTrailerName 
kParsingTrailerValue 

Definition at line 91 of file HTTP1xCodec.h.

91  : uint8_t {
92  kParsingHeaderIdle,
93  kParsingHeaderStart,
94  kParsingHeaderName,
95  kParsingHeaderValue,
96  kParsingHeadersComplete,
97  kParsingTrailerName,
98  kParsingTrailerValue
99  };

Used to keep track of whether a client requested keep-alive. This is only useful to support HTTP 1.0 keep-alive for a downstream connection where keep-alive is disabled unless the client requested it.

Enumerator
UNSET 
ENABLED 
DISABLED 

Definition at line 108 of file HTTP1xCodec.h.

108  : uint8_t {
109  UNSET,
110  ENABLED, // incoming message requested keepalive
111  DISABLED, // incoming message disabled keepalive
112  };

Constructor & Destructor Documentation

proxygen::HTTP1xCodec::HTTP1xCodec ( TransportDirection  direction,
bool  forceUpstream1_1 = false 
)
explicit

Definition at line 81 of file HTTP1xCodec.cpp.

References http_parser::data, proxygen::DOWNSTREAM, http_parser_init(), HTTP_REQUEST, HTTP_RESPONSE, parser_, and proxygen::UPSTREAM.

82  : callback_(nullptr),
83  ingressTxnID_(0),
84  egressTxnID_(0),
85  currentIngressBuf_(nullptr),
87  transportDirection_(direction),
89  forceUpstream1_1_(forceUpstream1_1),
90  parserActive_(false),
91  pendingEOF_(false),
92  parserPaused_(false),
93  parserError_(false),
94  requestPending_(false),
95  responsePending_(false),
96  egressChunked_(false),
97  inChunk_(false),
98  lastChunkWritten_(false),
99  keepalive_(true),
101  connectRequest_(false),
102  headRequest_(false),
103  expectNoResponseBody_(false),
104  mayChunkEgress_(false),
105  is1xxResponse_(false),
106  inRecvLastChunk_(false),
107  ingressUpgrade_(false),
109  egressUpgrade_(false),
110  nativeUpgrade_(false),
111  headersComplete_(false) {
112  switch (direction) {
115  break;
118  break;
119  default:
120  LOG(FATAL) << "Unknown transport direction.";
121  }
122  parser_.data = this;
123 }
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
HeaderParseState headerParseState_
Definition: HTTP1xCodec.h:170
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
void http_parser_init(http_parser *parser, enum http_parser_type t)
Definition: http_parser.c:2166
void * data
Definition: http_parser.h:242
KeepaliveRequested keepaliveRequested_
Definition: HTTP1xCodec.h:172
const folly::IOBuf * currentIngressBuf_
Definition: HTTP1xCodec.h:157
proxygen::HTTP1xCodec::~HTTP1xCodec ( )
override

Definition at line 125 of file HTTP1xCodec.cpp.

125  {
126  // This code used to throw a parse error there were unterminated headers
127  // being parsed. None of the cases where this can happen relied on the parse
128  // error.
129 }

Member Function Documentation

void proxygen::HTTP1xCodec::addDateHeader ( folly::IOBufQueue writeBuf,
size_t &  len 
)
private

Definition at line 306 of file HTTP1xCodec.cpp.

References appendLiteral, and proxygen::HTTPMessage::formatDateHeader().

Referenced by generateHeader().

306  {
307  appendLiteral(writeBuf, len, "Date: ");
308  appendString(writeBuf, len, HTTPMessage::formatDateHeader());
309  appendLiteral(writeBuf, len, CRLF);
310 }
#define appendLiteral(queue, len, str)
Definition: HTTP1xCodec.cpp:68
static std::string formatDateHeader()
bool proxygen::HTTP1xCodec::closeOnEgressComplete ( ) const
inlineoverridevirtual

Checks whether the socket needs to be closed when EOM is sent. This is used during CONNECT when EOF needs to be sent after upgrade to notify the server

Implements proxygen::HTTPCodec.

Definition at line 49 of file HTTP1xCodec.h.

References egressUpgrade_.

49 { return egressUpgrade_; }
HTTPCodec::StreamID proxygen::HTTP1xCodec::createStream ( )
overridevirtual

Reserve a stream ID.

Returns
A stream ID on success, or zero on error.

Implements proxygen::HTTPCodec.

Definition at line 132 of file HTTP1xCodec.cpp.

References proxygen::DOWNSTREAM, egressTxnID_, ingressTxnID_, and transportDirection_.

Referenced by getTransportDirection(), TEST(), and TEST_P().

132  {
134  return ++ingressTxnID_;
135  } else {
136  return ++egressTxnID_;
137  }
138 }
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
size_t proxygen::HTTP1xCodec::generateBody ( folly::IOBufQueue writeBuf,
StreamID  stream,
std::unique_ptr< folly::IOBuf chain,
folly::Optional< uint8_t padding,
bool  eom 
)
overridevirtual

Write part of an egress message body.

This will automatically generate a chunk header and footer around the data if necessary (e.g. you haven't manually sent a chunk header and the message should be chunked).

Parameters
paddingOptionally add padding bytes to the body if possible
eomimplicitly generate the EOM marker with this body frame
Returns
number of bytes written

Implements proxygen::HTTPCodec.

Definition at line 657 of file HTTP1xCodec.cpp.

References folly::IOBufQueue::append(), folly::IOBuf::computeChainDataLength(), egressChunked_, egressTxnID_, generateEOM(), inChunk_, and folly::gen::move.

Referenced by supportsPushTransactions(), and TEST().

661  {
662  DCHECK_EQ(txn, egressTxnID_);
663  if (!chain) {
664  return 0;
665  }
666  size_t buflen = chain->computeChainDataLength();
667  size_t totLen = buflen;
668  if (totLen == 0) {
669  if (eom) {
670  totLen += generateEOM(writeBuf, txn);
671  }
672  return totLen;
673  }
674 
675  if (egressChunked_ && !inChunk_) {
676  char chunkLenBuf[32];
677  int rc = snprintf(chunkLenBuf, sizeof(chunkLenBuf), "%zx\r\n", buflen);
678  CHECK_GT(rc, 0);
679  CHECK_LT(size_t(rc), sizeof(chunkLenBuf));
680 
681  writeBuf.append(chunkLenBuf, rc);
682  totLen += rc;
683 
684  writeBuf.append(std::move(chain));
685  writeBuf.append("\r\n", 2);
686  totLen += 2;
687  } else {
688  writeBuf.append(std::move(chain));
689  }
690  if (eom) {
691  totLen += generateEOM(writeBuf, txn);
692  }
693 
694  return totLen;
695 }
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
Definition: IOBufQueue.cpp:143
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
size_t generateEOM(folly::IOBufQueue &writeBuf, StreamID txn) override
size_t proxygen::HTTP1xCodec::generateChunkHeader ( folly::IOBufQueue writeBuf,
StreamID  stream,
size_t  length 
)
overridevirtual

Write a body chunk header, if relevant.

Implements proxygen::HTTPCodec.

Definition at line 697 of file HTTP1xCodec.cpp.

References folly::IOBufQueue::append(), egressChunked_, and inChunk_.

Referenced by supportsPushTransactions().

699  {
700  // TODO: Format directly into the IOBuf, rather than copying after the fact.
701  // IOBufQueue::append() currently forces us to copy.
702 
703  CHECK(length) << "use sendEOM to terminate the message using the "
704  << "standard zero-length chunk. Don't "
705  << "send zero-length chunks using this API.";
706  if (egressChunked_) {
707  CHECK(!inChunk_);
708  inChunk_ = true;
709  char chunkLenBuf[32];
710  int rc = snprintf(chunkLenBuf, sizeof(chunkLenBuf), "%zx\r\n", length);
711  CHECK_GT(rc, 0);
712  CHECK_LT(size_t(rc), sizeof(chunkLenBuf));
713 
714  writeBuf.append(chunkLenBuf, rc);
715  return rc;
716  }
717 
718  return 0;
719 }
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
Definition: IOBufQueue.cpp:143
size_t proxygen::HTTP1xCodec::generateChunkTerminator ( folly::IOBufQueue writeBuf,
StreamID  stream 
)
overridevirtual

Write a body chunk terminator, if relevant.

Implements proxygen::HTTPCodec.

Definition at line 721 of file HTTP1xCodec.cpp.

References folly::IOBufQueue::append(), egressChunked_, and inChunk_.

Referenced by supportsPushTransactions().

722  {
723  if (egressChunked_ && inChunk_) {
724  inChunk_ = false;
725  writeBuf.append("\r\n", 2);
726  return 2;
727  }
728 
729  return 0;
730 }
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
Definition: IOBufQueue.cpp:143
size_t proxygen::HTTP1xCodec::generateEOM ( folly::IOBufQueue writeBuf,
StreamID  stream 
)
overridevirtual

Generate any protocol framing needed to finalize an egress message. This method must be called to complete a stream.

Returns
number of bytes written

Implements proxygen::HTTPCodec.

Definition at line 752 of file HTTP1xCodec.cpp.

References appendLiteral, proxygen::DOWNSTREAM, egressChunked_, egressTxnID_, headRequest_, inChunk_, lastChunkWritten_, requestPending_, responsePending_, transportDirection_, and proxygen::UPSTREAM.

Referenced by generateBody(), generateHeader(), supportsPushTransactions(), and TEST().

752  {
753  DCHECK_EQ(txn, egressTxnID_);
754  size_t len = 0;
755  if (egressChunked_) {
756  CHECK(!inChunk_);
758  lastChunkWritten_ = true;
759  } else {
760  // appending a 0\r\n only if it's not a HEAD and downstream request
761  if (!lastChunkWritten_) {
762  lastChunkWritten_ = true;
763  if (!(headRequest_ &&
765  appendLiteral(writeBuf, len, "0\r\n");
766  }
767  }
768  appendLiteral(writeBuf, len, CRLF);
769  }
770  }
771  switch (transportDirection_) {
773  responsePending_ = false;
774  break;
776  requestPending_ = false;
777  break;
778  }
779  return len;
780 }
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
#define appendLiteral(queue, len, str)
Definition: HTTP1xCodec.cpp:68
size_t proxygen::HTTP1xCodec::generateGoaway ( folly::IOBufQueue writeBuf,
StreamID  lastStream,
ErrorCode  code,
std::unique_ptr< folly::IOBuf debugData = nullptr 
)
overridevirtual

Generate any protocol framing needed to abort a connection.

Returns
number of bytes written

Implements proxygen::HTTPCodec.

Definition at line 791 of file HTTP1xCodec.cpp.

References disableKeepalivePending_.

Referenced by supportsPushTransactions().

795  {
796  // statusCode ignored for HTTP/1.1
797  // We won't be able to send anything else on the transport after this.
799  return 0;
800 }
void proxygen::HTTP1xCodec::generateHeader ( folly::IOBufQueue writeBuf,
StreamID  stream,
const HTTPMessage msg,
bool  eom = false,
HTTPHeaderSize size = nullptr 
)
overridevirtual

Write an egress message header. For pushed streams, you must specify the assocStream.

Return values
sizethe size of the generated message, both the actual size and the size of the uncompressed data.
Returns
None

Implements proxygen::HTTPCodec.

Definition at line 364 of file HTTP1xCodec.cpp.

References addDateHeader(), appendLiteral, proxygen::caseInsensitiveEqual(), wangle::HTTPHeaderSize::compressed, proxygen::CONNECT, connectRequest_, disableKeepalivePending_, proxygen::DOWNSTREAM, egressChunked_, egressTxnID_, egressUpgrade_, ENABLED, proxygen::ERROR, expectNoResponseBody_, forceUpstream1_1_, proxygen::HTTPHeaders::forEachWithCode(), generateEOM(), proxygen::GET, proxygen::HTTPMessage::getDefaultReason(), proxygen::HTTPMessage::getHeaders(), proxygen::HTTPMessage::getHTTPVersion(), proxygen::HTTPMessage::getIsChunked(), proxygen::HTTPMessage::getMethod(), proxygen::HTTPMessage::getMethodString(), proxygen::HTTPMessage::getStatusCode(), proxygen::HTTPMessage::getStatusMessage(), proxygen::HTTPMessage::getURL(), proxygen::HEAD, headRequest_, proxygen::HTTP_HEADER_CONNECTION, proxygen::HTTP_HEADER_CONTENT_LENGTH, proxygen::HTTP_HEADER_DATE, proxygen::HTTP_HEADER_SEC_WEBSOCKET_ACCEPT, proxygen::HTTP_HEADER_SEC_WEBSOCKET_KEY, proxygen::HTTP_HEADER_TRANSFER_ENCODING, proxygen::HTTP_HEADER_UPGRADE, http_parser::http_major, http_parser::http_minor, ingressTxnID_, ingressUpgrade_, proxygen::HTTPMessage::is1xxResponse(), is1xxResponse_, proxygen::HTTPMessage::isEgressWebsocketUpgrade(), folly::join(), keepalive_, keepaliveRequested_, proxygen::HTTPMessage::kHTTPVersion10, proxygen::HTTPMessage::kHTTPVersion11, lastChunkWritten_, max, mayChunkEgress_, proxygen::methodToString(), parser_, proxygen::POST, folly::IOBufQueue::postallocate(), folly::IOBufQueue::preallocate(), requestPending_, proxygen::RFC2616::responseBodyMustBeEmpty(), responsePending_, serializeWebsocketHeader(), folly::split(), statusCode, transportDirection_, folly::trimWhitespace(), wangle::HTTPHeaderSize::uncompressed, upgradeHeader_, proxygen::UPSTREAM, value, version, and proxygen::HTTPMessage::wantsKeepalive().

Referenced by supportsPushTransactions(), TEST(), and TEST_P().

368  {
370  keepalive_ = false;
371  }
372  const bool upstream = (transportDirection_ == TransportDirection::UPSTREAM);
373  const bool downstream = !upstream;
374  if (upstream) {
375  DCHECK_EQ(txn, egressTxnID_);
376  requestPending_ = true;
377  responsePending_ = true;
378  connectRequest_ = (msg.getMethod() == HTTPMethod::CONNECT);
379  headRequest_ = (msg.getMethod() == HTTPMethod::HEAD);
381  } else {
382  // In HTTP, transactions must be egressed sequentially -- no out of order
383  // responses. So txn must be egressTxnID_ + 1. Furthermore, we shouldn't
384  // ever egress a response before we see a request, so txn can't
385  // be > ingressTxnID_
386  if ((txn != egressTxnID_ + 1 &&
387  !(txn == egressTxnID_ && is1xxResponse_)) ||
388  (txn > ingressTxnID_)) {
389  LOG(DFATAL) << "Out of order, duplicate or premature HTTP response";
390  }
391  if (!is1xxResponse_) {
392  ++egressTxnID_;
393  }
394  is1xxResponse_ = msg.is1xxResponse() || msg.isEgressWebsocketUpgrade();
395 
398  RFC2616::responseBodyMustBeEmpty(msg.getStatusCode());
399  }
400 
401  int statusCode = 0;
402  StringPiece statusMessage;
403  if (downstream) {
404  statusCode = msg.getStatusCode();
405  statusMessage = msg.getStatusMessage();
406  // If a response to a websocket upgrade is being sent out, it must be 101.
407  // This is required since the application may not have changed the status,
408  // particularly when proxying between a H2 hop and a H1 hop.
409  if (msg.isEgressWebsocketUpgrade()) {
410  statusCode = 101;
411  statusMessage = HTTPMessage::getDefaultReason(101);
412  }
413  if (connectRequest_ && (statusCode >= 200 && statusCode < 300)) {
414  // Set egress upgrade flag if we are sending a 200 response
415  // to a CONNECT request we received earlier.
416  egressUpgrade_ = true;
417  } else if (statusCode == 101) {
418  // Set the upgrade flags if we upgraded after the request from client.
419  ingressUpgrade_ = true;
420  egressUpgrade_ = true;
421  }
422  else if (connectRequest_ && ingressUpgrade_) {
423  // Disable upgrade when rejecting CONNECT request
424  ingressUpgrade_ = false;
425 
426  // This codec/session is no longer useful as we might have
427  // forwarded some data before receiving the 200.
428  keepalive_ = false;
429  }
430  } else {
431  if (connectRequest_ || msg.isEgressWebsocketUpgrade()) {
432  // Sending a CONNECT request or a websocket upgrade request to an upstream
433  // server. This is used to determine the chunked setting below.
434  egressUpgrade_ = true;
435  }
436  }
437 
438  egressChunked_ = msg.getIsChunked() && !egressUpgrade_;
439  lastChunkWritten_ = false;
440  std::pair<uint8_t, uint8_t> version = msg.getHTTPVersion();
441  if (version > HTTPMessage::kHTTPVersion11) {
442  version = HTTPMessage::kHTTPVersion11;
443  }
444 
445  size_t len = 0;
446  switch (transportDirection_) {
448  DCHECK_NE(statusCode, 0);
449  if (version.first == 0 && version.second == 9) {
450  return;
451  }
452  appendLiteral(writeBuf, len, "HTTP/");
453  appendUint(writeBuf, len, version.first);
454  appendLiteral(writeBuf, len, ".");
455  appendUint(writeBuf, len, version.second);
456  appendLiteral(writeBuf, len, " ");
457  appendUint(writeBuf, len, statusCode);
458  appendLiteral(writeBuf, len, " ");
459  appendString(writeBuf, len, statusMessage);
460  break;
463  version = HTTPMessage::kHTTPVersion11;
464  }
465  if (msg.isEgressWebsocketUpgrade()) {
466  appendString(writeBuf, len, methodToString(HTTPMethod::GET));
467  } else {
468  appendString(writeBuf, len, msg.getMethodString());
469  }
470  appendLiteral(writeBuf, len, " ");
471  appendString(writeBuf, len, msg.getURL());
472  appendLiteral(writeBuf, len, " HTTP/");
473  appendUint(writeBuf, len, version.first);
474  appendLiteral(writeBuf, len, ".");
475  appendUint(writeBuf, len, version.second);
476  mayChunkEgress_ = (version.first == 1) && (version.second >= 1);
477  if (!upgradeHeader_.empty()) {
478  LOG(DFATAL) << "Attempted to pipeline HTTP request with pending upgrade";
479  upgradeHeader_.clear();
480  }
481  break;
482  }
483 
484  if (keepalive_ &&
485  (!msg.wantsKeepalive() ||
486  version.first < 1 ||
487  (downstream && version == HTTPMessage::kHTTPVersion10 &&
489  // Disable keepalive if
490  // - the message asked to turn it off
491  // - it's HTTP/0.9
492  // - this is a response to a 1.0 request that didn't say keep-alive
493  keepalive_ = false;
494  }
496  appendLiteral(writeBuf, len, CRLF);
497  if (version.first == 0 && version.second == 9) {
498  parser_.http_major = 0;
499  parser_.http_minor = 9;
500  return;
501  }
502  const string* deferredContentLength = nullptr;
503  bool hasTransferEncodingChunked = false;
504  bool hasDateHeader = false;
505  bool hasUpgradeHeader = false;
506  std::vector<StringPiece> connectionTokens;
507  size_t lastConnectionToken = 0;
508  bool egressWebsocketUpgrade = msg.isEgressWebsocketUpgrade();
509  bool hasUpgradeTokeninConnection = false;
510  msg.getHeaders().forEachWithCode([&] (HTTPHeaderCode code,
511  const string& header,
512  const string& value) {
513  if (code == HTTP_HEADER_CONTENT_LENGTH) {
514  // Write the Content-Length last (t1071703)
515  deferredContentLength = &value;
516  return; // continue
517  } else if (code == HTTP_HEADER_CONNECTION && (!is1xxResponse_ ||
518  egressWebsocketUpgrade)) {
519  static const string kClose = "close";
520  static const string kKeepAlive = "keep-alive";
521  folly::split(',', value, connectionTokens);
522  for (auto curConnectionToken = lastConnectionToken;
523  curConnectionToken < connectionTokens.size();
524  curConnectionToken++) {
525  auto token = trimWhitespace(connectionTokens[curConnectionToken]);
526  if (caseInsensitiveEqual(token, "upgrade")) {
527  hasUpgradeTokeninConnection = true;
528  }
529  if (caseInsensitiveEqual(token, kClose)) {
530  keepalive_ = false;
531  } else if (!caseInsensitiveEqual(token, kKeepAlive)) {
532  connectionTokens[lastConnectionToken++] = token;
533  } // else eat the keep-alive token
534  }
535  connectionTokens.resize(lastConnectionToken);
536  // We'll generate a new Connection header based on the keepalive_ state
537  return;
538  } else if (code == HTTP_HEADER_UPGRADE && txn == 1) {
539  hasUpgradeHeader = true;
540  if (upstream) {
541  // save in case we get a 101 Switching Protocols
543  }
544  } else if (!hasTransferEncodingChunked &&
546  if (!caseInsensitiveEqual(value, kChunked)) {
547  return;
548  }
549  hasTransferEncodingChunked = true;
550  if (!mayChunkEgress_) {
551  return;
552  }
553  } else if (!hasDateHeader && code == HTTP_HEADER_DATE) {
554  hasDateHeader = true;
555  } else if (egressWebsocketUpgrade &&
557  // will generate our own key per hop, not client's.
558  return;
559  } else if (egressWebsocketUpgrade &&
561  // will generate our own accept per hop, not client's.
562  return;
563  }
564  size_t lineLen = header.length() + value.length() + 4; // 4 for ": " + CRLF
565  auto writable = writeBuf.preallocate(lineLen,
566  std::max(lineLen, size_t(2000)));
567  char* dst = (char*)writable.first;
568  memcpy(dst, header.data(), header.length());
569  dst += header.length();
570  *dst++ = ':';
571  *dst++ = ' ';
572  memcpy(dst, value.data(), value.length());
573  dst += value.length();
574  *dst++ = '\r';
575  *dst = '\n';
576  DCHECK_EQ(size_t(++dst - (char*)writable.first), lineLen);
577  writeBuf.postallocate(lineLen);
578  len += lineLen;
579  });
580  bool bodyCheck =
581  (downstream && keepalive_ && !expectNoResponseBody_ && !egressUpgrade_) ||
582  // auto chunk POSTs and any request that came to us chunked
583  (upstream && ((msg.getMethod() == HTTPMethod::POST) || egressChunked_));
584  // TODO: 400 a 1.0 POST with no content-length
585  // clear egressChunked_ if the header wasn't actually set
586  egressChunked_ &= hasTransferEncodingChunked;
587  if (bodyCheck && !egressChunked_ && !deferredContentLength) {
588  // On a connection that would otherwise be eligible for keep-alive,
589  // we're being asked to send a response message with no Content-Length,
590  // no chunked encoding, and no special circumstances that would eliminate
591  // the need for a response body. If the client supports chunking, turn
592  // on chunked encoding now. Otherwise, turn off keepalives on this
593  // connection.
594  if (!hasTransferEncodingChunked && mayChunkEgress_) {
595  appendLiteral(writeBuf, len, "Transfer-Encoding: chunked\r\n");
596  egressChunked_ = true;
597  } else {
598  keepalive_ = false;
599  }
600  }
601  if (downstream && !hasDateHeader) {
602  addDateHeader(writeBuf, len);
603  }
604 
605  // websocket headers
606  if (msg.isEgressWebsocketUpgrade()) {
607  if (!hasUpgradeHeader && txn == 1) {
608  // upgradeHeader_ is set in serializeWwebsocketHeader for requests.
609  serializeWebsocketHeader(writeBuf, len, upstream);
610  if (!hasUpgradeTokeninConnection) {
611  connectionTokens.push_back(kUpgradeConnectionToken);
612  lastConnectionToken++;
613  }
614  } else {
615  LOG(ERROR) << folly::to<string>("Not serializing headers. "
616  "Upgrade headers present/txn: ",
617  hasUpgradeHeader, txn);
618  }
619  }
620 
621  if (!is1xxResponse_ || upstream || !connectionTokens.empty()) {
622  // We don't seem to add keep-alive/close and let the application add any
623  // for 1xx responses.
624  appendLiteral(writeBuf, len, "Connection: ");
625  if (connectionTokens.size() > 0) {
626  appendString(writeBuf, len, folly::join(", ", connectionTokens));
627  }
628  if (!is1xxResponse_) {
629  if (connectionTokens.size() > 0) {
630  appendString(writeBuf, len, ", ");
631  }
632  if (keepalive_) {
633  appendLiteral(writeBuf, len, "keep-alive");
634  } else {
635  appendLiteral(writeBuf, len, "close");
636  }
637  }
638  appendLiteral(writeBuf, len, "\r\n");
639  }
640 
641  if (deferredContentLength) {
642  appendLiteral(writeBuf, len, "Content-Length: ");
643  appendString(writeBuf, len, *deferredContentLength);
644  appendLiteral(writeBuf, len, CRLF);
645  }
646  appendLiteral(writeBuf, len, CRLF);
647  if (eom) {
648  len += generateEOM(writeBuf, txn);
649  }
650 
651  if (size) {
652  size->compressed = 0;
653  size->uncompressed = len;
654  }
655 }
bool responseBodyMustBeEmpty(unsigned status)
Definition: RFC2616.cpp:54
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
spdy::GoawayStatusCode statusCode
Definition: SPDYCodec.cpp:110
void serializeWebsocketHeader(folly::IOBufQueue &writeBuf, size_t &len, bool upstream)
bool caseInsensitiveEqual(folly::StringPiece s, folly::StringPiece t)
Definition: UtilInl.h:17
static const std::pair< uint8_t, uint8_t > kHTTPVersion10
Definition: HTTPMessage.h:229
unsigned short http_minor
Definition: http_parser.h:225
LogLevel max
Definition: LogLevel.cpp:31
#define appendLiteral(queue, len, str)
Definition: HTTP1xCodec.cpp:68
std::string upgradeHeader_
Definition: HTTP1xCodec.h:167
void split(const Delim &delimiter, const String &input, std::vector< OutputType > &out, bool ignoreEmpty)
Definition: String-inl.h:382
std::pair< void *, std::size_t > preallocate(std::size_t min, std::size_t newAllocationSize, std::size_t max=std::numeric_limits< std::size_t >::max())
Definition: IOBufQueue.h:356
ProtocolVersion version
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
const std::string & methodToString(HTTPMethod method)
Definition: HTTPMethod.cpp:46
static const std::pair< uint8_t, uint8_t > kHTTPVersion11
Definition: HTTPMessage.h:230
unsigned short http_major
Definition: http_parser.h:224
void addDateHeader(folly::IOBufQueue &writeBuf, size_t &len)
static const char *const value
Definition: Conv.cpp:50
StringPiece trimWhitespace(StringPiece sp)
Definition: String.h:568
void join(const Delim &delimiter, Iterator begin, Iterator end, String &output)
Definition: String-inl.h:498
constexpr folly::StringPiece kUpgradeConnectionToken
KeepaliveRequested keepaliveRequested_
Definition: HTTP1xCodec.h:172
static const char * getDefaultReason(uint16_t status)
Range< const char * > StringPiece
size_t generateEOM(folly::IOBufQueue &writeBuf, StreamID txn) override
void postallocate(std::size_t n)
Definition: IOBufQueue.h:380
size_t proxygen::HTTP1xCodec::generateRstStream ( folly::IOBufQueue writeBuf,
StreamID  stream,
ErrorCode  code 
)
overridevirtual

Generate any protocol framing needed to abort a stream.

Returns
number of bytes written

Implements proxygen::HTTPCodec.

Definition at line 782 of file HTTP1xCodec.cpp.

References disableKeepalivePending_.

Referenced by supportsPushTransactions().

784  {
785  // statusCode ignored for HTTP/1.1
786  // We won't be able to send anything else on the transport after this.
788  return 0;
789 }
size_t proxygen::HTTP1xCodec::generateTrailers ( folly::IOBufQueue writeBuf,
StreamID  stream,
const HTTPHeaders trailers 
)
overridevirtual

Write the message trailers

Returns
number of bytes written

Implements proxygen::HTTPCodec.

Definition at line 733 of file HTTP1xCodec.cpp.

References appendLiteral, egressChunked_, egressTxnID_, proxygen::HTTPHeaders::forEach(), inChunk_, and lastChunkWritten_.

Referenced by supportsPushTransactions(), and TEST().

735  {
736  DCHECK_EQ(txn, egressTxnID_);
737  size_t len = 0;
738  if (egressChunked_) {
739  CHECK(!inChunk_);
740  appendLiteral(writeBuf, len, "0\r\n");
741  lastChunkWritten_ = true;
742  trailers.forEach([&] (const string& trailer, const string& value) {
743  appendString(writeBuf, len, trailer);
744  appendLiteral(writeBuf, len, ": ");
745  appendString(writeBuf, len, value);
746  appendLiteral(writeBuf, len, CRLF);
747  });
748  }
749  return len;
750 }
#define appendLiteral(queue, len, str)
Definition: HTTP1xCodec.cpp:68
static const char *const value
Definition: Conv.cpp:50
std::string proxygen::HTTP1xCodec::generateWebsocketAccept ( const std::string acceptKey) const
private

Definition at line 326 of file HTTP1xCodec.cpp.

References folly::netops::accept(), proxygen::Base64::encode(), folly::ssl::OpenSSLHash::Digest::hash_final(), folly::ssl::OpenSSLHash::Digest::hash_init(), folly::ssl::OpenSSLHash::Digest::hash_update(), and proxygen::kWSMagicString.

Referenced by onHeadersComplete(), and serializeWebsocketHeader().

326  {
328  digest.hash_init(EVP_sha1());
329  digest.hash_update(folly::StringPiece(key));
330  digest.hash_update(kWSMagicString);
331  std::array<unsigned char, 20> arr;
332  folly::MutableByteRange accept(arr.data(), arr.size());
333  digest.hash_final(accept);
334  return Base64::encode(accept);
335 }
void hash_init(const EVP_MD *md)
Definition: OpenSSLHash.h:49
void hash_final(MutableByteRange out)
Definition: OpenSSLHash.h:62
void hash_update(ByteRange data)
Definition: OpenSSLHash.h:53
constexpr folly::StringPiece kWSMagicString
static std::string encode(folly::ByteRange buffer)
Definition: Base64.cpp:80
NetworkSocket accept(NetworkSocket s, sockaddr *addr, socklen_t *addrlen)
Definition: NetOps.cpp:71
std::string proxygen::HTTP1xCodec::generateWebsocketKey ( ) const
private

Definition at line 319 of file HTTP1xCodec.cpp.

References proxygen::Base64::encode(), folly::Random::secureRandom(), and string.

Referenced by serializeWebsocketHeader().

319  {
320  std::array<unsigned char, 16> arr;
321  folly::Random::secureRandom(arr.data(), arr.size());
322  return Base64::encode(folly::ByteRange(arr.data(), arr.size()));
323 }
static std::enable_if< std::is_integral< T >::value &&!std::is_same< T, bool >::value, T >::type secureRandom()
Definition: Random.h:112
static std::string encode(folly::ByteRange buffer)
Definition: Base64.cpp:80
const std::string & proxygen::HTTP1xCodec::getAllowedUpgradeProtocols ( )

Definition at line 812 of file HTTP1xCodec.cpp.

References allowedNativeUpgrades_.

Referenced by supportsPushTransactions(), and TEST().

812  {
813  return allowedNativeUpgrades_;
814 }
std::string allowedNativeUpgrades_
Definition: HTTP1xCodec.h:168
const http_parser_settings * proxygen::HTTP1xCodec::getParserSettings ( )
staticprivate

Definition at line 158 of file HTTP1xCodec.cpp.

References http_parser_settings::on_body, http_parser_settings::on_chunk_complete, http_parser_settings::on_chunk_header, http_parser_settings::on_header_field, http_parser_settings::on_header_value, http_parser_settings::on_headers_complete, http_parser_settings::on_message_begin, http_parser_settings::on_message_complete, http_parser_settings::on_reason, http_parser_settings::on_url, onBodyCB(), onChunkCompleteCB(), onChunkHeaderCB(), onHeaderFieldCB(), onHeadersCompleteCB(), onHeaderValueCB(), onMessageBeginCB(), onMessageCompleteCB(), onReasonCB(), and onUrlCB().

Referenced by onIngress(), and onIngressEOF().

158  {
159  static http_parser_settings parserSettings = [] {
171  return st;
172  }();
173  return &parserSettings;
174 }
http_data_cb on_header_field
Definition: http_parser.h:249
static int onChunkHeaderCB(http_parser *parser)
http_data_cb on_body
Definition: http_parser.h:252
static int onMessageCompleteCB(http_parser *parser)
static int onHeaderValueCB(http_parser *parser, const char *buf, size_t len)
static int onMessageBeginCB(http_parser *parser)
http_data_cb on_url
Definition: http_parser.h:248
static int onHeadersCompleteCB(http_parser *parser, const char *buf, size_t len)
static int onChunkCompleteCB(http_parser *parser)
static int onUrlCB(http_parser *parser, const char *buf, size_t len)
http_data_cb on_headers_complete
Definition: http_parser.h:251
static int onReasonCB(http_parser *parser, const char *buf, size_t len)
http_data_cb on_reason
Definition: http_parser.h:254
static int onBodyCB(http_parser *parser, const char *buf, size_t len)
http_data_cb on_header_value
Definition: http_parser.h:250
static int onHeaderFieldCB(http_parser *parser, const char *buf, size_t len)
http_cb on_message_complete
Definition: http_parser.h:253
CodecProtocol proxygen::HTTP1xCodec::getProtocol ( ) const
inlineoverridevirtual

Gets the session protocol currently used by the codec. This can be mapped to a string for logging and diagnostic use.

Implements proxygen::HTTPCodec.

Definition at line 28 of file HTTP1xCodec.h.

References proxygen::HTTP_1_1.

Referenced by TEST().

TransportDirection proxygen::HTTP1xCodec::getTransportDirection ( ) const
inlineoverridevirtual

Get the transport direction of this codec: DOWNSTREAM if the codec receives requests from clients or UPSTREAM if the codec sends requests to servers.

Implements proxygen::HTTPCodec.

Definition at line 36 of file HTTP1xCodec.h.

References createStream(), and transportDirection_.

36  {
37  return transportDirection_;
38  }
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
const std::string& proxygen::HTTP1xCodec::getUserAgent ( ) const
inlineoverridevirtual

Gets the user agent string of the client. Thus, it is only meaningful for a DOWNSTREAM session. Note that the value is available after onHeadersComplete(). It can help in diagnosing the interactions between different codec implementation.

Implements proxygen::HTTPCodec.

Definition at line 32 of file HTTP1xCodec.h.

References userAgent_.

32  {
33  return userAgent_;
34  }
std::string userAgent_
Definition: HTTP1xCodec.h:165
bool proxygen::HTTP1xCodec::isBusy ( ) const
overridevirtual

Check whether the codec still has at least one HTTP stream to parse.

Implements proxygen::HTTPCodec.

Definition at line 301 of file HTTP1xCodec.cpp.

References requestPending_, and responsePending_.

Referenced by setCallback().

301  {
303 }
bool proxygen::HTTP1xCodec::isParsingHeaders ( ) const
inlineprivate
bool proxygen::HTTP1xCodec::isReusable ( ) const
overridevirtual

Check whether the codec can process new streams. Typically, an implementing subclass will return true when a new codec is created and false once it encounters a situation that would prevent reuse of the underlying transport (e.g., a "Connection: close" in HTTP/1.x).

Note
A return value of true means that the codec can process new connections at some reasonable point in the future; that may mean "immediately," for codecs that support pipelined or interleaved requests, or "upon completion of the current stream" for codecs that do not.

Implements proxygen::HTTPCodec.

Definition at line 295 of file HTTP1xCodec.cpp.

References egressUpgrade_, ingressUpgrade_, keepalive_, parserError_, and websockAcceptKey_.

Referenced by setCallback().

295  {
297  websockAcceptKey_.empty();
298 }
std::string websockAcceptKey_
Definition: HTTP1xCodec.h:103
bool proxygen::HTTP1xCodec::isWaitingToDrain ( ) const
inlineoverridevirtual

Returns true if this codec is in a state where it accepting new requests but will soon begin to reject new requests. For SPDY and HTTP/2, this is true when the first GOAWAY NO_ERROR is sent during graceful shutdown.

Implements proxygen::HTTPCodec.

Definition at line 46 of file HTTP1xCodec.h.

46 { return false; }
int proxygen::HTTP1xCodec::onBody ( const char *  buf,
size_t  len 
)
private

Definition at line 1144 of file HTTP1xCodec.cpp.

References callback_, folly::IOBuf::cloneOne(), currentIngressBuf_, folly::IOBuf::data(), ingressTxnID_, inRecvLastChunk_, isParsingHeaders(), folly::IOBuf::length(), folly::gen::move, and proxygen::HTTPCodec::Callback::onBody().

Referenced by isParsingHeaderOrTrailerName(), and onBodyCB().

1144  {
1145  DCHECK(!isParsingHeaders());
1146  DCHECK(!inRecvLastChunk_);
1147  CHECK_NOTNULL(currentIngressBuf_);
1148  const char* dataStart = (const char*)currentIngressBuf_->data();
1149  const char* dataEnd = dataStart + currentIngressBuf_->length();
1150  DCHECK_GE(buf, dataStart);
1151  DCHECK_LE(buf + len, dataEnd);
1152  unique_ptr<IOBuf> clone(currentIngressBuf_->cloneOne());
1153  clone->trimStart(buf - dataStart);
1154  clone->trimEnd(dataEnd - (buf + len));
1155  DCHECK_EQ(len, clone->computeChainDataLength());
1156  callback_->onBody(ingressTxnID_, std::move(clone), 0);
1157  return 0;
1158 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const uint8_t * data() const
Definition: IOBuf.h:499
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
std::size_t length() const
Definition: IOBuf.h:533
std::unique_ptr< IOBuf > cloneOne() const
Definition: IOBuf.cpp:531
bool isParsingHeaders() const
Definition: HTTP1xCodec.h:117
virtual void onBody(StreamID stream, std::unique_ptr< folly::IOBuf > chain, uint16_t padding)=0
const folly::IOBuf * currentIngressBuf_
Definition: HTTP1xCodec.h:157
int proxygen::HTTP1xCodec::onBodyCB ( http_parser parser,
const char *  buf,
size_t  len 
)
staticprivate

Definition at line 1321 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onBody(), onParserError(), and parser_.

Referenced by getParserSettings().

1321  {
1322  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1323  DCHECK(codec != nullptr);
1324  DCHECK_EQ(&codec->parser_, parser);
1325 
1326  try {
1327  return codec->onBody(buf, len);
1328  } catch (const std::exception& ex) {
1329  // Note: http_parser appears to completely ignore the return value from the
1330  // on_body() callback. There seems to be no way to abort parsing after an
1331  // error in on_body().
1332  //
1333  // We handle this by checking if error_ is set after each call to
1334  // http_parser_execute().
1335  codec->onParserError(ex.what());
1336  return 1;
1337  }
1338 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
int proxygen::HTTP1xCodec::onChunkComplete ( )
private

Definition at line 1171 of file HTTP1xCodec.cpp.

References callback_, ingressTxnID_, inRecvLastChunk_, and proxygen::HTTPCodec::Callback::onChunkComplete().

Referenced by isParsingHeaderOrTrailerName(), and onChunkCompleteCB().

1171  {
1172  if (inRecvLastChunk_) {
1173  inRecvLastChunk_ = false;
1174  } else {
1176  }
1177  return 0;
1178 }
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
virtual void onChunkComplete(StreamID)
Definition: HTTPCodec.h:156
int proxygen::HTTP1xCodec::onChunkCompleteCB ( http_parser parser)
staticprivate

Definition at line 1353 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onChunkComplete(), onParserError(), and parser_.

Referenced by getParserSettings().

1353  {
1354  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1355  DCHECK(codec != nullptr);
1356  DCHECK_EQ(&codec->parser_, parser);
1357 
1358  try {
1359  return codec->onChunkComplete();
1360  } catch (const std::exception& ex) {
1361  codec->onParserError(ex.what());
1362  return 1;
1363  }
1364 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
int proxygen::HTTP1xCodec::onChunkHeader ( size_t  len)
private

Definition at line 1160 of file HTTP1xCodec.cpp.

References callback_, ingressTxnID_, inRecvLastChunk_, and proxygen::HTTPCodec::Callback::onChunkHeader().

Referenced by isParsingHeaderOrTrailerName(), and onChunkHeaderCB().

1160  {
1161  if (len > 0) {
1163  } else {
1164  VLOG(5) << "Suppressed onChunkHeader callback for final zero length "
1165  << "chunk";
1166  inRecvLastChunk_ = true;
1167  }
1168  return 0;
1169 }
virtual void onChunkHeader(StreamID, size_t)
Definition: HTTPCodec.h:148
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
int proxygen::HTTP1xCodec::onChunkHeaderCB ( http_parser parser)
staticprivate

Definition at line 1340 of file HTTP1xCodec.cpp.

References codec, http_parser::content_length, http_parser::data, onChunkHeader(), onParserError(), and parser_.

Referenced by getParserSettings().

1340  {
1341  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1342  DCHECK(codec != nullptr);
1343  DCHECK_EQ(&codec->parser_, parser);
1344 
1345  try {
1346  return codec->onChunkHeader(parser->content_length);
1347  } catch (const std::exception& ex) {
1348  codec->onParserError(ex.what());
1349  return 1;
1350  }
1351 }
CodecFactory codec
void * data
Definition: http_parser.h:242
int64_t content_length
Definition: http_parser.h:221
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
int proxygen::HTTP1xCodec::onHeaderField ( const char *  buf,
size_t  len 
)
private

Definition at line 866 of file HTTP1xCodec.cpp.

References folly::Range< Iter >::advance(), folly::Range< Iter >::begin(), currentHeaderName_, currentHeaderNameStringPiece_, folly::Range< Iter >::end(), headerParseState_, isParsingHeaderOrTrailerName(), kParsingHeaderName, kParsingHeadersComplete, kParsingHeaderValue, kParsingTrailerName, kParsingTrailerValue, msg_, pushHeaderNameAndValue(), folly::Range< Iter >::reset(), folly::Range< Iter >::size(), and trailers_.

Referenced by isParsingHeaderOrTrailerName(), and onHeaderFieldCB().

866  {
868  pushHeaderNameAndValue(msg_->getHeaders());
870  if (!trailers_) {
871  trailers_.reset(new HTTPHeaders());
872  }
874  }
875 
877 
878  // we're already parsing a header name
879  if (currentHeaderName_.empty()) {
880  // but we've been keeping it in currentHeaderNameStringPiece_ until now
881  if (currentHeaderNameStringPiece_.end() == buf) {
882  // the header name we are currently reading is contiguous in memory,
883  // and so we just adjust the right end of our StringPiece;
884  // this is likely because onIngress() hasn't been called since we got
885  // the previous chunk (otherwise currentHeaderName_ would be nonempty)
887  } else {
888  // this is just for safety - if for any reason there is a discontinuity
889  // even though we are during the same onIngress() call,
890  // we fall back to currentHeaderName_
893  currentHeaderName_.append(buf, len);
894  }
895  } else {
896  // we had already fallen back to currentHeaderName_ before
897  currentHeaderName_.append(buf, len);
898  }
899 
900  } else {
901  // we're not yet parsing a header name - this is the first chunk
902  // (typically, there is only one)
904 
907  } else {
909  }
910  }
911  return 0;
912 }
std::unique_ptr< HTTPMessage > msg_
Definition: HTTP1xCodec.h:158
HeaderParseState headerParseState_
Definition: HTTP1xCodec.h:170
void advance(size_type n)
Definition: Range.h:672
folly::StringPiece currentHeaderNameStringPiece_
Definition: HTTP1xCodec.h:162
constexpr size_type size() const
Definition: Range.h:431
std::string currentHeaderName_
Definition: HTTP1xCodec.h:161
bool isParsingHeaderOrTrailerName() const
Definition: HTTP1xCodec.h:123
constexpr Iter end() const
Definition: Range.h:455
constexpr Iter begin() const
Definition: Range.h:452
void pushHeaderNameAndValue(HTTPHeaders &hdrs)
std::unique_ptr< HTTPHeaders > trailers_
Definition: HTTP1xCodec.h:160
void reset(Iter start, size_type size)
Definition: Range.h:421
int proxygen::HTTP1xCodec::onHeaderFieldCB ( http_parser parser,
const char *  buf,
size_t  len 
)
staticprivate

Definition at line 1278 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onHeaderField(), onParserError(), and parser_.

Referenced by getParserSettings().

1278  {
1279  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1280  DCHECK(codec != nullptr);
1281  DCHECK_EQ(&codec->parser_, parser);
1282 
1283  try {
1284  return codec->onHeaderField(buf, len);
1285  } catch (const std::exception& ex) {
1286  codec->onParserError(ex.what());
1287  return 1;
1288  }
1289 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
int proxygen::HTTP1xCodec::onHeadersComplete ( size_t  len)
private

Definition at line 926 of file HTTP1xCodec.cpp.

References folly::netops::accept(), allowedNativeUpgrades_, callback_, proxygen::caseInsensitiveEqual(), proxygen::checkForProtocolUpgrade(), proxygen::CONNECT, connectRequest_, DISABLED, proxygen::DOWNSTREAM, egressUpgrade_, ENABLED, proxygen::ERROR, folly::pushmi::operators::error(), expectNoResponseBody_, F_CHUNKED, F_UPGRADE, http_parser::flags, g(), generateWebsocketAccept(), proxygen::getCodecProtocolString(), proxygen::ParseURL::hasHost(), folly::Optional< Value >::hasValue(), proxygen::HEAD, headerParseState_, headersComplete_, headerSize_, headRequest_, proxygen::ParseURL::hostAndPort(), proxygen::HTTP_1_1, proxygen::HTTP_HEADER_CONTENT_LENGTH, proxygen::HTTP_HEADER_HOST, proxygen::HTTP_HEADER_SEC_WEBSOCKET_ACCEPT, proxygen::HTTP_HEADER_SEC_WEBSOCKET_KEY, proxygen::HTTP_HEADER_TRANSFER_ENCODING, proxygen::HTTP_HEADER_UPGRADE, proxygen::HTTP_HEADER_USER_AGENT, http_parser::http_major, http_method_str(), http_parser::http_minor, ingressTxnID_, ingressUpgrade_, is1xxResponse_, keepalive_, keepaliveRequested_, kParsingHeadersComplete, kParsingHeaderValue, folly::makeGuard(), mayChunkEgress_, http_parser::method, folly::gen::move, msg_, nativeUpgrade_, proxygen::HTTPCodec::Callback::onHeadersComplete(), proxygen::HTTPCodec::Callback::onNativeProtocolUpgrade(), parser_, pushHeaderNameAndValue(), reason_, proxygen::RFC2616::responseBodyMustBeEmpty(), http_parser::status_code, string, transportDirection_, wangle::HTTPHeaderSize::uncompressed, UNSET, http_parser::upgrade, upgradeHeader_, upgradeRequest_, upgradeResult_, proxygen::UPSTREAM, url_, userAgent_, value, folly::Optional< Value >::value(), and websockAcceptKey_.

Referenced by isParsingHeaderOrTrailerName(), onHeadersCompleteCB(), and onIngress().

926  {
928  pushHeaderNameAndValue(msg_->getHeaders());
929  }
930 
931  // discard messages with folded or multiple valued Transfer-Encoding headers
932  // ex : "chunked , zorg\r\n" or "\r\n chunked \r\n" (t12767790)
933  HTTPHeaders& hdrs = msg_->getHeaders();
934  const std::string& headerVal =
935  hdrs.getSingleOrEmpty(HTTP_HEADER_TRANSFER_ENCODING);
936  if (!headerVal.empty() && !caseInsensitiveEqual(headerVal, kChunked)) {
937  LOG(ERROR) << "Invalid Transfer-Encoding header. Value =" << headerVal;
938  return -1;
939  }
940 
941  // discard messages with multiple content-length headers (t12767790)
942  if (hdrs.getNumberOfValues(HTTP_HEADER_CONTENT_LENGTH) > 1) {
943  // Only reject the message if the Content-Length headers have different
944  // values
946  bool error = hdrs.forEachValueOfHeader(
948  if (!contentLen.hasValue()) {
949  contentLen = value;
950  return false;
951  }
952  return (contentLen.value() != value);
953  });
954 
955  if (error) {
956  LOG(ERROR) << "Invalid message, multiple Content-Length headers";
957  return -1;
958  }
959  }
960 
961  // Update the HTTPMessage with the values parsed from the header
962  msg_->setHTTPVersion(parser_.http_major, parser_.http_minor);
963  msg_->setIsChunked((parser_.flags & F_CHUNKED));
964 
966  // Set the method type
967  msg_->setMethod(http_method_str(static_cast<http_method>(parser_.method)));
968 
969  connectRequest_ = (msg_->getMethod() == HTTPMethod::CONNECT);
970 
971  // If this is a headers-only request, we shouldn't send
972  // an entity-body in the response.
973  headRequest_ = (msg_->getMethod() == HTTPMethod::HEAD);
974 
975  ParseURL parseUrl = msg_->setURL(std::move(url_));
976  url_.clear();
977 
978  if (parseUrl.hasHost()) {
979  // RFC 2616 5.2.1 states "If Request-URI is an absoluteURI, the host
980  // is part of the Request-URI. Any Host header field value in the
981  // request MUST be ignored."
982  auto hostAndPort = parseUrl.hostAndPort();
983  VLOG(4) << "Adding inferred host header: " << hostAndPort;
984  msg_->getHeaders().set(HTTP_HEADER_HOST, hostAndPort);
985  }
986 
987  // If the client sent us an HTTP/1.x with x >= 1, we may send
988  // chunked responses.
989  mayChunkEgress_ = ((parser_.http_major == 1) && (parser_.http_minor >= 1));
990  } else {
991  msg_->setStatusCode(parser_.status_code);
992  msg_->setStatusMessage(std::move(reason_));
993  reason_.clear();
994  }
995 
996  auto g = folly::makeGuard([this] {
997  // Always clear the outbound upgrade header after we receive a response
999  parser_.status_code != 100) {
1000  upgradeHeader_.clear();
1001  }
1002  });
1005  if (connectRequest_ &&
1006  (parser_.status_code >= 200 && parser_.status_code < 300)) {
1007  // Enable upgrade if this is a 200 response to a CONNECT
1008  // request we sent earlier
1009  ingressUpgrade_ = true;
1010  } else if (parser_.status_code == 101) {
1011  // Set the upgrade flags if the server has upgraded.
1012  const std::string& serverUpgrade =
1013  msg_->getHeaders().getSingleOrEmpty(HTTP_HEADER_UPGRADE);
1014  if (serverUpgrade.empty() ||
1015  upgradeHeader_.empty()) {
1016  LOG(ERROR) << "Invalid 101 response, empty upgrade headers";
1017  return -1;
1018  }
1020  serverUpgrade,
1021  false /* client mode */);
1022  if (result) {
1023  ingressUpgrade_ = true;
1024  egressUpgrade_ = true;
1025  if (result->first != CodecProtocol::HTTP_1_1) {
1027  ingressTxnID_, result->first, result->second, *msg_);
1028  if (success) {
1029  nativeUpgrade_ = true;
1030  msg_->setIsUpgraded(ingressUpgrade_);
1031  return 1; // no message body if successful
1032  }
1033  } else if (result->second == getCodecProtocolString(result->first)) {
1034  // someone upgraded to http/1.1? Reset upgrade flags
1035  ingressUpgrade_ = false;
1036  egressUpgrade_ = false;
1037  }
1038  // else, there's some non-native upgrade
1039  } else {
1040  LOG(ERROR) << "Invalid 101 response, client/server upgrade mismatch "
1041  "client=" << upgradeHeader_ << " server=" << serverUpgrade;
1042  return -1;
1043  }
1044  } else if (parser_.upgrade || parser_.flags & F_UPGRADE) {
1045  // Ignore upgrade header for upstream response messages with status code
1046  // different from 101 in case if it was not a response to CONNECT.
1047  parser_.upgrade = false;
1048  parser_.flags &= ~F_UPGRADE;
1049  }
1050  }
1051  else {
1052  if (connectRequest_) {
1053  // Enable upgrade by default for the CONNECT requests.
1054  // If we locally reject CONNECT, we will disable this flag while
1055  // sending the reject response. If we forward the req to upstream proxy,
1056  // we will start forwarding data to the proxy without waiting for
1057  // the response from the proxy server.
1058  ingressUpgrade_ = true;
1059  } else if (!allowedNativeUpgrades_.empty() && ingressTxnID_ == 1) {
1060  upgradeHeader_ = msg_->getHeaders().getSingleOrEmpty(HTTP_HEADER_UPGRADE);
1061  if (!upgradeHeader_.empty() && !allowedNativeUpgrades_.empty()) {
1064  true /* server mode */);
1065  if (result && result->first != CodecProtocol::HTTP_1_1) {
1066  nativeUpgrade_ = true;
1067  upgradeResult_ = *result;
1068  // unfortunately have to copy because msg_ is passed to
1069  // onHeadersComplete
1070  upgradeRequest_ = std::make_unique<HTTPMessage>(*msg_);
1071  }
1072  }
1073  }
1074  }
1075  msg_->setIsUpgraded(ingressUpgrade_);
1076 
1077  const std::string& upgrade = hdrs.getSingleOrEmpty(HTTP_HEADER_UPGRADE);
1079  msg_->setIngressWebsocketUpgrade();
1081  // response.
1082  const std::string& accept = hdrs.getSingleOrEmpty(
1084  if (accept != websockAcceptKey_) {
1085  LOG(ERROR) << "Mismatch in expected ws accept key: " <<
1086  "upstream: " << accept << " expected: " << websockAcceptKey_;
1087  return -1;
1088  }
1089  } else {
1090  // request.
1091  auto key = hdrs.getSingleOrEmpty(HTTP_HEADER_SEC_WEBSOCKET_KEY);
1092  DCHECK(websockAcceptKey_.empty());
1094  }
1095  }
1096 
1097  bool msgKeepalive = msg_->computeKeepalive();
1098  if (!msgKeepalive) {
1099  keepalive_ = false;
1100  }
1102  // Remember whether this was an HTTP 1.0 request with keepalive enabled
1103  if (msgKeepalive && msg_->isHTTP1_0() &&
1107  } else {
1109  }
1110  }
1111 
1112  // Determine whether the HTTP parser should ignore any headers
1113  // that indicate the presence of a message body. This is needed,
1114  // for example, if the message is a response to a request with
1115  // method==HEAD.
1116  bool ignoreBody;
1118  ignoreBody = false;
1119  } else {
1120  is1xxResponse_ = msg_->is1xxResponse();
1121  if (expectNoResponseBody_) {
1122  ignoreBody = true;
1123  } else {
1124  ignoreBody = RFC2616::responseBodyMustBeEmpty(msg_->getStatusCode());
1125  }
1126  }
1127 
1128  headersComplete_ = true;
1129  headerSize_.uncompressed += len;
1130  msg_->setIngressHeaderSize(headerSize_);
1131 
1132  if (userAgent_.empty()) {
1133  userAgent_ = msg_->getHeaders().getSingleOrEmpty(HTTP_HEADER_USER_AGENT);
1134  }
1136 
1137  // 1 is a magic value that tells the http_parser not to expect a
1138  // message body even if the message header implied the presence
1139  // of one (e.g., via a Content-Length)
1140  return (ignoreBody) ? 1 : 0;
1141 }
std::pair< CodecProtocol, std::string > upgradeResult_
Definition: HTTP1xCodec.h:173
unsigned char flags
Definition: http_parser.h:215
bool responseBodyMustBeEmpty(unsigned status)
Definition: RFC2616.cpp:54
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
std::unique_ptr< HTTPMessage > msg_
Definition: HTTP1xCodec.h:158
constexpr folly::StringPiece kUpgradeToken
bool caseInsensitiveEqual(folly::StringPiece s, folly::StringPiece t)
Definition: UtilInl.h:17
unsigned short http_minor
Definition: http_parser.h:225
std::unique_ptr< HTTPMessage > upgradeRequest_
Definition: HTTP1xCodec.h:159
HeaderParseState headerParseState_
Definition: HTTP1xCodec.h:170
std::string userAgent_
Definition: HTTP1xCodec.h:165
std::string upgradeHeader_
Definition: HTTP1xCodec.h:167
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
Definition: error.h:48
bool equals(const const_range_type &other, Comp &&eq) const
Definition: Range.h:868
unsigned short status_code
Definition: http_parser.h:226
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
const char * http_method_str(enum http_method m)
Definition: http_parser.c:2159
HTTPHeaderSize headerSize_
Definition: HTTP1xCodec.h:169
folly::Optional< std::pair< CodecProtocol, std::string > > checkForProtocolUpgrade(const std::string &clientUpgrade, const std::string &serverUpgrade, bool serverMode)
const std::string & getCodecProtocolString(CodecProtocol proto)
unsigned char method
Definition: http_parser.h:227
unsigned short http_major
Definition: http_parser.h:224
FOLLY_CPP14_CONSTEXPR bool hasValue() const noexcept
Definition: Optional.h:300
static const char *const value
Definition: Conv.cpp:50
FOLLY_NODISCARD detail::ScopeGuardImplDecay< F, true > makeGuard(F &&f) noexcept(noexcept(detail::ScopeGuardImplDecay< F, true >(static_cast< F && >(f))))
Definition: ScopeGuard.h:184
std::string allowedNativeUpgrades_
Definition: HTTP1xCodec.h:168
virtual void onHeadersComplete(StreamID stream, std::unique_ptr< HTTPMessage > msg)=0
const char * string
Definition: Conv.cpp:212
g_t g(f_t)
std::string websockAcceptKey_
Definition: HTTP1xCodec.h:103
void pushHeaderNameAndValue(HTTPHeaders &hdrs)
FOLLY_CPP14_CONSTEXPR const Value & value() const &
Definition: Optional.h:268
KeepaliveRequested keepaliveRequested_
Definition: HTTP1xCodec.h:172
std::string generateWebsocketAccept(const std::string &acceptKey) const
virtual bool onNativeProtocolUpgrade(StreamID, CodecProtocol, const std::string &, HTTPMessage &)
Definition: HTTPCodec.h:271
NetworkSocket accept(NetworkSocket s, sockaddr *addr, socklen_t *addrlen)
Definition: NetOps.cpp:71
int proxygen::HTTP1xCodec::onHeadersCompleteCB ( http_parser parser,
const char *  buf,
size_t  len 
)
staticprivate

Definition at line 1305 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onHeadersComplete(), onParserError(), and parser_.

Referenced by getParserSettings().

1307  {
1308  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1309  DCHECK(codec != nullptr);
1310  DCHECK_EQ(&codec->parser_, parser);
1311 
1312  try {
1313  return codec->onHeadersComplete(len);
1314  } catch (const std::exception& ex) {
1315  codec->onParserError(ex.what());
1316  return 3;
1317  }
1318 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
int proxygen::HTTP1xCodec::onHeaderValue ( const char *  buf,
size_t  len 
)
private
int proxygen::HTTP1xCodec::onHeaderValueCB ( http_parser parser,
const char *  buf,
size_t  len 
)
staticprivate

Definition at line 1292 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onHeaderValue(), onParserError(), and parser_.

Referenced by getParserSettings().

1292  {
1293  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1294  DCHECK(codec != nullptr);
1295  DCHECK_EQ(&codec->parser_, parser);
1296 
1297  try {
1298  return codec->onHeaderValue(buf, len);
1299  } catch (const std::exception& ex) {
1300  codec->onParserError(ex.what());
1301  return 1;
1302  }
1303 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
size_t proxygen::HTTP1xCodec::onIngress ( const folly::IOBuf buf)
overridevirtual

Parse ingress data.

Parameters
bufA single IOBuf of data to parse
Returns
Number of bytes consumed.

Implements proxygen::HTTPCodec.

Definition at line 177 of file HTTP1xCodec.cpp.

References folly::Range< Iter >::begin(), callback_, folly::IOBuf::clone(), folly::IOBuf::computeChainDataLength(), currentHeaderName_, currentHeaderNameStringPiece_, currentIngressBuf_, folly::IOBuf::data(), folly::Range< Iter >::empty(), getParserSettings(), headersComplete_, headerSize_, HPE_OK, HPE_PAUSED, http_parser::http_major, http_parser::http_minor, HTTP_PARSER_ERRNO, http_parser_execute(), ingressTxnID_, ingressUpgradeComplete_, folly::IOBuf::length(), msg_, proxygen::HTTPCodec::Callback::onBody(), onHeadersComplete(), onIngressEOF(), onMessageBegin(), onParserError(), parser_, parserActive_, parserError_, pendingEOF_, folly::Range< Iter >::size(), transportDirection_, wangle::HTTPHeaderSize::uncompressed, and proxygen::UPSTREAM.

Referenced by setCallback(), TEST(), and TEST_P().

177  {
178  if (parserError_) {
179  return 0;
180  } else if (ingressUpgradeComplete_) {
181  callback_->onBody(ingressTxnID_, buf.clone(), 0);
182  return buf.computeChainDataLength();
183  } else {
184  // Callers responsibility to prevent calling onIngress from a callback
185  CHECK(!parserActive_);
186  parserActive_ = true;
187  currentIngressBuf_ = &buf;
189  parser_.http_major == 0 && parser_.http_minor == 9) {
190  // HTTP/0.9 responses have no header block, so create a fake 200 response
191  // and put the codec in upgrade mode
192  onMessageBegin();
193  msg_->setStatusCode(200);
195  parserActive_ = false;
197  return onIngress(buf);
198  }
199  size_t bytesParsed = http_parser_execute(&parser_,
201  (const char*)buf.data(),
202  buf.length());
203  // in case we parsed a section of the headers but we're not done parsing
204  // the headers we need to keep accounting of it for total header size
205  if (!headersComplete_) {
206  headerSize_.uncompressed += bytesParsed;
207  }
208  parserActive_ = false;
211  if (parserError_) {
212  onParserError();
213  }
215  // we currently are storing a chunk of header name via pointers in
216  // currentHeaderNameStringPiece_, but the currentIngressBuf_ is about to
217  // vanish and so we need to copy over that data to currentHeaderName_
220  }
221  currentIngressBuf_ = nullptr;
222  if (pendingEOF_) {
223  onIngressEOF();
224  pendingEOF_ = false;
225  }
226  return bytesParsed;
227  }
228 }
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
std::unique_ptr< HTTPMessage > msg_
Definition: HTTP1xCodec.h:158
unsigned short http_minor
Definition: http_parser.h:225
size_t http_parser_execute(http_parser *parser, const http_parser_settings *settings, const char *data, size_t len)
Definition: http_parser.c:602
folly::StringPiece currentHeaderNameStringPiece_
Definition: HTTP1xCodec.h:162
constexpr size_type size() const
Definition: Range.h:431
const uint8_t * data() const
Definition: IOBuf.h:499
std::unique_ptr< IOBuf > clone() const
Definition: IOBuf.cpp:527
std::string currentHeaderName_
Definition: HTTP1xCodec.h:161
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
constexpr bool empty() const
Definition: Range.h:443
#define HTTP_PARSER_ERRNO(p)
Definition: http_parser.h:202
HTTPHeaderSize headerSize_
Definition: HTTP1xCodec.h:169
std::size_t length() const
Definition: IOBuf.h:533
unsigned short http_major
Definition: http_parser.h:224
size_t onIngress(const folly::IOBuf &buf) override
int onHeadersComplete(size_t len)
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
void onParserError(const char *what=nullptr)
constexpr Iter begin() const
Definition: Range.h:452
virtual void onBody(StreamID stream, std::unique_ptr< folly::IOBuf > chain, uint16_t padding)=0
const folly::IOBuf * currentIngressBuf_
Definition: HTTP1xCodec.h:157
void onIngressEOF() override
static const http_parser_settings * getParserSettings()
void proxygen::HTTP1xCodec::onIngressEOF ( )
overridevirtual

Finish parsing when the ingress stream has ended.

Implements proxygen::HTTPCodec.

Definition at line 231 of file HTTP1xCodec.cpp.

References callback_, getParserSettings(), HPE_OK, HPE_PAUSED, HTTP_PARSER_ERRNO, http_parser_execute(), ingressTxnID_, ingressUpgradeComplete_, proxygen::HTTPCodec::Callback::onMessageComplete(), onParserError(), parser_, parserActive_, parserError_, and pendingEOF_.

Referenced by onIngress(), setCallback(), and TEST().

231  {
232  if (parserError_) {
233  return;
234  }
235  if (parserActive_) {
236  pendingEOF_ = true;
237  return;
238  }
241  return;
242  }
243  parserActive_ = true;
244  if (http_parser_execute(&parser_, getParserSettings(), nullptr, 0) != 0) {
245  parserError_ = true;
246  } else {
249  }
250  parserActive_ = false;
251  if (parserError_) {
252  onParserError();
253  }
254 }
virtual void onMessageComplete(StreamID stream, bool upgrade)=0
size_t http_parser_execute(http_parser *parser, const http_parser_settings *settings, const char *data, size_t len)
Definition: http_parser.c:602
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
#define HTTP_PARSER_ERRNO(p)
Definition: http_parser.h:202
void onParserError(const char *what=nullptr)
static const http_parser_settings * getParserSettings()
int proxygen::HTTP1xCodec::onMessageBegin ( )
private

Definition at line 817 of file HTTP1xCodec.cpp.

References callback_, proxygen::DOWNSTREAM, headerParseState_, headersComplete_, headerSize_, ingressTxnID_, is1xxResponse_, kParsingHeaderStart, msg_, proxygen::HTTPCodec::Callback::onMessageBegin(), requestPending_, responsePending_, trailers_, transportDirection_, wangle::HTTPHeaderSize::uncompressed, and proxygen::UPSTREAM.

Referenced by isParsingHeaderOrTrailerName(), onIngress(), and onMessageBeginCB().

817  {
818  headersComplete_ = false;
821  msg_.reset(new HTTPMessage());
822  trailers_.reset();
824  requestPending_ = true;
825  responsePending_ = true;
826  }
827  // If there was a 1xx on this connection, don't increment the ingress txn id
829  !is1xxResponse_) {
830  ++ingressTxnID_;
831  }
833  is1xxResponse_ = false;
834  }
836  return 0;
837 }
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
std::unique_ptr< HTTPMessage > msg_
Definition: HTTP1xCodec.h:158
virtual void onMessageBegin(StreamID stream, HTTPMessage *msg)=0
HeaderParseState headerParseState_
Definition: HTTP1xCodec.h:170
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
HTTPHeaderSize headerSize_
Definition: HTTP1xCodec.h:169
std::unique_ptr< HTTPHeaders > trailers_
Definition: HTTP1xCodec.h:160
int proxygen::HTTP1xCodec::onMessageBeginCB ( http_parser parser)
staticprivate

Definition at line 1236 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onMessageBegin(), onParserError(), and parser_.

Referenced by getParserSettings().

1236  {
1237  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1238  DCHECK(codec != nullptr);
1239  DCHECK_EQ(&codec->parser_, parser);
1240 
1241  try {
1242  return codec->onMessageBegin();
1243  } catch (const std::exception& ex) {
1244  codec->onParserError(ex.what());
1245  return 1;
1246  }
1247 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
int proxygen::HTTP1xCodec::onMessageComplete ( )
private

Definition at line 1180 of file HTTP1xCodec.cpp.

References callback_, proxygen::DOWNSTREAM, headerParseState_, ingressTxnID_, ingressUpgrade_, ingressUpgradeComplete_, inRecvLastChunk_, is1xxResponse_, isParsingHeaders(), kParsingHeaderIdle, kParsingTrailerValue, folly::gen::move, nativeUpgrade_, proxygen::HTTPCodec::Callback::onMessageComplete(), proxygen::HTTPCodec::Callback::onNativeProtocolUpgrade(), proxygen::HTTPCodec::Callback::onTrailersComplete(), pushHeaderNameAndValue(), requestPending_, responsePending_, setParserPaused(), trailers_, transportDirection_, upgradeRequest_, upgradeResult_, and proxygen::UPSTREAM.

Referenced by isParsingHeaderOrTrailerName(), and onMessageCompleteCB().

1180  {
1181  DCHECK(!isParsingHeaders());
1182  DCHECK(!inRecvLastChunk_);
1184  if (!trailers_) {
1185  trailers_.reset(new HTTPHeaders());
1186  }
1188  }
1189 
1191  if (trailers_) {
1193  }
1194 
1195  switch (transportDirection_) {
1197  {
1198  requestPending_ = false;
1199  if (upgradeRequest_) {
1202  *upgradeRequest_);
1203  upgradeRequest_.reset();
1204  }
1205  // else there was no match, OR we upgraded to http/1.1 OR someone specified
1206  // a non-native protocol in the setAllowedUpgradeProtocols. No-ops
1207  break;
1208  }
1211  }
1212 
1213  // For downstream, always call onMessageComplete. If native upgrade,
1214  // pass upgrade=false. Else pass ingressUpgrade_.
1215  // For upstream, call onMessagComplete if not native upgrade.
1216  if (!nativeUpgrade_) {
1219  // native upgrade and downstream.
1221  }
1222  // else we suppressed onHeadersComplete, suppress onMessageComplete also.
1223  // The new codec will handle these callbacks with the real message
1224 
1225  if (ingressUpgrade_) {
1226  ingressUpgradeComplete_ = true;
1227  // If upgrade is complete, any pending data should not be parsed.
1228  // It must be forwarded directly to the handler.
1229  setParserPaused(true);
1230  }
1231 
1232  return 0;
1233 }
std::pair< CodecProtocol, std::string > upgradeResult_
Definition: HTTP1xCodec.h:173
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
std::unique_ptr< HTTPMessage > upgradeRequest_
Definition: HTTP1xCodec.h:159
HeaderParseState headerParseState_
Definition: HTTP1xCodec.h:170
virtual void onMessageComplete(StreamID stream, bool upgrade)=0
virtual void onTrailersComplete(StreamID stream, std::unique_ptr< HTTPHeaders > trailers)=0
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
bool isParsingHeaders() const
Definition: HTTP1xCodec.h:117
void setParserPaused(bool paused) override
void pushHeaderNameAndValue(HTTPHeaders &hdrs)
std::unique_ptr< HTTPHeaders > trailers_
Definition: HTTP1xCodec.h:160
virtual bool onNativeProtocolUpgrade(StreamID, CodecProtocol, const std::string &, HTTPMessage &)
Definition: HTTPCodec.h:271
int proxygen::HTTP1xCodec::onMessageCompleteCB ( http_parser parser)
staticprivate

Definition at line 1367 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onMessageComplete(), onParserError(), and parser_.

Referenced by getParserSettings().

1367  {
1368  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1369  DCHECK(codec != nullptr);
1370  DCHECK_EQ(&codec->parser_, parser);
1371 
1372  try {
1373  return codec->onMessageComplete();
1374  } catch (const std::exception& ex) {
1375  codec->onParserError(ex.what());
1376  return 1;
1377  }
1378 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
void proxygen::HTTP1xCodec::onParserError ( const char *  what = nullptr)
private

Invoked when a parsing error occurs. It will send an exception to the callback object to report the error and do any other cleanup needed. It optionally takes a message to pass to the generated HTTPException passed to callback_.

Definition at line 257 of file HTTP1xCodec.cpp.

References callback_, folly::IOBuf::cloneOne(), currentIngressBuf_, proxygen::DOWNSTREAM, egressTxnID_, folly::pushmi::operators::error(), HPE_HEADER_OVERFLOW, HPE_HUGE_CHUNK_SIZE, HPE_HUGE_CONTENT_LENGTH, HPE_INVALID_CHUNK_SIZE, HPE_INVALID_CONSTANT, HPE_INVALID_EOF_STATE, HPE_INVALID_VERSION, http_errno_description(), HTTP_PARSER_ERRNO, proxygen::HTTPException::INGRESS, ingressTxnID_, inRecvLastChunk_, proxygen::kErrorEOF, proxygen::kErrorParseBody, proxygen::kErrorParseHeader, proxygen::kErrorUnknown, folly::gen::move, msg_, proxygen::HTTPCodec::Callback::onError(), parser_, proxygen::HTTPException::setCurrentIngressBuf(), proxygen::HTTPException::setHttpStatusCode(), proxygen::HTTPException::setPartialMsg(), proxygen::Exception::setProxygenError(), and transportDirection_.

Referenced by isParsingHeaderOrTrailerName(), onBodyCB(), onChunkCompleteCB(), onChunkHeaderCB(), onHeaderFieldCB(), onHeadersCompleteCB(), onHeaderValueCB(), onIngress(), onIngressEOF(), onMessageBeginCB(), onMessageCompleteCB(), onReasonCB(), and onUrlCB().

257  {
258  inRecvLastChunk_ = false;
259  http_errno parser_errno = HTTP_PARSER_ERRNO(&parser_);
261  what ? what : folly::to<std::string>(
262  "Error parsing message: ",
263  http_errno_description(parser_errno)
264  ));
265  // generate a string of parsed headers so that we can pass it to callback
266  if (msg_) {
267  error.setPartialMsg(std::move(msg_));
268  }
269  // store the ingress buffer
270  if (currentIngressBuf_) {
271  error.setCurrentIngressBuf(currentIngressBuf_->cloneOne());
272  }
275  error.setHttpStatusCode(400);
276  } // else we've already egressed a response for this txn, don't attempt a 400
277  // See http_parser.h for what these error codes mean
278  if (parser_errno == HPE_INVALID_EOF_STATE) {
279  error.setProxygenError(kErrorEOF);
280  } else if (parser_errno == HPE_HEADER_OVERFLOW ||
281  parser_errno == HPE_INVALID_CONSTANT ||
282  (parser_errno >= HPE_INVALID_VERSION &&
283  parser_errno <= HPE_HUGE_CONTENT_LENGTH)) {
284  error.setProxygenError(kErrorParseHeader);
285  } else if (parser_errno == HPE_INVALID_CHUNK_SIZE ||
286  parser_errno == HPE_HUGE_CHUNK_SIZE) {
287  error.setProxygenError(kErrorParseBody);
288  } else {
289  error.setProxygenError(kErrorUnknown);
290  }
292 }
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
std::unique_ptr< HTTPMessage > msg_
Definition: HTTP1xCodec.h:158
virtual void onError(StreamID stream, const HTTPException &error, bool newTxn=false)=0
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
Definition: error.h:48
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
#define HTTP_PARSER_ERRNO(p)
Definition: http_parser.h:202
const char * http_errno_description(enum http_errno err)
Definition: http_parser.c:2186
std::unique_ptr< IOBuf > cloneOne() const
Definition: IOBuf.cpp:531
http_errno
Definition: http_parser.h:196
const folly::IOBuf * currentIngressBuf_
Definition: HTTP1xCodec.h:157
static int proxygen::HTTP1xCodec::onPathCB ( http_parser parser,
const char *  buf,
size_t  len 
)
staticprivate
static int proxygen::HTTP1xCodec::onQueryStringCB ( http_parser parser,
const char *  buf,
size_t  len 
)
staticprivate
int proxygen::HTTP1xCodec::onReason ( const char *  buf,
size_t  len 
)
private

Definition at line 846 of file HTTP1xCodec.cpp.

References reason_.

Referenced by isParsingHeaderOrTrailerName(), and onReasonCB().

846  {
847  reason_.append(buf, len);
848  return 0;
849 }
int proxygen::HTTP1xCodec::onReasonCB ( http_parser parser,
const char *  buf,
size_t  len 
)
staticprivate

Definition at line 1264 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onParserError(), onReason(), and parser_.

Referenced by getParserSettings().

1264  {
1265  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1266  DCHECK(codec != nullptr);
1267  DCHECK_EQ(&codec->parser_, parser);
1268 
1269  try {
1270  return codec->onReason(buf, len);
1271  } catch (const std::exception& ex) {
1272  codec->onParserError(ex.what());
1273  return 1;
1274  }
1275 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
int proxygen::HTTP1xCodec::onURL ( const char *  buf,
size_t  len 
)
private

Definition at line 840 of file HTTP1xCodec.cpp.

References url_.

Referenced by isParsingHeaderOrTrailerName(), and onUrlCB().

840  {
841  url_.append(buf, len);
842  return 0;
843 }
int proxygen::HTTP1xCodec::onUrlCB ( http_parser parser,
const char *  buf,
size_t  len 
)
staticprivate

Definition at line 1250 of file HTTP1xCodec.cpp.

References codec, http_parser::data, onParserError(), onURL(), and parser_.

Referenced by getParserSettings().

1250  {
1251  HTTP1xCodec* codec = static_cast<HTTP1xCodec*>(parser->data);
1252  DCHECK(codec != nullptr);
1253  DCHECK_EQ(&codec->parser_, parser);
1254 
1255  try {
1256  return codec->onURL(buf, len);
1257  } catch (const std::exception& ex) {
1258  codec->onParserError(ex.what());
1259  return 1;
1260  }
1261 }
CodecFactory codec
void * data
Definition: http_parser.h:242
HTTP1xCodec(TransportDirection direction, bool forceUpstream1_1=false)
Definition: HTTP1xCodec.cpp:81
void proxygen::HTTP1xCodec::pushHeaderNameAndValue ( HTTPHeaders hdrs)
private

Push out header name-value pair to hdrs and clear currentHeader*_

Definition at line 851 of file HTTP1xCodec.cpp.

References proxygen::HTTPHeaders::add(), proxygen::HTTPHeaders::addFromCodec(), folly::Range< Iter >::begin(), folly::Range< Iter >::clear(), currentHeaderName_, currentHeaderNameStringPiece_, currentHeaderValue_, LIKELY, folly::gen::move, and folly::Range< Iter >::size().

Referenced by isParsingHeaderOrTrailerName(), onHeaderField(), onHeadersComplete(), and onMessageComplete().

851  {
852  if (LIKELY(currentHeaderName_.empty())) {
853  hdrs.addFromCodec(currentHeaderNameStringPiece_.begin(),
856  } else {
857  hdrs.add(currentHeaderName_,
859  currentHeaderName_.clear();
860  }
862  currentHeaderValue_.clear();
863 }
std::string currentHeaderValue_
Definition: HTTP1xCodec.h:163
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define LIKELY(x)
Definition: Likely.h:47
folly::StringPiece currentHeaderNameStringPiece_
Definition: HTTP1xCodec.h:162
constexpr size_type size() const
Definition: Range.h:431
std::string currentHeaderName_
Definition: HTTP1xCodec.h:161
void clear()
Definition: Range.h:411
constexpr Iter begin() const
Definition: Range.h:452
void proxygen::HTTP1xCodec::serializeWebsocketHeader ( folly::IOBufQueue writeBuf,
size_t &  len,
bool  upstream 
)
private

Serialize websocket headers into a buffer

Definition at line 337 of file HTTP1xCodec.cpp.

References appendLiteral, generateWebsocketAccept(), generateWebsocketKey(), upgradeHeader_, and websockAcceptKey_.

Referenced by generateHeader(), and isParsingHeaderOrTrailerName().

339  {
340  if (upstream) {
341  appendLiteral(writeBuf, len, "Upgrade: ");
342  appendString(writeBuf, len, kUpgradeToken.str());
343  appendLiteral(writeBuf, len, CRLF);
345 
346  auto key = generateWebsocketKey();
347  appendLiteral(writeBuf, len, "Sec-WebSocket-Key: ");
348  appendString(writeBuf, len, key);
349  appendLiteral(writeBuf, len, CRLF);
350  DCHECK(websockAcceptKey_.empty());
352  } else {
353  appendLiteral(writeBuf, len, "Upgrade: ");
354  appendString(writeBuf, len, kUpgradeToken.str());
355  appendLiteral(writeBuf, len, CRLF);
356 
357  appendLiteral(writeBuf, len, "Sec-WebSocket-Accept: ");
358  appendString(writeBuf, len, websockAcceptKey_);
359  appendLiteral(writeBuf, len, CRLF);
360  }
361 }
std::string str() const
Definition: Range.h:591
constexpr folly::StringPiece kUpgradeToken
#define appendLiteral(queue, len, str)
Definition: HTTP1xCodec.cpp:68
std::string upgradeHeader_
Definition: HTTP1xCodec.h:167
std::string generateWebsocketKey() const
std::string websockAcceptKey_
Definition: HTTP1xCodec.h:103
std::string generateWebsocketAccept(const std::string &acceptKey) const
void proxygen::HTTP1xCodec::setAllowedUpgradeProtocols ( std::list< std::string protocols)

Definition at line 802 of file HTTP1xCodec.cpp.

References allowedNativeUpgrades_, proxygen::DOWNSTREAM, and transportDirection_.

Referenced by supportsPushTransactions().

802  {
804  for (const auto& proto: protocols) {
805  allowedNativeUpgrades_ += folly::to<string>(proto, ",");
806  }
807  if (!allowedNativeUpgrades_.empty()) {
809  }
810 }
TransportDirection transportDirection_
Definition: HTTP1xCodec.h:171
std::string allowedNativeUpgrades_
Definition: HTTP1xCodec.h:168
void proxygen::HTTP1xCodec::setCallback ( Callback callback)
inlineoverridevirtual

Set the callback to notify on ingress events

Parameters
callbackThe callback object

Implements proxygen::HTTPCodec.

Definition at line 40 of file HTTP1xCodec.h.

References callback_, isBusy(), isReusable(), onIngress(), onIngressEOF(), and setParserPaused().

Referenced by proxygen::RFC1867Codec::RFC1867Codec(), TEST(), and TEST_P().

40 { callback_ = callback; }
HTTPCodec::Callback * callback_
Definition: HTTP1xCodec.h:153
void proxygen::HTTP1xCodec::setParserPaused ( bool  paused)
overridevirtual

Pause or resume the ingress parser

Parameters
pausedWhether the caller wants the parser to be paused

Implements proxygen::HTTPCodec.

Definition at line 141 of file HTTP1xCodec.cpp.

References HPE_OK, HPE_PAUSED, HTTP_PARSER_ERRNO, http_parser_pause(), parser_, parserError_, and parserPaused_.

Referenced by proxygen::RFC1867Codec::onBody(), proxygen::RFC1867Codec::onError(), proxygen::RFC1867Codec::onMessageComplete(), onMessageComplete(), proxygen::RFC1867Codec::onTrailersComplete(), setCallback(), and TEST().

141  {
142  if ((paused == parserPaused_) || parserError_) {
143  // If we're bailing early, we better be paused already
144  DCHECK(parserError_ ||
145  (HTTP_PARSER_ERRNO(&parser_) == HPE_PAUSED) == paused);
146  return;
147  }
148  if (paused) {
149  if (HTTP_PARSER_ERRNO(&parser_) == HPE_OK) {
151  }
152  } else {
154  }
155  parserPaused_ = paused;
156 }
void http_parser_pause(http_parser *parser, int paused)
Definition: http_parser.c:2431
#define HTTP_PARSER_ERRNO(p)
Definition: http_parser.h:202
bool proxygen::HTTP1xCodec::supportsNextProtocol ( const std::string npn)
static
Returns
true if the codec supports the given NPN protocol.

Definition at line 1380 of file HTTP1xCodec.cpp.

Referenced by proxygen::DefaultHTTPCodecFactory::getCodec(), proxygen::HTTPDefaultSessionCodecFactory::getCodec(), and supportsPushTransactions().

1380  {
1381  return npn.length() == 8 && (npn == "http/1.0" || npn == "http/1.1");
1382 }
bool proxygen::HTTP1xCodec::supportsParallelRequests ( ) const
inlineoverridevirtual

Check whether the codec supports the processing of multiple requests in parallel.

Implements proxygen::HTTPCodec.

Definition at line 50 of file HTTP1xCodec.h.

50 { return false; }
bool proxygen::HTTP1xCodec::supportsPushTransactions ( ) const
inlineoverridevirtual

Member Data Documentation

std::string proxygen::HTTP1xCodec::allowedNativeUpgrades_
private
bool proxygen::HTTP1xCodec::connectRequest_
private

Definition at line 187 of file HTTP1xCodec.h.

Referenced by generateHeader(), and onHeadersComplete().

std::string proxygen::HTTP1xCodec::currentHeaderName_
private

Definition at line 161 of file HTTP1xCodec.h.

Referenced by onHeaderField(), onIngress(), and pushHeaderNameAndValue().

folly::StringPiece proxygen::HTTP1xCodec::currentHeaderNameStringPiece_
private

Definition at line 162 of file HTTP1xCodec.h.

Referenced by onHeaderField(), onIngress(), and pushHeaderNameAndValue().

std::string proxygen::HTTP1xCodec::currentHeaderValue_
private

Definition at line 163 of file HTTP1xCodec.h.

Referenced by onHeaderValue(), and pushHeaderNameAndValue().

const folly::IOBuf* proxygen::HTTP1xCodec::currentIngressBuf_
private

Definition at line 157 of file HTTP1xCodec.h.

Referenced by onBody(), onIngress(), and onParserError().

bool proxygen::HTTP1xCodec::disableKeepalivePending_
private

Definition at line 185 of file HTTP1xCodec.h.

Referenced by generateGoaway(), generateHeader(), and generateRstStream().

bool proxygen::HTTP1xCodec::egressChunked_
private
StreamID proxygen::HTTP1xCodec::egressTxnID_
private
bool proxygen::HTTP1xCodec::egressUpgrade_
private
bool proxygen::HTTP1xCodec::expectNoResponseBody_
private

Definition at line 189 of file HTTP1xCodec.h.

Referenced by generateHeader(), and onHeadersComplete().

bool proxygen::HTTP1xCodec::forceUpstream1_1_
private

Definition at line 174 of file HTTP1xCodec.h.

Referenced by generateHeader().

HeaderParseState proxygen::HTTP1xCodec::headerParseState_
private
bool proxygen::HTTP1xCodec::headersComplete_
private

Definition at line 197 of file HTTP1xCodec.h.

Referenced by onHeadersComplete(), onIngress(), and onMessageBegin().

HTTPHeaderSize proxygen::HTTP1xCodec::headerSize_
private

Definition at line 169 of file HTTP1xCodec.h.

Referenced by onHeadersComplete(), onIngress(), and onMessageBegin().

bool proxygen::HTTP1xCodec::headRequest_
private

Definition at line 188 of file HTTP1xCodec.h.

Referenced by generateEOM(), generateHeader(), and onHeadersComplete().

bool proxygen::HTTP1xCodec::inChunk_
private
bool proxygen::HTTP1xCodec::ingressUpgrade_
private

Definition at line 193 of file HTTP1xCodec.h.

Referenced by generateHeader(), isReusable(), onHeadersComplete(), and onMessageComplete().

bool proxygen::HTTP1xCodec::ingressUpgradeComplete_
private

Definition at line 194 of file HTTP1xCodec.h.

Referenced by onIngress(), onIngressEOF(), and onMessageComplete().

bool proxygen::HTTP1xCodec::inRecvLastChunk_
private
bool proxygen::HTTP1xCodec::is1xxResponse_
private
bool proxygen::HTTP1xCodec::keepalive_
private

Definition at line 184 of file HTTP1xCodec.h.

Referenced by generateHeader(), isReusable(), and onHeadersComplete().

KeepaliveRequested proxygen::HTTP1xCodec::keepaliveRequested_
private

Definition at line 172 of file HTTP1xCodec.h.

Referenced by generateHeader(), and onHeadersComplete().

bool proxygen::HTTP1xCodec::lastChunkWritten_
private

Definition at line 183 of file HTTP1xCodec.h.

Referenced by generateEOM(), generateHeader(), and generateTrailers().

bool proxygen::HTTP1xCodec::mayChunkEgress_
private

Definition at line 190 of file HTTP1xCodec.h.

Referenced by generateHeader(), and onHeadersComplete().

std::unique_ptr<HTTPMessage> proxygen::HTTP1xCodec::msg_
private
bool proxygen::HTTP1xCodec::nativeUpgrade_
private

Definition at line 196 of file HTTP1xCodec.h.

Referenced by onHeadersComplete(), and onMessageComplete().

bool proxygen::HTTP1xCodec::parserActive_
private

Definition at line 175 of file HTTP1xCodec.h.

Referenced by onIngress(), and onIngressEOF().

bool proxygen::HTTP1xCodec::parserError_
private

Definition at line 178 of file HTTP1xCodec.h.

Referenced by isReusable(), onIngress(), onIngressEOF(), and setParserPaused().

bool proxygen::HTTP1xCodec::parserPaused_
private

Definition at line 177 of file HTTP1xCodec.h.

Referenced by setParserPaused().

bool proxygen::HTTP1xCodec::pendingEOF_
private

Definition at line 176 of file HTTP1xCodec.h.

Referenced by onIngress(), and onIngressEOF().

std::string proxygen::HTTP1xCodec::reason_
private

Definition at line 166 of file HTTP1xCodec.h.

Referenced by onHeadersComplete(), and onReason().

bool proxygen::HTTP1xCodec::requestPending_
private

Definition at line 179 of file HTTP1xCodec.h.

Referenced by generateEOM(), generateHeader(), isBusy(), onMessageBegin(), and onMessageComplete().

bool proxygen::HTTP1xCodec::responsePending_
private

Definition at line 180 of file HTTP1xCodec.h.

Referenced by generateEOM(), generateHeader(), isBusy(), onMessageBegin(), and onMessageComplete().

std::unique_ptr<HTTPHeaders> proxygen::HTTP1xCodec::trailers_
private

Definition at line 160 of file HTTP1xCodec.h.

Referenced by onHeaderField(), onMessageBegin(), and onMessageComplete().

std::string proxygen::HTTP1xCodec::upgradeHeader_
private

Definition at line 167 of file HTTP1xCodec.h.

Referenced by generateHeader(), onHeadersComplete(), and serializeWebsocketHeader().

std::unique_ptr<HTTPMessage> proxygen::HTTP1xCodec::upgradeRequest_
private

Definition at line 159 of file HTTP1xCodec.h.

Referenced by onHeadersComplete(), and onMessageComplete().

std::pair<CodecProtocol, std::string> proxygen::HTTP1xCodec::upgradeResult_
private

Definition at line 173 of file HTTP1xCodec.h.

Referenced by onHeadersComplete(), and onMessageComplete().

std::string proxygen::HTTP1xCodec::url_
private

Definition at line 164 of file HTTP1xCodec.h.

Referenced by onHeadersComplete(), and onURL().

std::string proxygen::HTTP1xCodec::userAgent_
private

Definition at line 165 of file HTTP1xCodec.h.

Referenced by getUserAgent(), and onHeadersComplete().

std::string proxygen::HTTP1xCodec::websockAcceptKey_
mutableprivate

Definition at line 103 of file HTTP1xCodec.h.

Referenced by isReusable(), onHeadersComplete(), and serializeWebsocketHeader().


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