int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
                              size_t bodylen) {
  const auto &req = downstream->request();
  auto &resp = downstream->response();
  auto &balloc = downstream->get_block_allocator();
  auto config = get_config();
  auto &httpconf = config->http;

  auto connection_close = false;

  auto worker = handler_->get_worker();

  if (httpconf.max_requests <= num_requests_ ||
      worker->get_graceful_shutdown()) {
    resp.fs.add_header_token(StringRef::from_lit("connection"),
                             StringRef::from_lit("close"), false,
                             http2::HD_CONNECTION);
    connection_close = true;
  } else if (req.http_major <= 0 ||
             (req.http_major == 1 && req.http_minor == 0)) {
    connection_close = true;
  } else {
    auto c = resp.fs.header(http2::HD_CONNECTION);
    if (c && util::strieq_l("close", c->value)) {
      connection_close = true;
    }
  }

  if (connection_close) {
    resp.connection_close = true;
    handler_->set_should_close_after_write(true);
  }

  auto output = downstream->get_response_buf();

  output->append("HTTP/1.1 ");
  output->append(http2::stringify_status(balloc, resp.http_status));
  output->append(' ');
  output->append(http2::get_reason_phrase(resp.http_status));
  output->append("\r\n");

  for (auto &kv : resp.fs.headers()) {
    if (kv.name.empty() || kv.name[0] == ':') {
      continue;
    }
    http2::capitalize(output, kv.name);
    output->append(": ");
    output->append(kv.value);
    output->append("\r\n");
  }

  if (!resp.fs.header(http2::HD_SERVER)) {
    output->append("Server: ");
    output->append(config->http.server_name);
    output->append("\r\n");
  }

  for (auto &p : httpconf.add_response_headers) {
    output->append(p.name);
    output->append(": ");
    output->append(p.value);
    output->append("\r\n");
  }

  output->append("\r\n");

  output->append(body, bodylen);

  downstream->response_sent_body_length += bodylen;
  downstream->set_response_state(DownstreamState::MSG_COMPLETE);

  return 0;
}
int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
                              size_t bodylen) {
  const auto &req = downstream->request();
  auto &resp = downstream->response();
  auto &balloc = downstream->get_block_allocator();
  auto config = get_config();
  auto &httpconf = config->http;

  auto connection_close = false;

  auto worker = handler_->get_worker();

  if (httpconf.max_requests <= num_requests_ ||
      worker->get_graceful_shutdown()) {
    resp.fs.add_header_token(StringRef::from_lit("connection"),
                             StringRef::from_lit("close"), false,
                             http2::HD_CONNECTION);
    connection_close = true;
  } else if (req.http_major <= 0 ||
             (req.http_major == 1 && req.http_minor == 0)) {
    connection_close = true;
  } else {
    auto c = resp.fs.header(http2::HD_CONNECTION);
    if (c && util::strieq_l("close", c->value)) {
      connection_close = true;
    }
  }

  if (connection_close) {
    resp.connection_close = true;
    handler_->set_should_close_after_write(true);
  }

  auto output = downstream->get_response_buf();

  output->append("HTTP/1.1 ");
  output->append(http2::stringify_status(balloc, resp.http_status));
  output->append(' ');
  output->append(http2::get_reason_phrase(resp.http_status));
  output->append("\r\n");

  for (auto &kv : resp.fs.headers()) {
    if (kv.name.empty() || kv.name[0] == ':') {
      continue;
    }
    http2::capitalize(output, kv.name);
    output->append(": ");
    output->append(kv.value);
    output->append("\r\n");
  }

  if (!resp.fs.header(http2::HD_SERVER)) {
    output->append("Server: ");
    output->append(config->http.server_name);
    output->append("\r\n");
  }

  for (auto &p : httpconf.add_response_headers) {
    output->append(p.name);
    output->append(": ");
    output->append(p.value);
    output->append("\r\n");
  }

  output->append("\r\n");

  output->append(body, bodylen);

  downstream->response_sent_body_length += bodylen;
  downstream->set_response_state(DownstreamState::MSG_COMPLETE);

  return 0;
}