proxygen
HTTPDownstreamSession.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
11 
15 
16 #include <folly/CppAttributes.h>
17 
18 namespace proxygen {
19 
21 }
22 
23 void
25  // Create virtual nodes should happen before startNow since ingress may come
26  // before we can finish startNow. Since maxLevel = 0, this is a no-op unless
27  // SPDY is used. And no frame will be sent to peer, so ignore returned value.
30 }
31 
32 void
34  HTTPMessage* msg) {
35  VLOG(5) << "setupOnHeadersComplete txn=" << txn << ", id=" << txn->getID()
36  << ", handlder=" << txn->getHandler() << ", msg=" << msg;
37  if (txn->getHandler()) {
38  // handler is installed before setupOnHeadersComplete callback. It must be
39  // an EX_HEADERS from client side, and ENABLE_EX_HEADERS == 1
40  const auto* settings = codec_->getIngressSettings();
41  CHECK(settings && settings->getSetting(SettingsId::ENABLE_EX_HEADERS, 0));
42  CHECK(txn->getControlStream());
43  return;
44  }
45 
46  // We need to find a Handler to process the transaction.
47  // Note: The handler is responsible for freeing itself
48  // when it has finished processing the transaction. The
49  // transaction is responsible for freeing itself when both the
50  // ingress and egress messages have completed (or failed).
52 
53  // In the general case, delegate to the handler factory to generate
54  // a handler for the transaction.
55  handler = getController()->getRequestHandler(*txn, msg);
56  CHECK(handler);
57 
58  DestructorGuard dg(this);
59  auto txnID = txn->getID();
60  txn->setHandler(handler);
62 }
63 
66  HTTPTransaction* txn) {
68 }
69 
70 void
72  bool codecWasReusable) {
73  if (!codec_->isReusable()) {
74  // If the codec turned unreusable, some thing wrong must have happened.
75  // Basically, the proxy decides the connection is not reusable.
76  // e.g, an error message is being sent with Connection: close
77  if (codecWasReusable) {
78  uint32_t statusCode = headers.getStatusCode();
79  if (statusCode >= 500) {
81  } else {
82  if (statusCode >= 400) {
84  } else {
85  // should not be here
87  }
88  }
89  } else {
90  // shouldn't happen... this case is detected by REQ_NOTREUSABLE
92  }
93  }
94 }
95 
97  for (const auto& txn: transactions_) {
98  if (txn.second.isPushed() && !txn.second.isEgressStarted()) {
99  return false;
100  }
101  }
102  return true;
103 }
104 
105 bool
108  const std::string& protocolString,
109  HTTPMessage& msg) {
110  VLOG(4) << *this << " onNativeProtocolUpgrade streamID=" << streamID <<
111  " protocol=" << protocolString;
112  auto txn = findTransaction(streamID);
113  CHECK(txn);
114  if (txn->canSendHeaders()) {
115  // Create the new Codec
116  auto codec = HTTPCodecFactory::getCodec(protocol,
118  CHECK(codec);
119  if (!codec->onIngressUpgradeMessage(msg)) {
120  VLOG(4) << *this << " codec rejected upgrade";
121  return false;
122  }
123 
124  // Send a 101 Switching Protocols message while we still have HTTP codec
125  // Note: it's possible that the client timed out waiting for a
126  // 100-continue and ended up here first. In this case the 100 may go
127  // out in the new protocol
128  HTTPMessage switchingProtos;
129  switchingProtos.setHTTPVersion(1, 1);
130  switchingProtos.setStatusCode(101);
131  switchingProtos.setStatusMessage("Switching Protocols");
132  switchingProtos.getHeaders().set(HTTP_HEADER_UPGRADE, protocolString);
133  switchingProtos.getHeaders().set(HTTP_HEADER_CONNECTION, "Upgrade");
134  txn->sendHeaders(switchingProtos);
135  // no sendEOM for 1xx
136 
137  // This will actually switch the protocol
139  streamID, std::move(codec), protocolString);
140  if (ret) {
142  }
143  return ret;
144  } else {
145  VLOG(4) << *this << " plaintext upgrade failed due to early response";
146  return false;
147  }
148 }
149 
150 } // proxygen
virtual const HTTPSettings * getIngressSettings() const
Definition: HTTPCodec.h:657
virtual void setHandler(Handler *handler)
bool onNativeProtocolUpgradeImpl(HTTPCodec::StreamID txn, std::unique_ptr< HTTPCodec > codec, const std::string &protocolString)
spdy::GoawayStatusCode statusCode
Definition: SPDYCodec.cpp:110
HTTPCodecFilterChain codec_
HTTPTransaction * findTransaction(HTTPCodec::StreamID streamID)
virtual std::unique_ptr< HTTPCodec > getCodec(const std::string &protocolHint, TransportDirection direction, bool isTLS)=0
virtual HTTPTransactionHandler * getRequestHandler(HTTPTransaction &txn, HTTPMessage *msg)=0
void setStatusMessage(T &&msg)
Definition: HTTPMessage.h:242
uint16_t getStatusCode() const
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
CodecFactory codec
void setNewTransactionPauseState(HTTPCodec::StreamID streamID)
HTTPTransaction::Handler * getTransactionTimeoutHandler(HTTPTransaction *txn) override
HTTP2PriorityQueue txnEgressQueue_
Definition: HTTPSession.h:690
static http_parser_settings settings
Definition: test.c:1529
const folly::SocketAddress & getLocalAddress() const noexceptoverride
Definition: HTTPSession.h:122
void setupOnHeadersComplete(HTTPTransaction *txn, HTTPMessage *msg) override
void startNow() override
virtual HTTPTransactionHandler * getTransactionTimeoutHandler(HTTPTransaction *txn, const folly::SocketAddress &localAddress)=0
bool onNativeProtocolUpgrade(HTTPCodec::StreamID streamID, CodecProtocol protocol, const std::string &protocolString, HTTPMessage &msg) override
void handler(int, siginfo_t *, void *)
void set(folly::StringPiece name, const std::string &value)
Definition: HTTPHeaders.h:119
HTTPSessionController * getController()
void setCloseReason(ConnectionCloseReason reason)
virtual size_t addPriorityNodes(PriorityQueue &, folly::IOBufQueue &, uint8_t)
Definition: HTTPCodec.h:696
const Handler * getHandler() const
HTTPHeaders & getHeaders()
Definition: HTTPMessage.h:273
folly::Optional< HTTPCodec::StreamID > getControlStream() const
std::map< HTTPCodec::StreamID, HTTPTransaction > transactions_
Definition: HTTPSession.h:692
folly::IOBufQueue writeBuf_
Definition: HTTPSession.h:684
const char * string
Definition: Conv.cpp:212
void setHTTPVersion(uint8_t major, uint8_t minor)
virtual bool isReusable() const =0
uint64_t StreamID
Definition: HTTPCodec.h:49
bool allTransactionsStarted() const override
HTTPCodec::StreamID getID() const
uint32_t streamID
Definition: SPDYCodec.cpp:131
void onHeadersSent(const HTTPMessage &headers, bool codecWasReusable) override
void setStatusCode(uint16_t status)