29 #include <boost/optional/optional_io.hpp> 37 using namespace folly;
43 { SettingsId::INITIAL_WINDOW_SIZE, 65536 }
46 { SettingsId::SETTINGS_HTTP_CERT_AUTH, 128}
49 { SettingsId::SETTINGS_HTTP_CERT_AUTH, 128}
63 .WillRepeatedly(ReturnPointee(&transportGood_));
65 .WillRepeatedly(
Assign(&transportGood_,
false));
67 .WillRepeatedly(
Return(&eventBase_));
69 .WillRepeatedly(SaveArg<0>(&transportCb_));
70 EXPECT_CALL(mockController_, getGracefulShutdownTimeout())
71 .WillRepeatedly(
Return(std::chrono::milliseconds(0)));
74 .WillRepeatedly(SaveArg<0>(&codecCallback_));
76 .WillRepeatedly(
Return(
true));
78 .WillRepeatedly(
Return(
true));
80 .WillRepeatedly(
Return(TransportDirection::DOWNSTREAM));
83 .WillRepeatedly(
Return(
true));
85 .WillRepeatedly(
Return(CodecProtocol::SPDY_3_1));
91 .WillRepeatedly(
Return(
true));
95 .WillRepeatedly(ReturnPointee(&reusable_));
97 .WillRepeatedly(ReturnPointee(&drainPending_));
100 .WillRepeatedly(
Return(65536));
103 return pushStreamID_ += 2;
106 .WillRepeatedly(
Invoke([&] { doubleGoaway_ =
true; }));
111 std::shared_ptr<folly::IOBuf>) {
114 drainPending_ = doubleGoaway_;
115 }
else if (!drainPending_) {
118 drainPending_ =
false;
121 writeBuf.
append(
string(
"x"));
126 .WillRepeatedly(
Return(1));
130 .WillRepeatedly(
Return(0));
132 HTTPSession::setDefaultReadBufferLimit(65536);
134 transactionTimeouts_.get(),
136 &mockController_, std::unique_ptr<HTTPCodec>(
codec_),
138 httpSession_->startNow();
143 std::shared_ptr<IOBuf> ,
146 if (invokeWriteSuccess_) {
149 cbs_.push_back(callback);
155 for (
auto& cb : cbs_) {
161 HTTPSession::setDefaultWriteBufferLimit(65536);
179 transportCb_->getReadBuffer(&buf, &bufSize);
180 transportCb_->readDataAvailable(bufSize);
183 void testGoaway(
bool doubleGoaway,
bool dropConnection);
185 void testConnFlowControlBlocked(
bool timeout);
200 bool reusable_{
true};
201 bool transportGood_{
true};
202 bool drainPending_{
false};
203 bool doubleGoaway_{
false};
204 bool liveGoaways_{
false};
205 bool invokeWriteSuccess_{
false};
207 std::vector<folly::AsyncTransportWrapper::WriteCallback*>
cbs_;
221 .WillOnce(
Return(&handler1))
222 .WillOnce(
Return(&handler2));
226 handler1.
txn_ = txn; }));
228 .WillOnce(
Invoke([&handler1] (std::shared_ptr<HTTPMessage>) {
236 handler2.
txn_ = txn; }));
238 .WillOnce(
Invoke([&handler2] (std::shared_ptr<HTTPMessage>) {
247 folly::to<std::string>(
"WriteTimeout on transaction id: ",
271 eventBase_.runAfterDelay(
275 }, transactionTimeouts_->getDefaultTimeout().count() / 2);
278 eventBase_.runAfterDelay(
279 [] {}, transactionTimeouts_->getDefaultTimeout().count() + 100);
292 .WillOnce(
Return(&handler));
294 .WillOnce(SaveArg<0>(&handler.
txn_));
297 .WillOnce(
Invoke([&] (std::shared_ptr<HTTPMessage>) {
307 pushHandler.
txn_ = txn; }));
331 httpSession_->dropConnection();
347 .WillOnce(
Return(&handler));
351 handler.
txn_ = txn; }));
353 .WillOnce(
Invoke([&] (std::shared_ptr<HTTPMessage>) {
372 pushHandler1.
txn_ = txn; }));
377 pushHandler2.
txn_ = txn; }));
383 folly::to<std::string>(
"StreamUnacknowledged on transaction id: ",
411 httpSession_->dropConnection();
426 .WillOnce(
Return(&handler));
430 handler.
txn_ = txn; }));
432 .WillOnce(
Invoke([&] (std::shared_ptr<HTTPMessage>) {
451 pushHandler1.
txn_ = txn; }));
457 "Stream aborted, streamID=2, code=CANCEL",
464 pushHandler2.
txn_ = txn; }));
484 httpSession_->dropConnection();
497 .WillOnce(
Return(&handler));
501 handler.
txn_ = txn; }));
503 .WillOnce(
Invoke([&] (std::shared_ptr<HTTPMessage>) {
523 pushHandler1.
txn_ = txn; }));
529 "Stream aborted, streamID=1, code=CANCEL",
536 pushHandler2.
txn_ = txn; }));
542 "Stream aborted, streamID=1, code=CANCEL",
552 "Stream aborted, streamID=1, code=CANCEL",
568 httpSession_->dropConnection();
581 .WillOnce(
Return(&handler));
583 .WillOnce(SaveArg<0>(&handler.
txn_));
586 .WillOnce(
Invoke([&] (std::shared_ptr<HTTPMessage> msg) {
590 pri.exclusive, pri.weight));
594 pushHandler.
txn_ = txn; }));
600 .WillRepeatedly(
Return(1));
606 "Downstream attempts to send ingress, abort.",
633 httpSession_->dropConnection();
643 .WillRepeatedly(
Return());
646 .WillOnce(
Return(&handler1));
650 handler1.
txn_ = txn; }));
657 httpSession_->timeoutExpired();
658 EXPECT_EQ(httpSession_->getConnectionCloseReason(),
659 ConnectionCloseReason::kMAX_REASON);
662 .WillOnce(
Invoke([&handler1] () {
669 httpSession_->timeoutExpired();
670 EXPECT_EQ(httpSession_->getConnectionCloseReason(),
671 ConnectionCloseReason::kMAX_REASON);
674 .WillRepeatedly(
Invoke([] (
676 std::shared_ptr<folly::IOBuf>,
688 httpSession_->timeoutExpired();
689 EXPECT_EQ(httpSession_->getConnectionCloseReason(),
694 httpSession_->dropConnection();
705 .WillOnce(
Return(&handler1));
709 handler1.
txn_ = txn; }));
726 codecCallback_->onPingRequest(1);
732 httpSession_->dropConnection();
742 .WillOnce(
Return(&handler1));
746 handler1.
txn_ = txn; }));
768 httpSession_->dropConnection();
775 auto chunkStr = chunk->clone()->moveToFbString();
779 httpSession_->setDefaultReadBufferLimit(10);
782 .WillOnce(
Return(&handler));
786 handler.txn_ = txn; }));
789 handler.txn_->pauseIngress();
793 .WillRepeatedly(
Invoke([&] (
795 const shared_ptr<IOBuf>&,
802 for (
int i = 0;
i < 2;
i++) {
808 .WillOnce(ExpectString(chunkStr))
809 .WillOnce(ExpectString(chunkStr));
815 eventBase_.tryRunAfterDelay([&handler,
this] {
816 handler.txn_->resumeIngress();
817 handler.sendReplyWithBody(200, 100);
818 eventBase_.runInLoop([
this] { httpSession_->dropConnection(); });
836 .WillOnce(
Return(&handler1));
840 handler1.
txn_ = txn; }));
843 codecCallback_->onSettings(
844 {{SettingsId::INITIAL_WINDOW_SIZE, 4000}});
855 eventBase_.runInLoop([
this] {
857 codecCallback_->onWindowUpdate(1, 4000);
859 eventBase_.runAfterDelay([
this] {
861 codecCallback_->onWindowUpdate(1, 6000);
863 eventBase_.runAfterDelay([
this] {
865 codecCallback_->onWindowUpdate(1, 4000);
875 eventBase_.runInLoop([
this] {
877 codecCallback_->onWindowUpdate(1, 4000);
891 std::ostringstream
stream;
892 stream << *handler1.
txn_ << *httpSession_
894 << httpSession_->getPeerAddress();
902 .WillRepeatedly(
Invoke([] (
904 std::shared_ptr<folly::IOBuf>,
909 httpSession_->dropConnection();
917 auto bufStr = buf->clone()->moveToFbString();
922 .WillOnce(
Return(&handler1));
926 handler1.
txn_ = txn; }));
930 eventBase_.tryRunAfterDelay([&handler1] {
935 .WillOnce(
Invoke([&handler1, &bufStr] (
936 std::shared_ptr<folly::IOBuf> chain) {
937 EXPECT_EQ(bufStr, chain->moveToFbString());
957 .WillRepeatedly(
Invoke([] (
959 std::shared_ptr<folly::IOBuf>,
965 httpSession_->dropConnection();
975 auto wantToWriteStr = folly::to<string>(wantToWrite);
982 invokeWriteSuccess_ =
true;
985 .WillOnce(
Return(&handler1));
987 .WillOnce(SaveArg<0>(&handler1.txn_));
997 unsigned bodyLen = 0;
1001 std::shared_ptr<folly::IOBuf> chain,
1004 bodyLen += chain->computeChainDataLength();
1008 codecCallback_->onMessageBegin(1, req1.get());
1009 codecCallback_->onHeadersComplete(1,
std::move(req1));
1010 codecCallback_->onWindowUpdate(1, wantToWrite);
1012 handler1.txn_->sendHeaders(*resp1);
1013 handler1.txn_->sendBody(
makeBuf(wantToWrite));
1014 handler1.txn_->sendEOM();
1019 .WillOnce(
Return(&handler2));
1021 .WillOnce(SaveArg<0>(&handler2.txn_));
1032 auto writeCount = writeCount_;
1035 codecCallback_->onMessageBegin(3, req2.get());
1036 codecCallback_->onHeadersComplete(3,
std::move(req2));
1037 handler2.txn_->sendHeaders(*resp2);
1055 codecCallback_->onWindowUpdate(1, 1);
1058 eventBase_.runAfterDelay([] {}, 500);
1060 transactionTimeouts_->cancelAll();
1064 codecCallback_->onWindowUpdate(0, 10);
1071 codecCallback_->onAbort(handler1.txn_->getID(),
1072 ErrorCode::INTERNAL_ERROR);
1077 httpSession_->dropConnection();
1084 testConnFlowControlBlocked(
false);
1088 testConnFlowControlBlocked(
true);
1096 unsigned kNumChunks = 10;
1098 auto wantToWriteStr = folly::to<string>(wantToWrite);
1100 auto req1Body =
makeBuf(wantToWrite);
1103 .WillOnce(
Return(&handler1));
1105 .WillOnce(SaveArg<0>(&handler1.txn_));
1108 for (
unsigned i = 0;
i < kNumChunks; ++
i) {
1115 codecCallback_->onMessageBegin(1, req1.get());
1116 codecCallback_->onHeadersComplete(1,
std::move(req1));
1119 for (
unsigned i = 0;
i < kNumChunks; ++
i) {
1122 codecCallback_->onMessageComplete(1,
false);
1126 httpSession_->dropConnection();
1136 unique_ptr<HTTPMessage> resp;
1137 unique_ptr<folly::IOBuf> respBody;
1142 .WillOnce(
Return(&handler1));
1144 .WillOnce(SaveArg<0>(&handler1.txn_));
1149 handler1.txn_->pauseIngress();
1155 std::shared_ptr<folly::IOBuf> chain,
1158 auto len = chain->computeChainDataLength();
1163 codecCallback_->onWindowUpdate(0, respSize);
1164 codecCallback_->onMessageBegin(1, req.get());
1165 codecCallback_->onHeadersComplete(1,
std::move(req));
1169 codecCallback_->onWindowUpdate(1, respSize);
1170 handler1.txn_->sendHeaders(*resp);
1171 handler1.txn_->sendBody(
std::move(respBody));
1178 httpSession_->dropConnection();
1185 .WillRepeatedly(
Return(
true));
1193 .WillOnce(
Return(&handler));
1195 .WillOnce(SaveArg<0>(&handler.txn_));
1198 .WillOnce(
Invoke([&] (std::shared_ptr<HTTPMessage>) {
1199 auto pushTxn = handler.txn_->newPushedTransaction(&pushHandler);
1201 httpSession_->notifyPendingShutdown();
1205 handler.txn_->getPriority());
1211 .WillOnce(SaveArg<0>(&pushHandler.
txn_));
1217 handler.sendReply();
1223 codecCallback_->onMessageBegin(1, req.get());
1224 codecCallback_->onHeadersComplete(1,
std::move(req));
1225 codecCallback_->onMessageComplete(1,
false);
1230 httpSession_->dropConnection();
1246 transportCb_->getReadBuffer(&buf, &bufSize);
1247 transportCb_->readDataAvailable(bufSize);
1261 httpSession_->closeWhenIdle();
1276 bool dropConnection) {
1280 liveGoaways_ =
true;
1283 .WillOnce(
Return(&handler));
1285 .WillOnce(SaveArg<0>(&handler.txn_));
1290 handler.sendReply();
1297 codec_->enableDoubleGoawayDrain();
1302 httpSession_->notifyPendingShutdown();
1309 codecCallback_->onMessageBegin(1, req1.get());
1310 codecCallback_->onHeadersComplete(1,
std::move(req1));
1311 codecCallback_->onMessageComplete(1,
false);
1317 const shared_ptr<IOBuf>,
1322 if (doubleGoaway || !dropConnection) {
1326 eventBase_.loopOnce();
1329 if (dropConnection) {
1339 httpSession_->dropConnection();
1342 httpSession_->closeWhenIdle();
1350 testGoaway(
true,
true);
1353 testGoaway(
true,
false);
1356 testGoaway(
false,
true);
1359 testGoaway(
false,
false);
1366 liveGoaways_ =
true;
1372 .WillOnce(
Assign(&transportGood_,
false));
1373 httpSession_->dropConnection();
1380 liveGoaways_ =
false;
1386 .WillOnce(
Assign(&transportGood_,
false));
1387 httpSession_->dropConnection();
1396 HTTPException err(HTTPException::Direction::INGRESS,
"foo");
1400 .WillOnce(
Return(
nullptr));
1403 codecCallback_->onMessageBegin(1, &req);
1405 httpSession_->closeWhenIdle();
1407 codecCallback_->onError(1, err,
false);
1411 eventBase_.loopOnce();
1423 httpSession_->closeWhenIdle();
1428 codecCallback_->onPingRequest(1);
1437 codecCallback_->onSettings(
1438 {{SettingsId::INITIAL_WINDOW_SIZE, 4000}});
1441 httpSession_->dropConnection();
1448 SignatureScheme::ecdsa_secp256r1_sha256);
1449 std::vector<fizz::Extension> extensions;
1452 std::unique_ptr<StrictMock<MockSecondaryAuthManager>> secondAuthManager_(
1454 httpSession_->setSecondAuthManager(
std::move(secondAuthManager_));
1456 httpSession_->getSecondAuthManager());
1467 auto encodedSize = httpSession_->sendCertificateRequest(
1473 httpSession_->dropConnection();
folly::HHWheelTimer::UniquePtr makeInternalTimeoutSet(EventBase *evb)
virtual void resumeIngress()
void setHttpStatusCode(uint32_t statusCode)
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
const uint32_t kInitialWindow
void timeoutExpired() noexceptoverride
GTEST_API_ Cardinality AtLeast(int n)
ProxygenError getProxygenError() const
#define ASSERT_EQ(val1, val2)
void testConnFlowControlBlocked(bool timeout)
const SocketAddress peerAddr
bool hasCodecStatusCode() const
StreamCodecFactory stream
http2::PriorityUpdate getPriority() const
#define EXPECT_EQ(val1, val2)
constexpr detail::Map< Move > move
EventBase * getEventBase()
void onWriteChain(folly::AsyncTransportWrapper::WriteCallback *callback, std::shared_ptr< IOBuf >, WriteFlags)
HTTPDownstreamSession * httpSession_
void sendReplyWithBody(uint32_t code, uint32_t content_length, bool keepalive=true, bool sendEOM=true, bool hasTrailers=false)
—— Concurrent Priority Queue Implementation ——
const wangle::TransportInfo mockTransportInfo
std::unique_ptr< Codec > codec_
std::unique_ptr< HTTPMessage > makePostRequest(uint32_t contentLength)
PolymorphicAction< internal::InvokeWithoutArgsAction< FunctionImpl > > InvokeWithoutArgs(FunctionImpl function_impl)
internal::ReturnRefAction< R > ReturnRef(R &x)
~MockCodecDownstreamTest() override
void handler(int, siginfo_t *, void *)
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
void writeBuf(const Buf &buf, folly::io::Appender &out)
std::unique_ptr< AsyncTransportWrapper, Destructor > UniquePtr
void getLocalAddress(folly::SocketAddress &addr) const
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
void testGoaway(bool doubleGoaway, bool dropConnection)
const HTTPSettings kIngressCertAuthSettings
std::size_t length() const
ErrorCode getCodecStatusCode() const
void sendHeaders(uint32_t code, uint32_t content_length, bool keepalive=true, HeaderMap headers=HeaderMap())
std::vector< SignatureScheme > supported_signature_algorithms
StrictMock< MockController > mockController_
HTTPSettings kEgressCertAuthSettings
void fakeMockCodec(MockHTTPCodec &codec)
std::vector< folly::AsyncTransportWrapper::WriteCallback * > cbs_
virtual void pauseIngress()
void sendBody(uint32_t content_length)
std::unique_ptr< HHWheelTimer, Destructor > UniquePtr
std::unique_ptr< HTTPMessage > makeResponse(uint16_t statusCode)
MockCodecDownstreamTest()
bool hasProxygenError() const
virtual HTTPTransaction * newPushedTransaction(HTTPPushTransactionHandler *handler)
folly::AsyncTransportWrapper::ReadCallback * transportCb_
StrictMock< MockHTTPCodec > * codec_
std::size_t computeChainDataLength() const
#define EXPECT_TRUE(condition)
void sendPushHeaders(const std::string &path, const std::string &host, uint32_t content_length, http2::PriorityUpdate pri)
HTTPMessage getGetRequest(const std::string &url)
AsyncFizzClient::UniquePtr transport_
folly::HHWheelTimer::UniquePtr transactionTimeouts_
const SocketAddress localAddr
PolymorphicAction< internal::AssignAction< T1, T2 > > Assign(T1 *ptr, T2 val)
internal::DoBothAction< Action1, Action2 > DoAll(Action1 a1, Action2 a2)
std::unique_ptr< HTTPMessage > makeGetRequest()
#define EXPECT_CALL(obj, call)
const internal::AnythingMatcher _
virtual void writeSuccess() noexcept=0
virtual void writeErr(size_t bytesWritten, const AsyncSocketException &ex) noexcept=0
#define EXPECT_FALSE(condition)
Extension encodeExtension(const TokenBindingParameters ¶ms)
HTTPCodec::StreamID getID() const
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
const char * what(void) const noexceptoverride
const HTTPSettings kDefaultIngressSettings
NiceMock< MockAsyncTransport > * transport_
internal::ReturnAction< R > Return(R value)
TEST_F(AcceptorTest, TestCanAcceptWithNoConnectionCounter)