HTTPSession::transactionTimeout(HTTPTransaction* txn) noexcept {
  // A transaction has timed out.  If the transaction does not have
  // a Handler yet, because we haven't yet received the full request
  // headers, we give it a DirectResponseHandler that generates an
  // error page.
  VLOG(3) << "Transaction timeout for streamID=" << txn->getID();
  if (!codec_->supportsParallelRequests()) {
    // this error should only prevent us from reading/handling more errors
    // on serial streams
    ingressError_ = true;
  }

  if (!txn->getHandler() &&
      txn->getEgressState() == HTTPTransactionEgressSM::State::Start) {
    VLOG(4) << *this << " Timed out receiving headers";
    if (infoCallback_) {
      infoCallback_->onIngressError(*this, kErrorTimeout);
    }
    if (codec_->supportsParallelRequests()) {
      // This can only happen with HTTP/2 where the HEADERS frame is incomplete
      // and we time out waiting for the CONTINUATION.  Abort the request.
      //
      // It would maybe be a little nicer to use the timeout handler for these
      // also.
      txn->sendAbort();
      return;
    }

    VLOG(4) << *this << " creating direct error handler";
    auto handler = getTransactionTimeoutHandler(txn);
    txn->setHandler(handler);
  }

  // Tell the transaction about the timeout.  The transaction will
  // communicate the timeout to the handler, and the handler will
  // decide how to proceed.
  txn->onIngressTimeout();
}
HTTPSession::transactionTimeout(HTTPTransaction* txn) noexcept {
   
   
   
   
  VLOG(3) << "Transaction timeout for streamID=" << txn->getID();
  if (!codec_->supportsParallelRequests()) {
     
     
    ingressError_ = true;
  }

  if (!txn->getHandler() &&
      txn->getEgressState() == HTTPTransactionEgressSM::State::Start) {
    VLOG(4) << *this << " Timed out receiving headers";
    if (infoCallback_) {
      infoCallback_->onIngressError(*this, kErrorTimeout);
    }
    if (codec_->supportsParallelRequests()) {
       
       
       
       
       
      txn->sendAbort();
      return;
    }

    VLOG(4) << *this << " creating direct error handler";
    auto handler = getTransactionTimeoutHandler(txn);
    txn->setHandler(handler);
  }

   
   
   
  txn->onIngressTimeout();
}