proxygen
HTTPUpstreamSession.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  */
12 
17 
18 namespace proxygen {
19 
21 
23  return sock_ ? sock_->isReplaySafe() : false;
24 }
25 
27  VLOG(4) << "isReusable: " << *this
28  << ", liveTransactions_=" << liveTransactions_
29  << ", isClosing()=" << isClosing()
30  << ", sock_->connecting()=" << sock_->connecting()
31  << ", codec_->isReusable()=" << codec_->isReusable()
32  << ", codec_->isBusy()=" << codec_->isBusy()
33  << ", numActiveWrites_=" << numActiveWrites_
34  << ", writeTimeout_.isScheduled()=" << writeTimeout_.isScheduled()
35  << ", ingressError_=" << ingressError_
36  << ", hasMoreWrites()=" << hasMoreWrites()
37  << ", codec_->supportsParallelRequests()="
39  return
40  !isClosing() &&
41  !sock_->connecting() &&
42  codec_->isReusable() &&
43  !codec_->isBusy() &&
44  !ingressError_ &&
46  // These conditions only apply to serial codec sessions
47  !hasMoreWrites() &&
48  liveTransactions_ == 0 &&
50 }
51 
53  VLOG(5) << "isClosing: " << *this
54  << ", sock_->good()=" << sock_->good()
55  << ", draining_=" << draining_
56  << ", readsShutdown()=" << readsShutdown()
57  << ", writesShutdown()=" << writesShutdown()
58  << ", writesDraining_=" << writesDraining_
59  << ", resetAfterDrainingWrites_=" << resetAfterDrainingWrites_;
60  return
61  !sock_->good() ||
62  draining_ ||
63  readsShutdown() ||
64  writesShutdown() ||
67 }
68 
70  // startNow in base class CHECKs this session has not started.
72  // Upstream specific:
73  // create virtual priority nodes and send Priority frames to peer if necessary
74  if (priorityMapFactory_) {
75  priorityAdapter_ = priorityMapFactory_->createVirtualStreams(this);
76  scheduleWrite();
77  } else {
78  // TODO/T17420249 Move this to the PriorityAdapter and remove it from the
79  // codec.
80  auto bytes = codec_->addPriorityNodes(
82  writeBuf_,
84  if (bytes) {
85  scheduleWrite();
86  }
87  }
88 }
89 
93  // This session doesn't support any more parallel transactions
94  return nullptr;
95  }
96 
97  if (!started_) {
98  startNow();
99  }
100 
103 
104  if (txn) {
105  DestructorGuard dg(this);
106  auto txnID = txn->getID();
107  txn->setHandler(CHECK_NOTNULL(handler));
109  }
110  return txn;
111 }
112 
114  HTTPTransaction* /*txn*/) {
115  // No special handler for upstream requests that time out
116  return nullptr;
117 }
118 
120  for (const auto& txn: transactions_) {
121  if (!txn.second.isPushed() && !txn.second.isEgressStarted()) {
122  return false;
123  }
124  }
125  return true;
126 }
127 
130  const std::string& protocolString,
131  HTTPMessage&) {
132 
133  VLOG(4) << *this << " onNativeProtocolUpgrade streamID=" << streamID <<
134  " protocol=" << protocolString;
135 
136  if (protocol != CodecProtocol::HTTP_2) {
137  return false;
138  }
139 
140  // Create the new Codec
141  std::unique_ptr<HTTPCodec> codec =
142  std::make_unique<HTTP2Codec>(TransportDirection::UPSTREAM);
143 
144  bool ret = onNativeProtocolUpgradeImpl(streamID, std::move(codec),
145  protocolString);
146  if (ret) {
147  auto bytes = codec_->addPriorityNodes(
149  writeBuf_,
151  if (bytes) {
152  scheduleWrite();
153  }
154  }
155  return ret;
156 }
157 
159  while (!transactions_.empty()) {
160  auto txn = transactions_.begin();
161  detach(&txn->second);
162  }
163 }
164 
165 bool HTTPUpstreamSession::isDetachable(bool checkSocket) const {
166  if (checkSocket && sock_ && !sock_->isDetachable()) {
167  return false;
168  }
169  return transactions_.size() == 0 && getNumIncomingStreams() == 0 &&
170  !writesPaused();
171 }
172 
173 void
175  folly::EventBase* eventBase,
176  folly::SSLContextPtr sslContext,
177  const WheelTimerInstance& timeout,
179  HeaderCodec::Stats* headerCodecStats,
180  HTTPSessionController* controller) {
182  timeout_ = timeout;
183  setController(controller);
184  setSessionStats(stats);
185  if (sock_) {
186  sock_->attachEventBase(eventBase);
187  maybeAttachSSLContext(sslContext);
188  }
189  codec_.foreach(fn);
190  codec_->setHeaderCodecStats(headerCodecStats);
191  resumeReadsImpl();
193 }
194 
196  folly::SSLContextPtr sslContext) const {
197 #ifndef NO_ASYNCSSLSOCKET
198  auto sslSocket = sock_->getUnderlyingTransport<folly::AsyncSSLSocket>();
199  if (sslSocket && sslContext) {
200  sslSocket->attachSSLContext(sslContext);
201  }
202 #endif
203 }
204 
205 void
207  CHECK(transactions_.empty());
209  pauseReadsImpl();
210  if (sock_) {
211  if (detachSSLContext) {
213  }
214  sock_->detachEventBase();
215  }
217  setController(nullptr);
218  setSessionStats(nullptr);
219  // The codec filters *shouldn't* be accessible while the socket is detached,
220  // I hope
221  codec_->setHeaderCodecStats(nullptr);
222  auto cm = getConnectionManager();
223  if (cm) {
224  cm->removeConnection(this);
225  }
226 }
227 
229 #ifndef NO_ASYNCSSLSOCKET
230  auto sslSocket = sock_->getUnderlyingTransport<folly::AsyncSSLSocket>();
231  if (sslSocket) {
232  sslSocket->detachSSLContext();
233  }
234 #endif
235 }
236 
237 } // proxygen
void detachThreadLocals(bool detachSSLContext=false) override
HTTPTransaction * createTransaction(HTTPCodec::StreamID streamID, const folly::Optional< HTTPCodec::StreamID > &assocStreamID, const folly::Optional< HTTPCodec::ExAttributes > &exAttributes, const http2::PriorityUpdate &priority=http2::DefaultPriority)
bool onNativeProtocolUpgradeImpl(HTTPCodec::StreamID txn, std::unique_ptr< HTTPCodec > codec, const std::string &protocolString)
virtual StreamID createStream()=0
void setSessionStats(HTTPSessionStats *stats) override
void foreach(folly::FunctionRef< void(FilterChainType *)> fn)
Definition: FilterChain.h:349
HTTPTransaction * newTransaction(HTTPTransaction::Handler *handler) override
HTTPCodecFilterChain codec_
std::unique_ptr< PriorityAdapter > priorityAdapter_
void rescheduleLoopCallbacks()
Definition: HTTPSession.h:650
WriteTimeout writeTimeout_
Definition: HTTPSession.h:681
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
CodecFactory codec
void setNewTransactionPauseState(HTTPCodec::StreamID streamID)
bool writesPaused() const
Definition: HTTPSession.h:642
folly::AsyncTransportWrapper::UniquePtr sock_
Definition: HTTPSession.h:697
HTTP2PriorityQueue txnEgressQueue_
Definition: HTTPSession.h:690
void startNow() override
bool isReplaySafe() const override
WheelTimerInstance timeout_
Definition: HTTPSession.h:699
void handler(int, siginfo_t *, void *)
void attachThreadLocals(const WheelTimerInstance &timeout)
class HTTP2PriorityQueue
std::function< void(HTTPCodecFilter *)> FilterIteratorFn
HTTPTransaction::Handler * getTransactionTimeoutHandler(HTTPTransaction *txn) override
std::shared_ptr< SSLContext > SSLContextPtr
Definition: SSLContext.h:628
void maybeAttachSSLContext(folly::SSLContextPtr sslContext) const
virtual size_t addPriorityNodes(PriorityQueue &, folly::IOBufQueue &, uint8_t)
Definition: HTTPCodec.h:696
bool readsShutdown() const
Definition: HTTPSession.h:634
ConnectionManager * getConnectionManager()
bool writesShutdown() const
Definition: HTTPSession.h:646
uint32_t liveTransactions_
Definition: HTTPSession.h:695
std::shared_ptr< const PriorityMapFactory > priorityMapFactory_
void attachThreadLocals(folly::EventBase *eventBase, folly::SSLContextPtr sslContext, const WheelTimerInstance &timeout, HTTPSessionStats *stats, FilterIteratorFn fn, HeaderCodec::Stats *headerCodecStats, HTTPSessionController *controller) override
std::map< HTTPCodec::StreamID, HTTPTransaction > transactions_
Definition: HTTPSession.h:692
folly::IOBufQueue writeBuf_
Definition: HTTPSession.h:684
void setController(HTTPSessionController *controller)
const char * string
Definition: Conv.cpp:212
bool onNativeProtocolUpgrade(HTTPCodec::StreamID streamID, CodecProtocol protocol, const std::string &protocolString, HTTPMessage &msg) override
virtual bool isReusable() const =0
static const folly::Optional< StreamID > NoStream
Definition: HTTPCodec.h:51
uint64_t StreamID
Definition: HTTPCodec.h:49
uint32_t getNumIncomingStreams() const override
Definition: HTTPSession.h:84
virtual void setHeaderCodecStats(HeaderCodec::Stats *)
Definition: HTTPCodec.h:670
bool allTransactionsStarted() const override
void detach(HTTPTransaction *txn) noexceptoverride
bool isDetachable(bool checkSocket=true) const override
uint32_t streamID
Definition: SPDYCodec.cpp:131
virtual bool isBusy() const =0
virtual bool supportsParallelRequests() const =0
bool supportsMoreTransactions() const
bool hasMoreWrites() const
static const folly::Optional< ExAttributes > NoExAttributes
Definition: HTTPCodec.h:66