/*
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/bio.h>
#include <vector>
#include <string>
#include "ts_lua_util.h"
#include "ts_lua_client_cert_helpers.h"

typedef enum {
  TS_LUA_PP_INFO_VERSION   = TS_PP_INFO_VERSION,
  TS_LUA_PP_INFO_SRC_ADDR  = TS_PP_INFO_SRC_ADDR,
  TS_LUA_PP_INFO_SRC_PORT  = TS_PP_INFO_SRC_PORT,
  TS_LUA_PP_INFO_DST_ADDR  = TS_PP_INFO_DST_ADDR,
  TS_LUA_PP_INFO_DST_PORT  = TS_PP_INFO_DST_PORT,
  TS_LUA_PP_INFO_PROTOCOL  = TS_PP_INFO_PROTOCOL,
  TS_LUA_PP_INFO_SOCK_TYPE = TS_PP_INFO_SOCK_TYPE
} TSLuaPPInfoKey;

ts_lua_var_item ts_lua_pp_info_key_vars[] = {
  TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_VERSION),  TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_SRC_ADDR),
  TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_SRC_PORT), TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_DST_ADDR),
  TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_DST_PORT), TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_PROTOCOL),
  TS_LUA_MAKE_VAR_ITEM(TS_LUA_PP_INFO_SOCK_TYPE)};

static void ts_lua_inject_client_request_client_addr_api(lua_State *L);
static void ts_lua_inject_client_request_server_addr_api(lua_State *L);

static int ts_lua_client_request_header_get(lua_State *L);
static int ts_lua_client_request_header_set(lua_State *L);
static int ts_lua_client_request_header_table_get(lua_State *L);
static int ts_lua_client_request_header_table_set(lua_State *L);
static int ts_lua_client_request_get_headers(lua_State *L);
static int ts_lua_client_request_get_header_block(lua_State *L);
static int ts_lua_client_request_get_url(lua_State *L);
static int ts_lua_client_request_get_pristine_url(lua_State *L);
static int ts_lua_client_request_get_url_host(lua_State *L);
static int ts_lua_client_request_set_url_host(lua_State *L);
static int ts_lua_client_request_get_url_port(lua_State *L);
static int ts_lua_client_request_set_url_port(lua_State *L);
static int ts_lua_client_request_get_url_scheme(lua_State *L);
static int ts_lua_client_request_set_url_scheme(lua_State *L);

static int ts_lua_client_request_get_uri(lua_State *L);
static int ts_lua_client_request_set_uri(lua_State *L);
static int ts_lua_client_request_set_uri_args(lua_State *L);
static int ts_lua_client_request_get_uri_args(lua_State *L);
static int ts_lua_client_request_get_method(lua_State *L);
static int ts_lua_client_request_set_method(lua_State *L);
static int ts_lua_client_request_get_version(lua_State *L);
static int ts_lua_client_request_set_version(lua_State *L);

static int ts_lua_client_request_get_body_size(lua_State *L);
static int ts_lua_client_request_get_header_size(lua_State *L);

static void ts_lua_inject_client_request_socket_api(lua_State *L);
static void ts_lua_inject_client_request_header_api(lua_State *L);
static void ts_lua_inject_client_request_header_table_api(lua_State *L);
static void ts_lua_inject_client_request_headers_api(lua_State *L);
static void ts_lua_inject_client_request_url_api(lua_State *L);
static void ts_lua_inject_client_request_uri_api(lua_State *L);
static void ts_lua_inject_client_request_args_api(lua_State *L);
static void ts_lua_inject_client_request_method_api(lua_State *L);
static void ts_lua_inject_client_request_version_api(lua_State *L);
static void ts_lua_inject_client_request_body_size_api(lua_State *L);
static void ts_lua_inject_client_request_header_size_api(lua_State *L);

static int ts_lua_client_request_client_addr_get_ip(lua_State *L);
static int ts_lua_client_request_client_addr_get_port(lua_State *L);
static int ts_lua_client_request_client_addr_get_addr(lua_State *L);
static int ts_lua_client_request_client_addr_get_incoming_port(lua_State *L);
static int ts_lua_client_request_client_addr_get_verified_addr(lua_State *L);
static int ts_lua_client_request_client_addr_set_verified_addr(lua_State *L);

static void ts_lua_inject_client_request_ssl_reused_api(lua_State *L);
static int  ts_lua_client_request_get_ssl_reused(lua_State *L);
static void ts_lua_inject_client_request_ssl_cipher_api(lua_State *L);
static int  ts_lua_client_request_get_ssl_cipher(lua_State *L);
static void ts_lua_inject_client_request_ssl_protocol_api(lua_State *L);
static int  ts_lua_client_request_get_ssl_protocol(lua_State *L);
static void ts_lua_inject_client_request_ssl_curve_api(lua_State *L);
static int  ts_lua_client_request_get_ssl_curve(lua_State *L);

static void ts_lua_inject_client_request_cert_api(lua_State *L);
static int  ts_lua_client_request_client_cert_get_pem(lua_State *L);
static int  ts_lua_client_request_client_cert_get_subject(lua_State *L);
static int  ts_lua_client_request_client_cert_get_issuer(lua_State *L);
static int  ts_lua_client_request_client_cert_get_serial(lua_State *L);
static int  ts_lua_client_request_client_cert_get_signature(lua_State *L);
static int  ts_lua_client_request_client_cert_get_not_before(lua_State *L);
static int  ts_lua_client_request_client_cert_get_not_after(lua_State *L);
static int  ts_lua_client_request_client_cert_get_version(lua_State *L);
static int  ts_lua_client_request_client_cert_get_san_dns(lua_State *L);
static int  ts_lua_client_request_client_cert_get_san_ip(lua_State *L);
static int  ts_lua_client_request_client_cert_get_san_email(lua_State *L);
static int  ts_lua_client_request_client_cert_get_san_uri(lua_State *L);
static int  ts_lua_client_request_server_cert_get_pem(lua_State *L);
static int  ts_lua_client_request_server_cert_get_subject(lua_State *L);
static int  ts_lua_client_request_server_cert_get_issuer(lua_State *L);
static int  ts_lua_client_request_server_cert_get_serial(lua_State *L);
static int  ts_lua_client_request_server_cert_get_signature(lua_State *L);
static int  ts_lua_client_request_server_cert_get_not_before(lua_State *L);
static int  ts_lua_client_request_server_cert_get_not_after(lua_State *L);
static int  ts_lua_client_request_server_cert_get_version(lua_State *L);
static int  ts_lua_client_request_server_cert_get_san_dns(lua_State *L);
static int  ts_lua_client_request_server_cert_get_san_ip(lua_State *L);
static int  ts_lua_client_request_server_cert_get_san_email(lua_State *L);
static int  ts_lua_client_request_server_cert_get_san_uri(lua_State *L);

static void ts_lua_inject_client_request_pp_info_api(lua_State *L);
static int  ts_lua_client_request_get_pp_info(lua_State *L);
static int  ts_lua_client_request_get_pp_info_int(lua_State *L);

void
ts_lua_inject_client_request_api(lua_State *L)
{
  lua_newtable(L);

  ts_lua_inject_client_request_socket_api(L);
  ts_lua_inject_client_request_header_api(L);
  ts_lua_inject_client_request_header_table_api(L);
  ts_lua_inject_client_request_headers_api(L);
  ts_lua_inject_client_request_url_api(L);
  ts_lua_inject_client_request_uri_api(L);
  ts_lua_inject_client_request_args_api(L);
  ts_lua_inject_client_request_method_api(L);
  ts_lua_inject_client_request_version_api(L);
  ts_lua_inject_client_request_body_size_api(L);
  ts_lua_inject_client_request_header_size_api(L);
  ts_lua_inject_client_request_ssl_reused_api(L);
  ts_lua_inject_client_request_ssl_cipher_api(L);
  ts_lua_inject_client_request_ssl_protocol_api(L);
  ts_lua_inject_client_request_ssl_curve_api(L);
  ts_lua_inject_client_request_cert_api(L);
  ts_lua_inject_client_request_pp_info_api(L);

  lua_setfield(L, -2, "client_request");
}

static void
ts_lua_inject_client_request_socket_api(lua_State *L)
{
  ts_lua_inject_client_request_client_addr_api(L);
  ts_lua_inject_client_request_server_addr_api(L);
}

static void
ts_lua_inject_client_request_client_addr_api(lua_State *L)
{
  lua_newtable(L);

  lua_pushcfunction(L, ts_lua_client_request_client_addr_get_ip);
  lua_setfield(L, -2, "get_ip");

  lua_pushcfunction(L, ts_lua_client_request_client_addr_get_port);
  lua_setfield(L, -2, "get_port");

  lua_pushcfunction(L, ts_lua_client_request_client_addr_get_addr);
  lua_setfield(L, -2, "get_addr");

  lua_pushcfunction(L, ts_lua_client_request_client_addr_get_incoming_port);
  lua_setfield(L, -2, "get_incoming_port");

  lua_pushcfunction(L, ts_lua_client_request_client_addr_get_verified_addr);
  lua_setfield(L, -2, "get_verified_addr");

  lua_pushcfunction(L, ts_lua_client_request_client_addr_set_verified_addr);
  lua_setfield(L, -2, "set_verified_addr");

  lua_setfield(L, -2, "client_addr");
}

static void
ts_lua_inject_client_request_server_addr_api(lua_State *L ATS_UNUSED)
{
  return;
}

static void
ts_lua_inject_client_request_header_api(lua_State *L)
{
  lua_newtable(L); /* .header */

  lua_createtable(L, 0, 2); /* metatable for .header */

  lua_pushcfunction(L, ts_lua_client_request_header_get);
  lua_setfield(L, -2, "__index");
  lua_pushcfunction(L, ts_lua_client_request_header_set);
  lua_setfield(L, -2, "__newindex");

  lua_setmetatable(L, -2);

  lua_setfield(L, -2, "header");
}

static int
ts_lua_client_request_header_get(lua_State *L)
{
  const char *key;
  const char *val;
  int         val_len;
  size_t      key_len;
  int         count;

  TSMLoc           field_loc, next_field_loc;
  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  /*  we skip the first argument that is the table */
  key = luaL_checklstring(L, 2, &key_len);

  if (key && key_len) {
    field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len);

    if (field_loc != TS_NULL_MLOC) {
      count = 0;
      while (field_loc != TS_NULL_MLOC) {
        val = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &val_len);
        next_field_loc = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
        lua_pushlstring(L, val, val_len);
        count++;
        // multiple headers with the same name must be semantically the same as one value which is comma separated
        if (next_field_loc != TS_NULL_MLOC) {
          lua_pushlstring(L, ",", 1);
          count++;
        }
        TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
        field_loc = next_field_loc;
      }
      lua_concat(L, count);
    } else {
      lua_pushnil(L);
    }

  } else {
    lua_pushnil(L);
  }

  return 1;
}

static int
ts_lua_client_request_header_set(lua_State *L)
{
  const char *key;
  const char *val;
  size_t      val_len;
  size_t      key_len;
  int         remove;
  int         first;

  TSMLoc field_loc, tmp;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  remove = 0;
  val    = nullptr;

  /*   we skip the first argument that is the table */
  key = luaL_checklstring(L, 2, &key_len);
  if (lua_isnil(L, 3)) {
    remove = 1;
  } else {
    val = luaL_checklstring(L, 3, &val_len);
  }

  field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len);

  if (remove) {
    while (field_loc != TS_NULL_MLOC) {
      tmp = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
      TSMimeHdrFieldDestroy(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
      TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
      field_loc = tmp;
    }
  } else if (field_loc != TS_NULL_MLOC) {
    first = 1;
    while (field_loc != TS_NULL_MLOC) {
      tmp = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
      if (first) {
        first = 0;
        TSMimeHdrFieldValueStringSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, val, val_len);
      } else {
        TSMimeHdrFieldDestroy(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
      }
      TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
      field_loc = tmp;
    }
  } else if (TSMimeHdrFieldCreateNamed(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len, &field_loc) !=
             TS_SUCCESS) {
    TSError("[ts_lua][%s] TSMimeHdrFieldCreateNamed error", __FUNCTION__);
    return 0;

  } else {
    TSMimeHdrFieldValueStringSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, val, val_len);
    TSMimeHdrFieldAppend(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
  }

  if (field_loc != TS_NULL_MLOC) {
    TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
  }

  return 0;
}

static void
ts_lua_inject_client_request_header_table_api(lua_State *L)
{
  lua_newtable(L); /* .header */

  lua_createtable(L, 0, 2); /* metatable for .header */

  lua_pushcfunction(L, ts_lua_client_request_header_table_get);
  lua_setfield(L, -2, "__index");
  lua_pushcfunction(L, ts_lua_client_request_header_table_set);
  lua_setfield(L, -2, "__newindex");

  lua_setmetatable(L, -2);

  lua_setfield(L, -2, "header_table");
}

static int
ts_lua_client_request_header_table_get(lua_State *L)
{
  const char *key;
  const char *val;
  int         val_len;
  size_t      key_len;
  int         count;

  TSMLoc           field_loc, next_field_loc;
  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  /*  we skip the first argument that is the table */
  key = luaL_checklstring(L, 2, &key_len);

  if (key && key_len) {
    field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len);

    if (field_loc != TS_NULL_MLOC) {
      lua_newtable(L);
      count = 0;
      while (field_loc != TS_NULL_MLOC) {
        val = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &val_len);
        next_field_loc = TSMimeHdrFieldNextDup(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
        count++;

        lua_pushlstring(L, val, val_len);
        lua_rawseti(L, -2, count);

        TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
        field_loc = next_field_loc;
      }

    } else {
      lua_pushnil(L);
    }

  } else {
    lua_pushnil(L);
  }

  return 1;
}

static int
ts_lua_client_request_header_table_set(lua_State * /* L ATS_UNUSED */)
{
  return 0;
}

static void
ts_lua_inject_client_request_headers_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_headers);
  lua_setfield(L, -2, "get_headers");

  lua_pushcfunction(L, ts_lua_client_request_get_header_block);
  lua_setfield(L, -2, "get_header_block");
}

static int
ts_lua_client_request_get_headers(lua_State *L)
{
  const char *name;
  const char *value;
  int         name_len;
  int         value_len;
  TSMLoc      field_loc;
  TSMLoc      next_field_loc;
  const char *tvalue;
  size_t      tvalue_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  lua_newtable(L);

  field_loc = TSMimeHdrFieldGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, 0);

  while (field_loc != TS_NULL_MLOC) {
    name = TSMimeHdrFieldNameGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, &name_len);
    if (name && name_len) {
      // retrieve the header name from table
      lua_pushlstring(L, name, name_len);
      lua_gettable(L, -2);
      if (lua_isnil(L, -1)) {
        // if header name does not exist in the table, insert it
        lua_pop(L, 1);
        value =
          TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &value_len);
        lua_pushlstring(L, name, name_len);
        lua_pushlstring(L, value, value_len);
        lua_rawset(L, -3);
      } else {
        // if header name exists in the table, append a command and the new value to the end of the existing value
        tvalue = lua_tolstring(L, -1, &tvalue_len);
        lua_pop(L, 1);
        value =
          TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &value_len);
        lua_pushlstring(L, name, name_len);
        lua_pushlstring(L, tvalue, tvalue_len);
        lua_pushlstring(L, ",", 1);
        lua_pushlstring(L, value, value_len);
        lua_concat(L, 3);
        lua_rawset(L, -3);
      }
    }

    next_field_loc = TSMimeHdrFieldNext(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
    TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
    field_loc = next_field_loc;
  }

  return 1;
}

static int
ts_lua_client_request_get_header_block(lua_State *L)
{
  TSIOBuffer       output_buffer;
  TSIOBufferReader reader;
  int              total_avail;

  TSIOBufferBlock block;
  const char     *block_start;
  int64_t         block_avail;

  char   *output_string;
  int64_t output_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  output_buffer = TSIOBufferCreate();
  reader        = TSIOBufferReaderAlloc(output_buffer);

  TSMimeHdrPrint(http_ctx->client_request_hdrp, output_buffer);

  total_avail = TSIOBufferReaderAvail(reader);

  output_string = static_cast<char *>(TSmalloc(total_avail + 1));
  output_len    = 0;

  block = TSIOBufferReaderStart(reader);
  while (block) {
    block_start = TSIOBufferBlockReadStart(block, reader, &block_avail);

    if (block_avail == 0) {
      break;
    }

    memcpy(output_string + output_len, block_start, block_avail);
    output_len += block_avail;

    TSIOBufferReaderConsume(reader, block_avail);
    block = TSIOBufferReaderStart(reader);
  }

  output_string[output_len] = '\0';
  output_len++;

  TSIOBufferReaderFree(reader);
  TSIOBufferDestroy(output_buffer);

  if (output_string && output_len) {
    lua_pushlstring(L, output_string, output_len);
  } else {
    lua_pushnil(L);
  }

  TSfree(output_string);
  return 1;
}

static void
ts_lua_inject_client_request_url_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_url);
  lua_setfield(L, -2, "get_url");

  lua_pushcfunction(L, ts_lua_client_request_get_pristine_url);
  lua_setfield(L, -2, "get_pristine_url");

  lua_pushcfunction(L, ts_lua_client_request_get_url_host);
  lua_setfield(L, -2, "get_url_host");
  lua_pushcfunction(L, ts_lua_client_request_set_url_host);
  lua_setfield(L, -2, "set_url_host");

  lua_pushcfunction(L, ts_lua_client_request_get_url_port);
  lua_setfield(L, -2, "get_url_port");
  lua_pushcfunction(L, ts_lua_client_request_set_url_port);
  lua_setfield(L, -2, "set_url_port");

  lua_pushcfunction(L, ts_lua_client_request_get_url_scheme);
  lua_setfield(L, -2, "get_url_scheme");
  lua_pushcfunction(L, ts_lua_client_request_set_url_scheme);
  lua_setfield(L, -2, "set_url_scheme");
}

static void
ts_lua_inject_client_request_uri_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_set_uri);
  lua_setfield(L, -2, "set_uri");

  lua_pushcfunction(L, ts_lua_client_request_get_uri);
  lua_setfield(L, -2, "get_uri");
}

static int
ts_lua_client_request_get_url(lua_State *L)
{
  char *url;
  int   url_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  url = TSHttpTxnEffectiveUrlStringGet(http_ctx->txnp, &url_len);

  if (url) {
    lua_pushlstring(L, url, url_len);
    TSfree(url);

  } else {
    lua_pushnil(L);
  }

  return 1;
}

static int
ts_lua_client_request_get_pristine_url(lua_State *L)
{
  char *url;
  int   url_len;

  TSMBuffer bufp;
  TSMLoc    url_loc;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  if (TSHttpTxnPristineUrlGet(http_ctx->txnp, &bufp, &url_loc) != TS_SUCCESS) {
    return 0;
  }

  url = TSUrlStringGet(bufp, url_loc, &url_len);

  if (url) {
    lua_pushlstring(L, url, url_len);
    TSfree(url);

  } else {
    lua_pushnil(L);
  }

  TSHandleMLocRelease(bufp, nullptr, url_loc);

  return 1;
}

static int
ts_lua_client_request_get_url_host(lua_State *L)
{
  const char *host;
  int         len = 0;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  host = TSUrlHostGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &len);

  if (len == 0) {
    char const *key     = "Host";
    char const *l_key   = "host";
    int         key_len = 4;

    TSMLoc field_loc;

    field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, key, key_len);
    if (field_loc) {
      host = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &len);
      TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);

    } else {
      field_loc = TSMimeHdrFieldFind(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, l_key, key_len);
      if (field_loc) {
        host = TSMimeHdrFieldValueStringGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc, -1, &len);
        TSHandleMLocRelease(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, field_loc);
      }
    }
  }

  lua_pushlstring(L, host, len);

  return 1;
}

static int
ts_lua_client_request_set_url_host(lua_State *L)
{
  const char *host;
  size_t      len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

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

  TSUrlHostSet(http_ctx->client_request_bufp, http_ctx->client_request_url, host, len);

  return 0;
}

static int
ts_lua_client_request_get_url_port(lua_State *L)
{
  int port;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  port = TSUrlPortGet(http_ctx->client_request_bufp, http_ctx->client_request_url);

  lua_pushnumber(L, port);

  return 1;
}

static int
ts_lua_client_request_set_url_port(lua_State *L)
{
  int port;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  // NOLINTNEXTLINE
  port = luaL_checkint(L, 1);

  TSUrlPortSet(http_ctx->client_request_bufp, http_ctx->client_request_url, port);

  return 0;
}

static int
ts_lua_client_request_get_url_scheme(lua_State *L)
{
  const char *scheme;
  int         len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  scheme = TSUrlSchemeGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &len);

  lua_pushlstring(L, scheme, len);

  return 1;
}

static int
ts_lua_client_request_set_url_scheme(lua_State *L)
{
  const char *scheme;
  size_t      len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

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

  TSUrlSchemeSet(http_ctx->client_request_bufp, http_ctx->client_request_url, scheme, len);

  return 0;
}

static int
ts_lua_client_request_get_uri(lua_State *L)
{
  const char *path;
  int         path_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  path = TSUrlPathGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &path_len);

  lua_pushlstring(L, "/", 1);
  lua_pushlstring(L, path, path_len >= TS_LUA_MAX_URL_LENGTH - 1 ? TS_LUA_MAX_URL_LENGTH - 2 : path_len);
  lua_concat(L, 2);

  return 1;
}

static int
ts_lua_client_request_set_uri(lua_State *L)
{
  const char *path;
  size_t      path_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  path = luaL_checklstring(L, 1, &path_len);

  if (*path == '/') {
    path++;
    path_len--;
  }

  TSUrlPathSet(http_ctx->client_request_bufp, http_ctx->client_request_url, path, path_len);

  return 0;
}

static void
ts_lua_inject_client_request_args_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_set_uri_args);
  lua_setfield(L, -2, "set_uri_args");

  lua_pushcfunction(L, ts_lua_client_request_get_uri_args);
  lua_setfield(L, -2, "get_uri_args");
}

static int
ts_lua_client_request_get_uri_args(lua_State *L)
{
  const char *param;
  int         param_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  param = TSUrlHttpQueryGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &param_len);

  if (param && param_len > 0) {
    lua_pushlstring(L, param, param_len);
  } else {
    lua_pushnil(L);
  }

  return 1;
}

static int
ts_lua_client_request_set_uri_args(lua_State *L)
{
  const char *param;
  size_t      param_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  param = luaL_checklstring(L, 1, &param_len);
  TSUrlHttpQuerySet(http_ctx->client_request_bufp, http_ctx->client_request_url, param, param_len);

  return 0;
}

static int
ts_lua_client_request_client_addr_get_ip(lua_State *L)
{
  struct sockaddr const *client_ip;
  char                   cip[128] = "";
  ts_lua_http_ctx       *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp);

  if (client_ip == nullptr) {
    lua_pushnil(L);

  } else {
    if (client_ip->sa_family == AF_INET) {
      inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)client_ip)->sin_addr, cip, sizeof(cip));
    } else if (client_ip->sa_family == AF_INET6) {
      inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)client_ip)->sin6_addr, cip, sizeof(cip));
    }

    lua_pushstring(L, cip);
  }

  return 1;
}

static int
ts_lua_client_request_client_addr_get_port(lua_State *L)
{
  struct sockaddr const *client_ip;
  ts_lua_http_ctx       *http_ctx;
  int                    port = 0;

  GET_HTTP_CONTEXT(http_ctx, L);

  client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp);

  if (client_ip == nullptr) {
    lua_pushnil(L);

  } else {
    if (client_ip->sa_family == AF_INET) {
      port = ((struct sockaddr_in *)client_ip)->sin_port;
    } else if (client_ip->sa_family == AF_INET6) {
      port = ((struct sockaddr_in6 *)client_ip)->sin6_port;
    }

    lua_pushnumber(L, port);
  }

  return 1;
}

static int
ts_lua_client_request_client_addr_get_incoming_port(lua_State *L)
{
  struct sockaddr const *incoming_addr;
  ts_lua_http_ctx       *http_ctx;
  int                    port = 0;

  GET_HTTP_CONTEXT(http_ctx, L);

  incoming_addr = TSHttpTxnIncomingAddrGet(http_ctx->txnp);

  if (incoming_addr == nullptr) {
    lua_pushnil(L);

  } else {
    if (incoming_addr->sa_family == AF_INET) {
      port = ((struct sockaddr_in *)incoming_addr)->sin_port;
    } else if (incoming_addr->sa_family == AF_INET6) {
      port = ((struct sockaddr_in6 *)incoming_addr)->sin6_port;
    }

    lua_pushnumber(L, ntohs(port));
  }

  return 1;
}

static int
ts_lua_client_request_client_addr_get_addr(lua_State *L)
{
  struct sockaddr const *client_ip;
  ts_lua_http_ctx       *http_ctx;
  int                    port     = 0;
  int                    family   = AF_UNSPEC;
  char                   cip[128] = "";

  GET_HTTP_CONTEXT(http_ctx, L);

  client_ip = TSHttpTxnClientAddrGet(http_ctx->txnp);

  if (client_ip == nullptr) {
    lua_pushnil(L);
    lua_pushnil(L);
    lua_pushnil(L);

  } else {
    if (client_ip->sa_family == AF_INET) {
      port = ntohs(((struct sockaddr_in *)client_ip)->sin_port);
      inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)client_ip)->sin_addr, cip, sizeof(cip));
      family = AF_INET;
    } else if (client_ip->sa_family == AF_INET6) {
      port = ntohs(((struct sockaddr_in6 *)client_ip)->sin6_port);
      inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)client_ip)->sin6_addr, cip, sizeof(cip));
      family = AF_INET6;
    } else if (client_ip->sa_family == AF_UNIX) {
      family = AF_UNIX;
    }

    lua_pushstring(L, cip);
    lua_pushnumber(L, port);
    lua_pushnumber(L, family);
  }

  return 3;
}

static void
ts_lua_inject_client_request_method_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_method);
  lua_setfield(L, -2, "get_method");

  lua_pushcfunction(L, ts_lua_client_request_set_method);
  lua_setfield(L, -2, "set_method");
}

static int
ts_lua_client_request_get_method(lua_State *L)
{
  const char *method;
  int         method_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  method = TSHttpHdrMethodGet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, &method_len);

  if (method && method_len) {
    lua_pushlstring(L, method, method_len);
  } else {
    lua_pushnil(L);
  }

  return 1;
}

static int
ts_lua_client_request_set_method(lua_State *L)
{
  const char *method;
  size_t      method_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  method = luaL_checklstring(L, 1, &method_len);

  if (method) {
    TSHttpHdrMethodSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, method, method_len);
  }

  return 0;
}

static void
ts_lua_inject_client_request_body_size_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_body_size);
  lua_setfield(L, -2, "get_body_size");
}

static int
ts_lua_client_request_get_body_size(lua_State *L)
{
  int64_t          body_size;
  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  body_size = TSHttpTxnClientReqBodyBytesGet(http_ctx->txnp);
  lua_pushnumber(L, body_size);

  return 1;
}

static void
ts_lua_inject_client_request_version_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_version);
  lua_setfield(L, -2, "get_version");

  lua_pushcfunction(L, ts_lua_client_request_set_version);
  lua_setfield(L, -2, "set_version");
}

static int
ts_lua_client_request_get_version(lua_State *L)
{
  int  version;
  char buf[32];
  int  n;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  version = TSHttpHdrVersionGet(http_ctx->client_request_bufp, http_ctx->client_request_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;
}

static int
ts_lua_client_request_set_version(lua_State *L)
{
  const char  *version;
  size_t       len;
  unsigned int major, minor;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

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

  if (sscanf(version, "%2u.%2u", &major, &minor) != 2) {
    return luaL_error(L, "failed to set version. Format must be X.Y");
  }

  TSHttpHdrVersionSet(http_ctx->client_request_bufp, http_ctx->client_request_hdrp, TS_HTTP_VERSION(major, minor));

  return 0;
}

static void
ts_lua_inject_client_request_header_size_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_header_size);
  lua_setfield(L, -2, "get_header_size");
}

static int
ts_lua_client_request_get_header_size(lua_State *L)
{
  int              header_size;
  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  header_size = TSHttpTxnClientReqHdrBytesGet(http_ctx->txnp);
  lua_pushnumber(L, header_size);

  return 1;
}

static void
ts_lua_inject_client_request_ssl_reused_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_ssl_reused);
  lua_setfield(L, -2, "get_ssl_reused");
}

static int
ts_lua_client_request_get_ssl_reused(lua_State *L)
{
  int              ssl_reused = 0;
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);
  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    ssl_reused = TSVConnIsSslReused(client_conn);
  }

  lua_pushnumber(L, ssl_reused);

  return 1;
}

static void
ts_lua_inject_client_request_ssl_cipher_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_ssl_cipher);
  lua_setfield(L, -2, "get_ssl_cipher");
}

static int
ts_lua_client_request_get_ssl_cipher(lua_State *L)
{
  const char      *ssl_cipher = "-";
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    ssl_cipher = TSVConnSslCipherGet(client_conn);
  }

  lua_pushstring(L, ssl_cipher);

  return 1;
}

static void
ts_lua_inject_client_request_ssl_protocol_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_ssl_protocol);
  lua_setfield(L, -2, "get_ssl_protocol");
}

static int
ts_lua_client_request_get_ssl_protocol(lua_State *L)
{
  const char      *ssl_protocol = "-";
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    ssl_protocol = TSVConnSslProtocolGet(client_conn);
  }

  lua_pushstring(L, ssl_protocol);

  return 1;
}

static void
ts_lua_inject_client_request_ssl_curve_api(lua_State *L)
{
  lua_pushcfunction(L, ts_lua_client_request_get_ssl_curve);
  lua_setfield(L, -2, "get_ssl_curve");
}

static int
ts_lua_client_request_get_ssl_curve(lua_State *L)
{
  const char      *ssl_curve = "-";
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    ssl_curve = TSVConnSslCurveGet(client_conn);
  }

  lua_pushstring(L, ssl_curve);

  return 1;
}

// Certificate API Functions
static void
ts_lua_inject_client_request_cert_api(lua_State *L)
{
  // Client certificate functions
  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_pem);
  lua_setfield(L, -2, "client_cert_get_pem");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_subject);
  lua_setfield(L, -2, "client_cert_get_subject");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_issuer);
  lua_setfield(L, -2, "client_cert_get_issuer");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_serial);
  lua_setfield(L, -2, "client_cert_get_serial");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_signature);
  lua_setfield(L, -2, "client_cert_get_signature");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_not_before);
  lua_setfield(L, -2, "client_cert_get_not_before");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_not_after);
  lua_setfield(L, -2, "client_cert_get_not_after");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_version);
  lua_setfield(L, -2, "client_cert_get_version");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_san_dns);
  lua_setfield(L, -2, "client_cert_get_san_dns");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_san_ip);
  lua_setfield(L, -2, "client_cert_get_san_ip");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_san_email);
  lua_setfield(L, -2, "client_cert_get_san_email");

  lua_pushcfunction(L, ts_lua_client_request_client_cert_get_san_uri);
  lua_setfield(L, -2, "client_cert_get_san_uri");

  // Server certificate functions
  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_pem);
  lua_setfield(L, -2, "server_cert_get_pem");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_subject);
  lua_setfield(L, -2, "server_cert_get_subject");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_issuer);
  lua_setfield(L, -2, "server_cert_get_issuer");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_serial);
  lua_setfield(L, -2, "server_cert_get_serial");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_signature);
  lua_setfield(L, -2, "server_cert_get_signature");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_not_before);
  lua_setfield(L, -2, "server_cert_get_not_before");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_not_after);
  lua_setfield(L, -2, "server_cert_get_not_after");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_version);
  lua_setfield(L, -2, "server_cert_get_version");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_san_dns);
  lua_setfield(L, -2, "server_cert_get_san_dns");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_san_ip);
  lua_setfield(L, -2, "server_cert_get_san_ip");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_san_email);
  lua_setfield(L, -2, "server_cert_get_san_email");

  lua_pushcfunction(L, ts_lua_client_request_server_cert_get_san_uri);
  lua_setfield(L, -2, "server_cert_get_san_uri");
}

// Client Certificate Functions
static int
ts_lua_client_request_client_cert_get_pem(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::string pem = get_x509_pem_string(cert);
        X509_free(cert);
        if (!pem.empty()) {
          lua_pushlstring(L, pem.c_str(), pem.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_subject(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::string subject = get_x509_name_string(X509_get_subject_name(cert));
        X509_free(cert);
        if (!subject.empty()) {
          lua_pushlstring(L, subject.c_str(), subject.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_issuer(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::string issuer = get_x509_name_string(X509_get_issuer_name(cert));
        X509_free(cert);
        if (!issuer.empty()) {
          lua_pushlstring(L, issuer.c_str(), issuer.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_serial(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::string serial = get_x509_serial_string(cert);
        X509_free(cert);
        if (!serial.empty()) {
          lua_pushlstring(L, serial.c_str(), serial.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_signature(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::string sig = get_x509_signature_string(cert);
        X509_free(cert);
        if (!sig.empty()) {
          lua_pushlstring(L, sig.c_str(), sig.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_not_before(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::string not_before = get_x509_time_string(X509_get_notBefore(cert));
        X509_free(cert);
        if (!not_before.empty()) {
          lua_pushlstring(L, not_before.c_str(), not_before.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_not_after(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::string not_after = get_x509_time_string(X509_get_notAfter(cert));
        X509_free(cert);
        if (!not_after.empty()) {
          lua_pushlstring(L, not_after.c_str(), not_after.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_version(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        long version = X509_get_version(cert);
        X509_free(cert);
        lua_pushinteger(L, version);
        return 1;
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_san_dns(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::vector<std::string> dns_names = get_x509_san_strings(cert, GEN_DNS);
        X509_free(cert);

        if (!dns_names.empty()) {
          lua_newtable(L);
          for (size_t i = 0; i < dns_names.size(); i++) {
            lua_pushlstring(L, dns_names[i].c_str(), dns_names[i].length());
            lua_rawseti(L, -2, i + 1);
          }
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_san_ip(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::vector<std::string> ip_addrs = get_x509_san_strings(cert, GEN_IPADD);
        X509_free(cert);

        if (!ip_addrs.empty()) {
          lua_newtable(L);
          for (size_t i = 0; i < ip_addrs.size(); i++) {
            lua_pushlstring(L, ip_addrs[i].c_str(), ip_addrs[i].length());
            lua_rawseti(L, -2, i + 1);
          }
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_san_email(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::vector<std::string> emails = get_x509_san_strings(cert, GEN_EMAIL);
        X509_free(cert);

        if (!emails.empty()) {
          lua_newtable(L);
          for (size_t i = 0; i < emails.size(); i++) {
            lua_pushlstring(L, emails[i].c_str(), emails[i].length());
            lua_rawseti(L, -2, i + 1);
          }
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_cert_get_san_uri(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL *ssl = reinterpret_cast<SSL *>(ssl_conn);
#ifdef OPENSSL_IS_OPENSSL3
      X509 *cert = SSL_get1_peer_certificate(ssl);
#else
      X509 *cert = SSL_get_peer_certificate(ssl);
#endif
      if (cert) {
        std::vector<std::string> uris = get_x509_san_strings(cert, GEN_URI);
        X509_free(cert);

        if (!uris.empty()) {
          lua_newtable(L);
          for (size_t i = 0; i < uris.size(); i++) {
            lua_pushlstring(L, uris[i].c_str(), uris[i].length());
            lua_rawseti(L, -2, i + 1);
          }
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

// Server Certificate Functions
static int
ts_lua_client_request_server_cert_get_pem(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::string pem = get_x509_pem_string(cert);
        if (!pem.empty()) {
          lua_pushlstring(L, pem.c_str(), pem.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_subject(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::string subject = get_x509_name_string(X509_get_subject_name(cert));
        if (!subject.empty()) {
          lua_pushlstring(L, subject.c_str(), subject.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_issuer(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::string issuer = get_x509_name_string(X509_get_issuer_name(cert));
        if (!issuer.empty()) {
          lua_pushlstring(L, issuer.c_str(), issuer.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_serial(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::string serial = get_x509_serial_string(cert);
        if (!serial.empty()) {
          lua_pushlstring(L, serial.c_str(), serial.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_signature(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::string sig = get_x509_signature_string(cert);
        if (!sig.empty()) {
          lua_pushlstring(L, sig.c_str(), sig.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_not_before(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::string not_before = get_x509_time_string(X509_get_notBefore(cert));
        if (!not_before.empty()) {
          lua_pushlstring(L, not_before.c_str(), not_before.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_not_after(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::string not_after = get_x509_time_string(X509_get_notAfter(cert));
        if (!not_after.empty()) {
          lua_pushlstring(L, not_after.c_str(), not_after.length());
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_version(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        long version = X509_get_version(cert);
        lua_pushinteger(L, version);
        return 1;
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_san_dns(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::vector<std::string> dns_names = get_x509_san_strings(cert, GEN_DNS);

        if (!dns_names.empty()) {
          lua_newtable(L);
          for (size_t i = 0; i < dns_names.size(); i++) {
            lua_pushlstring(L, dns_names[i].c_str(), dns_names[i].length());
            lua_rawseti(L, -2, i + 1);
          }
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_san_ip(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::vector<std::string> ip_addrs = get_x509_san_strings(cert, GEN_IPADD);

        if (!ip_addrs.empty()) {
          lua_newtable(L);
          for (size_t i = 0; i < ip_addrs.size(); i++) {
            lua_pushlstring(L, ip_addrs[i].c_str(), ip_addrs[i].length());
            lua_rawseti(L, -2, i + 1);
          }
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_san_email(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::vector<std::string> emails = get_x509_san_strings(cert, GEN_EMAIL);

        if (!emails.empty()) {
          lua_newtable(L);
          for (size_t i = 0; i < emails.size(); i++) {
            lua_pushlstring(L, emails[i].c_str(), emails[i].length());
            lua_rawseti(L, -2, i + 1);
          }
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_server_cert_get_san_uri(lua_State *L)
{
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnIsSsl(client_conn)) {
    TSSslConnection ssl_conn = TSVConnSslConnectionGet(client_conn);
    if (ssl_conn) {
      SSL  *ssl  = reinterpret_cast<SSL *>(ssl_conn);
      X509 *cert = SSL_get_certificate(ssl);
      if (cert) {
        std::vector<std::string> uris = get_x509_san_strings(cert, GEN_URI);

        if (!uris.empty()) {
          lua_newtable(L);
          for (size_t i = 0; i < uris.size(); i++) {
            lua_pushlstring(L, uris[i].c_str(), uris[i].length());
            lua_rawseti(L, -2, i + 1);
          }
          return 1;
        }
      }
    }
  }

  lua_pushnil(L);
  return 1;
}

static void
ts_lua_inject_client_request_pp_info_api(lua_State *L)
{
  size_t i;

  for (i = 0; i < sizeof(ts_lua_pp_info_key_vars) / sizeof(ts_lua_var_item); i++) {
    lua_pushinteger(L, ts_lua_pp_info_key_vars[i].nvar);
    lua_setglobal(L, ts_lua_pp_info_key_vars[i].svar);
  }

  lua_pushcfunction(L, ts_lua_client_request_get_pp_info);
  lua_setfield(L, -2, "get_pp_info");

  lua_pushcfunction(L, ts_lua_client_request_get_pp_info_int);
  lua_setfield(L, -2, "get_pp_info_int");
}

static int
ts_lua_client_request_get_pp_info(lua_State *L)
{
  uint16_t         key;
  const char      *value = nullptr;
  int              length;
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  key = static_cast<uint16_t>(luaL_checkinteger(L, 1));

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnPPInfoGet(client_conn, key, &value, &length) == TS_SUCCESS) {
    if (key == TS_PP_INFO_SRC_ADDR || key == TS_PP_INFO_DST_ADDR) {
      // For addresses, convert sockaddr to string
      char                ip_str[INET6_ADDRSTRLEN];
      const sockaddr     *addr = reinterpret_cast<const sockaddr *>(value);
      const sockaddr_in  *addr_in;
      const sockaddr_in6 *addr_in6;

      if (addr->sa_family == AF_INET) {
        addr_in = reinterpret_cast<const sockaddr_in *>(addr);
        inet_ntop(AF_INET, &addr_in->sin_addr, ip_str, sizeof(ip_str));
      } else if (addr->sa_family == AF_INET6) {
        addr_in6 = reinterpret_cast<const sockaddr_in6 *>(addr);
        inet_ntop(AF_INET6, &addr_in6->sin6_addr, ip_str, sizeof(ip_str));
      } else {
        lua_pushnil(L);
        return 1;
      }
      lua_pushstring(L, ip_str);
    } else {
      // For other types, return as string
      lua_pushlstring(L, value, length);
    }
    return 1;
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_get_pp_info_int(lua_State *L)
{
  uint16_t         key;
  TSMgmtInt        value;
  ts_lua_http_ctx *http_ctx;
  TSHttpSsn        ssnp;
  TSVConn          client_conn;

  GET_HTTP_CONTEXT(http_ctx, L);

  key = static_cast<uint16_t>(luaL_checkinteger(L, 1));

  ssnp        = TSHttpTxnSsnGet(http_ctx->txnp);
  client_conn = TSHttpSsnClientVConnGet(ssnp);

  if (TSVConnPPInfoIntGet(client_conn, key, &value) == TS_SUCCESS) {
    lua_pushinteger(L, value);
    return 1;
  }

  lua_pushnil(L);
  return 1;
}

static int
ts_lua_client_request_client_addr_get_verified_addr(lua_State *L)
{
  struct sockaddr const *verified_addr;
  ts_lua_http_ctx       *http_ctx;
  int                    family   = AF_UNSPEC;
  char                   vip[128] = "";

  GET_HTTP_CONTEXT(http_ctx, L);

  if (TSHttpTxnVerifiedAddrGet(http_ctx->txnp, &verified_addr) == TS_SUCCESS) {
    if (verified_addr->sa_family == AF_INET) {
      inet_ntop(AF_INET, (const void *)&((struct sockaddr_in *)verified_addr)->sin_addr, vip, sizeof(vip));
      family = AF_INET;
      lua_pushstring(L, vip);
      lua_pushnumber(L, family);
    } else if (verified_addr->sa_family == AF_INET6) {
      inet_ntop(AF_INET6, (const void *)&((struct sockaddr_in6 *)verified_addr)->sin6_addr, vip, sizeof(vip));
      family = AF_INET6;
      lua_pushstring(L, vip);
      lua_pushnumber(L, family);
    } else {
      lua_pushnil(L);
      lua_pushnil(L);
    }
  } else {
    lua_pushnil(L);
    lua_pushnil(L);
  }

  return 2;
}

static int
ts_lua_client_request_client_addr_set_verified_addr(lua_State *L)
{
  union {
    struct sockaddr_in  sin4;
    struct sockaddr_in6 sin6;
    struct sockaddr     sa;
  } addr;
  memset(&addr, 0, sizeof(addr));
  ts_lua_http_ctx *http_ctx;
  int              n;
  int              family;
  const char      *vip;
  size_t           vip_len;

  GET_HTTP_CONTEXT(http_ctx, L);

  n = lua_gettop(L);

  if (n == 2) {
    vip    = luaL_checklstring(L, 1, &vip_len);
    family = luaL_checknumber(L, 2);

    if (family == AF_INET) {
      addr.sin4.sin_family = AF_INET;
      addr.sin4.sin_port   = 0;
      if (!inet_pton(family, vip, &addr.sin4.sin_addr)) {
        return luaL_error(L, "invalid ipv4 address");
      }
    } else if (family == AF_INET6) {
      addr.sin6.sin6_family = AF_INET6;
      addr.sin6.sin6_port   = 0;
      if (!inet_pton(family, vip, &addr.sin6.sin6_addr)) {
        return luaL_error(L, "invalid ipv6 address");
      }
    } else {
      return luaL_error(L, "invalid address family");
    }

    TSHttpTxnVerifiedAddrSet(http_ctx->txnp, &addr.sa);
  } else {
    return luaL_error(L, "incorrect # of arguments to ts.client_request.client_addr.set_verified_addr, receiving %d instead of 2",
                      n);
  }

  return 0;
}
