bool ActiveStreamDecoderFilter::recreateStream(const ResponseHeaderMap* headers) {
  // Because the filter's and the HCM view of if the stream has a body and if
  // the stream is complete may differ, re-check bytesReceived() to make sure
  // there was no body from the HCM's point of view.
  if (!complete()) {
    return false;
  }

  parent_.stream_info_.setResponseCodeDetails(
      StreamInfo::ResponseCodeDetails::get().InternalRedirect);

  if (headers != nullptr) {
    // The call to setResponseHeaders is needed to ensure that the headers are properly logged in
    // access logs before the stream is destroyed. Since the function expects a ResponseHeaderPtr&&,
    // ownership of the headers must be passed. This cannot happen earlier in the flow (such as in
    // the call to setupRedirect) because at that point it is still possible for the headers to be
    // used in a different logical branch. We work around this by creating a copy and passing
    // ownership of the copy instead.
    ResponseHeaderMapPtr headers_copy = createHeaderMap<ResponseHeaderMapImpl>(*headers);
    parent_.filter_manager_callbacks_.setResponseHeaders(std::move(headers_copy));
    parent_.filter_manager_callbacks_.chargeStats(*headers);
  }

  parent_.filter_manager_callbacks_.recreateStream(parent_.stream_info_.filter_state_);

  return true;
}
bool ActiveStreamDecoderFilter::recreateStream(const ResponseHeaderMap* headers) {
   
   
   
  if (!complete()) {
    return false;
  }

  parent_.stream_info_.setResponseCodeDetails(
      StreamInfo::ResponseCodeDetails::get().InternalRedirect);

  if (headers != nullptr) {
     
     
     
     
     
     
    ResponseHeaderMapPtr headers_copy = createHeaderMap<ResponseHeaderMapImpl>(*headers);
    parent_.filter_manager_callbacks_.setResponseHeaders(std::move(headers_copy));
    parent_.filter_manager_callbacks_.chargeStats(*headers);
  }

  parent_.filter_manager_callbacks_.recreateStream(parent_.stream_info_.filter_state_);

  return true;
}