nghttpx: Fix crash with backend failure
This commit is contained in:
parent
53989dc70c
commit
0af9629cc1
|
@ -97,9 +97,6 @@ int Http2DownstreamConnection::attach_downstream(Downstream *downstream) {
|
|||
http2session_->add_downstream_connection(this);
|
||||
if (http2session_->get_state() == Http2Session::DISCONNECTED) {
|
||||
http2session_->signal_write();
|
||||
if (http2session_->get_state() == Http2Session::DISCONNECTED) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
downstream_ = downstream;
|
||||
|
|
|
@ -165,6 +165,22 @@ void writecb(struct ev_loop *loop, ev_io *w, int revents) {
|
|||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
void initiate_connection_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
||||
auto http2session = static_cast<Http2Session *>(w->data);
|
||||
ev_timer_stop(loop, w);
|
||||
if (http2session->initiate_connection() != 0) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
SSLOG(INFO, http2session) << "Could not initiate backend connection";
|
||||
}
|
||||
http2session->disconnect(true);
|
||||
assert(http2session->get_num_dconns() == 0);
|
||||
delete http2session;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
|
||||
Worker *worker, DownstreamAddrGroup *group)
|
||||
: dlnext(nullptr),
|
||||
|
@ -199,6 +215,9 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
|
|||
ev_timer_init(&settings_timer_, settings_timeout_cb, 0., 10.);
|
||||
|
||||
settings_timer_.data = this;
|
||||
|
||||
ev_timer_init(&initiate_connection_timer_, initiate_connection_cb, 0., 0.);
|
||||
initiate_connection_timer_.data = this;
|
||||
}
|
||||
|
||||
Http2Session::~Http2Session() {
|
||||
|
@ -224,6 +243,7 @@ int Http2Session::disconnect(bool hard) {
|
|||
conn_.rlimit.stopw();
|
||||
conn_.wlimit.stopw();
|
||||
|
||||
ev_timer_stop(conn_.loop, &initiate_connection_timer_);
|
||||
ev_timer_stop(conn_.loop, &settings_timer_);
|
||||
ev_timer_stop(conn_.loop, &connchk_timer_);
|
||||
|
||||
|
@ -1600,14 +1620,15 @@ int Http2Session::downstream_write() {
|
|||
void Http2Session::signal_write() {
|
||||
switch (state_) {
|
||||
case Http2Session::DISCONNECTED:
|
||||
if (!ev_is_active(&initiate_connection_timer_)) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
LOG(INFO) << "Start connecting to backend server";
|
||||
}
|
||||
if (initiate_connection() != 0) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
SSLOG(INFO, this) << "Could not initiate backend connection";
|
||||
}
|
||||
disconnect(true);
|
||||
// Since the timer is set to 0., these will feed 2 events. We
|
||||
// will stop the timer in the initiate_connection_timer_ to void
|
||||
// 2nd event.
|
||||
ev_timer_start(conn_.loop, &initiate_connection_timer_);
|
||||
ev_feed_event(conn_.loop, &initiate_connection_timer_, 0);
|
||||
}
|
||||
break;
|
||||
case Http2Session::CONNECTED:
|
||||
|
|
|
@ -211,6 +211,8 @@ private:
|
|||
// connection check has started, this timer is started again and
|
||||
// traps PING ACK timeout.
|
||||
ev_timer connchk_timer_;
|
||||
// timer to initiate connection. usually, this fires immediately.
|
||||
ev_timer initiate_connection_timer_;
|
||||
DList<Http2DownstreamConnection> dconns_;
|
||||
DList<StreamData> streams_;
|
||||
std::function<int(Http2Session &)> read_, write_;
|
||||
|
|
Loading…
Reference in New Issue