HTTPSession::onMessageComplete(HTTPCodec::StreamID streamID,
                               bool upgrade) {
  DestructorGuard dg(this);
  // The codec's parser detected the end of the ingress message for
  // this transaction.
  VLOG(4) << "processing ingress message complete for " << *this <<
    ", streamID=" << streamID;
  HTTPTransaction* txn = findTransaction(streamID);
  if (!txn) {
    invalidStream(streamID);
    return;
  }

  if (upgrade) {
    /* Send the upgrade callback to the transaction and the handler.
     * Currently we support upgrades for only HTTP sessions and not SPDY
     * sessions.
     */
    ingressUpgraded_ = true;
    txn->onIngressUpgrade(UpgradeProtocol::TCP);
    return;
  }

  // txnIngressFinished = !1xx response
  const bool txnIngressFinished =
    txn->isDownstream() || !txn->extraResponseExpected();
  if (txnIngressFinished) {
    decrementTransactionCount(txn, true, false);
  }
  txn->onIngressEOM();

  // The codec knows, based on the semantics of whatever protocol it
  // supports, whether it's valid for any more ingress messages to arrive
  // after this one.  For example, an HTTP/1.1 request containing
  // "Connection: close" indicates the end of the ingress, whereas a
  // SPDY session generally can handle more messages at any time.
  //
  // If the connection is not reusable, we close the read side of it
  // but not the write side.  There are two reasons why more writes
  // may occur after this point:
  //   * If there are previous writes buffered up in the pendingWrites_
  //     queue, we need to attempt to complete them.
  //   * The Handler associated with the transaction may want to
  //     produce more egress data when the ingress message is fully
  //     complete.  (As a common example, an application that handles
  //     form POSTs may not be able to even start generating a response
  //     until it has received the full request body.)
  //
  // There may be additional checks that need to be performed that are
  // specific to requests or responses, so we call the subclass too.
  if (!codec_->isReusable() &&
      txnIngressFinished &&
      !codec_->supportsParallelRequests()) {
    VLOG(4) << *this << " cannot reuse ingress";
    shutdownTransport(true, false);
  }
}
HTTPSession::onMessageComplete(HTTPCodec::StreamID streamID,
                               bool upgrade) {
  DestructorGuard dg(this);
   
   
  VLOG(4) << "processing ingress message complete for " << *this <<
    ", streamID=" << streamID;
  HTTPTransaction* txn = findTransaction(streamID);
  if (!txn) {
    invalidStream(streamID);
    return;
  }

  if (upgrade) {
     
    ingressUpgraded_ = true;
    txn->onIngressUpgrade(UpgradeProtocol::TCP);
    return;
  }

   
  const bool txnIngressFinished =
    txn->isDownstream() || !txn->extraResponseExpected();
  if (txnIngressFinished) {
    decrementTransactionCount(txn, true, false);
  }
  txn->onIngressEOM();

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
  if (!codec_->isReusable() &&
      txnIngressFinished &&
      !codec_->supportsParallelRequests()) {
    VLOG(4) << *this << " cannot reuse ingress";
    shutdownTransport(true, false);
  }
}