void HQStreamCodec::onHeadersComplete()

in proxygen/lib/http/codec/HQStreamCodec.cpp [205:266]


void HQStreamCodec::onHeadersComplete(HTTPHeaderSize decodedSize,
                                      bool acknowledge) {
  CHECK(parserPaused_);
  decodeInfo_.onHeadersComplete(decodedSize);
  auto resumeParser = folly::makeGuard([this] { setParserPaused(false); });
  auto g2 = folly::makeGuard(activationHook_());

  // Check parsing error
  DCHECK_EQ(decodeInfo_.decodeError, HPACK::DecodeError::NONE);
  // Leave msg in decodeInfo_ for now, to keep the parser paused
  if (!decodeInfo_.parsingError.empty()) {
    LOG(ERROR) << "Failed parsing header list for stream=" << streamId_
               << ", error=" << decodeInfo_.parsingError;
    if (!decodeInfo_.headerErrorValue.empty()) {
      std::cerr << " value=" << decodeInfo_.headerErrorValue << std::endl;
    }
    HTTPException err(
        HTTPException::Direction::INGRESS,
        fmt::format("HQStreamCodec stream error: stream={} status={} error:{}",
                    streamId_,
                    400,
                    decodeInfo_.parsingError));
    if (parsingTrailers_) {
      err.setHttp3ErrorCode(HTTP3::ErrorCode::HTTP_MESSAGE_ERROR);
    } else {
      err.setHttpStatusCode(400);
    }
    err.setProxygenError(kErrorParseHeader);
    callback_->onError(streamId_, err, true);
    resumeParser.dismiss();
    return;
  }
  std::unique_ptr<HTTPMessage> msg = std::move(decodeInfo_.msg);
  msg->setAdvancedProtocolString(getCodecProtocolString(CodecProtocol::HQ));

  if (curHeader_.type == hq::FrameType::HEADERS) {
    if (!finalIngressHeadersSeen_ &&
        (msg->isRequest() || !msg->is1xxResponse())) {
      finalIngressHeadersSeen_ = true;
    }
  }

  if (transportDirection_ == TransportDirection::DOWNSTREAM &&
      msg->getMethod() == HTTPMethod::CONNECT) {
    isConnect_ = true;
  }

  if (acknowledge) {
    qpackDecoderWriteBuf_.append(headerCodec_.encodeHeaderAck(streamId_));
  }
  // Report back what we've parsed
  if (callback_) {
    if (parsingTrailers_) {
      auto trailerHeaders =
          std::make_unique<HTTPHeaders>(msg->extractHeaders());
      callback_->onTrailersComplete(streamId_, std::move(trailerHeaders));
    } else {
      // TODO: should we treat msg as chunked like H2?
      callback_->onHeadersComplete(streamId_, std::move(msg));
    }
  }
}