static int
ts_lua_client_response_set_error_resp(lua_State *L)
{
  int n, status;
  const char *body;
  const char *reason;
  int reason_len;
  size_t body_len;
  int resp_len;
  char *resp_buf;
  TSMLoc field_loc;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_CLIENT_RESPONSE_HDR(http_ctx);

  n = lua_gettop(L);

  status = luaL_checkinteger(L, 1);

  reason = TSHttpHdrReasonLookup(status);
  reason_len = strlen(reason);

  TSHttpHdrStatusSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, status);
  TSHttpHdrReasonSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, reason, reason_len);

  body_len = 0;

  if (n == 2) {
    body = luaL_checklstring(L, 2, &body_len);
  }

  if (body_len && body) {
    resp_buf = TSmalloc(body_len);
    memcpy(resp_buf, body, body_len);
    resp_len = body_len;

  } else {
    resp_buf = TSmalloc(reason_len);
    memcpy(resp_buf, reason, reason_len);
    resp_len = reason_len;
  }

  field_loc = TSMimeHdrFieldFind(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, TS_MIME_FIELD_TRANSFER_ENCODING,
                                 TS_MIME_LEN_TRANSFER_ENCODING);

  if (field_loc) {
    TSMimeHdrFieldDestroy(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc);
    TSHandleMLocRelease(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc);
  }

  TSHttpTxnErrorBodySet(http_ctx->txnp, resp_buf, resp_len, NULL);

  return 0;
}
static int
ts_lua_client_response_get_status(lua_State *L)
{
  int status;
  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_CLIENT_RESPONSE_HDR(http_ctx);

  status = TSHttpHdrStatusGet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp);

  lua_pushinteger(L, status);

  return 1;
}
static int
ts_lua_client_response_set_version(lua_State *L)
{
  const char *version;
  size_t len;
  int major, minor;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_CLIENT_RESPONSE_HDR(http_ctx);

  version = luaL_checklstring(L, 1, &len);

  sscanf(version, "%2u.%2u", &major, &minor);

  TSHttpHdrVersionSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, TS_HTTP_VERSION(major, minor));

  return 0;
}
static int
ts_lua_client_response_get_headers(lua_State * L)
{
  const char *name;
  const char *value;
  int name_len;
  int value_len;
  TSMLoc field_loc;
  TSMLoc next_field_loc;

  ts_lua_http_ctx *http_ctx;

  http_ctx = ts_lua_get_http_ctx(L);

  TS_LUA_CHECK_CLIENT_RESPONSE_HDR(http_ctx);

  lua_newtable(L);

  field_loc = TSMimeHdrFieldGet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, 0);

  while (field_loc) {

    name = TSMimeHdrFieldNameGet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc, &name_len);
    if (name && name_len) {

      value =
        TSMimeHdrFieldValueStringGet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc, -1,
                                     &value_len);
      lua_pushlstring(L, name, name_len);
      lua_pushlstring(L, value, value_len);
      lua_rawset(L, -3);
    }

    next_field_loc = TSMimeHdrFieldNext(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc);
    TSHandleMLocRelease(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc);
    field_loc = next_field_loc;
  }

  return 1;
}
static int
ts_lua_client_response_set_status(lua_State *L)
{
  int status;
  const char *reason;
  int reason_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_CLIENT_RESPONSE_HDR(http_ctx);

  status = luaL_checkint(L, 1);

  reason = TSHttpHdrReasonLookup(status);
  reason_len = strlen(reason);

  TSHttpHdrStatusSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, status);
  TSHttpHdrReasonSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, reason, reason_len);

  return 0;
}
static int
ts_lua_client_response_get_version(lua_State *L)
{
  int version;
  char buf[32];
  int n;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_CLIENT_RESPONSE_HDR(http_ctx);

  version = TSHttpHdrVersionGet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp);

  n = snprintf(buf, sizeof(buf), "%d.%d", TS_HTTP_MAJOR(version), TS_HTTP_MINOR(version));
  if (n >= (int)sizeof(buf)) {
    lua_pushlstring(L, buf, sizeof(buf) - 1);
  } else if (n > 0) {
    lua_pushlstring(L, buf, n);
  }

  return 1;
}