void ConnectionManagerImpl::ActiveStream::refreshDurationTimeout() {
  if (!filter_manager_.streamInfo().route_entry_ || !request_headers_) {
    return;
  }
  auto& route = filter_manager_.streamInfo().route_entry_;

  auto grpc_timeout = Grpc::Common::getGrpcTimeout(*request_headers_);
  std::chrono::milliseconds timeout;
  bool disable_timer = false;

  if (!grpc_timeout || !route->grpcTimeoutHeaderMax()) {
    // Either there is no grpc-timeout header or special timeouts for it are not
    // configured. Use stream duration.
    if (route->maxStreamDuration()) {
      timeout = route->maxStreamDuration().value();
      if (timeout == std::chrono::milliseconds(0)) {
        // Explicitly configured 0 means no timeout.
        disable_timer = true;
      }
    } else {
      // Fall back to HCM config. If no HCM duration limit exists, disable
      // timers set by any prior route configuration.
      const auto max_stream_duration = connection_manager_.config_.maxStreamDuration();
      if (max_stream_duration.has_value() && max_stream_duration.value().count()) {
        timeout = max_stream_duration.value();
      } else {
        disable_timer = true;
      }
    }
  } else {
    // Start with the timeout equal to the gRPC timeout header.
    timeout = grpc_timeout.value();
    // If there's a valid cap, apply it.
    if (timeout > route->grpcTimeoutHeaderMax().value() &&
        route->grpcTimeoutHeaderMax().value() != std::chrono::milliseconds(0)) {
      timeout = route->grpcTimeoutHeaderMax().value();
    }

    // Apply the configured offset.
    if (timeout != std::chrono::milliseconds(0) && route->grpcTimeoutHeaderOffset()) {
      const auto offset = route->grpcTimeoutHeaderOffset().value();
      if (offset < timeout) {
        timeout -= offset;
      } else {
        timeout = std::chrono::milliseconds(0);
      }
    }
  }

  // Disable any existing timer if configured to do so.
  if (disable_timer) {
    if (max_stream_duration_timer_) {
      max_stream_duration_timer_->disableTimer();
      if (route->usingNewTimeouts() && Grpc::Common::isGrpcRequestHeaders(*request_headers_)) {
        request_headers_->removeGrpcTimeout();
      }
    }
    return;
  }

  // Set the header timeout before doing used-time adjustments.
  // This may result in the upstream not getting the latest results, but also
  // avoids every request getting a custom timeout based on envoy think time.
  if (route->usingNewTimeouts() && Grpc::Common::isGrpcRequestHeaders(*request_headers_)) {
    Grpc::Common::toGrpcTimeout(std::chrono::milliseconds(timeout), *request_headers_);
  }

  // See how long this stream has been alive, and adjust the timeout
  // accordingly.
  std::chrono::duration time_used = std::chrono::duration_cast<std::chrono::milliseconds>(
      connection_manager_.timeSource().monotonicTime() -
      filter_manager_.streamInfo().startTimeMonotonic());
  if (timeout > time_used) {
    timeout -= time_used;
  } else {
    timeout = std::chrono::milliseconds(0);
  }

  // Finally create (if necessary) and enable the timer.
  if (!max_stream_duration_timer_) {
    max_stream_duration_timer_ =
        connection_manager_.read_callbacks_->connection().dispatcher().createTimer(
            [this]() -> void { onStreamMaxDurationReached(); });
  }
  max_stream_duration_timer_->enableTimer(timeout);
}