/** @file

  Implements the Traffic Server C API functions.

  @section license License

  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 <atomic>
#include <tuple>
#include <unordered_map>
#include <string_view>
#include <string>
#include <charconv>

#include "iocore/net/NetVConnection.h"
#include "iocore/net/NetHandler.h"
#include "iocore/net/UDPNet.h"
#include "tscore/ink_config.h"
#include "tscore/ink_platform.h"
#include "tscore/ink_base64.h"
#include "tscore/Encoding.h"
#include "tscore/PluginUserArgs.h"
#include "tscore/Layout.h"
#include "tscore/Diags.h"
#include "tsutil/Metrics.h"

#include "api/InkAPIInternal.h"
#include "api/HttpAPIHooks.h"
#include "proxy/logging/Log.h"
#include "proxy/hdrs/URL.h"
#include "proxy/hdrs/MIME.h"
#include "proxy/hdrs/HTTP.h"
#include "proxy/ProxySession.h"
#include "proxy/http2/Http2ClientSession.h"
#include "proxy/PoolableSession.h"
#include "proxy/http/HttpSM.h"
#include "proxy/http/HttpConfig.h"
#include "proxy/http/OverridableConfigDefs.h"
#include "proxy/PluginHttpConnect.h"
#include "../iocore/net/P_Net.h"
#include "../iocore/net/P_UnixNet.h"
#include "../iocore/net/P_SSLNetVConnection.h"
#include "../iocore/cache/P_CacheHttp.h"
#include "../iocore/cache/CacheVC.h"
#include "records/RecCore.h"
#include "../records/P_RecCore.h"
#include "../records/P_RecDefs.h"
#include "../iocore/net/P_SSLConfig.h"
#include "../iocore/net/P_SSLClientUtils.h"
#include "iocore/dns/DNSProcessor.h"
#include "iocore/net/ConnectionTracker.h"
#include "iocore/net/SSLAPIHooks.h"
#include "iocore/net/SSLDiags.h"
#include "iocore/net/TLSBasicSupport.h"
#include "iocore/net/TLSSNISupport.h"
#include "iocore/eventsystem/ConfigProcessor.h"
#include "proxy/Plugin.h"
#include "proxy/logging/LogObject.h"
#include "proxy/logging/LogConfig.h"
#include "proxy/PluginVC.h"
#include "proxy/http/HttpSessionAccept.h"
#include "proxy/PluginVC.h"
#include "proxy/FetchSM.h"
#include "api/LifecycleAPIHooks.h"
#include "proxy/http/HttpDebugNames.h"
#include "iocore/aio/AIO.h"
#include "iocore/eventsystem/Tasks.h"

#include "../iocore/net/P_OCSPStapling.h"
#include "records/RecDefs.h"
#include "records/RecCore.h"
#include "records/RecYAMLDecoder.h"
#include "iocore/utils/Machine.h"
#include "proxy/http/HttpProxyServerMain.h"
#include "shared/overridable_txn_vars.h"
#include "mgmt/config/FileManager.h"

#include "mgmt/rpc/jsonrpc/JsonRPC.h"
#include <swoc/bwf_base.h>
#include <swoc/IPRange.h>
#include "ts/ts.h"

/****************************************************************
 *  IMPORTANT - READ ME
 * Any plugin using the IO Core must enter
 *   with a held mutex.  SDK 1.0, 1.1 & 2.0 did not
 *   have this restriction so we need to add a mutex
 *   to Plugin's Continuation if it tries to use the IOCore
 * Not only does the plugin have to have a mutex
 *   before entering the IO Core.  The mutex needs to be held.
 *   We now take out the mutex on each call to ensure it is
 *   held for the entire duration of the IOCore call
 ***************************************************************/

// helper macro for setting HTTPHdr data
#define SET_HTTP_HDR(_HDR, _BUF_PTR, _OBJ_PTR)          \
  _HDR.m_heap = ((HdrHeapSDKHandle *)_BUF_PTR)->m_heap; \
  _HDR.m_http = (HTTPHdrImpl *)_OBJ_PTR;                \
  _HDR.m_mime = _HDR.m_http->m_fields_impl;

// This assert is for internal API use only.
#if TS_USE_FAST_SDK
#define sdk_assert(EX) (void)(EX)
#else
#define sdk_assert(EX) ((void)((EX) ? (void)0 : _TSReleaseAssert(#EX, __FILE__, __LINE__)))
#endif

namespace rpc
{
extern std::mutex              g_rpcHandlingMutex;
extern std::condition_variable g_rpcHandlingCompletion;
extern swoc::Rv<YAML::Node>    g_rpcHandlerResponseData;
extern bool                    g_rpcHandlerProcessingCompleted;
} // namespace rpc

static ts::Metrics &global_api_metrics = ts::Metrics::instance();

ConfigUpdateCbTable *global_config_cbs = nullptr;

// Fetchpages SM
extern ClassAllocator<FetchSM, false> FetchSMAllocator;

/* From proxy/http/HttpProxyServerMain.c: */
extern bool ssl_register_protocol(const char *, Continuation *);

// External converters.
extern MgmtConverter const &HttpDownServerCacheTimeConv;

extern HttpSessionAccept                        *plugin_http_accept;
extern HttpSessionAccept                        *plugin_http_transparent_accept;
extern thread_local PluginThreadContext         *pluginThreadContext;
extern ClassAllocator<INKContInternal, false>    INKContAllocator;
extern ClassAllocator<INKVConnInternal, false>   INKVConnAllocator;
static ClassAllocator<MIMEFieldSDKHandle, false> mHandleAllocator("MIMEFieldSDKHandle");

// forward declarations
TSReturnCode sdk_sanity_check_null_ptr(void const *ptr);
TSReturnCode sdk_sanity_check_mbuffer(TSMBuffer bufp);

namespace
{

DbgCtl dbg_ctl_plugin{"plugin"};
DbgCtl dbg_ctl_parent_select{"parent_select"};
DbgCtl dbg_ctl_iocore_net{"iocore_net"};
DbgCtl dbg_ctl_cache_url{"cache_url"};
DbgCtl dbg_ctl_ssl{"ssl"};
DbgCtl dbg_ctl_ssl_cert_update{"ssl.cert_update"};
DbgCtl dbg_ctl_ssl_session_cache_insert{"ssl.session_cache.insert"};
DbgCtl dbg_ctl_rpc_api{"rpc.api"};

} // end anonymous namespace

/******************************************************/
/* Allocators for field handles and standalone fields */
/******************************************************/
static MIMEFieldSDKHandle *
sdk_alloc_field_handle(TSMBuffer /* bufp ATS_UNUSED */, MIMEHdrImpl *mh)
{
  MIMEFieldSDKHandle *handle = THREAD_ALLOC(mHandleAllocator, this_thread());

  // TODO: Should remove this when memory allocation can't fail.
  sdk_assert(sdk_sanity_check_null_ptr((void *)handle) == TS_SUCCESS);

  obj_init_header(handle, HdrHeapObjType::FIELD_SDK_HANDLE, sizeof(MIMEFieldSDKHandle), 0);
  handle->mh = mh;

  return handle;
}

static void
sdk_free_field_handle(TSMBuffer bufp, MIMEFieldSDKHandle *field_handle)
{
  if (sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS) {
    THREAD_FREE(field_handle, mHandleAllocator, this_thread());
  }
}

// Defines in InkAPIInternal.cc
extern char traffic_server_version[128];
extern int  ts_major_version;
extern int  ts_minor_version;
extern int  ts_patch_version;

/** Reservation for a user arg.
 */
struct UserArg {
  TSUserArgType type;
  std::string   name;        ///< Name of reserving plugin.
  std::string   description; ///< Description of use for this arg.
};

// Managing the user args tables, and the global storage (which is assumed to be the biggest, by far).
UserArg                                 UserArgTable[TS_USER_ARGS_COUNT][MAX_USER_ARGS[TS_USER_ARGS_GLB]];
static PluginUserArgs<TS_USER_ARGS_GLB> global_user_args;
std::atomic<int>                        UserArgIdx[TS_USER_ARGS_COUNT]; // Table of next reserved index.

////////////////////////////////////////////////////////////////////
//
// API error logging
//
////////////////////////////////////////////////////////////////////
void
TSStatus(const char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  StatusV(fmt, args);
  va_end(args);
}

void
TSNote(const char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  NoteV(fmt, args);
  va_end(args);
}

void
TSWarning(const char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  WarningV(fmt, args);
  va_end(args);
}

void
TSError(const char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  ErrorV(fmt, args);
  va_end(args);
}

void
TSFatal(const char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  FatalV(fmt, args);
  va_end(args);
}

void
TSAlert(const char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  AlertV(fmt, args);
  va_end(args);
}

void
TSEmergency(const char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  EmergencyV(fmt, args);
  va_end(args);
}

// Assert in debug AND optim
void
_TSReleaseAssert(const char *text, const char *file, int line)
{
  _ink_assert(text, file, line);
}

// Assert only in debug
int
#ifdef DEBUG
_TSAssert(const char *text, const char *file, int line)
{
  _ink_assert(text, file, line);
  return 0;
}
#else
_TSAssert(const char *, const char *, int)
{
  return 0;
}
#endif

////////////////////////////////////////////////////////////////////
//
// SDK Interoperability Support
//
// ----------------------------------------------------------------
//
// Standalone Fields (SDK Version-Interoperability Hack)
//
//
// A "standalone" field is an ugly hack for portability with old
// versions of the SDK that mirrored the old header system.  In
// the old system, you could create arbitrary tiny little field
// objects, distinct from MIME header objects, and link them
// together.  In the new header system, all fields are internal
// constituents of the MIME header.  To preserve the semantics of
// the old SDK, we need to maintain the concept of fields that
// are created outside of a MIME header.  Whenever a field is
// "attached" to a MIME header, it is copied into the MIME header
// field's slot, and the handle to the field is updated to refer
// to the new field.
//
// Hopefully, we can eliminate this old compatibility interface and
// migrate users to the newer semantics quickly.
//
// ----------------------------------------------------------------
//
// MIMEField SDK Handles (SDK Version-Interoperability Hack)
//
// MIMEField "handles" are used by the SDK as an indirect reference
// to the MIMEField.  Because versions 1 & 2 of the SDK allowed
// standalone fields that existed without associated MIME headers,
// and because the version 3 SDK requires an associated MIME header
// for all field mutation operations (for presence bits, etc.) we
// need a data structure that:
//
//   * identifies standalone fields and stores field name/value
//     information for fields that are not yet in a header
//   * redirects the field to a real header field when the field
//     is inserted into a header
//   * maintains the associated MIMEHdrImpl when returning field
//     slots from lookup and create functions
//
// If the MIMEHdrImpl pointer is null, then the handle points
// to a standalone field, otherwise the handle points to a field
// within the MIME header.
//
////////////////////////////////////////////////////////////////////

/*****************************************************************/
/* Handles to headers are impls, but need to handle MIME or HTTP */
/*****************************************************************/

inline MIMEHdrImpl *
_hdr_obj_to_mime_hdr_impl(HdrHeapObjImpl *obj)
{
  MIMEHdrImpl *impl;
  if (static_cast<HdrHeapObjType>(obj->m_type) == HdrHeapObjType::HTTP_HEADER) {
    impl = static_cast<HTTPHdrImpl *>(obj)->m_fields_impl;
  } else if (static_cast<HdrHeapObjType>(obj->m_type) == HdrHeapObjType::MIME_HEADER) {
    impl = static_cast<MIMEHdrImpl *>(obj);
  } else {
    ink_release_assert(!"mloc not a header type");
    impl = nullptr; /* gcc does not know about 'ink_release_assert' - make it happy */
  }
  return impl;
}

inline MIMEHdrImpl *
_hdr_mloc_to_mime_hdr_impl(TSMLoc mloc)
{
  return _hdr_obj_to_mime_hdr_impl(reinterpret_cast<HdrHeapObjImpl *>(mloc));
}

TSReturnCode
sdk_sanity_check_field_handle(TSMLoc field, TSMLoc parent_hdr = nullptr)
{
  if (field == TS_NULL_MLOC) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *field_handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  if (static_cast<HdrHeapObjType>(field_handle->m_type) != HdrHeapObjType::FIELD_SDK_HANDLE) {
    return TS_ERROR;
  }

  if (parent_hdr != nullptr) {
    MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(parent_hdr);
    if (field_handle->mh != mh) {
      return TS_ERROR;
    }
  }
  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_mbuffer(TSMBuffer bufp)
{
  HdrHeapSDKHandle *handle = reinterpret_cast<HdrHeapSDKHandle *>(bufp);
  if ((handle == nullptr) || (handle->m_heap == nullptr) || (handle->m_heap->m_magic != HdrBufMagic::ALIVE)) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_mime_hdr_handle(TSMLoc field)
{
  if (field == TS_NULL_MLOC) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *field_handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  if (static_cast<HdrHeapObjType>(field_handle->m_type) != HdrHeapObjType::MIME_HEADER) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_url_handle(TSMLoc field)
{
  if (field == TS_NULL_MLOC) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *field_handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  if (static_cast<HdrHeapObjType>(field_handle->m_type) != HdrHeapObjType::URL) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_http_hdr_handle(TSMLoc field)
{
  if (field == TS_NULL_MLOC) {
    return TS_ERROR;
  }

  HTTPHdrImpl *field_handle = reinterpret_cast<HTTPHdrImpl *>(field);
  if (static_cast<HdrHeapObjType>(field_handle->m_type) != HdrHeapObjType::HTTP_HEADER) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_continuation(TSCont cont)
{
  if ((cont == nullptr) || (reinterpret_cast<INKContInternal *>(cont)->m_free_magic == INKCONT_INTERN_MAGIC_DEAD)) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_fetch_sm(TSFetchSM fetch_sm)
{
  if (fetch_sm == nullptr) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_http_ssn(TSHttpSsn ssnp)
{
  if (ssnp == nullptr) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_txn(TSHttpTxn txnp)
{
  if ((txnp != nullptr) && ((reinterpret_cast<HttpSM *>(txnp))->magic == HttpSmMagic_t::ALIVE)) {
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

TSReturnCode
sdk_sanity_check_mime_parser(TSMimeParser parser)
{
  if (parser == nullptr) {
    return TS_ERROR;
  }
  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_http_parser(TSHttpParser parser)
{
  if (parser == nullptr) {
    return TS_ERROR;
  }
  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_alt_info(TSHttpAltInfo info)
{
  if (info == nullptr) {
    return TS_ERROR;
  }
  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_hook_id(TSHttpHookID id)
{
  return HttpAPIHooks::is_valid(id) ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
sdk_sanity_check_lifecycle_hook_id(TSLifecycleHookID id)
{
  return LifecycleAPIHooks::is_valid(id) ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
sdk_sanity_check_ssl_hook_id(TSHttpHookID id)
{
  if (id < TS_SSL_FIRST_HOOK || id > TS_SSL_LAST_HOOK) {
    return TS_ERROR;
  }
  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_null_ptr(void const *ptr)
{
  return ptr == nullptr ? TS_ERROR : TS_SUCCESS;
}

// Plugin metric IDs index the plugin RSB, so bounds check against that.
static TSReturnCode
sdk_sanity_check_stat_id(int id)
{
  return (global_api_metrics.valid(id) ? TS_SUCCESS : TS_ERROR);
}

static TSReturnCode
sdk_sanity_check_rpc_handler_options(const TSRPCHandlerOptions *opt)
{
  if (nullptr == opt) {
    return TS_ERROR;
  }

  if (opt->auth.restricted < 0 || opt->auth.restricted > 1) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

/**
  The function checks if the buffer is Modifiable and returns true if
  it is modifiable, else returns false.

*/
bool
isWriteable(TSMBuffer bufp)
{
  if (bufp != nullptr) {
    return (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap->m_writeable;
  }
  return false;
}

////////////////////////////////////////////////////////////////////
//
// API memory management
//
////////////////////////////////////////////////////////////////////

void *
_TSmalloc(size_t size, const char * /* path ATS_UNUSED */)
{
  return ats_malloc(size);
}

void *
_TSrealloc(void *ptr, size_t size, const char * /* path ATS_UNUSED */)
{
  return ats_realloc(ptr, size);
}

// length has to be int64_t and not size_t, since -1 means to call strlen() to get length
char *
_TSstrdup(const char *str, int64_t length, const char *path)
{
  return _xstrdup(str, length, path);
}

size_t
TSstrlcpy(char *dst, const char *str, size_t siz)
{
  return ink_strlcpy(dst, str, siz);
}

size_t
TSstrlcat(char *dst, const char *str, size_t siz)
{
  return ink_strlcat(dst, str, siz);
}

void
TSfree(void *ptr)
{
  ats_free(ptr);
}

////////////////////////////////////////////////////////////////////
//
// Encoding utility
//
////////////////////////////////////////////////////////////////////
TSReturnCode
TSBase64Decode(const char *str, size_t str_len, unsigned char *dst, size_t dst_size, size_t *length)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)str) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)dst) == TS_SUCCESS);

  return ats_base64_decode(str, str_len, dst, dst_size, length) ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSBase64Encode(const char *str, size_t str_len, char *dst, size_t dst_size, size_t *length)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)str) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)dst) == TS_SUCCESS);

  return ats_base64_encode(str, str_len, dst, dst_size, length) ? TS_SUCCESS : TS_ERROR;
}

////////////////////////////////////////////////////////////////////
//
// API utility routines
//
////////////////////////////////////////////////////////////////////

ink_hrtime
TShrtime()
{
  return ink_get_hrtime();
}

////////////////////////////////////////////////////////////////////
//
// API install and plugin locations
//
////////////////////////////////////////////////////////////////////

const char *
TSInstallDirGet()
{
  static std::string prefix = Layout::get()->prefix;
  return prefix.c_str();
}

const char *
TSConfigDirGet()
{
  static std::string sysconfdir = RecConfigReadConfigDir();
  return sysconfdir.c_str();
}

const char *
TSRuntimeDirGet()
{
  static std::string runtimedir = RecConfigReadRuntimeDir();
  return runtimedir.c_str();
}

const char *
TSTrafficServerVersionGet()
{
  return traffic_server_version;
}

int
TSTrafficServerVersionGetMajor()
{
  return ts_major_version;
}
int
TSTrafficServerVersionGetMinor()
{
  return ts_minor_version;
}
int
TSTrafficServerVersionGetPatch()
{
  return ts_patch_version;
}

const char *
TSPluginDirGet()
{
  static std::string path = RecConfigReadPluginDir();
  return path.c_str();
}

////////////////////////////////////////////////////////////////////
//
// Plugin registration
//
////////////////////////////////////////////////////////////////////

TSReturnCode
TSPluginRegister(const TSPluginRegistrationInfo *plugin_info)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)plugin_info) == TS_SUCCESS);

  if (!plugin_reg_current) {
    return TS_ERROR;
  }

  plugin_reg_current->plugin_registered = true;

  if (plugin_info->plugin_name) {
    plugin_reg_current->plugin_name = ats_strdup(plugin_info->plugin_name);
  }

  if (plugin_info->vendor_name) {
    plugin_reg_current->vendor_name = ats_strdup(plugin_info->vendor_name);
  }

  if (plugin_info->support_email) {
    plugin_reg_current->support_email = ats_strdup(plugin_info->support_email);
  }

  return TS_SUCCESS;
}

TSReturnCode
TSPluginDSOReloadEnable(int enabled)
{
  TSReturnCode ret = TS_SUCCESS;
  if (!plugin_reg_current) {
    return TS_ERROR;
  }

  if (!enabled) {
    if (!PluginDso::loadedPlugins()->addPluginPathToDsoOptOutTable(plugin_reg_current->plugin_path)) {
      ret = TS_ERROR;
    }
  }

  return ret;
}

////////////////////////////////////////////////////////////////////
//
// API file management
//
////////////////////////////////////////////////////////////////////

TSFile
TSfopen(const char *filename, const char *mode)
{
  FileImpl *file;

  file = new FileImpl;
  if (!file->fopen(filename, mode)) {
    delete file;
    return nullptr;
  }

  return reinterpret_cast<TSFile>(file);
}

void
TSfclose(TSFile filep)
{
  FileImpl *file = reinterpret_cast<FileImpl *>(filep);
  file->fclose();
  delete file;
}

ssize_t
TSfread(TSFile filep, void *buf, size_t length)
{
  FileImpl *file = reinterpret_cast<FileImpl *>(filep);
  return file->fread(buf, length);
}

ssize_t
TSfwrite(TSFile filep, const void *buf, size_t length)
{
  FileImpl *file = reinterpret_cast<FileImpl *>(filep);
  return file->fwrite(buf, length);
}

void
TSfflush(TSFile filep)
{
  FileImpl *file = reinterpret_cast<FileImpl *>(filep);
  file->fflush();
}

char *
TSfgets(TSFile filep, char *buf, size_t length)
{
  FileImpl *file = reinterpret_cast<FileImpl *>(filep);
  return file->fgets(buf, length);
}

////////////////////////////////////////////////////////////////////
//
// Header component object handles
//
////////////////////////////////////////////////////////////////////

TSReturnCode
TSHandleMLocRelease(TSMBuffer bufp, TSMLoc parent, TSMLoc mloc)
{
  MIMEFieldSDKHandle *field_handle;
  HdrHeapObjImpl     *obj = reinterpret_cast<HdrHeapObjImpl *>(mloc);

  if (mloc == TS_NULL_MLOC) {
    return TS_SUCCESS;
  }

  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);

  switch (static_cast<HdrHeapObjType>(obj->m_type)) {
  case HdrHeapObjType::URL:
  case HdrHeapObjType::HTTP_HEADER:
  case HdrHeapObjType::MIME_HEADER:
    return TS_SUCCESS;

  case HdrHeapObjType::FIELD_SDK_HANDLE:
    field_handle = static_cast<MIMEFieldSDKHandle *>(obj);
    if (sdk_sanity_check_field_handle(mloc, parent) != TS_SUCCESS) {
      return TS_ERROR;
    }

    sdk_free_field_handle(bufp, field_handle);
    return TS_SUCCESS;

  default:
    ink_release_assert(!"invalid mloc");
    return TS_ERROR;
  }
}

////////////////////////////////////////////////////////////////////
//
// HdrHeaps (previously known as "Marshal Buffers")
//
////////////////////////////////////////////////////////////////////

// TSMBuffer: pointers to HdrHeapSDKHandle objects

TSMBuffer
TSMBufferCreate()
{
  TSMBuffer         bufp;
  HdrHeapSDKHandle *new_heap = new HdrHeapSDKHandle;

  new_heap->m_heap = new_HdrHeap();
  bufp             = reinterpret_cast<TSMBuffer>(new_heap);
  // TODO: Should remove this when memory allocation is guaranteed to fail.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  return bufp;
}

TSReturnCode
TSMBufferDestroy(TSMBuffer bufp)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  HdrHeapSDKHandle *sdk_heap = reinterpret_cast<HdrHeapSDKHandle *>(bufp);
  sdk_heap->m_heap->destroy();
  delete sdk_heap;
  return TS_SUCCESS;
}

////////////////////////////////////////////////////////////////////
//
// URLs
//
////////////////////////////////////////////////////////////////////

// TSMBuffer: pointers to HdrHeapSDKHandle objects
// TSMLoc:    pointers to URLImpl objects
TSReturnCode
TSUrlCreate(TSMBuffer bufp, TSMLoc *locp)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr(locp) == TS_SUCCESS);

  if (isWriteable(bufp)) {
    HdrHeap *heap = reinterpret_cast<HdrHeapSDKHandle *>(bufp)->m_heap;
    *locp         = reinterpret_cast<TSMLoc>(url_create(heap));
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

TSReturnCode
TSUrlClone(TSMBuffer dest_bufp, TSMBuffer src_bufp, TSMLoc src_url, TSMLoc *locp)
{
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(src_url) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr(locp) == TS_SUCCESS);

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  HdrHeap *s_heap, *d_heap;
  URLImpl *s_url, *d_url;

  s_heap = reinterpret_cast<HdrHeapSDKHandle *>(src_bufp)->m_heap;
  d_heap = reinterpret_cast<HdrHeapSDKHandle *>(dest_bufp)->m_heap;
  s_url  = reinterpret_cast<URLImpl *>(src_url);

  d_url = url_copy(s_url, s_heap, d_heap, (s_heap != d_heap));
  *locp = reinterpret_cast<TSMLoc>(d_url);
  return TS_SUCCESS;
}

TSReturnCode
TSUrlCopy(TSMBuffer dest_bufp, TSMLoc dest_obj, TSMBuffer src_bufp, TSMLoc src_obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(src_obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(dest_obj) == TS_SUCCESS);

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  HdrHeap *s_heap, *d_heap;
  URLImpl *s_url, *d_url;

  s_heap = reinterpret_cast<HdrHeapSDKHandle *>(src_bufp)->m_heap;
  d_heap = reinterpret_cast<HdrHeapSDKHandle *>(dest_bufp)->m_heap;
  s_url  = reinterpret_cast<URLImpl *>(src_obj);
  d_url  = reinterpret_cast<URLImpl *>(dest_obj);

  url_copy_onto(s_url, s_heap, d_url, d_heap, (s_heap != d_heap));
  return TS_SUCCESS;
}

void
TSUrlPrint(TSMBuffer bufp, TSMLoc obj, TSIOBuffer iobufp)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_iocore_structure(iobufp) == TS_SUCCESS);

  MIOBuffer     *b = reinterpret_cast<MIOBuffer *>(iobufp);
  IOBufferBlock *blk;
  int            bufindex;
  int            tmp, dumpoffset;
  int            done;
  URL            u;

  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
  dumpoffset   = 0;

  do {
    blk = b->get_current_block();
    if (!blk || blk->write_avail() == 0) {
      b->add_block();
      blk = b->get_current_block();
    }

    bufindex = 0;
    tmp      = dumpoffset;

    done = u.print(blk->end(), blk->write_avail(), &bufindex, &tmp);

    dumpoffset += bufindex;
    b->fill(bufindex);
  } while (!done);
}

TSParseResult
TSUrlParse(TSMBuffer bufp, TSMLoc obj, const char **start, const char *end)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)start) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)*start) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)end) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_PARSE_ERROR;
  }

  URL u;
  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
  url_clear(u.m_url_impl);
  return static_cast<TSParseResult>(u.parse(start, end));
}

int
TSUrlLengthGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  URLImpl *url_impl = reinterpret_cast<URLImpl *>(obj);
  return url_length_get(url_impl);
}

char *
TSUrlStringGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  // bufp is not actually used anymore, so it can be null.
  if (bufp) {
    sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  }
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)length) == TS_SUCCESS);

  URLImpl *url_impl = reinterpret_cast<URLImpl *>(obj);
  return url_string_get(url_impl, nullptr, length, nullptr);
}

using URLPartGetF = std::string_view (URL::*)() const noexcept;
using URLPartSetF = void (URL::*)(std::string_view);

static const std::string_view
URLPartGet(TSMBuffer bufp, TSMLoc obj, URLPartGetF url_f)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  URL u;

  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);

  return (u.*url_f)();
}

static TSReturnCode
URLPartSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length, URLPartSetF url_f)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  URL u;
  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);

  if (!value) {
    length = 0;
  } else if (length < 0) {
    length = strlen(value);
  }
  (u.*url_f)(std::string_view{value, static_cast<std::string_view::size_type>(length)});

  return TS_SUCCESS;
}

const char *
TSUrlRawSchemeGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  auto scheme{URLPartGet(bufp, obj, &URL::scheme_get)};
  if (length) {
    *length = static_cast<int>(scheme.length());
  }
  return scheme.data();
}

const char *
TSUrlSchemeGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  char const *data = TSUrlRawSchemeGet(bufp, obj, length);
  if (data && *length) {
    return data;
  }
  switch (reinterpret_cast<URLImpl *>(obj)->m_url_type) {
  case URLType::HTTP:
    data    = URL_SCHEME_HTTP.c_str();
    *length = static_cast<int>(URL_SCHEME_HTTP.length());
    break;
  case URLType::HTTPS:
    data    = URL_SCHEME_HTTPS.c_str();
    *length = static_cast<int>(URL_SCHEME_HTTPS.length());
    break;
  default:
    *length = 0;
    data    = nullptr;
  }
  return data;
}

TSReturnCode
TSUrlSchemeSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  return URLPartSet(bufp, obj, value, length, &URL::scheme_set);
}

/* Internet specific URLs */

const char *
TSUrlUserGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  auto user{URLPartGet(bufp, obj, &URL::user_get)};
  if (length) {
    *length = static_cast<int>(user.length());
  }
  return user.data();
}

TSReturnCode
TSUrlUserSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  return URLPartSet(bufp, obj, value, length, &URL::user_set);
}

const char *
TSUrlPasswordGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  auto password{URLPartGet(bufp, obj, &URL::password_get)};
  if (length) {
    *length = static_cast<int>(password.length());
  }
  return password.data();
}

TSReturnCode
TSUrlPasswordSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  return URLPartSet(bufp, obj, value, length, &URL::password_set);
}

const char *
TSUrlHostGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  auto host{URLPartGet(bufp, obj, &URL::host_get)};
  if (length) {
    *length = static_cast<int>(host.length());
  }
  return host.data();
}

TSReturnCode
TSUrlHostSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  return URLPartSet(bufp, obj, value, length, &URL::host_set);
}

int
TSUrlPortGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  URL u;
  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);

  return u.port_get();
}

int
TSUrlRawPortGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  URL u;
  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);

  return u.port_get_raw();
}

TSReturnCode
TSUrlPortSet(TSMBuffer bufp, TSMLoc obj, int port)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  if (!isWriteable(bufp) || (port < 0)) {
    return TS_ERROR;
  }

  URL u;

  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
  u.port_set(port);
  return TS_SUCCESS;
}

/* FTP and HTTP specific URLs  */

const char *
TSUrlPathGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  auto path{URLPartGet(bufp, obj, &URL::path_get)};
  if (length) {
    *length = static_cast<int>(path.length());
  }
  return path.data();
}

TSReturnCode
TSUrlPathSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  return URLPartSet(bufp, obj, value, length, &URL::path_set);
}

/* FTP specific URLs */

int
TSUrlFtpTypeGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  URL u;
  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
  return u.type_code_get();
}

TSReturnCode
TSUrlFtpTypeSet(TSMBuffer bufp, TSMLoc obj, int type)
{
  // The valid values are : 0, 65('A'), 97('a'),
  // 69('E'), 101('e'), 73 ('I') and 105('i').
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  if ((type == 0 || type == 'A' || type == 'E' || type == 'I' || type == 'a' || type == 'i' || type == 'e') && isWriteable(bufp)) {
    URL u;

    u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
    u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
    u.type_code_set(type);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

/* HTTP specific URLs */

const char *
TSUrlHttpQueryGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  auto query{URLPartGet(bufp, obj, &URL::query_get)};
  if (length) {
    *length = static_cast<int>(query.length());
  }
  return query.data();
}

TSReturnCode
TSUrlHttpQuerySet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  return URLPartSet(bufp, obj, value, length, &URL::query_set);
}

const char *
TSUrlHttpFragmentGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  auto fragment{URLPartGet(bufp, obj, &URL::fragment_get)};
  if (length) {
    *length = static_cast<int>(fragment.length());
  }
  return fragment.data();
}

TSReturnCode
TSUrlHttpFragmentSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  return URLPartSet(bufp, obj, value, length, &URL::fragment_set);
}

// URL percent encoding
TSReturnCode
TSStringPercentEncode(const char *str, int str_len, char *dst, size_t dst_size, size_t *length, const unsigned char *map)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)str) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)dst) == TS_SUCCESS);

  int new_len; // Unfortunately, a lot of the core uses "int" for length's internally...

  if (str_len < 0) {
    str_len = strlen(str);
  }

  sdk_assert(str_len < static_cast<int>(dst_size));

  // TODO: Perhaps we should make escapify_url() deal with const properly...
  // You would think making escapify_url const correct for the source argument would be easy, but in the case where
  // No escaping is needed, the source argument is returned.  If there is a destination argument, the source is copied over
  // However, if there is no destination argument, none is allocated.  I don't understand the full possibility of calling cases.
  // It seems like we might want to review how this is being called and perhaps create a number of smaller accessor methods that
  // can be set up correctly.
  if (nullptr == Encoding::pure_escapify_url(nullptr, const_cast<char *>(str), str_len, &new_len, dst, dst_size, map)) {
    if (length) {
      *length = 0;
    }
    return TS_ERROR;
  }

  if (length) {
    *length = new_len;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSStringPercentDecode(const char *str, size_t str_len, char *dst, size_t dst_size, size_t *length)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)str) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)dst) == TS_SUCCESS);

  if (0 == str_len) {
    str_len = strlen(str);
  }

  // return unescapifyStr(str);
  char       *buffer = dst;
  const char *src    = str;
  int         s      = 0; // State, which we don't really use

  // TODO: We should check for "failures" here?
  unescape_str(buffer, buffer + dst_size, src, src + str_len, s);

  size_t data_written   = std::min<size_t>(buffer - dst, dst_size - 1);
  *(dst + data_written) = '\0';

  if (length) {
    *length = (data_written);
  }

  return TS_SUCCESS;
}

TSReturnCode
TSUrlPercentEncode(TSMBuffer bufp, TSMLoc obj, char *dst, size_t dst_size, size_t *length, const unsigned char *map)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  char        *url;
  int          url_len;
  TSReturnCode ret;
  URLImpl     *url_impl = reinterpret_cast<URLImpl *>(obj);

  // TODO: at some point, it might be nice to allow this to write to a pre-allocated buffer
  url = url_string_get(url_impl, nullptr, &url_len, nullptr);
  ret = TSStringPercentEncode(url, url_len, dst, dst_size, length, map);
  ats_free(url);

  return ret;
}

// pton
TSReturnCode
TSIpStringToAddr(const char *str, size_t str_len, sockaddr *addr)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)str) == TS_SUCCESS);

  if (0 != ats_ip_pton(std::string_view(str, str_len), addr)) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

////////////////////////////////////////////////////////////////////
//
// MIME Headers
//
////////////////////////////////////////////////////////////////////

/**************/
/* MimeParser */
/**************/

TSMimeParser
TSMimeParserCreate()
{
  TSMimeParser parser = reinterpret_cast<TSMimeParser>(ats_malloc(sizeof(MIMEParser)));

  mime_parser_init(reinterpret_cast<MIMEParser *>(parser));
  return parser;
}

void
TSMimeParserClear(TSMimeParser parser)
{
  sdk_assert(sdk_sanity_check_mime_parser(parser) == TS_SUCCESS);

  mime_parser_clear(reinterpret_cast<MIMEParser *>(parser));
}

void
TSMimeParserDestroy(TSMimeParser parser)
{
  sdk_assert(sdk_sanity_check_mime_parser(parser) == TS_SUCCESS);

  mime_parser_clear(reinterpret_cast<MIMEParser *>(parser));
  ats_free(parser);
}

/***********/
/* MimeHdr */
/***********/

// TSMBuffer: pointers to HdrHeapSDKHandle objects
// TSMLoc:    pointers to MIMEFieldSDKHandle objects

TSReturnCode
TSMimeHdrCreate(TSMBuffer bufp, TSMLoc *locp)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If not allowed, set *locp to TS_NULL_MLOC.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)locp) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  *locp = reinterpret_cast<TSMLoc>(mime_hdr_create((reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap));
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrDestroy(TSMBuffer bufp, TSMLoc obj)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(obj) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS));

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(obj);

  mime_hdr_destroy((reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap, mh);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrClone(TSMBuffer dest_bufp, TSMBuffer src_bufp, TSMLoc src_hdr, TSMLoc *locp)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If not allowed, set *locp to TS_NULL_MLOC.
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mime_hdr_handle(src_hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(src_hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)locp) == TS_SUCCESS);

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  HdrHeap     *s_heap, *d_heap;
  MIMEHdrImpl *s_mh, *d_mh;

  s_heap = (reinterpret_cast<HdrHeapSDKHandle *>(src_bufp))->m_heap;
  d_heap = (reinterpret_cast<HdrHeapSDKHandle *>(dest_bufp))->m_heap;
  s_mh   = _hdr_mloc_to_mime_hdr_impl(src_hdr);

  d_mh  = mime_hdr_clone(s_mh, s_heap, d_heap, (s_heap != d_heap));
  *locp = reinterpret_cast<TSMLoc>(d_mh);

  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrCopy(TSMBuffer dest_bufp, TSMLoc dest_obj, TSMBuffer src_bufp, TSMLoc src_obj)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(src_obj) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(src_obj) == TS_SUCCESS));
  sdk_assert((sdk_sanity_check_mime_hdr_handle(dest_obj) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(dest_obj) == TS_SUCCESS));

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  HdrHeap     *s_heap, *d_heap;
  MIMEHdrImpl *s_mh, *d_mh;

  s_heap = (reinterpret_cast<HdrHeapSDKHandle *>(src_bufp))->m_heap;
  d_heap = (reinterpret_cast<HdrHeapSDKHandle *>(dest_bufp))->m_heap;
  s_mh   = _hdr_mloc_to_mime_hdr_impl(src_obj);
  d_mh   = _hdr_mloc_to_mime_hdr_impl(dest_obj);

  mime_hdr_fields_clear(d_heap, d_mh);
  mime_hdr_copy_onto(s_mh, s_heap, d_mh, d_heap, (s_heap != d_heap));
  return TS_SUCCESS;
}

void
TSMimeHdrPrint(TSMLoc obj, TSIOBuffer iobufp)
{
  sdk_assert((sdk_sanity_check_mime_hdr_handle(obj) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_iocore_structure(iobufp) == TS_SUCCESS);

  MIMEHdrImpl const *mh = _hdr_mloc_to_mime_hdr_impl(obj);
  MIOBuffer         *b  = reinterpret_cast<MIOBuffer *>(iobufp);
  IOBufferBlock     *blk;
  int                bufindex;
  int                tmp, dumpoffset = 0;
  int                done;

  do {
    blk = b->get_current_block();
    if (!blk || blk->write_avail() == 0) {
      b->add_block();
      blk = b->get_current_block();
    }

    bufindex = 0;
    tmp      = dumpoffset;
    done     = mime_hdr_print(mh, blk->end(), blk->write_avail(), &bufindex, &tmp);

    dumpoffset += bufindex;
    b->fill(bufindex);
  } while (!done);
}

TSParseResult
TSMimeHdrParse(TSMimeParser parser, TSMBuffer bufp, TSMLoc obj, const char **start, const char *end)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(obj) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_null_ptr((void *)start) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)*start) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)end) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_PARSE_ERROR;
  }

  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(obj);

  return static_cast<TSParseResult>(mime_parser_parse(reinterpret_cast<MIMEParser *>(parser),
                                                      (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap, mh, start, end, false,
                                                      false, false));
}

int
TSMimeHdrLengthGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(obj) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS));

  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(obj);
  return mime_hdr_length_get(mh);
}

TSReturnCode
TSMimeHdrFieldsClear(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(obj) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS));

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(obj);

  mime_hdr_fields_clear((reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap, mh);
  return TS_SUCCESS;
}

int
TSMimeHdrFieldsCount(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(obj) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS));

  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(obj);
  return mime_hdr_fields_count(mh);
}

// The following three helper functions should not be used in plugins! Since they are not used
// by plugins, there's no need to validate the input.
static const char *
TSMimeFieldValueGet(TSMBuffer /* bufp ATS_UNUSED */, TSMLoc field_obj, int idx, int *value_len_ptr)
{
  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field_obj);

  if (idx >= 0) {
    return mime_field_value_get_comma_val(handle->field_ptr, value_len_ptr, idx);
  } else {
    auto value{handle->field_ptr->value_get()};
    *value_len_ptr = static_cast<int>(value.length());
    return value.data();
  }
}

static void
TSMimeFieldValueSet(TSMBuffer bufp, TSMLoc field_obj, int idx, const char *value, int length)
{
  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field_obj);
  HdrHeap            *heap   = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;

  if (length == -1) {
    length = strlen(value);
  }

  if (idx >= 0) {
    mime_field_value_set_comma_val(heap, handle->mh, handle->field_ptr, idx,
                                   std::string_view{value, static_cast<std::string_view::size_type>(length)});
  } else {
    mime_field_value_set(heap, handle->mh, handle->field_ptr,
                         std::string_view{value, static_cast<std::string_view::size_type>(length)}, true);
  }
}

static void
TSMimeFieldValueInsert(TSMBuffer bufp, TSMLoc field_obj, const char *value, int length, int idx)
{
  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field_obj);
  HdrHeap            *heap   = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;

  if (length == -1) {
    length = strlen(value);
  }

  mime_field_value_insert_comma_val(heap, handle->mh, handle->field_ptr, idx,
                                    std::string_view{value, static_cast<std::string_view::size_type>(length)});
}

/****************/
/* MimeHdrField */
/****************/

// TSMBuffer: pointers to HdrHeapSDKHandle objects
// TSMLoc:    pointers to MIMEFieldSDKHandle objects

TSMLoc
TSMimeHdrFieldGet(TSMBuffer bufp, TSMLoc hdr_obj, int idx)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr_obj) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(hdr_obj) == TS_SUCCESS));
  sdk_assert(idx >= 0);

  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(hdr_obj);
  MIMEField   *f  = mime_hdr_field_get(mh, idx);

  if (f == nullptr) {
    return TS_NULL_MLOC;
  }

  MIMEFieldSDKHandle *h = sdk_alloc_field_handle(bufp, mh);

  h->field_ptr = f;
  return reinterpret_cast<TSMLoc>(h);
}

TSMLoc
TSMimeHdrFieldFind(TSMBuffer bufp, TSMLoc hdr_obj, const char *name, int length)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr_obj) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(hdr_obj) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_null_ptr((void *)name) == TS_SUCCESS);

  if (length == -1) {
    length = strlen(name);
  }

  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(hdr_obj);
  MIMEField   *f  = mime_hdr_field_find(mh, std::string_view{name, static_cast<std::string_view::size_type>(length)});

  if (f == nullptr) {
    return TS_NULL_MLOC;
  }

  MIMEFieldSDKHandle *h = sdk_alloc_field_handle(bufp, mh);

  h->field_ptr = f;
  return reinterpret_cast<TSMLoc>(h);
}

TSReturnCode
TSMimeHdrFieldAppend(TSMBuffer bufp, TSMLoc mh_mloc, TSMLoc field_mloc)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(mh_mloc) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(mh_mloc) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field_mloc) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEField          *mh_field;
  MIMEHdrImpl        *mh           = _hdr_mloc_to_mime_hdr_impl(mh_mloc);
  MIMEFieldSDKHandle *field_handle = reinterpret_cast<MIMEFieldSDKHandle *>(field_mloc);

  //////////////////////////////////////////////////////////////////////
  // The field passed in field_mloc might have been allocated from    //
  // inside a MIME header (the correct way), or it might have been    //
  // created in isolation as a "standalone field" (the old way).      //
  //                                                                  //
  // If it's a standalone field (the associated mime header is null), //
  // then we need to now allocate a real field inside the header,     //
  // copy over the data, and convert the standalone field into a      //
  // forwarding pointer to the real field, in case it's used again    //
  //////////////////////////////////////////////////////////////////////
  if (field_handle->mh == nullptr) {
    HdrHeap *heap = ((reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap);

    // allocate a new hdr field and copy any pre-set info
    mh_field = mime_field_create(heap, mh);

    // FIX: is it safe to copy everything over?
    memcpy(mh_field, field_handle->field_ptr, sizeof(MIMEField));

    // now set up the forwarding ptr from standalone field to hdr field
    field_handle->mh        = mh;
    field_handle->field_ptr = mh_field;
  }

  ink_assert(field_handle->mh == mh);
  ink_assert(field_handle->field_ptr->m_ptr_name);

  mime_hdr_field_attach(mh, field_handle->field_ptr, 1, nullptr);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldRemove(TSMBuffer bufp, TSMLoc mh_mloc, TSMLoc field_mloc)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(mh_mloc) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(mh_mloc) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field_mloc, mh_mloc) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *field_handle = reinterpret_cast<MIMEFieldSDKHandle *>(field_mloc);

  if (field_handle->mh != nullptr) {
    MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(mh_mloc);
    ink_assert(mh == field_handle->mh);
    sdk_sanity_check_field_handle(field_mloc, mh_mloc);
    mime_hdr_field_detach(mh, field_handle->field_ptr, false); // only detach this dup
  }
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldDestroy(TSMBuffer bufp, TSMLoc mh_mloc, TSMLoc field_mloc)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(mh_mloc) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(mh_mloc) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field_mloc, mh_mloc) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *field_handle = reinterpret_cast<MIMEFieldSDKHandle *>(field_mloc);

  if (field_handle->mh == nullptr) { // NOT SUPPORTED!!
    ink_release_assert(!"Failed MH");
  } else {
    MIMEHdrImpl *mh   = _hdr_mloc_to_mime_hdr_impl(mh_mloc);
    HdrHeap     *heap = ((reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap);

    ink_assert(mh == field_handle->mh);
    if (sdk_sanity_check_field_handle(field_mloc, mh_mloc) != TS_SUCCESS) {
      return TS_ERROR;
    }

    // detach and delete this field, but not all dups
    mime_hdr_field_delete(heap, mh, field_handle->field_ptr, false);
  }
  // for consistence, the handle will not be released here.
  // users will be required to do it.
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldCreate(TSMBuffer bufp, TSMLoc mh_mloc, TSMLoc *locp)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If not allowed, set *locp to TS_NULL_MLOC.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(mh_mloc) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(mh_mloc) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_null_ptr((void *)locp) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEHdrImpl        *mh   = _hdr_mloc_to_mime_hdr_impl(mh_mloc);
  HdrHeap            *heap = ((reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap);
  MIMEFieldSDKHandle *h    = sdk_alloc_field_handle(bufp, mh);

  h->field_ptr = mime_field_create(heap, mh);
  *locp        = reinterpret_cast<TSMLoc>(h);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldCreateNamed(TSMBuffer bufp, TSMLoc mh_mloc, const char *name, int name_len, TSMLoc *locp)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(mh_mloc) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(mh_mloc) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_null_ptr((void *)name) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)locp) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  if (name_len == -1) {
    name_len = strlen(name);
  }

  MIMEHdrImpl        *mh   = _hdr_mloc_to_mime_hdr_impl(mh_mloc);
  HdrHeap            *heap = ((reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap);
  MIMEFieldSDKHandle *h    = sdk_alloc_field_handle(bufp, mh);
  h->field_ptr = mime_field_create_named(heap, mh, std::string_view{name, static_cast<std::string_view::size_type>(name_len)});
  *locp        = reinterpret_cast<TSMLoc>(h);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldCopy(TSMBuffer dest_bufp, TSMLoc dest_hdr, TSMLoc dest_field, TSMBuffer src_bufp, TSMLoc src_hdr, TSMLoc src_field)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(src_hdr) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(src_hdr) == TS_SUCCESS));
  sdk_assert((sdk_sanity_check_mime_hdr_handle(dest_hdr) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(dest_hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(src_field, src_hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_field_handle(dest_field, dest_hdr) == TS_SUCCESS);

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  bool                dest_attached;
  MIMEFieldSDKHandle *s_handle = reinterpret_cast<MIMEFieldSDKHandle *>(src_field);
  MIMEFieldSDKHandle *d_handle = reinterpret_cast<MIMEFieldSDKHandle *>(dest_field);
  HdrHeap            *d_heap   = (reinterpret_cast<HdrHeapSDKHandle *>(dest_bufp))->m_heap;

  // FIX: This tortuous detach/change/attach algorithm is due to the
  //      fact that we can't change the name of an attached header (assertion)

  // TODO: This is never used ... is_live() has no side effects, so this should be ok
  // to not call, so commented out
  // src_attached = (s_handle->mh && s_handle->field_ptr->is_live());
  dest_attached = (d_handle->mh && d_handle->field_ptr->is_live());

  if (dest_attached) {
    mime_hdr_field_detach(d_handle->mh, d_handle->field_ptr, false);
  }

  mime_field_name_value_set(
    d_heap, d_handle->mh, d_handle->field_ptr, s_handle->field_ptr->m_wks_idx,
    std::string_view{s_handle->field_ptr->m_ptr_name, static_cast<std::string_view::size_type>(s_handle->field_ptr->m_len_name)},
    std::string_view{s_handle->field_ptr->m_ptr_value, static_cast<std::string_view::size_type>(s_handle->field_ptr->m_len_value)},
    0, 0, true);

  if (dest_attached) {
    mime_hdr_field_attach(d_handle->mh, d_handle->field_ptr, 1, nullptr);
  }
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldClone(TSMBuffer dest_bufp, TSMLoc dest_hdr, TSMBuffer src_bufp, TSMLoc src_hdr, TSMLoc src_field, TSMLoc *locp)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If not allowed, set *locp to TS_NULL_MLOC.
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(dest_hdr) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(dest_hdr) == TS_SUCCESS));
  sdk_assert((sdk_sanity_check_mime_hdr_handle(src_hdr) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(src_hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(src_field, src_hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)locp) == TS_SUCCESS);

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  // This is sort of sub-optimal, since we'll check the args again. TODO.
  if (TSMimeHdrFieldCreate(dest_bufp, dest_hdr, locp) == TS_SUCCESS) {
    TSMimeHdrFieldCopy(dest_bufp, dest_hdr, *locp, src_bufp, src_hdr, src_field);
    return TS_SUCCESS;
  }
  // TSMimeHdrFieldCreate() failed for some reason.
  return TS_ERROR;
}

TSReturnCode
TSMimeHdrFieldCopyValues(TSMBuffer dest_bufp, TSMLoc dest_hdr, TSMLoc dest_field, TSMBuffer src_bufp, TSMLoc src_hdr,
                         TSMLoc src_field)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(src_hdr) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(src_hdr) == TS_SUCCESS));
  sdk_assert((sdk_sanity_check_mime_hdr_handle(dest_hdr) == TS_SUCCESS) ||
             (sdk_sanity_check_http_hdr_handle(dest_hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(src_field, src_hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_field_handle(dest_field, dest_hdr) == TS_SUCCESS);

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *s_handle = reinterpret_cast<MIMEFieldSDKHandle *>(src_field);
  MIMEFieldSDKHandle *d_handle = reinterpret_cast<MIMEFieldSDKHandle *>(dest_field);
  HdrHeap            *d_heap   = (reinterpret_cast<HdrHeapSDKHandle *>(dest_bufp))->m_heap;
  MIMEField          *s_field, *d_field;

  s_field = s_handle->field_ptr;
  d_field = d_handle->field_ptr;
  mime_field_value_set(d_heap, d_handle->mh, d_field,
                       std::string_view{s_field->m_ptr_value, static_cast<std::string_view::size_type>(s_field->m_len_value)},
                       true);
  return TS_SUCCESS;
}

TSMLoc
TSMimeHdrFieldNext(TSMBuffer bufp, TSMLoc hdr, TSMLoc field)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (auto handle = reinterpret_cast<MIMEFieldSDKHandle *>(field); handle->mh != nullptr) {
    if (auto spot = handle->mh->find(handle->field_ptr); spot != handle->mh->end()) {
      if (++spot != handle->mh->end()) {
        MIMEFieldSDKHandle *h = sdk_alloc_field_handle(bufp, handle->mh);
        h->field_ptr          = &*spot;
        return reinterpret_cast<TSMLoc>(h);
      }
    }
  }

  return TS_NULL_MLOC;
}

TSMLoc
TSMimeHdrFieldNextDup(TSMBuffer bufp, TSMLoc hdr, TSMLoc field)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  MIMEHdrImpl        *mh           = _hdr_mloc_to_mime_hdr_impl(hdr);
  MIMEFieldSDKHandle *field_handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  MIMEField          *next         = field_handle->field_ptr->m_next_dup;
  if (next == nullptr) {
    return TS_NULL_MLOC;
  }

  MIMEFieldSDKHandle *next_handle = sdk_alloc_field_handle(bufp, mh);
  next_handle->field_ptr          = next;
  return reinterpret_cast<TSMLoc>(next_handle);
}

int
TSMimeHdrFieldLengthGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  return mime_field_length_get(handle->field_ptr);
}

const char *
TSMimeHdrFieldNameGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int *length)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)length) == TS_SUCCESS);

  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  auto                name{handle->field_ptr->name_get()};
  *length = static_cast<int>(name.length());
  return name.data();
}

TSReturnCode
TSMimeHdrFieldNameSet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, const char *name, int length)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)name) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  if (length == -1) {
    length = strlen(name);
  }

  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  HdrHeap            *heap   = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;

  int attached = (handle->mh && handle->field_ptr->is_live());

  if (attached) {
    mime_hdr_field_detach(handle->mh, handle->field_ptr, false);
  }

  handle->field_ptr->name_set(heap, handle->mh, std::string_view{name, static_cast<std::string_view::size_type>(length)});

  if (attached) {
    mime_hdr_field_attach(handle->mh, handle->field_ptr, 1, nullptr);
  }
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValuesClear(TSMBuffer bufp, TSMLoc hdr, TSMLoc field)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  HdrHeap            *heap   = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;

  /**
   * Modified the string value passed from an empty string ("") to null.
   * An empty string is also considered to be a token. The correct value of
   * the field after this function should be null.
   */
  mime_field_value_set(heap, handle->mh, handle->field_ptr, std::string_view{nullptr, 0}, true);
  return TS_SUCCESS;
}

int
TSMimeHdrFieldValuesCount(TSMBuffer bufp, TSMLoc hdr, TSMLoc field)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  return mime_field_value_get_comma_val_count(handle->field_ptr);
}

const char *
TSMimeHdrFieldValueStringGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, int *value_len_ptr)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value_len_ptr) == TS_SUCCESS);

  return TSMimeFieldValueGet(bufp, field, idx, value_len_ptr);
}

time_t
TSMimeHdrFieldValueDateGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  int         value_len;
  const char *value_str = TSMimeFieldValueGet(bufp, field, -1, &value_len);

  if (value_str == nullptr) {
    return static_cast<time_t>(0);
  }

  return mime_parse_date(value_str, value_str + value_len);
}

time_t
TSMimeParseDate(char const *const value_str, int const value_len)
{
  if (value_str == nullptr) {
    return static_cast<time_t>(0);
  }

  return mime_parse_date(value_str, value_str + value_len);
}

int
TSMimeHdrFieldValueIntGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  int         value_len;
  const char *value_str = TSMimeFieldValueGet(bufp, field, idx, &value_len);

  if (value_str == nullptr) {
    return 0;
  }

  return mime_parse_int(value_str, value_str + value_len);
}

int64_t
TSMimeHdrFieldValueInt64Get(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  int         value_len;
  const char *value_str = TSMimeFieldValueGet(bufp, field, idx, &value_len);

  if (value_str == nullptr) {
    return 0;
  }

  return mime_parse_int64(value_str, value_str + value_len);
}

unsigned int
TSMimeHdrFieldValueUintGet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  int         value_len;
  const char *value_str = TSMimeFieldValueGet(bufp, field, idx, &value_len);

  if (value_str == nullptr) {
    return 0;
  }

  return mime_parse_uint(value_str, value_str + value_len);
}

TSReturnCode
TSMimeHdrFieldValueStringSet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, const char *value, int length)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  if (length == -1) {
    length = strlen(value);
  }

  TSMimeFieldValueSet(bufp, field, idx, value, length);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueDateSet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, time_t value)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  char tmp[33];
  int  len = mime_format_date(tmp, value);

  // idx is ignored and we overwrite all existing values
  // TSMimeFieldValueSet(bufp, field_obj, idx, tmp, len);
  TSMimeFieldValueSet(bufp, field, -1, tmp, len);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeFormatDate(time_t const value_time, char *const value_str, int *const value_length)
{
  if (value_length == nullptr) {
    return TS_ERROR;
  }

  if (*value_length < 33) {
    return TS_ERROR;
  }

  *value_length = mime_format_date(value_str, value_time);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueIntSet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, int value)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  char tmp[16];
  int  len = mime_format_int(tmp, value, sizeof(tmp));

  TSMimeFieldValueSet(bufp, field, idx, tmp, len);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueInt64Set(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, int64_t value)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  char tmp[20];
  int  len = mime_format_int64(tmp, value, sizeof(tmp));

  TSMimeFieldValueSet(bufp, field, idx, tmp, len);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueUintSet(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, unsigned int value)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  char tmp[16];
  int  len = mime_format_uint(tmp, value, sizeof(tmp));

  TSMimeFieldValueSet(bufp, field, idx, tmp, len);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueAppend(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, const char *value, int length)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value) == TS_SUCCESS);
  sdk_assert(idx >= 0);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  HdrHeap            *heap   = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;

  if (length == -1) {
    length = strlen(value);
  }
  mime_field_value_extend_comma_val(heap, handle->mh, handle->field_ptr, idx,
                                    std::string_view{value, static_cast<std::string_view::size_type>(length)});
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueStringInsert(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, const char *value, int length)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR, else return TS_SUCCESS.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  if (length == -1) {
    length = strlen(value);
  }
  TSMimeFieldValueInsert(bufp, field, value, length, idx);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueIntInsert(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, int value)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR, else return TS_SUCCESS.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  char tmp[16];
  int  len = mime_format_int(tmp, value, sizeof(tmp));

  TSMimeFieldValueInsert(bufp, field, tmp, len, idx);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueUintInsert(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx, unsigned int value)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR, else return TS_SUCCESS.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  char tmp[16];
  int  len = mime_format_uint(tmp, value, sizeof(tmp));

  TSMimeFieldValueInsert(bufp, field, tmp, len, idx);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueDateInsert(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, time_t value)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR, else return TS_SUCCESS
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  if (TSMimeHdrFieldValuesClear(bufp, hdr, field) == TS_ERROR) {
    return TS_ERROR;
  }

  char tmp[33];
  int  len = mime_format_date(tmp, value);
  // idx ignored, overwrite all existing values
  // (void)TSMimeFieldValueInsert(bufp, field_obj, tmp, len, idx);
  (void)TSMimeFieldValueSet(bufp, field, -1, tmp, len);
  return TS_SUCCESS;
}

TSReturnCode
TSMimeHdrFieldValueDelete(TSMBuffer bufp, TSMLoc hdr, TSMLoc field, int idx)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert((sdk_sanity_check_mime_hdr_handle(hdr) == TS_SUCCESS) || (sdk_sanity_check_http_hdr_handle(hdr) == TS_SUCCESS));
  sdk_assert(sdk_sanity_check_field_handle(field, hdr) == TS_SUCCESS);
  sdk_assert(idx >= 0);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  MIMEFieldSDKHandle *handle = reinterpret_cast<MIMEFieldSDKHandle *>(field);
  HdrHeap            *heap   = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;

  mime_field_value_delete_comma_val(heap, handle->mh, handle->field_ptr, idx);
  return TS_SUCCESS;
}

const char *
TSMimeHdrStringToWKS(const char *str, int length)
{
  if (length < 0) {
    return hdrtoken_string_to_wks(str);
  } else {
    return hdrtoken_string_to_wks(str, length);
  }
}

/**************/
/* HttpParser */
/**************/
TSHttpParser
TSHttpParserCreate()
{
  TSHttpParser parser = reinterpret_cast<TSHttpParser>(ats_malloc(sizeof(HTTPParser)));
  http_parser_init(reinterpret_cast<HTTPParser *>(parser));

  return parser;
}

void
TSHttpParserClear(TSHttpParser parser)
{
  sdk_assert(sdk_sanity_check_http_parser(parser) == TS_SUCCESS);
  http_parser_clear(reinterpret_cast<HTTPParser *>(parser));
}

void
TSHttpParserDestroy(TSHttpParser parser)
{
  sdk_assert(sdk_sanity_check_http_parser(parser) == TS_SUCCESS);
  http_parser_clear(reinterpret_cast<HTTPParser *>(parser));
  ats_free(parser);
}

/***********/
/* HttpHdr */
/***********/

TSMLoc
TSHttpHdrCreate(TSMBuffer bufp)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);

  HTTPHdr h;
  h.m_heap = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  h.create(HTTPType::UNKNOWN);
  return reinterpret_cast<TSMLoc>(h.m_http);
}

void
TSHttpHdrDestroy(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);

  // No more objects counts in heap or deallocation
  //   so do nothing!

  // HDR FIX ME - Did this free the MBuffer in Pete's old system
}

TSReturnCode
TSHttpHdrClone(TSMBuffer dest_bufp, TSMBuffer src_bufp, TSMLoc src_hdr, TSMLoc *locp)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If not allowed, set *locp to TS_NULL_MLOC.
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(src_hdr) == TS_SUCCESS);

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  HdrHeap     *s_heap, *d_heap;
  HTTPHdrImpl *s_hh, *d_hh;

  s_heap = (reinterpret_cast<HdrHeapSDKHandle *>(src_bufp))->m_heap;
  d_heap = (reinterpret_cast<HdrHeapSDKHandle *>(dest_bufp))->m_heap;
  s_hh   = reinterpret_cast<HTTPHdrImpl *>(src_hdr);

  if (static_cast<HdrHeapObjType>(s_hh->m_type) != HdrHeapObjType::HTTP_HEADER) {
    return TS_ERROR;
  }

  // TODO: This is never used
  // inherit_strs = (s_heap != d_heap ? true : false);
  d_hh  = http_hdr_clone(s_hh, s_heap, d_heap);
  *locp = reinterpret_cast<TSMLoc>(d_hh);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpHdrCopy(TSMBuffer dest_bufp, TSMLoc dest_obj, TSMBuffer src_bufp, TSMLoc src_obj)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(src_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(dest_bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(dest_obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(src_obj) == TS_SUCCESS);

  if (!isWriteable(dest_bufp)) {
    return TS_ERROR;
  }

  bool         inherit_strs;
  HdrHeap     *s_heap, *d_heap;
  HTTPHdrImpl *s_hh, *d_hh;

  s_heap = (reinterpret_cast<HdrHeapSDKHandle *>(src_bufp))->m_heap;
  d_heap = (reinterpret_cast<HdrHeapSDKHandle *>(dest_bufp))->m_heap;
  s_hh   = reinterpret_cast<HTTPHdrImpl *>(src_obj);
  d_hh   = reinterpret_cast<HTTPHdrImpl *>(dest_obj);

  if ((static_cast<HdrHeapObjType>(s_hh->m_type) != HdrHeapObjType::HTTP_HEADER) ||
      (static_cast<HdrHeapObjType>(d_hh->m_type) != HdrHeapObjType::HTTP_HEADER)) {
    return TS_ERROR;
  }

  inherit_strs = (s_heap != d_heap ? true : false);
  TSHttpHdrTypeSet(dest_bufp, dest_obj, static_cast<TSHttpType>(s_hh->m_polarity));
  http_hdr_copy_onto(s_hh, s_heap, d_hh, d_heap, inherit_strs);
  return TS_SUCCESS;
}

void
TSHttpHdrPrint(TSMBuffer bufp, TSMLoc obj, TSIOBuffer iobufp)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_iocore_structure(iobufp) == TS_SUCCESS);

  MIOBuffer     *b = reinterpret_cast<MIOBuffer *>(iobufp);
  IOBufferBlock *blk;
  HTTPHdr        h;
  int            bufindex;
  int            tmp, dumpoffset;
  int            done;

  SET_HTTP_HDR(h, bufp, obj);
  ink_assert(static_cast<HdrHeapObjType>(h.m_http->m_type) == HdrHeapObjType::HTTP_HEADER);

  dumpoffset = 0;
  do {
    blk = b->get_current_block();
    if (!blk || blk->write_avail() == 0) {
      b->add_block();
      blk = b->get_current_block();
    }

    bufindex = 0;
    tmp      = dumpoffset;

    done = h.print(blk->end(), blk->write_avail(), &bufindex, &tmp);

    dumpoffset += bufindex;
    b->fill(bufindex);
  } while (!done);
}

TSParseResult
TSHttpHdrParseReq(TSHttpParser parser, TSMBuffer bufp, TSMLoc obj, const char **start, const char *end)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)start) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)*start) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)end) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_PARSE_ERROR;
  }

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  ink_assert(static_cast<HdrHeapObjType>(h.m_http->m_type) == HdrHeapObjType::HTTP_HEADER);
  TSHttpHdrTypeSet(bufp, obj, TS_HTTP_TYPE_REQUEST);
  return static_cast<TSParseResult>(h.parse_req(reinterpret_cast<HTTPParser *>(parser), start, end, false));
}

TSParseResult
TSHttpHdrParseResp(TSHttpParser parser, TSMBuffer bufp, TSMLoc obj, const char **start, const char *end)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)start) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)*start) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)end) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_PARSE_ERROR;
  }

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  ink_assert(static_cast<HdrHeapObjType>(h.m_http->m_type) == HdrHeapObjType::HTTP_HEADER);
  TSHttpHdrTypeSet(bufp, obj, TS_HTTP_TYPE_RESPONSE);
  return static_cast<TSParseResult>(h.parse_resp(reinterpret_cast<HTTPParser *>(parser), start, end, false));
}

int
TSHttpHdrLengthGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  ink_assert(static_cast<HdrHeapObjType>(h.m_http->m_type) == HdrHeapObjType::HTTP_HEADER);
  return h.length_get();
}

TSHttpType
TSHttpHdrTypeGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);

  HTTPHdr h;
  SET_HTTP_HDR(h, bufp, obj);
  /* Don't need the assert as the check is done in sdk_sanity_check_http_hdr_handle
     ink_assert(h.m_http->m_type == HdrHeapObjType::HTTP_HEADER);
   */
  return static_cast<TSHttpType>(h.type_get());
}

TSReturnCode
TSHttpHdrTypeSet(TSMBuffer bufp, TSMLoc obj, TSHttpType type)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert((type >= TS_HTTP_TYPE_UNKNOWN) && (type <= TS_HTTP_TYPE_RESPONSE));

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  ink_assert(static_cast<HdrHeapObjType>(h.m_http->m_type) == HdrHeapObjType::HTTP_HEADER);

  // FIX: why are we using an HTTPHdr here?  why can't we
  //      just manipulate the impls directly?

  // In Pete's MBuffer system you can change the type
  //   at will.  Not so anymore.  We need to try to
  //   fake the difference.  We not going to let
  //   people change the types of a header.  If they
  //   try, too bad.
  if (h.m_http->m_polarity == HTTPType::UNKNOWN) {
    if (type == static_cast<TSHttpType>(HTTPType::REQUEST)) {
      h.m_http->u.req.m_url_impl = url_create(h.m_heap);
      h.m_http->m_polarity       = static_cast<HTTPType>(type);
    } else if (type == static_cast<TSHttpType>(HTTPType::RESPONSE)) {
      h.m_http->m_polarity = static_cast<HTTPType>(type);
    }
  }
  return TS_SUCCESS;
}

int
TSHttpHdrVersionGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  HTTPVersion ver = h.version_get();
  return ver.get_flat_version();
}

TSReturnCode
TSHttpHdrVersionSet(TSMBuffer bufp, TSMLoc obj, int ver)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  HTTPHdr     h;
  HTTPVersion version{ver};

  SET_HTTP_HDR(h, bufp, obj);
  ink_assert(static_cast<HdrHeapObjType>(h.m_http->m_type) == HdrHeapObjType::HTTP_HEADER);

  h.version_set(version);
  return TS_SUCCESS;
}

const char *
TSHttpHdrMethodGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)length) == TS_SUCCESS);

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  auto method{h.method_get()};
  *length = static_cast<int>(method.length());
  return method.data();
}

TSReturnCode
TSHttpHdrMethodSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  if (length < 0) {
    length = strlen(value);
  }

  h.method_set(std::string_view{value, static_cast<std::string_view::size_type>(length)});
  return TS_SUCCESS;
}

const char *
TSHttpHdrHostGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)length) == TS_SUCCESS);

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  auto host{h.host_get()};
  *length = static_cast<int>(host.length());
  return host.data();
}

TSReturnCode
TSHttpHdrUrlGet(TSMBuffer bufp, TSMLoc obj, TSMLoc *locp)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);

  HTTPHdrImpl *hh = reinterpret_cast<HTTPHdrImpl *>(obj);

  if (hh->m_polarity != HTTPType::REQUEST) {
    return TS_ERROR;
  }

  *locp = (reinterpret_cast<TSMLoc>(hh->u.req.m_url_impl));
  return TS_SUCCESS;
}

TSReturnCode
TSHttpHdrUrlSet(TSMBuffer bufp, TSMLoc obj, TSMLoc url)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(url) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  HdrHeap     *heap = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  HTTPHdrImpl *hh   = reinterpret_cast<HTTPHdrImpl *>(obj);

  if (static_cast<HdrHeapObjType>(hh->m_type) != HdrHeapObjType::HTTP_HEADER) {
    return TS_ERROR;
  }

  URLImpl *url_impl = reinterpret_cast<URLImpl *>(url);
  http_hdr_url_set(heap, hh, url_impl);
  return TS_SUCCESS;
}

TSHttpStatus
TSHttpHdrStatusGet(TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  return static_cast<TSHttpStatus>(h.status_get());
}

TSReturnCode
TSHttpHdrStatusSet(TSMBuffer bufp, TSMLoc obj, TSHttpStatus status, TSHttpTxn txnp, std::string_view setter)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  ink_assert(static_cast<HdrHeapObjType>(h.m_http->m_type) == HdrHeapObjType::HTTP_HEADER);
  h.status_set(static_cast<HTTPStatus>(status));

  if (txnp != nullptr && !setter.empty()) {
    sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
    HttpSM *sm                               = reinterpret_cast<HttpSM *>(txnp);
    sm->t_state.http_return_code_setter_name = setter;
  }
  return TS_SUCCESS;
}

TSReturnCode
TSHttpHdrStatusSet(TSMBuffer bufp, TSMLoc obj, TSHttpStatus status)
{
  return TSHttpHdrStatusSet(bufp, obj, status, nullptr, std::string_view{});
}

const char *
TSHttpHdrReasonGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)length) == TS_SUCCESS);

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  auto reason{h.reason_get()};
  *length = static_cast<int>(reason.length());
  return reason.data();
}

TSReturnCode
TSHttpHdrReasonSet(TSMBuffer bufp, TSMLoc obj, const char *value, int length)
{
  // Allow to modify the buffer only
  // if bufp is modifiable. If bufp is not modifiable return
  // TS_ERROR. If allowed, return TS_SUCCESS. Changed the
  // return value of function from void to TSReturnCode.
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value) == TS_SUCCESS);

  if (!isWriteable(bufp)) {
    return TS_ERROR;
  }

  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);
  /* Don't need the assert as the check is done in sdk_sanity_check_http_hdr_handle
     ink_assert(h.m_http->m_type == HdrHeapObjType::HTTP_HEADER);
  */

  if (length < 0) {
    length = strlen(value);
  }
  h.reason_set(std::string_view{value, static_cast<std::string_view::size_type>(length)});
  return TS_SUCCESS;
}

const char *
TSHttpHdrReasonLookup(TSHttpStatus status)
{
  return http_hdr_reason_lookup(static_cast<HTTPStatus>(status));
}

////////////////////////////////////////////////////////////////////
//
// Cache
//
////////////////////////////////////////////////////////////////////

inline TSReturnCode
sdk_sanity_check_cachekey(TSCacheKey key)
{
  if (nullptr == key) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSCacheKey
TSCacheKeyCreate()
{
  TSCacheKey key = reinterpret_cast<TSCacheKey>(new CacheInfo());

  // TODO: Probably remove this when we can be use "NEW" can't fail.
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);
  return key;
}

TSReturnCode
TSCacheKeyDigestSet(TSCacheKey key, const char *input, int length)
{
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_iocore_structure((void *)input) == TS_SUCCESS);
  sdk_assert(length > 0);
  CacheInfo *ci = reinterpret_cast<CacheInfo *>(key);

  if (ci->magic != CACHE_INFO_MAGIC_ALIVE) {
    return TS_ERROR;
  }

  CryptoContext().hash_immediate(ci->cache_key, input, length);
  return TS_SUCCESS;
}

TSReturnCode
TSCacheKeyDigestFromUrlSet(TSCacheKey key, TSMLoc url)
{
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);

  if ((reinterpret_cast<CacheInfo *>(key))->magic != CACHE_INFO_MAGIC_ALIVE) {
    return TS_ERROR;
  }

  url_CryptoHash_get(reinterpret_cast<URLImpl *>(url), &(reinterpret_cast<CacheInfo *>(key))->cache_key);
  return TS_SUCCESS;
}

TSReturnCode
TSCacheKeyDataTypeSet(TSCacheKey key, TSCacheDataType type)
{
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);

  if ((reinterpret_cast<CacheInfo *>(key))->magic != CACHE_INFO_MAGIC_ALIVE) {
    return TS_ERROR;
  }

  switch (type) {
  case TS_CACHE_DATA_TYPE_NONE:
    (reinterpret_cast<CacheInfo *>(key))->frag_type = CACHE_FRAG_TYPE_NONE;
    break;
  case TS_CACHE_DATA_TYPE_OTHER: /* other maps to http */
  case TS_CACHE_DATA_TYPE_HTTP:
    (reinterpret_cast<CacheInfo *>(key))->frag_type = CACHE_FRAG_TYPE_HTTP;
    break;
  default:
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSCacheKeyHostNameSet(TSCacheKey key, const char *hostname, int host_len)
{
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)hostname) == TS_SUCCESS);
  sdk_assert(host_len > 0);

  if ((reinterpret_cast<CacheInfo *>(key))->magic != CACHE_INFO_MAGIC_ALIVE) {
    return TS_ERROR;
  }

  CacheInfo *i = reinterpret_cast<CacheInfo *>(key);
  /* need to make a copy of the hostname. The caller
     might deallocate it anytime in the future */
  i->hostname = static_cast<char *>(ats_malloc(host_len));
  memcpy(i->hostname, hostname, host_len);
  i->len = host_len;
  return TS_SUCCESS;
}

TSReturnCode
TSCacheKeyPinnedSet(TSCacheKey key, time_t pin_in_cache)
{
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);

  if ((reinterpret_cast<CacheInfo *>(key))->magic != CACHE_INFO_MAGIC_ALIVE) {
    return TS_ERROR;
  }

  CacheInfo *i    = reinterpret_cast<CacheInfo *>(key);
  i->pin_in_cache = pin_in_cache;
  return TS_SUCCESS;
}

TSReturnCode
TSCacheKeyDestroy(TSCacheKey key)
{
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);

  if ((reinterpret_cast<CacheInfo *>(key))->magic != CACHE_INFO_MAGIC_ALIVE) {
    return TS_ERROR;
  }

  CacheInfo *i = reinterpret_cast<CacheInfo *>(key);

  ats_free(i->hostname);
  i->magic = CACHE_INFO_MAGIC_DEAD;
  delete i;
  return TS_SUCCESS;
}

TSCacheHttpInfo
TSCacheHttpInfoCopy(TSCacheHttpInfo infop)
{
  CacheHTTPInfo *new_info = new CacheHTTPInfo;

  new_info->copy(reinterpret_cast<CacheHTTPInfo *>(infop));
  return reinterpret_cast<TSCacheHttpInfo>(new_info);
}

void
TSCacheHttpInfoReqGet(TSCacheHttpInfo infop, TSMBuffer *bufp, TSMLoc *obj)
{
  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);

  *(reinterpret_cast<HTTPHdr **>(bufp)) = info->request_get();
  *obj                                  = reinterpret_cast<TSMLoc>(info->request_get()->m_http);
  sdk_assert(sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS);
}

void
TSCacheHttpInfoRespGet(TSCacheHttpInfo infop, TSMBuffer *bufp, TSMLoc *obj)
{
  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);

  *(reinterpret_cast<HTTPHdr **>(bufp)) = info->response_get();
  *obj                                  = reinterpret_cast<TSMLoc>(info->response_get()->m_http);
  sdk_assert(sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS);
}

time_t
TSCacheHttpInfoReqSentTimeGet(TSCacheHttpInfo infop)
{
  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);
  return info->request_sent_time_get();
}

time_t
TSCacheHttpInfoRespReceivedTimeGet(TSCacheHttpInfo infop)
{
  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);
  return info->response_received_time_get();
}

int64_t
TSCacheHttpInfoSizeGet(TSCacheHttpInfo infop)
{
  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);
  return info->object_size_get();
}

void
TSCacheHttpInfoReqSet(TSCacheHttpInfo infop, TSMBuffer bufp, TSMLoc obj)
{
  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);

  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);
  info->request_set(&h);
}

void
TSCacheHttpInfoRespSet(TSCacheHttpInfo infop, TSMBuffer bufp, TSMLoc obj)
{
  HTTPHdr h;

  SET_HTTP_HDR(h, bufp, obj);

  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);
  info->response_set(&h);
}

int
TSCacheHttpInfoVector(TSCacheHttpInfo infop, void *data, int length)
{
  CacheHTTPInfo      *info = reinterpret_cast<CacheHTTPInfo *>(infop);
  CacheHTTPInfoVector vector;

  vector.insert(info);

  int size = vector.marshal_length();

  if (size > length) {
    // error
    return 0;
  }

  return vector.marshal(static_cast<char *>(data), length);
}

void
TSCacheHttpInfoDestroy(TSCacheHttpInfo infop)
{
  (reinterpret_cast<CacheHTTPInfo *>(infop))->destroy();
}

TSCacheHttpInfo
TSCacheHttpInfoCreate()
{
  CacheHTTPInfo *info = new CacheHTTPInfo;
  info->create();

  return reinterpret_cast<TSCacheHttpInfo>(info);
}

////////////////////////////////////////////////////////////////////
//
// Configuration
//
////////////////////////////////////////////////////////////////////

unsigned int
TSConfigSet(unsigned int id, void *data, TSConfigDestroyFunc funcp)
{
  INKConfigImpl *config  = new INKConfigImpl;
  config->mdata          = data;
  config->m_destroy_func = funcp;
  return configProcessor.set(id, config);
}

TSConfig
TSConfigGet(unsigned int id)
{
  return reinterpret_cast<TSConfig>(configProcessor.get(id));
}

void
TSConfigRelease(unsigned int id, TSConfig configp)
{
  configProcessor.release(id, reinterpret_cast<ConfigInfo *>(configp));
}

void *
TSConfigDataGet(TSConfig configp)
{
  INKConfigImpl *config = reinterpret_cast<INKConfigImpl *>(configp);
  return config->mdata;
}

////////////////////////////////////////////////////////////////////
//
// Management
//
////////////////////////////////////////////////////////////////////

void
TSMgmtUpdateRegister(TSCont contp, const char *plugin_name, const char *plugin_file_name)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)plugin_name) == TS_SUCCESS);

  global_config_cbs->insert(reinterpret_cast<INKContInternal *>(contp), plugin_name, plugin_file_name);
}

TSReturnCode
TSMgmtIntGet(const char *var_name, TSMgmtInt *result)
{
  auto tmp{RecGetRecordInt(var_name)};

  // Try the old librecords first
  if (!tmp) {
    int id = global_api_metrics.lookup(var_name);

    if (id == ts::Metrics::NOT_FOUND) {
      return TS_ERROR;
    } else {
      *result = global_api_metrics[id].load();
    }
  } else {
    *result = tmp.value();
  }

  return TS_SUCCESS;
}

TSReturnCode
TSMgmtCounterGet(const char *var_name, TSMgmtCounter *result)
{
  auto tmp{RecGetRecordCounter(var_name)};

  // Try the old librecords first
  if (!tmp) {
    int id = global_api_metrics.lookup(var_name);

    if (id == ts::Metrics::NOT_FOUND) {
      return TS_ERROR;
    } else {
      *result = global_api_metrics[id].load();
    }
  } else {
    *result = tmp.value();
  }

  return TS_SUCCESS;
}

// ToDo: These don't have the new metrics, only librecords.
TSReturnCode
TSMgmtFloatGet(const char *var_name, TSMgmtFloat *result)
{
  auto tmp{RecGetRecordFloat(const_cast<char *>(var_name))};
  if (tmp) {
    *result = tmp.value();
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

TSReturnCode
TSMgmtStringGet(const char *var_name, TSMgmtString *result)
{
  auto tmp_str{RecGetRecordStringAlloc(const_cast<char *>(var_name))};
  auto tmp{ats_as_c_str(tmp_str)};

  if (tmp) {
    *result = ats_strdup(tmp);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSMgmtSourceGet(const char *var_name, TSMgmtSource *source)
{
  return REC_ERR_OKAY == RecGetRecordSource(var_name, reinterpret_cast<RecSourceT *>(source)) ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSMgmtDataTypeGet(const char *var_name, TSRecordDataType *result)
{
  return REC_ERR_OKAY == RecGetRecordDataType(var_name, reinterpret_cast<RecDataT *>(result)) ? TS_SUCCESS : TS_ERROR;
}

////////////////////////////////////////////////////////////////////
//
// Continuations
//
////////////////////////////////////////////////////////////////////

TSCont
TSContCreate(TSEventFunc funcp, TSMutex mutexp)
{
  // mutexp can be null
  if (mutexp != nullptr) {
    sdk_assert(sdk_sanity_check_mutex(mutexp) == TS_SUCCESS);
  }

  if (pluginThreadContext) {
    pluginThreadContext->acquire();
  }

  INKContInternal *i = THREAD_ALLOC(INKContAllocator, this_thread());

  i->init(funcp, mutexp, pluginThreadContext);
  return reinterpret_cast<TSCont>(i);
}

void
TSContDestroy(TSCont contp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  if (i->m_context) {
    reinterpret_cast<PluginThreadContext *>(i->m_context)->release();
  }

  i->destroy();
}

void
TSContDataSet(TSCont contp, void *data)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  i->mdata = data;
}

void *
TSContDataGet(TSCont contp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  return i->mdata;
}

TSAction
TSContScheduleOnPool(TSCont contp, TSHRTime timeout, TSThreadPool tp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  /* ensure we are on a EThread */
  sdk_assert(sdk_sanity_check_null_ptr((void *)this_ethread()) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  if (ink_atomic_increment(static_cast<int *>(&i->m_event_count), 1) < 0) {
    ink_assert(!"not reached");
  }

  EventType etype;

  switch (tp) {
  case TS_THREAD_POOL_NET:
    etype = ET_NET;
    break;
  case TS_THREAD_POOL_TASK:
    etype = ET_TASK;
    break;
  case TS_THREAD_POOL_DNS:
    etype = ET_DNS;
    break;
  case TS_THREAD_POOL_UDP:
    etype = ET_UDP;
    break;
  default:
    etype = ET_TASK;
    break;
  }

  TSAction action;
  if (timeout == 0) {
    action = reinterpret_cast<TSAction>(eventProcessor.schedule_imm(i, etype));
  } else {
    action = reinterpret_cast<TSAction>(eventProcessor.schedule_in(i, HRTIME_MSECONDS(timeout), etype));
  }

  /* This is a hack. Should be handled in ink_types */
  action = reinterpret_cast<TSAction>(reinterpret_cast<uintptr_t>(action) | 0x1);
  return action;
}

TSAction
TSContScheduleOnThread(TSCont contp, TSHRTime timeout, TSEventThread ethread)
{
  ink_release_assert(ethread != nullptr);

  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  if (ink_atomic_increment(static_cast<int *>(&i->m_event_count), 1) < 0) {
    ink_assert(!"not reached");
  }

  EThread *eth = reinterpret_cast<EThread *>(ethread);
  if (i->getThreadAffinity() == nullptr) {
    i->setThreadAffinity(eth);
  }

  TSAction action;
  if (timeout == 0) {
    action = reinterpret_cast<TSAction>(eth->schedule_imm(i));
  } else {
    action = reinterpret_cast<TSAction>(eth->schedule_in(i, HRTIME_MSECONDS(timeout)));
  }

  /* This is a hack. Should be handled in ink_types */
  action = reinterpret_cast<TSAction>(reinterpret_cast<uintptr_t>(action) | 0x1);
  return action;
}

std::vector<TSAction>
TSContScheduleOnEntirePool(TSCont contp, TSHRTime timeout, TSThreadPool tp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  /* ensure we are on a EThread */
  sdk_assert(sdk_sanity_check_null_ptr((void *)this_ethread()) == TS_SUCCESS);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  // This is to allow the continuation to be scheduled on multiple threads
  sdk_assert(i->mutex == nullptr);

  EventType etype;

  switch (tp) {
  case TS_THREAD_POOL_NET:
    etype = ET_NET;
    break;
  case TS_THREAD_POOL_TASK:
    etype = ET_TASK;
    break;
  case TS_THREAD_POOL_DNS:
    etype = ET_DNS;
    break;
  case TS_THREAD_POOL_UDP:
    etype = ET_UDP;
    break;
  default:
    etype = ET_TASK;
    break;
  }

  if (ink_atomic_increment(static_cast<int *>(&i->m_event_count), eventProcessor.thread_group[etype]._count) < 0) {
    ink_assert(!"not reached");
  }

  return eventProcessor.schedule_entire(i, HRTIME_MSECONDS(timeout), 0, etype, timeout == 0 ? EVENT_IMMEDIATE : EVENT_INTERVAL);
}

TSAction
TSContScheduleEveryOnPool(TSCont contp, TSHRTime every, TSThreadPool tp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  /* ensure we are on a EThread */
  sdk_assert(sdk_sanity_check_null_ptr((void *)this_ethread()) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  if (ink_atomic_increment(static_cast<int *>(&i->m_event_count), 1) < 0) {
    ink_assert(!"not reached");
  }

  EventType etype;

  switch (tp) {
  case TS_THREAD_POOL_NET:
    etype = ET_NET;
    break;
  case TS_THREAD_POOL_TASK:
    etype = ET_TASK;
    break;
  case TS_THREAD_POOL_DNS:
    etype = ET_DNS;
    break;
  case TS_THREAD_POOL_UDP:
    etype = ET_UDP;
    break;
  default:
    etype = ET_TASK;
    break;
  }

  TSAction action = reinterpret_cast<TSAction>(eventProcessor.schedule_every(i, HRTIME_MSECONDS(every), etype));

  /* This is a hack. Should be handled in ink_types */
  action = reinterpret_cast<TSAction>(reinterpret_cast<uintptr_t>(action) | 0x1);
  return action;
}

TSAction
TSContScheduleEveryOnThread(TSCont contp, TSHRTime every, TSEventThread ethread)
{
  ink_release_assert(ethread != nullptr);

  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  if (ink_atomic_increment(static_cast<int *>(&i->m_event_count), 1) < 0) {
    ink_assert(!"not reached");
  }

  EThread *eth = reinterpret_cast<EThread *>(ethread);
  if (i->getThreadAffinity() == nullptr) {
    i->setThreadAffinity(eth);
  }

  TSAction action = reinterpret_cast<TSAction>(eth->schedule_every(i, HRTIME_MSECONDS(every)));

  /* This is a hack. Should be handled in ink_types */
  action = reinterpret_cast<TSAction>(reinterpret_cast<uintptr_t>(action) | 0x1);
  return action;
}

std::vector<TSAction>
TSContScheduleEveryOnEntirePool(TSCont contp, TSHRTime every, TSThreadPool tp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  /* ensure we are on a EThread */
  sdk_assert(sdk_sanity_check_null_ptr((void *)this_ethread()) == TS_SUCCESS);

  sdk_assert(every != 0);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  // This is to allow the continuation to be scheduled on multiple threads
  sdk_assert(i->mutex == nullptr);

  EventType etype;

  switch (tp) {
  case TS_THREAD_POOL_NET:
    etype = ET_NET;
    break;
  case TS_THREAD_POOL_TASK:
    etype = ET_TASK;
    break;
  case TS_THREAD_POOL_DNS:
    etype = ET_DNS;
    break;
  case TS_THREAD_POOL_UDP:
    etype = ET_UDP;
    break;
  default:
    etype = ET_TASK;
    break;
  }

  if (ink_atomic_increment(static_cast<int *>(&i->m_event_count), eventProcessor.thread_group[etype]._count) < 0) {
    ink_assert(!"not reached");
  }

  return eventProcessor.schedule_entire(i, 0, HRTIME_MSECONDS(every), etype, EVENT_INTERVAL);
}

TSReturnCode
TSContThreadAffinitySet(TSCont contp, TSEventThread ethread)
{
  ink_release_assert(ethread != nullptr);

  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i               = reinterpret_cast<INKContInternal *>(contp);
  EThread         *thread_affinity = reinterpret_cast<EThread *>(ethread);

  if (i->setThreadAffinity(thread_affinity)) {
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

TSEventThread
TSContThreadAffinityGet(TSCont contp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  return reinterpret_cast<TSEventThread>(i->getThreadAffinity());
}

void
TSContThreadAffinityClear(TSCont contp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  i->clearThreadAffinity();
}

TSAction
TSHttpSchedule(TSCont contp, TSHttpTxn txnp, TSHRTime timeout)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  if (ink_atomic_increment(&i->m_event_count, 1) < 0) {
    ink_assert(!"not reached");
  }

  TSAction      action;
  Continuation *cont = reinterpret_cast<Continuation *>(contp);
  HttpSM       *sm   = reinterpret_cast<HttpSM *>(txnp);

  sm->set_http_schedule(cont);

  if (timeout == 0) {
    action = reinterpret_cast<TSAction>(eventProcessor.schedule_imm(sm, ET_NET));
  } else {
    action = reinterpret_cast<TSAction>(eventProcessor.schedule_in(sm, HRTIME_MSECONDS(timeout), ET_NET));
  }

  action = reinterpret_cast<TSAction>(reinterpret_cast<uintptr_t>(action) | 0x1);
  return action;
}

int
TSContCall(TSCont contp, TSEvent event, void *edata)
{
  Continuation *c = reinterpret_cast<Continuation *>(contp);
  WEAK_MUTEX_TRY_LOCK(lock, c->mutex, this_ethread());
  if (!lock.is_locked()) {
    // If we cannot get the lock, the caller needs to restructure to handle rescheduling
    ink_release_assert(0);
  }
  return c->handleEvent(static_cast<int>(event), edata);
}

TSMutex
TSContMutexGet(TSCont contp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  Continuation *c = reinterpret_cast<Continuation *>(contp);
  return reinterpret_cast<TSMutex>(c->mutex.get());
}

/* HTTP hooks */

void
TSHttpHookAdd(TSHttpHookID id, TSCont contp)
{
  INKContInternal *icontp;
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_hook_id(id) == TS_SUCCESS);

  icontp = reinterpret_cast<INKContInternal *>(contp);

  TSSslHookInternalID internalId{id};
  if (internalId.is_in_bounds()) {
    SSLAPIHooks::instance()->append(internalId, icontp);
  } else { // Follow through the regular HTTP hook framework
    http_global_hooks->append(id, icontp);
  }
}

void
TSLifecycleHookAdd(TSLifecycleHookID id, TSCont contp)
{
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_lifecycle_hook_id(id) == TS_SUCCESS);

  g_lifecycle_hooks->append(id, reinterpret_cast<INKContInternal *>(contp));
}

/* HTTP sessions */
void
TSHttpSsnHookAdd(TSHttpSsn ssnp, TSHttpHookID id, TSCont contp)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_hook_id(id) == TS_SUCCESS);

  ProxySession *cs = reinterpret_cast<ProxySession *>(ssnp);
  cs->hook_add(id, reinterpret_cast<INKContInternal *>(contp));
}

int
TSHttpSsnTransactionCount(TSHttpSsn ssnp)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);

  ProxySession *cs = reinterpret_cast<ProxySession *>(ssnp);
  return cs->get_transact_count();
}

TSVConn
TSHttpSsnClientVConnGet(TSHttpSsn ssnp)
{
  ProxySession *cs = reinterpret_cast<ProxySession *>(ssnp);
  return reinterpret_cast<TSVConn>(cs->get_netvc());
}

TSVConn
TSHttpSsnServerVConnGet(TSHttpSsn ssnp)
{
  PoolableSession *ss = reinterpret_cast<PoolableSession *>(ssnp);
  if (ss != nullptr) {
    return reinterpret_cast<TSVConn>(ss->get_netvc());
  }
  return nullptr;
}

TSVConn
TSHttpTxnServerVConnGet(TSHttpTxn txnp)
{
  TSVConn vconn = nullptr;
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  if (sm != nullptr) {
    ProxyTransaction *st = sm->get_server_txn();
    if (st != nullptr) {
      vconn = reinterpret_cast<TSVConn>(st->get_netvc());
    }
  }
  return vconn;
}

class TSHttpSsnCallback : public Continuation
{
public:
  TSHttpSsnCallback(ProxySession *cs, Ptr<ProxyMutex> m, TSEvent event) : Continuation(m), m_cs(cs), m_event(event)
  {
    SET_HANDLER(&TSHttpSsnCallback::event_handler);
  }

  int
  event_handler(int, void *)
  {
    // The current continuation is associated with the nethandler mutex.
    // We need to hold the nethandler mutex because the later Session logic may
    // activate the nethandler add_to_queue logic
    // Need to make sure we have the ProxySession mutex as well.
    EThread *eth = this_ethread();
    MUTEX_TRY_LOCK(trylock, m_cs->mutex, eth);
    if (!trylock.is_locked()) {
      eth->schedule_imm(this);
    } else {
      m_cs->handleEvent(static_cast<int>(m_event), nullptr);
      delete this;
    }
    return 0;
  }

private:
  ProxySession *m_cs;
  TSEvent       m_event;
};

void
TSHttpSsnReenable(TSHttpSsn ssnp, TSEvent event)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);

  ProxySession *cs  = reinterpret_cast<ProxySession *>(ssnp);
  EThread      *eth = this_ethread();

  // If this function is being executed on a thread created by the API
  // which is DEDICATED, the continuation needs to be called back on a
  // REGULAR thread. Specially an ET_NET thread
  if (!eth->is_event_type(ET_NET)) {
    EThread *affinity_thread = cs->getThreadAffinity();
    if (affinity_thread && affinity_thread->is_event_type(ET_NET)) {
      NetHandler *nh = get_NetHandler(affinity_thread);
      affinity_thread->schedule_imm(new TSHttpSsnCallback(cs, nh->mutex, event), ET_NET);
    } else {
      eventProcessor.schedule_imm(new TSHttpSsnCallback(cs, cs->mutex, event), ET_NET);
    }
  } else {
    MUTEX_TRY_LOCK(trylock, cs->mutex, eth);
    if (!trylock.is_locked()) {
      EThread *affinity_thread = cs->getThreadAffinity();
      if (affinity_thread && affinity_thread->is_event_type(ET_NET)) {
        NetHandler *nh = get_NetHandler(affinity_thread);
        affinity_thread->schedule_imm(new TSHttpSsnCallback(cs, nh->mutex, event), ET_NET);
      } else {
        eventProcessor.schedule_imm(new TSHttpSsnCallback(cs, cs->mutex, event), ET_NET);
      }
    } else {
      cs->handleEvent(static_cast<int>(event), nullptr);
    }
  }
}

/* HTTP transactions */
void
TSHttpTxnHookAdd(TSHttpTxn txnp, TSHttpHookID id, TSCont contp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_hook_id(id) == TS_SUCCESS);

  HttpSM  *sm   = reinterpret_cast<HttpSM *>(txnp);
  APIHook *hook = sm->txn_hook_get(id);

  // Traverse list of hooks and add a particular hook only once
  while (hook != nullptr) {
    if (hook->m_cont == reinterpret_cast<INKContInternal *>(contp)) {
      return;
    }
    hook = hook->m_link.next;
  }
  sm->txn_hook_add(id, reinterpret_cast<INKContInternal *>(contp));
}

TSHttpSsn
TSHttpTxnSsnGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return reinterpret_cast<TSHttpSsn>(sm->get_ua_txn() ? reinterpret_cast<TSHttpSsn>(sm->get_ua_txn()->get_proxy_ssn()) : nullptr);
}

TSReturnCode
TSHttpTxnClientReqGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)obj) == TS_SUCCESS);

  HttpSM  *sm   = reinterpret_cast<HttpSM *>(txnp);
  HTTPHdr *hptr = &(sm->t_state.hdr_info.client_request);

  if (hptr->valid()) {
    *(reinterpret_cast<HTTPHdr **>(bufp)) = hptr;
    *obj                                  = reinterpret_cast<TSMLoc>(hptr->m_http);
    if (sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS) {
      hptr->mark_target_dirty();
      return TS_SUCCESS;
      ;
    }
  }
  return TS_ERROR;
}

// pristine url is the url before remap
TSReturnCode
TSHttpTxnPristineUrlGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *url_loc)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)url_loc) == TS_SUCCESS);

  HttpSM  *sm   = reinterpret_cast<HttpSM *>(txnp);
  HTTPHdr *hptr = &(sm->t_state.hdr_info.client_request);

  if (hptr->valid()) {
    *(reinterpret_cast<HTTPHdr **>(bufp)) = hptr;
    *url_loc                              = reinterpret_cast<TSMLoc>(sm->t_state.unmapped_url.m_url_impl);

    if (sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS) {
      if (*url_loc == nullptr) {
        *url_loc = reinterpret_cast<TSMLoc>(hptr->m_http->u.req.m_url_impl);
      }
      if (*url_loc) {
        return TS_SUCCESS;
      }
    }
  }
  return TS_ERROR;
}

int
TSHttpTxnServerSsnTransactionCount(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  // Any value greater than zero indicates connection reuse.
  return sm->server_transact_count;
}

// Shortcut to just get the URL.
// The caller is responsible to free memory that is allocated for the string
// that is returned.
char *
TSHttpTxnEffectiveUrlStringGet(TSHttpTxn txnp, int *length)
{
  sdk_assert(TS_SUCCESS == sdk_sanity_check_txn(txnp));
  sdk_assert(sdk_sanity_check_null_ptr((void *)length) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->t_state.hdr_info.client_request.url_string_get(nullptr, length);
}

TSReturnCode
TSHttpHdrEffectiveUrlBufGet(TSMBuffer hdr_buf, TSMLoc hdr_loc, char *buf, int64_t size, int64_t *length)
{
  sdk_assert(sdk_sanity_check_mbuffer(hdr_buf) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_http_hdr_handle(hdr_loc) == TS_SUCCESS);
  if (size) {
    sdk_assert(sdk_sanity_check_null_ptr(buf) == TS_SUCCESS);
  }
  sdk_assert(sdk_sanity_check_null_ptr(length) == TS_SUCCESS);

  auto buf_handle = reinterpret_cast<HTTPHdr *>(hdr_buf);
  auto hdr_handle = reinterpret_cast<HTTPHdrImpl *>(hdr_loc);

  if (hdr_handle->m_polarity != HTTPType::REQUEST) {
    Dbg(dbg_ctl_plugin, "Trying to get a URL from response header %p", hdr_loc);
    return TS_ERROR;
  }

  int url_length = buf_handle->url_printed_length(URLNormalize::LC_SCHEME_HOST | URLNormalize::IMPLIED_SCHEME);

  sdk_assert(url_length >= 0);

  *length = url_length;

  // If the user-provided buffer is too small to hold the URL string, do not put anything in it.  This is not considered
  // an error case.
  //
  if (url_length <= size) {
    int index  = 0;
    int offset = 0;

    buf_handle->url_print(buf, size, &index, &offset, URLNormalize::LC_SCHEME_HOST | URLNormalize::IMPLIED_SCHEME);
  }

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnClientRespGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)obj) == TS_SUCCESS);

  HttpSM  *sm   = reinterpret_cast<HttpSM *>(txnp);
  HTTPHdr *hptr = &(sm->t_state.hdr_info.client_response);

  if (hptr->valid()) {
    *(reinterpret_cast<HTTPHdr **>(bufp)) = hptr;
    *obj                                  = reinterpret_cast<TSMLoc>(hptr->m_http);
    sdk_assert(sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSHttpTxnServerReqGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)obj) == TS_SUCCESS);

  HttpSM  *sm   = reinterpret_cast<HttpSM *>(txnp);
  HTTPHdr *hptr = &(sm->t_state.hdr_info.server_request);

  if (hptr->valid()) {
    *(reinterpret_cast<HTTPHdr **>(bufp)) = hptr;
    *obj                                  = reinterpret_cast<TSMLoc>(hptr->m_http);
    sdk_assert(sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSHttpTxnServerRespGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)obj) == TS_SUCCESS);

  HttpSM  *sm   = reinterpret_cast<HttpSM *>(txnp);
  HTTPHdr *hptr = &(sm->t_state.hdr_info.server_response);

  if (hptr->valid()) {
    *(reinterpret_cast<HTTPHdr **>(bufp)) = hptr;
    *obj                                  = reinterpret_cast<TSMLoc>(hptr->m_http);
    sdk_assert(sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSHttpTxnCachedReqGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)obj) == TS_SUCCESS);

  HttpSM   *sm         = reinterpret_cast<HttpSM *>(txnp);
  HTTPInfo *cached_obj = sm->t_state.cache_info.object_read;

  // The following check is need to prevent the HttpSM handle copy from going bad
  // Since the cache manages the header buffer, sm->t_state.cache_info.object_read
  // is the only way to tell if handle has gone bad.
  if ((!cached_obj) || (!cached_obj->valid())) {
    return TS_ERROR;
  }

  HTTPHdr *cached_hdr = sm->t_state.cache_info.object_read->request_get();

  if (!cached_hdr->valid()) {
    return TS_ERROR;
  }
  // We can't use the HdrHeapSDKHandle structure in the RamCache since multiple
  // threads can access. We need to create our own for the transaction and return that.
  HdrHeapSDKHandle **handle = &(sm->t_state.cache_req_hdr_heap_handle);

  if (*handle == nullptr) {
    *handle           = static_cast<HdrHeapSDKHandle *>(sm->t_state.arena.alloc(sizeof(HdrHeapSDKHandle)));
    (*handle)->m_heap = cached_hdr->m_heap;
  }

  *(reinterpret_cast<HdrHeapSDKHandle **>(bufp)) = *handle;
  *obj                                           = reinterpret_cast<TSMLoc>(cached_hdr->m_http);
  sdk_assert(sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnCachedRespGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)obj) == TS_SUCCESS);

  HttpSM   *sm         = reinterpret_cast<HttpSM *>(txnp);
  HTTPInfo *cached_obj = sm->t_state.cache_info.object_read;

  // The following check is need to prevent the HttpSM handle copy from going bad
  // Since the cache manages the header buffer, sm->t_state.cache_info.object_read
  // is the only way to tell if handle has gone bad.
  if ((!cached_obj) || (!cached_obj->valid())) {
    return TS_ERROR;
  }

  HTTPHdr *cached_hdr = sm->t_state.cache_info.object_read->response_get();

  if (!cached_hdr->valid()) {
    return TS_ERROR;
  }
  // We can't use the HdrHeapSDKHandle structure in the RamCache since multiple
  //  threads can access.  We need to create our own for the transaction and return that.
  HdrHeapSDKHandle **handle = &(sm->t_state.cache_resp_hdr_heap_handle);

  if (*handle == nullptr) {
    *handle = static_cast<HdrHeapSDKHandle *>(sm->t_state.arena.alloc(sizeof(HdrHeapSDKHandle)));
  }
  // Always reset the m_heap to make sure the heap is not stale
  (*handle)->m_heap = cached_hdr->m_heap;

  *(reinterpret_cast<HdrHeapSDKHandle **>(bufp)) = *handle;
  *obj                                           = reinterpret_cast<TSMLoc>(cached_hdr->m_http);
  sdk_assert(sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnCachedRespModifiableGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)obj) == TS_SUCCESS);

  HttpSM              *sm               = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::State *s                = &(sm->t_state);
  HTTPHdr             *c_resp           = nullptr;
  HTTPInfo            *cached_obj       = sm->t_state.cache_info.object_read;
  HTTPInfo            *cached_obj_store = &(sm->t_state.cache_info.object_store);

  if ((!cached_obj) || (!cached_obj->valid())) {
    return TS_ERROR;
  }

  if (!cached_obj_store->valid()) {
    cached_obj_store->create();
  }

  c_resp = cached_obj_store->response_get();
  if (!c_resp->valid()) {
    cached_obj_store->response_set(cached_obj->response_get());
  }
  c_resp                        = cached_obj_store->response_get();
  s->api_modifiable_cached_resp = true;

  ink_assert(c_resp != nullptr && c_resp->valid());
  *(reinterpret_cast<HTTPHdr **>(bufp)) = c_resp;
  *obj                                  = reinterpret_cast<TSMLoc>(c_resp->m_http);
  sdk_assert(sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnCacheLookupStatusGet(TSHttpTxn txnp, int *lookup_status)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)lookup_status) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  switch (sm->t_state.cache_lookup_result) {
  case HttpTransact::CacheLookupResult_t::MISS:
  case HttpTransact::CacheLookupResult_t::DOC_BUSY:
    *lookup_status = TS_CACHE_LOOKUP_MISS;
    break;
  case HttpTransact::CacheLookupResult_t::HIT_STALE:
    *lookup_status = TS_CACHE_LOOKUP_HIT_STALE;
    break;
  case HttpTransact::CacheLookupResult_t::HIT_WARNING:
  case HttpTransact::CacheLookupResult_t::HIT_FRESH:
    *lookup_status = TS_CACHE_LOOKUP_HIT_FRESH;
    break;
  case HttpTransact::CacheLookupResult_t::SKIPPED:
    *lookup_status = TS_CACHE_LOOKUP_SKIPPED;
    break;
  case HttpTransact::CacheLookupResult_t::NONE:
  default:
    return TS_ERROR;
  };
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnCacheLookupCountGet(TSHttpTxn txnp, int *lookup_count)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)lookup_count) == TS_SUCCESS);

  HttpSM *sm    = reinterpret_cast<HttpSM *>(txnp);
  *lookup_count = sm->t_state.cache_info.lookup_count;
  return TS_SUCCESS;
}

/* two hooks this function may gets called:
   TS_HTTP_READ_CACHE_HDR_HOOK   &
   TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK
 */
TSReturnCode
TSHttpTxnCacheLookupStatusSet(TSHttpTxn txnp, int cachelookup)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM                            *sm        = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::CacheLookupResult_t *sm_status = &(sm->t_state.cache_lookup_result);

  // converting from a miss to a hit is not allowed
  if (*sm_status == HttpTransact::CacheLookupResult_t::MISS && cachelookup != TS_CACHE_LOOKUP_MISS) {
    return TS_ERROR;
  }

  // here is to handle converting a hit to a miss
  if (cachelookup == TS_CACHE_LOOKUP_MISS && *sm_status != HttpTransact::CacheLookupResult_t::MISS) {
    sm->t_state.api_cleanup_cache_read = true;
    ink_assert(sm->t_state.transact_return_point != nullptr);
    sm->t_state.transact_return_point = HttpTransact::HandleCacheOpenRead;
  }

  switch (cachelookup) {
  case TS_CACHE_LOOKUP_MISS:
    *sm_status = HttpTransact::CacheLookupResult_t::MISS;
    break;
  case TS_CACHE_LOOKUP_HIT_STALE:
    *sm_status = HttpTransact::CacheLookupResult_t::HIT_STALE;
    break;
  case TS_CACHE_LOOKUP_HIT_FRESH:
    *sm_status = HttpTransact::CacheLookupResult_t::HIT_FRESH;
    break;
  default:
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnVerifiedAddrSet(TSHttpTxn txnp, const struct sockaddr *addr)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)addr) == TS_SUCCESS);

  HttpSM           *sm     = reinterpret_cast<HttpSM *>(txnp);
  ProxyTransaction *prxtxn = sm->get_ua_txn();

  prxtxn->set_verified_client_addr(addr);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnVerifiedAddrGet(TSHttpTxn txnp, const struct sockaddr **addr)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)addr) == TS_SUCCESS);

  HttpSM           *sm     = reinterpret_cast<HttpSM *>(txnp);
  ProxyTransaction *prxtxn = sm->get_ua_txn();

  *addr = prxtxn->get_verified_client_addr();
  if ((*addr)->sa_family == AF_UNSPEC) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnInfoIntGet(TSHttpTxn txnp, TSHttpTxnInfoKey key, TSMgmtInt *value)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value) == TS_SUCCESS);

  HttpSM      *s    = reinterpret_cast<HttpSM *>(txnp);
  HttpCacheSM *c_sm = &(s->get_cache_sm());

  switch (key) {
  case TS_TXN_INFO_CACHE_HIT_RAM:
    *value = (static_cast<TSMgmtInt>(c_sm->is_ram_cache_hit()));
    break;
  case TS_TXN_INFO_CACHE_COMPRESSED_IN_RAM:
    *value = (static_cast<TSMgmtInt>(c_sm->is_compressed_in_ram()));
    break;
  case TS_TXN_INFO_CACHE_HIT_RWW:
    *value = (static_cast<TSMgmtInt>(c_sm->is_readwhilewrite_inprogress()));
    break;
  case TS_TXN_INFO_CACHE_OPEN_READ_TRIES:
    *value = (static_cast<TSMgmtInt>(c_sm->get_open_read_tries()));
    break;
  case TS_TXN_INFO_CACHE_OPEN_WRITE_TRIES:
    *value = (static_cast<TSMgmtInt>(c_sm->get_open_write_tries()));
    break;
  case TS_TXN_INFO_CACHE_VOLUME:
    *value = (static_cast<TSMgmtInt>(c_sm->get_volume_number()));
    break;
  default:
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSHttpSsnInfoIntGet(TSHttpSsn ssnp, TSHttpSsnInfoKey key, TSMgmtInt *value, uint64_t sub_key)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value) == TS_SUCCESS);

  ProxySession *ssn = reinterpret_cast<ProxySession *>(ssnp);

  switch (key) {
  case TS_SSN_INFO_TRANSACTION_COUNT:
    *value = ssn->get_transact_count();
    break;
  case TS_SSN_INFO_RECEIVED_FRAME_COUNT:
    if (!ssn->is_protocol_framed()) {
      return TS_ERROR;
    }
    *value = ssn->get_received_frame_count(sub_key);
    break;
  default:
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

int
TSHttpTxnIsWebsocket(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->t_state.is_websocket;
}

const char *
TSHttpTxnCacheDiskPathGet(TSHttpTxn txnp, int *length)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM     *sm   = reinterpret_cast<HttpSM *>(txnp);
  char const *path = nullptr;

  if (HttpCacheSM *c_sm = &(sm->get_cache_sm()); c_sm) {
    path = c_sm->get_disk_path();
  }
  if (length) {
    *length = path ? strlen(path) : 0;
  }

  return path;
}

TSReturnCode
TSHttpTxnCacheLookupUrlGet(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  URL     u, *l_url;

  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
  if (!u.valid()) {
    return TS_ERROR;
  }

  l_url = sm->t_state.cache_info.lookup_url;
  if (l_url && l_url->valid()) {
    u.copy(l_url);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSHttpTxnCacheLookupUrlSet(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  URL     u, *l_url;

  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
  if (!u.valid()) {
    return TS_ERROR;
  }

  l_url = sm->t_state.cache_info.lookup_url;
  if (!l_url) {
    sm->t_state.cache_info.lookup_url_storage.create(nullptr);
    sm->t_state.cache_info.lookup_url = &(sm->t_state.cache_info.lookup_url_storage);
    l_url                             = sm->t_state.cache_info.lookup_url;
  }

  if (!l_url || !l_url->valid()) {
    return TS_ERROR;
  } else {
    l_url->copy(&u);
  }

  return TS_SUCCESS;
}

/**
 * timeout is in msec
 * overrides as proxy.config.http.transaction_active_timeout_out
 **/
void
TSHttpTxnActiveTimeoutSet(TSHttpTxn txnp, int timeout)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s          = &((reinterpret_cast<HttpSM *>(txnp))->t_state);
  s->api_txn_active_timeout_value = timeout;
}

/**
 * timeout is in msec
 * overrides as proxy.config.http.connect_attempts_timeout
 **/
void
TSHttpTxnConnectTimeoutSet(TSHttpTxn txnp, int timeout)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s           = &((reinterpret_cast<HttpSM *>(txnp))->t_state);
  s->api_txn_connect_timeout_value = timeout;
}

/**
 * timeout is in msec
 * overrides as proxy.config.dns.lookup_timeout
 **/
void
TSHttpTxnDNSTimeoutSet(TSHttpTxn txnp, int timeout)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s = &((reinterpret_cast<HttpSM *>(txnp))->t_state);

  s->api_txn_dns_timeout_value = timeout;
}

/**
 * timeout is in msec
 * overrides as proxy.config.http.transaction_no_activity_timeout_out
 **/
void
TSHttpTxnNoActivityTimeoutSet(TSHttpTxn txnp, int timeout)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s               = &((reinterpret_cast<HttpSM *>(txnp))->t_state);
  s->api_txn_no_activity_timeout_value = timeout;
}

TSReturnCode
TSHttpTxnServerRespNoStoreSet(TSHttpTxn txnp, int flag)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s          = &((reinterpret_cast<HttpSM *>(txnp))->t_state);
  s->api_server_response_no_store = (flag != 0);

  return TS_SUCCESS;
}

bool
TSHttpTxnServerRespNoStoreGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s = &((reinterpret_cast<HttpSM *>(txnp))->t_state);
  return s->api_server_response_no_store;
}

TSReturnCode
TSHttpTxnServerRespIgnore(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s          = &((reinterpret_cast<HttpSM *>(txnp))->t_state);
  HTTPInfo            *cached_obj = s->cache_info.object_read;
  HTTPHdr             *cached_resp;

  if (cached_obj == nullptr || !cached_obj->valid()) {
    return TS_ERROR;
  }

  cached_resp = cached_obj->response_get();
  if (cached_resp == nullptr || !cached_resp->valid()) {
    return TS_ERROR;
  }

  s->api_server_response_ignore = true;

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnShutDown(TSHttpTxn txnp, TSEvent event)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  if (event == TS_EVENT_HTTP_TXN_CLOSE) {
    return TS_ERROR;
  }

  HttpTransact::State *s  = &((reinterpret_cast<HttpSM *>(txnp))->t_state);
  s->api_http_sm_shutdown = true;

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnAborted(TSHttpTxn txnp, bool *client_abort)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(client_abort != nullptr);

  *client_abort = false;
  HttpSM *sm    = reinterpret_cast<HttpSM *>(txnp);
  switch (sm->t_state.squid_codes.log_code) {
  case SquidLogCode::ERR_CLIENT_ABORT:
  case SquidLogCode::ERR_CLIENT_READ_ERROR:
  case SquidLogCode::TCP_SWAPFAIL:
    // check for client abort and cache read error
    *client_abort = true;
    return TS_SUCCESS;
  default:
    break;
  }

  if (sm->t_state.current.server && sm->t_state.current.server->abort == HttpTransact::ABORTED) {
    // check for the server abort
    return TS_SUCCESS;
  }
  // there can be the case of transformation error.
  return TS_ERROR;
}

void
TSHttpTxnReqCacheableSet(TSHttpTxn txnp, int flag)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm                    = reinterpret_cast<HttpSM *>(txnp);
  sm->t_state.api_req_cacheable = (flag != 0);
}

void
TSHttpTxnRespCacheableSet(TSHttpTxn txnp, int flag)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm                     = reinterpret_cast<HttpSM *>(txnp);
  sm->t_state.api_resp_cacheable = (flag != 0);
}

int
TSHttpTxnClientReqIsServerStyle(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return (sm->t_state.hdr_info.client_req_is_server_style ? 1 : 0);
}

TSReturnCode
TSHttpTxnUpdateCachedObject(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM              *sm               = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::State *s                = &(sm->t_state);
  HTTPInfo            *cached_obj_store = &(sm->t_state.cache_info.object_store);
  HTTPHdr             *client_request   = &(sm->t_state.hdr_info.client_request);

  if (!cached_obj_store->valid() || !cached_obj_store->response_get()) {
    return TS_ERROR;
  }

  if (!cached_obj_store->request_get() && !client_request->valid()) {
    return TS_ERROR;
  }

  if (s->cache_info.write_lock_state == HttpTransact::CacheWriteLock_t::READ_RETRY) {
    return TS_ERROR;
  }

  s->api_update_cached_object = HttpTransact::UpdateCachedObject_t::PREPARE;
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnTransformRespGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM  *sm   = reinterpret_cast<HttpSM *>(txnp);
  HTTPHdr *hptr = &(sm->t_state.hdr_info.transform_response);

  if (hptr->valid()) {
    *(reinterpret_cast<HTTPHdr **>(bufp)) = hptr;
    *obj                                  = reinterpret_cast<TSMLoc>(hptr->m_http);
    return sdk_sanity_check_mbuffer(*bufp);
  }

  return TS_ERROR;
}

sockaddr const *
TSHttpSsnClientAddrGet(TSHttpSsn ssnp)
{
  ProxySession *cs = reinterpret_cast<ProxySession *>(ssnp);

  if (cs == nullptr) {
    return nullptr;
  }
  return cs->get_client_addr();
}
sockaddr const *
TSHttpTxnClientAddrGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp);
  return TSHttpSsnClientAddrGet(ssnp);
}

sockaddr const *
TSHttpSsnIncomingAddrGet(TSHttpSsn ssnp)
{
  ProxySession *cs = reinterpret_cast<ProxySession *>(ssnp);

  if (cs == nullptr) {
    return nullptr;
  }
  return cs->get_local_addr();
}
sockaddr const *
TSHttpTxnIncomingAddrGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp);
  return TSHttpSsnIncomingAddrGet(ssnp);
}

sockaddr const *
TSHttpTxnOutgoingAddrGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  const sockaddr   *retval = nullptr;
  NetVConnection   *vc     = nullptr;
  ProxyTransaction *ssn    = sm->get_server_txn();
  if (ssn == nullptr) {
    vc = sm->get_server_vc();
  } else {
    vc = ssn->get_netvc();
  }
  if (vc != nullptr) {
    retval = vc->get_local_addr();
  }
  return retval;
}

sockaddr const *
TSHttpTxnServerAddrGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return &sm->t_state.server_info.dst_addr.sa;
}

TSReturnCode
TSHttpTxnServerAddrSet(TSHttpTxn txnp, struct sockaddr const *addr)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  if (sm->t_state.dns_info.set_upstream_address(addr)) {
    sm->t_state.dns_info.os_addr_style = ResolveInfo::OS_Addr::USE_API;
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

void
TSHttpTxnClientIncomingPortSet(TSHttpTxn txnp, int port)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm                                            = reinterpret_cast<HttpSM *>(txnp);
  sm->t_state.client_info.dst_addr.network_order_port() = htons(port);
}

// [amc] This might use the port. The code path should do that but it
// hasn't been tested.
TSReturnCode
TSHttpTxnOutgoingAddrSet(TSHttpTxn txnp, const struct sockaddr *addr)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  sm->get_ua_txn()->upstream_outbound_options.outbound_port = ats_ip_port_host_order(addr);
  sm->get_ua_txn()->set_outbound_ip(swoc::IPAddr(addr));
  return TS_SUCCESS;
}

sockaddr const *
TSHttpTxnNextHopAddrGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  /**
   * Return zero if the server structure is not yet constructed.
   */
  if (sm->t_state.current.server == nullptr) {
    return nullptr;
  }

  return &sm->t_state.current.server->dst_addr.sa;
}

const char *
TSHttpTxnNextHopNameGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  /**
   * Return zero if the server structure is not yet constructed.
   */
  if (sm->t_state.current.server == nullptr) {
    return nullptr;
  }

  return sm->t_state.current.server->name;
}

int
TSHttpTxnNextHopPortGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  auto sm = reinterpret_cast<HttpSM const *>(txnp);
  /**
   * Return -1 if the server structure is not yet constructed.
   */
  if (nullptr == sm->t_state.current.server) {
    return -1;
  }
  return sm->t_state.current.server->dst_addr.host_order_port();
}

TSReturnCode
TSHttpTxnOutgoingTransparencySet(TSHttpTxn txnp, int flag)
{
  if (TS_SUCCESS != sdk_sanity_check_txn(txnp)) {
    return TS_ERROR;
  }

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  if (nullptr == sm || nullptr == sm->get_ua_txn()) {
    return TS_ERROR;
  }

  sm->get_ua_txn()->set_outbound_transparent(flag);
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnClientPacketMarkSet(TSHttpTxn txnp, int mark)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  if (nullptr == sm->get_ua_txn()) {
    return TS_ERROR;
  }

  NetVConnection *vc = sm->get_ua_txn()->get_netvc();
  if (nullptr == vc) {
    return TS_ERROR;
  }

  vc->options.packet_mark = static_cast<uint32_t>(mark);
  vc->apply_options();
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnServerPacketMarkSet(TSHttpTxn txnp, int mark)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  // change the mark on an active server session
  ProxyTransaction *ssn = sm->get_server_txn();
  if (nullptr != ssn) {
    NetVConnection *vc = ssn->get_netvc();
    if (vc != nullptr) {
      vc->options.packet_mark = static_cast<uint32_t>(mark);
      vc->apply_options();
    }
  }

  // update the transactions mark config for future connections
  TSHttpTxnConfigIntSet(txnp, TS_CONFIG_NET_SOCK_PACKET_MARK_OUT, mark);
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnClientPacketDscpSet(TSHttpTxn txnp, int dscp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  if (nullptr == sm->get_ua_txn()) {
    return TS_ERROR;
  }

  NetVConnection *vc = sm->get_ua_txn()->get_netvc();
  if (nullptr == vc) {
    return TS_ERROR;
  }

  vc->options.packet_tos = static_cast<uint32_t>(dscp) << 2;
  vc->apply_options();
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnServerPacketDscpSet(TSHttpTxn txnp, int dscp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  // change the tos on an active server session
  ProxyTransaction *ssn = sm->get_server_txn();
  if (nullptr != ssn) {
    NetVConnection *vc = ssn->get_netvc();
    if (vc != nullptr) {
      vc->options.packet_tos = static_cast<uint32_t>(dscp) << 2;
      vc->apply_options();
    }
  }

  // update the transactions mark config for future connections
  TSHttpTxnConfigIntSet(txnp, TS_CONFIG_NET_SOCK_PACKET_TOS_OUT, dscp << 2);
  return TS_SUCCESS;
}

// Set the body, or, if you provide a null buffer, clear the body message
void
TSHttpTxnErrorBodySet(TSHttpTxn txnp, char *buf, size_t buflength, char *mimetype)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM              *sm = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::State *s  = &(sm->t_state);

  // Cleanup anything already set.
  s->free_internal_msg_buffer();
  ats_free(s->internal_msg_buffer_type);

  s->internal_msg_buffer                     = buf;
  s->internal_msg_buffer_size                = buf ? buflength : 0;
  s->internal_msg_buffer_fast_allocator_size = -1;

  s->internal_msg_buffer_type = mimetype;
}

char *
TSHttpTxnErrorBodyGet(TSHttpTxn txnp, size_t *buflength, char **mimetype)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM              *sm = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::State *s  = &(sm->t_state);

  if (buflength) {
    *buflength = s->internal_msg_buffer_size;
  }

  if (mimetype) {
    *mimetype = s->internal_msg_buffer_type;
  }

  return s->internal_msg_buffer;
}

void
TSHttpTxnServerRequestBodySet(TSHttpTxn txnp, char *buf, int64_t buflength)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM              *sm = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::State *s  = &(sm->t_state);

  // Cleanup anything already set.
  s->free_internal_msg_buffer();

  if (buf) {
    s->api_server_request_body_set = true;
    s->internal_msg_buffer         = buf;
    s->internal_msg_buffer_size    = buflength;
  } else {
    s->api_server_request_body_set = false;
    s->internal_msg_buffer         = nullptr;
    s->internal_msg_buffer_size    = 0;
  }
  s->internal_msg_buffer_fast_allocator_size = -1;
}

void const *
TSHttpTxnNextHopStrategyGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  auto sm = reinterpret_cast<HttpSM const *>(txnp);

  return static_cast<void *>(sm->t_state.next_hop_strategy);
}

void
TSHttpTxnNextHopStrategySet(TSHttpTxn txnp, void const *stratptr)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  // null strategy falls back to parent.config
  // sdk_assert(sdk_sanity_check_null_ptr(strategy) == TS_SUCCESS);

  auto sm       = reinterpret_cast<HttpSM *>(txnp);
  auto strategy = reinterpret_cast<NextHopSelectionStrategy const *>(stratptr);

  sm->t_state.next_hop_strategy = const_cast<NextHopSelectionStrategy *>(strategy);
}

char const *
TSHttpNextHopStrategyNameGet(void const *stratptr)
{
  char const *name = nullptr;
  if (nullptr != stratptr) {
    auto strategy = reinterpret_cast<NextHopSelectionStrategy const *>(stratptr);
    name          = strategy->strategy_name.c_str();
  }

  return name;
}

void const *
TSHttpTxnNextHopNamedStrategyGet(TSHttpTxn txnp, const char *name)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)name) == TS_SUCCESS);

  auto sm = reinterpret_cast<HttpSM const *>(txnp);

  sdk_assert(sdk_sanity_check_null_ptr((void *)sm->m_remap) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)sm->m_remap->strategyFactory) == TS_SUCCESS);

  // HttpSM has a reference count handle to UrlRewrite which has a
  // pointer to NextHopStrategyFactory
  NextHopSelectionStrategy const *const strat = sm->m_remap->strategyFactory->strategyInstance(name);

  return static_cast<void const *>(strat);
}

TSReturnCode
TSHttpTxnParentProxyGet(TSHttpTxn txnp, const char **hostname, int *port)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  *hostname = sm->t_state.api_info.parent_proxy_name;
  *port     = sm->t_state.api_info.parent_proxy_port;

  return TS_SUCCESS;
}

void
TSHttpTxnParentProxySet(TSHttpTxn txnp, const char *hostname, int port)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)hostname) == TS_SUCCESS);
  sdk_assert(port > 0);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  sm->t_state.api_info.parent_proxy_name = sm->t_state.arena.str_store(hostname, strlen(hostname));
  sm->t_state.api_info.parent_proxy_port = port;
}

TSReturnCode
TSHttpTxnParentSelectionUrlGet(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  URL     u, *l_url;

  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
  if (!u.valid()) {
    return TS_ERROR;
  }

  l_url = sm->t_state.cache_info.parent_selection_url;
  if (l_url && l_url->valid()) {
    u.copy(l_url);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSHttpTxnParentSelectionUrlSet(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc obj)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_url_handle(obj) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  URL     u, *l_url;

  u.m_heap     = (reinterpret_cast<HdrHeapSDKHandle *>(bufp))->m_heap;
  u.m_url_impl = reinterpret_cast<URLImpl *>(obj);
  if (!u.valid()) {
    return TS_ERROR;
  }

  l_url = sm->t_state.cache_info.parent_selection_url;
  if (!l_url) {
    sm->t_state.cache_info.parent_selection_url_storage.create(nullptr);
    sm->t_state.cache_info.parent_selection_url = &(sm->t_state.cache_info.parent_selection_url_storage);
    l_url                                       = sm->t_state.cache_info.parent_selection_url;
  }

  if (!l_url || !l_url->valid()) {
    return TS_ERROR;
  } else {
    l_url->copy(&u);
  }

  Dbg(dbg_ctl_parent_select, "TSHttpTxnParentSelectionUrlSet() parent_selection_url : addr = %p val = %p",
      &(sm->t_state.cache_info.parent_selection_url), sm->t_state.cache_info.parent_selection_url);

  return TS_SUCCESS;
}

void
TSHttpTxnUntransformedRespCache(TSHttpTxn txnp, int on)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm                               = reinterpret_cast<HttpSM *>(txnp);
  sm->t_state.api_info.cache_untransformed = (on ? true : false);
}

void
TSHttpTxnTransformedRespCache(TSHttpTxn txnp, int on)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm                             = reinterpret_cast<HttpSM *>(txnp);
  sm->t_state.api_info.cache_transformed = (on ? true : false);
}

class TSHttpSMCallback : public Continuation
{
public:
  TSHttpSMCallback(HttpSM *sm, TSEvent event) : Continuation(sm->mutex), m_sm(sm), m_event(event)
  {
    SET_HANDLER(&TSHttpSMCallback::event_handler);
  }

  int
  event_handler(int, void *)
  {
    m_sm->state_api_callback(static_cast<int>(m_event), nullptr);
    delete this;
    return 0;
  }

private:
  HttpSM *m_sm;
  TSEvent m_event;
};

//----------------------------------------------------------------------------
void
TSHttpTxnReenable(TSHttpTxn txnp, TSEvent event)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM  *sm  = reinterpret_cast<HttpSM *>(txnp);
  EThread *eth = this_ethread();

  // TS-2271: If this function is being executed on a thread which was not
  // created using the ATS EThread API, eth will be null, and the
  // continuation needs to be called back on a REGULAR thread.
  //
  // If we are not coming from the thread associated with the state machine,
  // reschedule.  Also reschedule if we cannot get the state machine lock.
  if (eth != nullptr && sm->getThreadAffinity() == eth) {
    MUTEX_TRY_LOCK(trylock, sm->mutex, eth);
    if (trylock.is_locked()) {
      ink_assert(eth->is_event_type(ET_NET));
      sm->state_api_callback(static_cast<int>(event), nullptr);
      return;
    }
  }
  // Couldn't call the handler directly, schedule to the original SM thread
  TSHttpSMCallback *cb = new TSHttpSMCallback(sm, event);
  cb->setThreadAffinity(sm->getThreadAffinity());
  eventProcessor.schedule_imm(cb, ET_NET);
}

TSReturnCode TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, const char **description);

TSReturnCode
TSUserArgIndexReserve(TSUserArgType type, const char *name, const char *description, int *ptr_idx)
{
  sdk_assert(sdk_sanity_check_null_ptr(ptr_idx) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr(name) == TS_SUCCESS);
  sdk_assert(0 <= type && type < TS_USER_ARGS_COUNT);

  int idx;

  /* Since this function is meant to be called during plugin initialization we could end up "leaking" indices during plugins
   * reload. Make sure we allocate 1 index per name, also current TSUserArgIndexNameLookup() implementation assumes 1-1
   * relationship as well. */
  const char *desc;

  if (TS_SUCCESS == TSUserArgIndexNameLookup(type, name, &idx, &desc)) {
    // Found existing index.

    // No need to add get_user_arg_offset(type) here since
    // TSUserArgIndexNameLookup already does so.
    *ptr_idx = idx;
    return TS_SUCCESS;
  }

  idx       = UserArgIdx[type]++;
  int limit = MAX_USER_ARGS[type];

  if (idx < limit) {
    UserArg &arg(UserArgTable[type][idx]);
    arg.name = name;
    if (description) {
      arg.description = description;
    }
    *ptr_idx = idx + get_user_arg_offset(type);

    return TS_SUCCESS;
  }
  return TS_ERROR;
}

TSReturnCode
TSUserArgIndexLookup(TSUserArgType type, int idx, const char **name, const char **description)
{
  sdk_assert(0 <= type && type < TS_USER_ARGS_COUNT);
  sdk_assert(SanityCheckUserIndex(type, idx));
  idx -= get_user_arg_offset(type);
  if (sdk_sanity_check_null_ptr(name) == TS_SUCCESS) {
    if (idx < UserArgIdx[type]) {
      UserArg &arg(UserArgTable[type][idx]);
      *name = arg.name.c_str();
      if (description) {
        *description = arg.description.c_str();
      }
      return TS_SUCCESS;
    }
  }
  return TS_ERROR;
}

// Not particularly efficient, but good enough for now.
TSReturnCode
TSUserArgIndexNameLookup(TSUserArgType type, const char *name, int *arg_idx, const char **description)
{
  sdk_assert(sdk_sanity_check_null_ptr(arg_idx) == TS_SUCCESS);
  sdk_assert(0 <= type && type < TS_USER_ARGS_COUNT);

  std::string_view n{name};

  for (UserArg *arg = UserArgTable[type], *limit = arg + UserArgIdx[type]; arg < limit; ++arg) {
    if (arg->name == n) {
      if (description) {
        *description = arg->description.c_str();
      }
      *arg_idx = arg - UserArgTable[type] + get_user_arg_offset(type);
      return TS_SUCCESS;
    }
  }
  return TS_ERROR;
}

// -------------
void
TSUserArgSet(void *data, int arg_idx, void *arg)
{
  if (nullptr != data) {
    PluginUserArgsMixin *user_args = dynamic_cast<PluginUserArgsMixin *>(static_cast<Continuation *>(data));
    sdk_assert(user_args);

    user_args->set_user_arg(arg_idx, arg);
  } else {
    global_user_args.set_user_arg(arg_idx, arg);
  }
}

void *
TSUserArgGet(void *data, int arg_idx)
{
  if (nullptr != data) {
    PluginUserArgsMixin *user_args = dynamic_cast<PluginUserArgsMixin *>(static_cast<Continuation *>(data));
    sdk_assert(user_args);

    return user_args->get_user_arg(arg_idx);
  } else {
    return global_user_args.get_user_arg(arg_idx);
  }
}

void
TSHttpTxnStatusSet(TSHttpTxn txnp, TSHttpStatus status, std::string_view setter)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm                   = reinterpret_cast<HttpSM *>(txnp);
  sm->t_state.http_return_code = static_cast<HTTPStatus>(status);

  if (!setter.empty()) {
    sm->t_state.http_return_code_setter_name = setter;
  }
}

void
TSHttpTxnStatusSet(TSHttpTxn txnp, TSHttpStatus status)
{
  TSHttpTxnStatusSet(txnp, status, std::string_view{});
}

TSHttpStatus
TSHttpTxnStatusGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return static_cast<TSHttpStatus>(sm->t_state.http_return_code);
}

TSReturnCode
TSHttpTxnCntlSet(TSHttpTxn txnp, TSHttpCntlType cntl, bool data)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  switch (cntl) {
  case TS_HTTP_CNTL_LOGGING_MODE:
    sm->t_state.api_info.logging_enabled = data;
    break;

  case TS_HTTP_CNTL_INTERCEPT_RETRY_MODE:
    sm->t_state.api_info.retry_intercept_failures = data;
    break;

  case TS_HTTP_CNTL_RESPONSE_CACHEABLE:
    sm->t_state.api_resp_cacheable = data;
    break;

  case TS_HTTP_CNTL_REQUEST_CACHEABLE:
    sm->t_state.api_req_cacheable = data;
    break;

  case TS_HTTP_CNTL_SERVER_NO_STORE:
    sm->t_state.api_server_response_no_store = data;
    break;

  case TS_HTTP_CNTL_TXN_DEBUG:
    sm->debug_on = data;
    break;

  case TS_HTTP_CNTL_SKIP_REMAPPING:
    sm->t_state.api_skip_all_remapping = data;
    break;

  default:
    return TS_ERROR;
    break;
  }

  return TS_SUCCESS;
}

bool
TSHttpTxnCntlGet(TSHttpTxn txnp, TSHttpCntlType ctrl)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  switch (ctrl) {
  case TS_HTTP_CNTL_LOGGING_MODE:
    return sm->t_state.api_info.logging_enabled;
    break;

  case TS_HTTP_CNTL_INTERCEPT_RETRY_MODE:
    return sm->t_state.api_info.retry_intercept_failures;
    break;

  case TS_HTTP_CNTL_RESPONSE_CACHEABLE:
    return sm->t_state.api_resp_cacheable;
    break;

  case TS_HTTP_CNTL_REQUEST_CACHEABLE:
    return sm->t_state.api_req_cacheable;
    break;

  case TS_HTTP_CNTL_SERVER_NO_STORE:
    return sm->t_state.api_server_response_no_store;
    break;

  case TS_HTTP_CNTL_TXN_DEBUG:
    return sm->debug_on;
    break;

  case TS_HTTP_CNTL_SKIP_REMAPPING:
    return sm->t_state.api_skip_all_remapping;
    break;

  default:
    break;
  }

  return false; // Unknown here, but oh well.
}

/* This is kinda horky, we have to use TSServerState instead of
   HttpTransact::ServerState_t, otherwise we have a prototype
   mismatch in the public ts/ts.h interfaces. */
TSServerState
TSHttpTxnServerStateGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s = &((reinterpret_cast<HttpSM *>(txnp))->t_state);
  return static_cast<TSServerState>(s->current.state);
}

void
TSHttpTxnDebugSet(TSHttpTxn txnp, int on)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  (reinterpret_cast<HttpSM *>(txnp))->debug_on = on;
}

int
TSHttpTxnDebugGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  return (reinterpret_cast<HttpSM *>(txnp))->debug_on;
}

void
TSHttpSsnDebugSet(TSHttpSsn ssnp, int on)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  (reinterpret_cast<ProxySession *>(ssnp))->set_debug(0 != on);
}

int
TSHttpSsnDebugGet(TSHttpSsn ssnp, int *on)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  sdk_assert(on != nullptr);
  *on = (reinterpret_cast<ProxySession *>(ssnp))->debug();
  return TS_SUCCESS;
}

int
TSHttpTxnClientReqHdrBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->client_request_hdr_bytes;
}

int64_t
TSHttpTxnClientReqBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->client_request_body_bytes;
}

int
TSHttpTxnServerReqHdrBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->server_request_hdr_bytes;
}

int64_t
TSHttpTxnServerReqBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->server_request_body_bytes;
}

int
TSHttpTxnServerRespHdrBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->server_response_hdr_bytes;
}

int64_t
TSHttpTxnServerRespBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->server_response_body_bytes;
}

int
TSHttpTxnClientRespHdrBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->client_response_hdr_bytes;
}

int64_t
TSHttpTxnClientRespBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->client_response_body_bytes;
}

int
TSVConnIsSslReused(TSVConn sslp)
{
  NetVConnection    *vc     = reinterpret_cast<NetVConnection *>(sslp);
  SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc);

  return ssl_vc ? ssl_vc->getIsResumedSSLSession() : 0;
}

const char *
TSVConnSslCipherGet(TSVConn sslp)
{
  NetVConnection  *vc    = reinterpret_cast<NetVConnection *>(sslp);
  TLSBasicSupport *tlsbs = vc->get_service<TLSBasicSupport>();

  return tlsbs ? tlsbs->get_tls_cipher_suite() : nullptr;
}

const char *
TSVConnSslProtocolGet(TSVConn sslp)
{
  NetVConnection  *vc    = reinterpret_cast<NetVConnection *>(sslp);
  TLSBasicSupport *tlsbs = vc->get_service<TLSBasicSupport>();

  return tlsbs ? tlsbs->get_tls_protocol_name() : nullptr;
}

const char *
TSVConnSslCurveGet(TSVConn sslp)
{
  NetVConnection  *vc    = reinterpret_cast<NetVConnection *>(sslp);
  TLSBasicSupport *tlsbs = vc->get_service<TLSBasicSupport>();

  return tlsbs ? tlsbs->get_tls_curve() : nullptr;
}

int
TSHttpTxnPushedRespHdrBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->pushed_response_hdr_bytes;
}

int64_t
TSHttpTxnPushedRespBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->pushed_response_body_bytes;
}

// Get a particular milestone hrtime'r. Note that this can return 0, which means it has not
// been set yet.
TSReturnCode
TSHttpTxnMilestoneGet(TSHttpTxn txnp, TSMilestonesType milestone, ink_hrtime *time)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr(time) == TS_SUCCESS);
  HttpSM      *sm  = reinterpret_cast<HttpSM *>(txnp);
  TSReturnCode ret = TS_SUCCESS;

  if ((milestone < TS_MILESTONE_UA_BEGIN) || (milestone >= TS_MILESTONE_LAST_ENTRY)) {
    *time = -1;
    ret   = TS_ERROR;
  } else {
    *time = sm->milestones[milestone];
  }

  return ret;
}

TSReturnCode
TSHttpTxnCachedRespTimeGet(TSHttpTxn txnp, time_t *resp_time)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM   *sm         = reinterpret_cast<HttpSM *>(txnp);
  HTTPInfo *cached_obj = sm->t_state.cache_info.object_read;

  if (cached_obj == nullptr || !cached_obj->valid()) {
    return TS_ERROR;
  }

  *resp_time = cached_obj->response_received_time_get();
  return TS_SUCCESS;
}

int
TSHttpCurrentClientConnectionsGet()
{
  return Metrics::Gauge::load(http_rsb.current_client_connections);
}

int
TSHttpCurrentActiveClientConnectionsGet()
{
  return Metrics::Gauge::load(http_rsb.current_active_client_connections);
}

int
TSHttpCurrentIdleClientConnectionsGet()
{
  int64_t total  = Metrics::Gauge::load(http_rsb.current_client_connections);
  int64_t active = Metrics::Gauge::load(http_rsb.current_active_client_connections);

  if (total >= active) {
    return static_cast<int>(total - active);
  }

  return 0;
}

int
TSHttpCurrentCacheConnectionsGet()
{
  return Metrics::Gauge::load(http_rsb.current_cache_connections);
}

int
TSHttpCurrentServerConnectionsGet()
{
  return Metrics::Gauge::load(http_rsb.current_server_connections);
}

/* HTTP alternate selection */
TSReturnCode
TSHttpAltInfoClientReqGet(TSHttpAltInfo infop, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_alt_info(infop) == TS_SUCCESS);

  HttpAltInfo *info = reinterpret_cast<HttpAltInfo *>(infop);

  *(reinterpret_cast<HTTPHdr **>(bufp)) = &info->m_client_req;
  *obj                                  = reinterpret_cast<TSMLoc>(info->m_client_req.m_http);

  return sdk_sanity_check_mbuffer(*bufp);
}

TSReturnCode
TSHttpAltInfoCachedReqGet(TSHttpAltInfo infop, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_alt_info(infop) == TS_SUCCESS);

  HttpAltInfo *info = reinterpret_cast<HttpAltInfo *>(infop);

  *(reinterpret_cast<HTTPHdr **>(bufp)) = &info->m_cached_req;
  *obj                                  = reinterpret_cast<TSMLoc>(info->m_cached_req.m_http);

  return sdk_sanity_check_mbuffer(*bufp);
}

TSReturnCode
TSHttpAltInfoCachedRespGet(TSHttpAltInfo infop, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_alt_info(infop) == TS_SUCCESS);

  HttpAltInfo *info = reinterpret_cast<HttpAltInfo *>(infop);

  *(reinterpret_cast<HTTPHdr **>(bufp)) = &info->m_cached_resp;
  *obj                                  = reinterpret_cast<TSMLoc>(info->m_cached_resp.m_http);

  return sdk_sanity_check_mbuffer(*bufp);
}

void
TSHttpAltInfoQualitySet(TSHttpAltInfo infop, float quality)
{
  sdk_assert(sdk_sanity_check_alt_info(infop) == TS_SUCCESS);

  HttpAltInfo *info = reinterpret_cast<HttpAltInfo *>(infop);
  info->m_qvalue    = quality;
}

const char *
TSHttpTxnPluginTagGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->plugin_tag;
}

TSHttpConnectOptions
TSHttpConnectOptionsGet(TSConnectType connect_type)
{
  sdk_assert(connect_type > TS_CONNECT_UNDEFINED);
  sdk_assert(connect_type < TS_CONNECT_LAST_ENTRY);

  return TSHttpConnectOptions{.connect_type      = connect_type,
                              .addr              = nullptr,
                              .tag               = nullptr,
                              .id                = 0,
                              .buffer_index      = TS_IOBUFFER_SIZE_INDEX_32K,
                              .buffer_water_mark = TS_IOBUFFER_WATER_MARK_PLUGIN_VC_DEFAULT};
}

TSVConn
TSHttpConnectWithPluginId(sockaddr const *addr, const char *tag, int64_t id)
{
  TSHttpConnectOptions options = TSHttpConnectOptionsGet(TS_CONNECT_PLUGIN);
  options.addr                 = addr;
  options.tag                  = tag;
  options.id                   = id;

  return TSHttpConnectPlugin(&options);
}

TSVConn
TSHttpConnectPlugin(TSHttpConnectOptions *options)
{
  sdk_assert(options != nullptr);
  sdk_assert(options->connect_type == TS_CONNECT_PLUGIN);
  sdk_assert(options->addr);

  sdk_assert(ats_is_unix(options->addr) || ats_is_ip(options->addr));
  sdk_assert(ats_is_unix(options->addr) || ats_ip_port_cast(options->addr));
  return reinterpret_cast<TSVConn>(PluginHttpConnectInternal(options));
}

TSVConn
TSHttpConnect(sockaddr const *addr)
{
  return TSHttpConnectWithPluginId(addr, "plugin", 0);
}

TSVConn
TSHttpConnectTransparent(sockaddr const *client_addr, sockaddr const *server_addr)
{
  sdk_assert(ats_is_ip(client_addr));
  sdk_assert(ats_is_ip(server_addr));
  sdk_assert(!ats_is_ip_any(client_addr));
  sdk_assert(ats_ip_port_cast(client_addr));
  sdk_assert(!ats_is_ip_any(server_addr));
  sdk_assert(ats_ip_port_cast(server_addr));

  if (plugin_http_transparent_accept) {
    PluginVCCore *new_pvc = PluginVCCore::alloc(plugin_http_transparent_accept);

    // set active address expects host ordering and the above casts do not
    // swap when it is required
    new_pvc->set_active_addr(client_addr);
    new_pvc->set_passive_addr(server_addr);
    new_pvc->set_transparent(true, true);

    PluginVC *return_vc = new_pvc->connect();

    if (return_vc != nullptr) {
      PluginVC *other_side = return_vc->get_other_side();

      if (other_side != nullptr) {
        other_side->set_is_internal_request(true);
      }
    }

    return reinterpret_cast<TSVConn>(return_vc);
  }

  return nullptr;
}

/* Actions */
void
TSActionCancel(TSAction actionp)
{
  Action          *thisaction;
  INKContInternal *i;

  // Nothing to cancel
  if (actionp == nullptr) {
    return;
  }

  /* This is a hack. Should be handled in ink_types */
  if (reinterpret_cast<uintptr_t>(actionp) & 0x1) {
    thisaction = reinterpret_cast<Action *>(reinterpret_cast<uintptr_t>(actionp) - 1);
    if (thisaction) {
      i = static_cast<INKContInternal *>(thisaction->continuation);
      i->handle_event_count(EVENT_IMMEDIATE);
    } else { // The action pointer for an INKContInternal was effectively null, just go away
      return;
    }
  } else {
    thisaction = reinterpret_cast<Action *>(actionp);
  }

  thisaction->cancel();
}

// Currently no error handling necessary, actionp can be anything.
int
TSActionDone(TSAction actionp)
{
  return (reinterpret_cast<Action *>(actionp) == ACTION_RESULT_DONE) ? 1 : 0;
}

/* Connections */

TSVConn
TSVConnCreate(TSEventFunc event_funcp, TSMutex mutexp)
{
  if (mutexp == nullptr) {
    mutexp = reinterpret_cast<TSMutex>(new_ProxyMutex());
  }

  // TODO: probably don't need this if memory allocations fails properly
  sdk_assert(sdk_sanity_check_mutex(mutexp) == TS_SUCCESS);

  if (pluginThreadContext) {
    pluginThreadContext->acquire();
  }

  INKVConnInternal *i = THREAD_ALLOC(INKVConnAllocator, this_thread());

  sdk_assert(sdk_sanity_check_null_ptr((void *)i) == TS_SUCCESS);

  i->init(event_funcp, mutexp, pluginThreadContext);
  return reinterpret_cast<TSVConn>(i);
}

struct ActionSink : public Continuation {
  ActionSink() : Continuation(nullptr) { SET_HANDLER(&ActionSink::mainEvent); }
  int
  mainEvent(int event, void *edata)
  {
    // Just sink the event ...
    Dbg(dbg_ctl_iocore_net, "sinking event=%d (%s), edata=%p", event, HttpDebugNames::get_event_name(event), edata);
    return EVENT_CONT;
  }
};

static ActionSink a;

TSVConn
TSVConnFdCreate(int fd)
{
  UnixNetVConnection *vc;
  EThread            *t = this_ethread();

  if (unlikely(fd == NO_FD)) {
    return nullptr;
  }

  vc = static_cast<UnixNetVConnection *>(netProcessor.allocate_vc(t));
  if (vc == nullptr) {
    return nullptr;
  }

  // We need to set an Action to handle NET_EVENT_OPEN* events. Since we have a
  // socket already, we don't need to do anything in those events, so we can just
  // sink them. It's better to sink them here, than to make the NetVC code more
  // complex.
  vc->action_ = &a;

  vc->id          = net_next_connection_number();
  vc->submit_time = ink_get_hrtime();
  vc->mutex       = new_ProxyMutex();
  vc->set_is_transparent(false);
  vc->set_context(NetVConnectionContext_t::NET_VCONNECTION_OUT);

  // We should take the nh's lock and vc's lock before we get into the connectUp
  SCOPED_MUTEX_LOCK(lock, get_NetHandler(t)->mutex, t);
  SCOPED_MUTEX_LOCK(lock2, vc->mutex, t);

  if (vc->connectUp(t, fd) != CONNECT_SUCCESS) {
    return nullptr;
  }

  return reinterpret_cast<TSVConn>(vc);
}

TSVIO
TSVConnReadVIOGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = reinterpret_cast<VConnection *>(connp);
  TSVIO        data;

  if (vc->get_data(TS_API_DATA_READ_VIO, &data)) {
    return data;
  }

  return nullptr;
}

TSVIO
TSVConnWriteVIOGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = reinterpret_cast<VConnection *>(connp);
  TSVIO        data;

  if (vc->get_data(TS_API_DATA_WRITE_VIO, &data)) {
    return data;
  }

  return nullptr;
}

int
TSVConnClosedGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc   = reinterpret_cast<VConnection *>(connp);
  int          data = 0;
  bool         f    = vc->get_data(TS_API_DATA_CLOSED, &data);
  ink_assert(f); // This can fail in some cases, we need to track those down.
  return data;
}

TSVIO
TSVConnRead(TSVConn connp, TSCont contp, TSIOBuffer bufp, int64_t nbytes)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_iocore_structure(bufp) == TS_SUCCESS);
  sdk_assert(nbytes >= 0);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);
  VConnection *vc = reinterpret_cast<VConnection *>(connp);

  return reinterpret_cast<TSVIO>(
    vc->do_io_read(reinterpret_cast<INKContInternal *>(contp), nbytes, reinterpret_cast<MIOBuffer *>(bufp)));
}

TSVIO
TSVConnWrite(TSVConn connp, TSCont contp, TSIOBufferReader readerp, int64_t nbytes)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_iocore_structure(readerp) == TS_SUCCESS);
  sdk_assert(nbytes >= 0);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);
  VConnection *vc = reinterpret_cast<VConnection *>(connp);

  return reinterpret_cast<TSVIO>(
    vc->do_io_write(reinterpret_cast<INKContInternal *>(contp), nbytes, reinterpret_cast<IOBufferReader *>(readerp)));
}

void
TSVConnClose(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = reinterpret_cast<VConnection *>(connp);
  vc->do_io_close();
}

void
TSVConnAbort(TSVConn connp, int error)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = reinterpret_cast<VConnection *>(connp);
  vc->do_io_close(error);
}

void
TSVConnShutdown(TSVConn connp, int read, int write)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = reinterpret_cast<VConnection *>(connp);

  if (read && write) {
    vc->do_io_shutdown(IO_SHUTDOWN_READWRITE);
  } else if (read) {
    vc->do_io_shutdown(IO_SHUTDOWN_READ);
  } else if (write) {
    vc->do_io_shutdown(IO_SHUTDOWN_WRITE);
  }
}

int64_t
TSVConnCacheObjectSizeGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  CacheVC *vc = reinterpret_cast<CacheVC *>(connp);
  return vc->get_object_size();
}

void
TSVConnCacheHttpInfoSet(TSVConn connp, TSCacheHttpInfo infop)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  CacheVC *vc = reinterpret_cast<CacheVC *>(connp);
  if (static_cast<CacheOpType>(vc->op_type) == CacheOpType::Scan) {
    vc->set_http_info(reinterpret_cast<CacheHTTPInfo *>(infop));
  }
}

/* Transformations */

TSVConn
TSTransformCreate(TSEventFunc event_funcp, TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  return TSVConnCreate(event_funcp,
                       reinterpret_cast<TSMutex>(static_cast<Continuation *>(reinterpret_cast<HttpSM *>(txnp))->getMutex()));
}

TSVConn
TSTransformOutputVConnGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = reinterpret_cast<VConnection *>(connp);
  TSVConn      data;

  vc->get_data(TS_API_DATA_OUTPUT_VC, &data); // This case can't fail.
  return data;
}

void
TSHttpTxnServerIntercept(TSCont contp, TSHttpTxn txnp)
{
  HttpSM *http_sm = reinterpret_cast<HttpSM *>(txnp);

  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);

  TSIOBufferSizeIndex buffer_index      = TSPluginVCIOBufferIndexGet(txnp);
  TSIOBufferWaterMark buffer_water_mark = TSPluginVCIOBufferWaterMarkGet(txnp);

  http_sm->plugin_tunnel_type = HttpPluginTunnel_t::AS_SERVER;
  http_sm->plugin_tunnel      = PluginVCCore::alloc(reinterpret_cast<INKContInternal *>(contp), buffer_index, buffer_water_mark);
}

void
TSHttpTxnIntercept(TSCont contp, TSHttpTxn txnp)
{
  HttpSM *http_sm = reinterpret_cast<HttpSM *>(txnp);

  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);

  TSIOBufferSizeIndex buffer_index      = TSPluginVCIOBufferIndexGet(txnp);
  TSIOBufferWaterMark buffer_water_mark = TSPluginVCIOBufferWaterMarkGet(txnp);

  http_sm->plugin_tunnel_type = HttpPluginTunnel_t::AS_INTERCEPT;
  http_sm->plugin_tunnel      = PluginVCCore::alloc(reinterpret_cast<INKContInternal *>(contp), buffer_index, buffer_water_mark);
}

TSIOBufferSizeIndex
TSPluginVCIOBufferIndexGet(TSHttpTxn txnp)
{
  TSMgmtInt index;

  if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX, &index) == TS_SUCCESS &&
      index >= TS_IOBUFFER_SIZE_INDEX_128 && index <= MAX_BUFFER_SIZE_INDEX) {
    return static_cast<TSIOBufferSizeIndex>(index);
  }

  return TS_IOBUFFER_SIZE_INDEX_32K;
}

TSIOBufferWaterMark
TSPluginVCIOBufferWaterMarkGet(TSHttpTxn txnp)
{
  TSMgmtInt water_mark;

  if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK, &water_mark) == TS_SUCCESS &&
      water_mark > TS_IOBUFFER_WATER_MARK_UNDEFINED) {
    return static_cast<TSIOBufferWaterMark>(water_mark);
  }

  return TS_IOBUFFER_WATER_MARK_PLUGIN_VC_DEFAULT;
}

/* Net VConnections */
void
TSVConnInactivityTimeoutSet(TSVConn connp, TSHRTime timeout)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  NetVConnection *vc = reinterpret_cast<NetVConnection *>(connp);
  vc->set_inactivity_timeout(timeout);
}

void
TSVConnInactivityTimeoutCancel(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  NetVConnection *vc = reinterpret_cast<NetVConnection *>(connp);
  vc->cancel_inactivity_timeout();
}

void
TSVConnActiveTimeoutSet(TSVConn connp, TSHRTime timeout)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  NetVConnection *vc = reinterpret_cast<NetVConnection *>(connp);
  vc->set_active_timeout(timeout);
}

void
TSVConnActiveTimeoutCancel(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  NetVConnection *vc = reinterpret_cast<NetVConnection *>(connp);
  vc->cancel_active_timeout();
}

sockaddr const *
TSNetVConnLocalAddrGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);
  NetVConnection *vc = reinterpret_cast<NetVConnection *>(connp);
  return vc->get_local_addr();
}

sockaddr const *
TSNetVConnRemoteAddrGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);
  NetVConnection *vc = reinterpret_cast<NetVConnection *>(connp);
  return vc->get_remote_addr();
}

sockaddr const *
TSNetVConnClientAddrGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);
  NetVConnection *vc = reinterpret_cast<NetVConnection *>(connp);
  return vc->get_effective_remote_addr();
}

TSAction
TSNetConnect(TSCont contp, sockaddr const *addr)
{
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(ats_is_ip(addr));

  HttpConfigParams *http_config_param = HttpConfig::acquire();
  NetVCOptions      opt;
  if (http_config_param) {
    opt.set_sock_param(http_config_param->oride.sock_recv_buffer_size_out, http_config_param->oride.sock_send_buffer_size_out,
                       http_config_param->oride.sock_option_flag_out, http_config_param->oride.sock_packet_mark_out,
                       http_config_param->oride.sock_packet_tos_out);
    HttpConfig::release(http_config_param);
  }

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  return reinterpret_cast<TSAction>(netProcessor.connect_re(reinterpret_cast<INKContInternal *>(contp), addr, opt));
}

TSAction
TSNetConnectTransparent(TSCont contp, sockaddr const *client_addr, sockaddr const *server_addr)
{
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(ats_is_ip(server_addr));
  sdk_assert(ats_ip_are_compatible(client_addr, server_addr));

  NetVCOptions opt;
  opt.addr_binding = NetVCOptions::FOREIGN_ADDR;
  opt.local_ip.assign(client_addr);
  opt.local_port = ats_ip_port_host_order(client_addr);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  return reinterpret_cast<TSAction>(netProcessor.connect_re(reinterpret_cast<INKContInternal *>(contp), server_addr, opt));
}

TSCont
TSNetInvokingContGet(TSVConn conn)
{
  NetVConnection     *vc     = reinterpret_cast<NetVConnection *>(conn);
  UnixNetVConnection *net_vc = dynamic_cast<UnixNetVConnection *>(vc);
  TSCont              ret    = nullptr;
  if (net_vc) {
    const Action *action = net_vc->get_action();
    ret                  = reinterpret_cast<TSCont>(action->continuation);
  }
  return ret;
}

TSHttpTxn
TSNetInvokingTxnGet(TSVConn conn)
{
  TSCont    cont = TSNetInvokingContGet(conn);
  TSHttpTxn ret  = nullptr;
  if (cont) {
    Continuation *contobj = reinterpret_cast<Continuation *>(cont);
    HttpSM       *sm      = dynamic_cast<HttpSM *>(contobj);
    if (sm) {
      ret = reinterpret_cast<TSHttpTxn>(sm);
    }
  }
  return ret;
}

TSAction
TSNetAccept(TSCont contp, int port, int domain, int accept_threads)
{
  NetProcessor::AcceptOptions opt;

  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(port > 0);
  sdk_assert(accept_threads >= -1);

  // TODO: Does this imply that only one "accept thread" could be
  // doing an accept at any time?
  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  opt = make_net_accept_options(nullptr, accept_threads);

  // If it's not IPv6, force to IPv4.
  opt.ip_family       = domain == AF_INET6 ? AF_INET6 : AF_INET;
  opt.local_port      = port;
  opt.frequent_accept = false;

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);
  return reinterpret_cast<TSAction>(netProcessor.accept(i, opt));
}

TSReturnCode
TSNetAcceptNamedProtocol(TSCont contp, const char *protocol)
{
  sdk_assert(protocol != nullptr);
  sdk_assert(contp != nullptr);
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);

  if (!ssl_register_protocol(protocol, reinterpret_cast<INKContInternal *>(contp))) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

/* DNS Lookups */
/// Context structure for the lookup callback to the plugin.
struct TSResolveInfo {
  IpEndpoint    addr;             ///< Lookup result.
  HostDBRecord *record = nullptr; ///< Record for the FQDN.
};

static int
TSHostLookupTrampoline(TSCont contp, TSEvent ev, void *data)
{
  auto c = reinterpret_cast<INKContInternal *>(contp);
  // Set up the local context.
  TSResolveInfo ri;
  ri.record = static_cast<HostDBRecord *>(data);
  if (ri.record) {
    ri.record->rr_info()[0].data.ip.toSockAddr(ri.addr);
  }
  auto *target = reinterpret_cast<INKContInternal *>(c->mdata);
  // Deliver the message.
  target->handleEvent(ev, &ri);
  // Cleanup.
  c->destroy();
  return TS_SUCCESS;
};

TSAction
TSHostLookup(TSCont contp, const char *hostname, size_t namelen)
{
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)hostname) == TS_SUCCESS);
  sdk_assert(namelen > 0);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  // There is no place to store the actual sockaddr to which a pointer should be returned.
  // therefore an intermediate continuation is created to intercept the reply from HostDB.
  // Its handler can create the required sockaddr context on the stack and then forward
  // the event to the plugin continuation. The sockaddr cannot be placed in the HostDB
  // record because that is a shared object.
  auto bouncer = INKContAllocator.alloc();
  bouncer->init(&TSHostLookupTrampoline, reinterpret_cast<TSMutex>(reinterpret_cast<INKContInternal *>(contp)->mutex.get()));
  bouncer->mdata = contp;
  return reinterpret_cast<TSAction>(hostDBProcessor.getbyname_re(bouncer, hostname, namelen));
}

sockaddr const *
TSHostLookupResultAddrGet(TSHostLookupResult lookup_result)
{
  sdk_assert(sdk_sanity_check_hostlookup_structure(lookup_result) == TS_SUCCESS);
  auto ri{reinterpret_cast<TSResolveInfo *>(lookup_result)};
  return ri->addr.isValid() ? &ri->addr.sa : nullptr;
}

/*
 * checks if the cache is ready
 */

/* Cache VConnections */
TSAction
TSCacheRead(TSCont contp, TSCacheKey key)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  CacheInfo    *info = reinterpret_cast<CacheInfo *>(key);
  Continuation *i    = reinterpret_cast<INKContInternal *>(contp);

  return reinterpret_cast<TSAction>(cacheProcessor.open_read(
    i, &info->cache_key, info->frag_type, std::string_view{info->hostname, static_cast<std::string_view::size_type>(info->len)}));
}

TSAction
TSCacheWrite(TSCont contp, TSCacheKey key)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  CacheInfo    *info = reinterpret_cast<CacheInfo *>(key);
  Continuation *i    = reinterpret_cast<INKContInternal *>(contp);

  return reinterpret_cast<TSAction>(
    cacheProcessor.open_write(i, &info->cache_key, info->frag_type, 0, false, info->pin_in_cache,
                              std::string_view{info->hostname, static_cast<std::string_view::size_type>(info->len)}));
}

TSAction
TSCacheRemove(TSCont contp, TSCacheKey key)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_cachekey(key) == TS_SUCCESS);

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  CacheInfo       *info = reinterpret_cast<CacheInfo *>(key);
  INKContInternal *i    = reinterpret_cast<INKContInternal *>(contp);

  return reinterpret_cast<TSAction>(cacheProcessor.remove(
    i, &info->cache_key, info->frag_type, std::string_view{info->hostname, static_cast<std::string_view::size_type>(info->len)}));
}

TSAction
TSCacheScan(TSCont contp, TSCacheKey key, int KB_per_second)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);
  // NOTE: key can be NULl here, so don't check for it.

  FORCE_PLUGIN_SCOPED_MUTEX(contp);

  INKContInternal *i = reinterpret_cast<INKContInternal *>(contp);

  if (key) {
    CacheInfo *info = reinterpret_cast<CacheInfo *>(key);
    return reinterpret_cast<TSAction>(
      cacheProcessor.scan(i, std::string_view{info->hostname, static_cast<std::string_view::size_type>(info->len)}, KB_per_second));
  }
  return reinterpret_cast<TSAction>(cacheProcessor.scan(i, std::string_view{}, KB_per_second));
}

/************************   REC Stats API    **************************/
int
TSStatCreate(const char *the_name, TSRecordDataType /* the_type ATS_UNUSED */, TSStatPersistence /* persist ATS_UNUSED */,
             TSStatSync /* sync ATS_UNUSED */)
{
  int id = Metrics::Gauge::create(the_name); // Gauges allows for all "int" operations

  if (id == ts::Metrics::NOT_FOUND) {
    return TS_ERROR;
  }

  return id;
}

void
TSStatIntIncrement(int id, TSMgmtInt amount)
{
  sdk_assert(sdk_sanity_check_stat_id(id) == TS_SUCCESS);
  global_api_metrics.increment(id, amount);
}

void
TSStatIntDecrement(int id, TSMgmtInt amount)
{
  sdk_assert(sdk_sanity_check_stat_id(id) == TS_SUCCESS);
  global_api_metrics.decrement(id, amount);
}

TSMgmtInt
TSStatIntGet(int id)
{
  sdk_assert(sdk_sanity_check_stat_id(id) == TS_SUCCESS);
  return global_api_metrics[id].load();
}

void
TSStatIntSet(int id, TSMgmtInt value)
{
  sdk_assert(sdk_sanity_check_stat_id(id) == TS_SUCCESS);
  global_api_metrics[id].store(value);
}

TSReturnCode
TSStatFindName(const char *name, int *idp)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)name) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)idp) == TS_SUCCESS);

  int id = global_api_metrics.lookup(name);

  if (id == ts::Metrics::NOT_FOUND) {
    return TS_ERROR;
  } else {
    *idp = id;
    return TS_SUCCESS;
  }
}

/**************************   Logging API   ****************************/

TSReturnCode
TSTextLogObjectCreate(const char *filename, int mode, TSTextLogObject *new_object)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)filename) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)new_object) == TS_SUCCESS);

  if (mode < 0 || mode >= TS_LOG_MODE_INVALID_FLAG) {
    *new_object = nullptr;
    return TS_ERROR;
  }

  TextLogObject *tlog = new TextLogObject(
    filename, Log::config->logfile_dir, static_cast<bool>(mode) & TS_LOG_MODE_ADD_TIMESTAMP, nullptr, Log::config->rolling_enabled,
    Log::config->preproc_threads, Log::config->rolling_interval_sec, Log::config->rolling_offset_hr, Log::config->rolling_size_mb,
    Log::config->rolling_max_count, Log::config->rolling_min_count, Log::config->rolling_allow_empty);
  if (tlog == nullptr) {
    *new_object = nullptr;
    return TS_ERROR;
  }

  int err = (mode & TS_LOG_MODE_DO_NOT_RENAME ? Log::config->log_object_manager.manage_api_object(tlog, 0) :
                                                Log::config->log_object_manager.manage_api_object(tlog));
  if (err != LogObjectManager::NO_FILENAME_CONFLICTS) {
    delete tlog;
    *new_object = nullptr;
    return TS_ERROR;
  }

  *new_object = reinterpret_cast<TSTextLogObject>(tlog);
  return TS_SUCCESS;
}

TSReturnCode
TSTextLogObjectWrite(TSTextLogObject the_object, const char *format, ...)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)format) == TS_SUCCESS);

  TSReturnCode retVal = TS_SUCCESS;

  va_list ap;
  va_start(ap, format);
  switch ((reinterpret_cast<TextLogObject *>(the_object))->va_write(format, ap)) {
  case (Log::LOG_OK):
  case (Log::SKIP):
  case (Log::AGGR):
    break;
  case (Log::FULL):
    retVal = TS_ERROR;
    break;
  case (Log::FAIL):
    retVal = TS_ERROR;
    break;
  default:
    ink_assert(!"invalid return code");
  }
  va_end(ap);

  return retVal;
}

void
TSTextLogObjectFlush(TSTextLogObject the_object)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  (reinterpret_cast<TextLogObject *>(the_object))->force_new_buffer();
}

TSReturnCode
TSTextLogObjectDestroy(TSTextLogObject the_object)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  if (Log::config->log_object_manager.unmanage_api_object(reinterpret_cast<TextLogObject *>(the_object))) {
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

void
TSTextLogObjectHeaderSet(TSTextLogObject the_object, const char *header)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  (reinterpret_cast<TextLogObject *>(the_object))->set_log_file_header(header);
}

TSReturnCode
TSTextLogObjectRollingEnabledSet(TSTextLogObject the_object, int rolling_enabled)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  if (LogRollingEnabledIsValid(rolling_enabled)) {
    (reinterpret_cast<TextLogObject *>(the_object))->set_rolling_enabled(static_cast<Log::RollingEnabledValues>(rolling_enabled));
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

void
TSTextLogObjectRollingIntervalSecSet(TSTextLogObject the_object, int rolling_interval_sec)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  (reinterpret_cast<TextLogObject *>(the_object))->set_rolling_interval_sec(rolling_interval_sec);
}

void
TSTextLogObjectRollingOffsetHrSet(TSTextLogObject the_object, int rolling_offset_hr)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  (reinterpret_cast<TextLogObject *>(the_object))->set_rolling_offset_hr(rolling_offset_hr);
}

void
TSTextLogObjectRollingSizeMbSet(TSTextLogObject the_object, int rolling_size_mb)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  (reinterpret_cast<TextLogObject *>(the_object))->set_rolling_size_mb(rolling_size_mb);
}

TSReturnCode
TSHttpSsnClientFdGet(TSHttpSsn ssnp, int *fdp)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)fdp) == TS_SUCCESS);

  VConnection  *basecs = reinterpret_cast<VConnection *>(ssnp);
  ProxySession *cs     = dynamic_cast<ProxySession *>(basecs);

  if (cs == nullptr) {
    return TS_ERROR;
  }

  NetVConnection *vc = cs->get_netvc();
  if (vc == nullptr) {
    return TS_ERROR;
  }

  *fdp = vc->get_socket();
  return TS_SUCCESS;
}
TSReturnCode
TSHttpTxnClientFdGet(TSHttpTxn txnp, int *fdp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)fdp) == TS_SUCCESS);

  TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp);
  return TSHttpSsnClientFdGet(ssnp, fdp);
}

TSReturnCode
TSHttpTxnServerFdGet(TSHttpTxn txnp, int *fdp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)fdp) == TS_SUCCESS);

  HttpSM *sm               = reinterpret_cast<HttpSM *>(txnp);
  *fdp                     = -1;
  TSReturnCode      retval = TS_ERROR;
  ProxyTransaction *ss     = sm->get_server_txn();
  if (ss != nullptr) {
    NetVConnection *vc = ss->get_netvc();
    if (vc != nullptr) {
      *fdp   = vc->get_socket();
      retval = TS_SUCCESS;
    }
  }
  return retval;
}

void
load_config_file_callback(const char *parent_file, const char *remap_file)
{
  FileManager::instance().configFileChild(parent_file, remap_file);
}

/* Config file name setting */
TSReturnCode
TSMgmtConfigFileAdd(const char *parent, const char *fileName)
{
  load_config_file_callback(parent, fileName);
  return TS_SUCCESS;
}

TSReturnCode
TSCacheUrlSet(TSHttpTxn txnp, const char *url, int length)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  Dbg(dbg_ctl_cache_url, "[TSCacheUrlSet]");

  if (sm->t_state.cache_info.lookup_url == nullptr) {
    Dbg(dbg_ctl_cache_url, "[TSCacheUrlSet] changing the cache url to: %s", url);

    if (length == -1) {
      length = strlen(url);
    }

    sm->t_state.cache_info.lookup_url_storage.create(nullptr);
    sm->t_state.cache_info.lookup_url = &(sm->t_state.cache_info.lookup_url_storage);
    sm->t_state.cache_info.lookup_url->parse(url, length);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

void
TSCacheHttpInfoKeySet(TSCacheHttpInfo infop, TSCacheKey keyp)
{
  // TODO: Check input ?
  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);
  CryptoHash    *key  = reinterpret_cast<CryptoHash *>(keyp);

  info->object_key_set(*key);
}

void
TSCacheHttpInfoSizeSet(TSCacheHttpInfo infop, int64_t size)
{
  // TODO: Check input ?
  CacheHTTPInfo *info = reinterpret_cast<CacheHTTPInfo *>(infop);

  info->object_size_set(size);
}

// this function should be called at TS_EVENT_HTTP_READ_RESPONSE_HDR
void
TSHttpTxnRedirectUrlSet(TSHttpTxn txnp, const char *url, const int url_len)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)url) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  ats_free(sm->redirect_url);
  sm->redirect_url     = nullptr;
  sm->redirect_url_len = 0;

  sm->redirect_url       = const_cast<char *>(url);
  sm->redirect_url_len   = url_len;
  sm->enable_redirection = true;
  sm->redirection_tries  = 0;

  // Make sure we allow for at least one redirection.
  if (sm->t_state.txn_conf->number_of_redirections <= 0) {
    sm->t_state.setup_per_txn_configs();
    sm->t_state.my_txn_conf().number_of_redirections = 1;
  }
}

const char *
TSHttpTxnRedirectUrlGet(TSHttpTxn txnp, int *url_len_ptr)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  *url_len_ptr = sm->redirect_url_len;
  return sm->redirect_url;
}

int
TSHttpTxnRedirectRetries(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  return sm->redirection_tries;
}

char *
TSFetchRespGet(TSHttpTxn txnp, int *length)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)length) == TS_SUCCESS);
  FetchSM *fetch_sm = reinterpret_cast<FetchSM *>(txnp);
  return fetch_sm->resp_get(length);
}

TSReturnCode
TSFetchPageRespGet(TSHttpTxn txnp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)obj) == TS_SUCCESS);

  HTTPHdr *hptr = reinterpret_cast<HTTPHdr *>(txnp);

  if (hptr->valid()) {
    *(reinterpret_cast<HTTPHdr **>(bufp)) = hptr;
    *obj                                  = reinterpret_cast<TSMLoc>(hptr->m_http);
    return sdk_sanity_check_mbuffer(*bufp);
  }

  return TS_ERROR;
}

void
TSFetchPages(TSFetchUrlParams_t *params)
{
  TSFetchUrlParams_t *myparams = params;

  while (myparams != nullptr) {
    FetchSM  *fetch_sm = FetchSMAllocator.alloc();
    sockaddr *addr     = ats_ip_sa_cast(&myparams->ip);

    fetch_sm->init(reinterpret_cast<Continuation *>(myparams->contp), myparams->options, myparams->events, myparams->request,
                   myparams->request_len, addr);
    fetch_sm->httpConnect();
    myparams = myparams->next;
  }
}

TSFetchSM
TSFetchUrl(const char *headers, int request_len, sockaddr const *ip, TSCont contp, TSFetchWakeUpOptions callback_options,
           TSFetchEvent events)
{
  if (callback_options != NO_CALLBACK) {
    sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  }

  FetchSM *fetch_sm = FetchSMAllocator.alloc();

  fetch_sm->init(reinterpret_cast<Continuation *>(contp), callback_options, events, headers, request_len, ip);
  fetch_sm->httpConnect();

  return reinterpret_cast<TSFetchSM>(fetch_sm);
}

void
TSFetchFlagSet(TSFetchSM fetch_sm, int flags)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);
  (reinterpret_cast<FetchSM *>(fetch_sm))->set_fetch_flags(flags);
}

TSFetchSM
TSFetchCreate(TSCont contp, const char *method, const char *url, const char *version, struct sockaddr const *client_addr, int flags)
{
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(ats_is_ip(client_addr));

  FetchSM *fetch_sm = FetchSMAllocator.alloc();

  fetch_sm->ext_init(reinterpret_cast<Continuation *>(contp), method, url, version, client_addr, flags);

  return reinterpret_cast<TSFetchSM>(fetch_sm);
}

void
TSFetchHeaderAdd(TSFetchSM fetch_sm, const char *name, int name_len, const char *value, int value_len)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  (reinterpret_cast<FetchSM *>(fetch_sm))->ext_add_header(name, name_len, value, value_len);
}

void
TSFetchWriteData(TSFetchSM fetch_sm, const void *data, size_t len)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  (reinterpret_cast<FetchSM *>(fetch_sm))->ext_write_data(data, len);
}

ssize_t
TSFetchReadData(TSFetchSM fetch_sm, void *buf, size_t len)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  return (reinterpret_cast<FetchSM *>(fetch_sm))->ext_read_data(static_cast<char *>(buf), len);
}

void
TSFetchLaunch(TSFetchSM fetch_sm)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  (reinterpret_cast<FetchSM *>(fetch_sm))->ext_launch();
}

void
TSFetchDestroy(TSFetchSM fetch_sm)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  (reinterpret_cast<FetchSM *>(fetch_sm))->ext_destroy();
}

void
TSFetchUserDataSet(TSFetchSM fetch_sm, void *data)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  (reinterpret_cast<FetchSM *>(fetch_sm))->ext_set_user_data(data);
}

void *
TSFetchUserDataGet(TSFetchSM fetch_sm)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  return (reinterpret_cast<FetchSM *>(fetch_sm))->ext_get_user_data();
}

TSMBuffer
TSFetchRespHdrMBufGet(TSFetchSM fetch_sm)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  return (reinterpret_cast<FetchSM *>(fetch_sm))->resp_hdr_bufp();
}

TSMLoc
TSFetchRespHdrMLocGet(TSFetchSM fetch_sm)
{
  sdk_assert(sdk_sanity_check_fetch_sm(fetch_sm) == TS_SUCCESS);

  return (reinterpret_cast<FetchSM *>(fetch_sm))->resp_hdr_mloc();
}

int
TSHttpSsnIsInternal(TSHttpSsn ssnp)
{
  ProxySession *cs = reinterpret_cast<ProxySession *>(ssnp);

  if (!cs) {
    return 0;
  }

  NetVConnection *vc = cs->get_netvc();
  if (!vc) {
    return 0;
  }

  return vc->get_is_internal_request() ? 1 : 0;
}

int
TSHttpTxnIsInternal(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  return TSHttpSsnIsInternal(TSHttpTxnSsnGet(txnp));
}

static void
txn_error_get(TSHttpTxn txnp, bool client, bool sent, uint32_t &error_class, uint64_t &error_code)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM                             *sm                    = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::ConnectionAttributes *connection_attributes = nullptr;

  if (client == true) {
    // client
    connection_attributes = &sm->t_state.client_info;
  } else {
    // server
    connection_attributes = &sm->t_state.server_info;
  }

  if (sent == true) {
    // sent
    error_code  = connection_attributes->tx_error_code.code;
    error_class = static_cast<uint32_t>(connection_attributes->tx_error_code.cls);
  } else {
    // received
    error_code  = connection_attributes->rx_error_code.code;
    error_class = static_cast<uint32_t>(connection_attributes->rx_error_code.cls);
  }
}

void
TSHttpTxnClientReceivedErrorGet(TSHttpTxn txnp, uint32_t *error_class, uint64_t *error_code)
{
  txn_error_get(txnp, true, false, *error_class, *error_code);
}

void
TSHttpTxnClientSentErrorGet(TSHttpTxn txnp, uint32_t *error_class, uint64_t *error_code)
{
  txn_error_get(txnp, true, true, *error_class, *error_code);
}

void
TSHttpTxnServerReceivedErrorGet(TSHttpTxn txnp, uint32_t *error_class, uint64_t *error_code)
{
  txn_error_get(txnp, false, false, *error_class, *error_code);
}

void
TSHttpTxnServerSentErrorGet(TSHttpTxn txnp, uint32_t *error_class, uint64_t *error_code)
{
  txn_error_get(txnp, false, true, *error_class, *error_code);
}

TSReturnCode
TSHttpTxnServerPush(TSHttpTxn txnp, const char *url, int url_len)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(url != nullptr);

  if (url_len < 0) {
    url_len = strlen(url);
  }

  URL url_obj;
  url_obj.create(nullptr);
  if (url_obj.parse(url, url_len) == ParseResult::ERROR) {
    url_obj.destroy();
    return TS_ERROR;
  }

  HttpSM      *sm     = reinterpret_cast<HttpSM *>(txnp);
  Http2Stream *stream = dynamic_cast<Http2Stream *>(sm->get_ua_txn());
  if (stream == nullptr) {
    url_obj.destroy();
    return TS_ERROR;
  }

  Http2ClientSession *ua_session = static_cast<Http2ClientSession *>(stream->get_proxy_ssn());
  SCOPED_MUTEX_LOCK(lock, ua_session->mutex, this_ethread());
  if (ua_session->connection_state.is_state_closed() || ua_session->is_url_pushed(url, url_len)) {
    url_obj.destroy();
    return TS_ERROR;
  }

  HTTPHdr *hptr = &(sm->t_state.hdr_info.client_request);
  TSMLoc   obj  = reinterpret_cast<TSMLoc>(hptr->m_http);

  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(obj);
  MIMEField   *f  = mime_hdr_field_find(mh, static_cast<std::string_view>(MIME_FIELD_ACCEPT_ENCODING));
  if (!stream->push_promise(url_obj, f)) {
    url_obj.destroy();
    return TS_ERROR;
  }

  ua_session->add_url_to_pushed_table(url, url_len);

  url_obj.destroy();
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnClientStreamIdGet(TSHttpTxn txnp, uint64_t *stream_id)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(stream_id != nullptr);

  auto *sm     = reinterpret_cast<HttpSM *>(txnp);
  auto *stream = dynamic_cast<Http2Stream *>(sm->get_ua_txn());
  if (stream == nullptr) {
    return TS_ERROR;
  }
  *stream_id = stream->get_id();
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnClientStreamPriorityGet(TSHttpTxn txnp, TSHttpPriority *priority)
{
  static_assert(sizeof(TSHttpPriority) >= sizeof(TSHttp2Priority),
                "TSHttpPriorityType is incorrectly smaller than TSHttp2Priority.");
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(priority != nullptr);

  auto *sm     = reinterpret_cast<HttpSM *>(txnp);
  auto *stream = dynamic_cast<Http2Stream *>(sm->get_ua_txn());
  if (stream == nullptr) {
    return TS_ERROR;
  }

  auto *priority_out              = reinterpret_cast<TSHttp2Priority *>(priority);
  priority_out->priority_type     = HTTP_PRIORITY_TYPE_HTTP_2;
  priority_out->stream_dependency = stream->get_transaction_priority_dependence();
  priority_out->weight            = stream->get_transaction_priority_weight();

  return TS_SUCCESS;
}

TSReturnCode
TSAIORead(int fd, off_t offset, char *buf, size_t buffSize, TSCont contp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  Continuation *pCont = reinterpret_cast<Continuation *>(contp);
  AIOCallback  *pAIO  = new_AIOCallback();

  if (pAIO == nullptr) {
    return TS_ERROR;
  }

  pAIO->aiocb.aio_fildes = fd;
  pAIO->aiocb.aio_offset = offset;
  pAIO->aiocb.aio_nbytes = buffSize;

  pAIO->aiocb.aio_buf = buf;
  pAIO->action        = pCont;
  pAIO->thread        = pCont->mutex->thread_holding;

  if (ink_aio_read(pAIO, 1) == 1) {
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

char *
TSAIOBufGet(TSAIOCallback data)
{
  AIOCallback *pAIO = reinterpret_cast<AIOCallback *>(data);
  return static_cast<char *>(pAIO->aiocb.aio_buf);
}

int
TSAIONBytesGet(TSAIOCallback data)
{
  AIOCallback *pAIO = reinterpret_cast<AIOCallback *>(data);
  return static_cast<int>(pAIO->aio_result);
}

TSReturnCode
TSAIOWrite(int fd, off_t offset, char *buf, const size_t bufSize, TSCont contp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  Continuation *pCont = reinterpret_cast<Continuation *>(contp);
  AIOCallback  *pAIO  = new_AIOCallback();

  // TODO: Might be able to remove this when allocations can never fail.
  sdk_assert(sdk_sanity_check_null_ptr((void *)pAIO) == TS_SUCCESS);

  pAIO->aiocb.aio_fildes = fd;
  pAIO->aiocb.aio_offset = offset;
  pAIO->aiocb.aio_buf    = buf;
  pAIO->aiocb.aio_nbytes = bufSize;
  pAIO->action           = pCont;
  pAIO->thread           = pCont->mutex->thread_holding;

  if (ink_aio_write(pAIO, 1) == 1) {
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSAIOThreadNumSet(int thread_num)
{
  if (ink_aio_thread_num_set(thread_num)) {
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

void
TSRecordDump(int rec_type, TSRecordDumpCb callback, void *edata)
{
  RecDumpRecords(static_cast<RecT>(rec_type), reinterpret_cast<RecDumpEntryCb>(callback), edata);
}

/* ability to skip the remap phase of the State Machine
   this only really makes sense in TS_HTTP_READ_REQUEST_HDR_HOOK
*/
void
TSSkipRemappingSet(TSHttpTxn txnp, int flag)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm                         = reinterpret_cast<HttpSM *>(txnp);
  sm->t_state.api_skip_all_remapping = (flag != 0);
}

/* These are the default converter function sets for management data types. If those are used the
 * proper converters can be determined here. For other types the converters must be explicitly
 * specified.
 *
 * The purpose of these are to allow configuration elements to not be management types but more
 * natural types (e.g., an enumeration can be the actual enumeration, not an @c MgmtInt that needs
 * frequent casting). In effect the converter does the casting for the plugin API, isolating that
 * to this API handling, with the rest of the code base using the natural types.
 */

/// Unhandled API conversions.
/// Because the code around the specially handled types still uses this in the default case,
/// it must compile for those cases. To indicate unhandled, return @c nullptr for @a conv.
/// @internal This should be a temporary state, eventually the other cases should be handled
/// via specializations here.
/// @internal C++ note - THIS MUST BE FIRST IN THE DECLARATIONS or it might be falsely used.
template <typename T>
inline void *
_memberp_to_generic(T *ptr, MgmtConverter const *&conv)
{
  conv = nullptr;
  return ptr;
}

/// API conversion for @c MgmtInt, identify conversion as integer.
inline void *
_memberp_to_generic(MgmtInt *ptr, MgmtConverter const *&conv)
{
  static const MgmtConverter converter([](const void *data) -> MgmtInt { return *static_cast<const MgmtInt *>(data); },
                                       [](void *data, MgmtInt i) -> void { *static_cast<MgmtInt *>(data) = i; });

  conv = &converter;
  return ptr;
}

/// API conversion for @c MgmtByte, handles integer / byte size differences.
inline void *
_memberp_to_generic(MgmtByte *ptr, MgmtConverter const *&conv)
{
  static const MgmtConverter converter{[](const void *data) -> MgmtInt { return *static_cast<const MgmtByte *>(data); },
                                       [](void *data, MgmtInt i) -> void { *static_cast<MgmtByte *>(data) = i; }};

  conv = &converter;
  return ptr;
}

/// API conversion for @c MgmtFloat, identity conversion as float.
inline void *
_memberp_to_generic(MgmtFloat *ptr, MgmtConverter const *&conv)
{
  static const MgmtConverter converter{[](const void *data) -> MgmtFloat { return *static_cast<const MgmtFloat *>(data); },
                                       [](void *data, MgmtFloat f) -> void { *static_cast<MgmtFloat *>(data) = f; }};

  conv = &converter;
  return ptr;
}

/// API conversion for arbitrary enum.
/// Handle casting to and from the enum type @a E.
template <typename E>
inline auto
_memberp_to_generic(MgmtFloat *ptr, MgmtConverter const *&conv) -> typename std::enable_if<std::is_enum<E>::value, void *>::type
{
  static const MgmtConverter converter{
    [](const void *data) -> MgmtInt { return static_cast<MgmtInt>(*static_cast<const E *>(data)); },
    [](void *data, MgmtInt i) -> void { *static_cast<E *>(data) = static_cast<E>(i); }};

  conv = &converter;
  return ptr;
}

/**
 * X-Macro Dispatch for _conf_to_memberp()
 *
 * Don't be intimidated by the macros below - they're simpler than they look!
 * The end result is just a switch statement with one case per config, like:
 *
 *   switch (conf) {
 *     case TS_CONFIG_HTTP_CHUNKING_ENABLED:
 *       ret = _memberp_to_generic(&overridableHttpConfig->chunking_enabled, conv);
 *       break;
 *     case TS_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME:
 *       conv = &HttpDownServerCacheTimeConv;
 *       ret = &overridableHttpConfig->down_server_timeout;
 *       break;
 *     // ... ~130 more cases, one per overridable config ...
 *   }
 *
 * The macros just auto-generate these cases from OverridableConfigDefs.h so we
 * don't have to maintain them by hand. Here's how an entry becomes a case:
 *
 * Example 1 - Standard config (GENERIC converter):
 *   Entry in OverridableConfigDefs.h:
 *     X(HTTP_CHUNKING_ENABLED, chunking_enabled, "...", INT, GENERIC)
 *   Generates this case:
 *     case TS_CONFIG_HTTP_CHUNKING_ENABLED:
 *       ret = _memberp_to_generic(&overridableHttpConfig->chunking_enabled, conv);
 *       break;
 *
 * Example 2 - Custom converter:
 *   Entry in OverridableConfigDefs.h:
 *     X(HTTP_DOWN_SERVER_CACHE_TIME, down_server_timeout, "...", INT, HttpDownServerCacheTimeConv)
 *   Generates this case:
 *     case TS_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME:
 *       conv = &HttpDownServerCacheTimeConv;
 *       ret = &overridableHttpConfig->down_server_timeout;
 *       break;
 *
 * The magic is in _CONF_CASE_DISPATCH which uses the CONV parameter (5th field)
 * to select which _CONF_CASE_* macro generates the case. Token pasting (##)
 * turns "GENERIC" into _CONF_CASE_GENERIC, "NONE" into _CONF_CASE_NONE, etc.
 *
 * Built-in converter types:
 *   - GENERIC: Auto-selects converter based on member type (most common).
 *   - NONE: No-op for configs handled elsewhere (e.g., SSL strings).
 *   - Custom: Any other name maps to a _CONF_CASE_<name> macro defined below.
 *
 * To add a new custom converter:
 *   1. Define your MgmtConverter (e.g., MyConv with load/store lambdas).
 *   2. Add a macro here following this pattern:
 *        #define _CONF_CASE_MyConv(KEY, MEMBER) \
 *          case TS_CONFIG_##KEY: conv = &MyConv; \
 *            ret = &overridableHttpConfig->MEMBER; break;
 *   3. Add #undef _CONF_CASE_MyConv after _conf_to_memberp().
 *   4. Use "MyConv" as the CONV parameter in OverridableConfigDefs.h.
 */

// clang-format off

// GENERIC: Use _memberp_to_generic() which selects converter based on member type.
#define _CONF_CASE_GENERIC(KEY, MEMBER)                                         \
  case TS_CONFIG_##KEY: ret = _memberp_to_generic(&overridableHttpConfig->MEMBER, conv); break;

// NONE: No-op case for configs handled specially elsewhere.
#define _CONF_CASE_NONE(KEY, MEMBER)                                            \
  case TS_CONFIG_##KEY: break;

// Custom converter: Converts ts_seconds to/from integer seconds.
#define _CONF_CASE_HttpDownServerCacheTimeConv(KEY, MEMBER)                     \
  case TS_CONFIG_##KEY: conv = &HttpDownServerCacheTimeConv; ret = &overridableHttpConfig->MEMBER; break;

// Custom converter: Parses/formats HTTP status code lists (e.g., "404 500").
#define _CONF_CASE_HttpStatusCodeList_Conv(KEY, MEMBER)                         \
  case TS_CONFIG_##KEY: ret = &overridableHttpConfig->MEMBER; conv = &HttpStatusCodeList::Conv; break;

// Custom converters for ConnectionTracker config variables.
#define _CONF_CASE_ConnectionTracker_MIN_SERVER_CONV(KEY, MEMBER)               \
  case TS_CONFIG_##KEY: ret = &overridableHttpConfig->MEMBER; conv = &ConnectionTracker::MIN_SERVER_CONV; break;
#define _CONF_CASE_ConnectionTracker_MAX_SERVER_CONV(KEY, MEMBER)               \
  case TS_CONFIG_##KEY: ret = &overridableHttpConfig->MEMBER; conv = &ConnectionTracker::MAX_SERVER_CONV; break;
#define _CONF_CASE_ConnectionTracker_SERVER_MATCH_CONV(KEY, MEMBER)             \
  case TS_CONFIG_##KEY: ret = &overridableHttpConfig->MEMBER; conv = &ConnectionTracker::SERVER_MATCH_CONV; break;

// Custom converter: Parses/formats host resolution preference strings.
#define _CONF_CASE_HttpTransact_HOST_RES_CONV(KEY, MEMBER)                      \
  case TS_CONFIG_##KEY: ret = &overridableHttpConfig->MEMBER; conv = &HttpTransact::HOST_RES_CONV; break;

// Custom converter: Parses/formats targeted cache control header lists.
#define _CONF_CASE_TargetedCacheControlHeaders_Conv(KEY, MEMBER)                \
  case TS_CONFIG_##KEY: ret = &overridableHttpConfig->MEMBER; conv = &TargetedCacheControlHeaders::Conv; break;

// Dispatcher: Routes to _CONF_CASE_<CONV> based on the CONV parameter.
#define _CONF_CASE_DISPATCH(KEY, MEMBER, RECORD_NAME, DATA_TYPE, CONV) _CONF_CASE_##CONV(KEY, MEMBER)

// clang-format on

/**
 * Map a TSOverridableConfigKey to its corresponding struct member pointer.
 *
 * @param[in] conf The config key to look up.
 * @param[in] overridableHttpConfig Pointer to the config struct.
 * @param[out] conv set to the appropriate MgmtConverter.
 * @return Pointer to the struct member, or nullptr if not found/applicable.
 */
static void *
_conf_to_memberp(TSOverridableConfigKey conf, OverridableHttpConfigParams *overridableHttpConfig, MgmtConverter const *&conv)
{
  void *ret = nullptr;
  conv      = nullptr;

  switch (conf) {
    // This uses OVERRIDABLE_CONFIGS to generate cases for each config.
    // For example:
    //
    // case TS_CONFIG_HTTP_CHUNKING_ENABLED:
    //   ret = _memberp_to_generic(&overridableHttpConfig->chunking_enabled, conv);
    //   break;
    // case TS_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME:
    //   conv = &HttpDownServerCacheTimeConv;
    //   ret = &overridableHttpConfig->down_server_timeout;
    //   break;
    //
    // ... ~130 more cases, one per overridable config ...
    //
    OVERRIDABLE_CONFIGS(_CONF_CASE_DISPATCH)
  case TS_CONFIG_NULL:
  case TS_CONFIG_LAST_ENTRY:
    break;
  }

  return ret;
}

#undef _CONF_CASE_GENERIC
#undef _CONF_CASE_NONE
#undef _CONF_CASE_HttpDownServerCacheTimeConv
#undef _CONF_CASE_HttpStatusCodeList_Conv
#undef _CONF_CASE_ConnectionTracker_MIN_SERVER_CONV
#undef _CONF_CASE_ConnectionTracker_MAX_SERVER_CONV
#undef _CONF_CASE_ConnectionTracker_SERVER_MATCH_CONV
#undef _CONF_CASE_HttpTransact_HOST_RES_CONV
#undef _CONF_CASE_TargetedCacheControlHeaders_Conv
#undef _CONF_CASE_DISPATCH

// 2nd little helper function to find the struct member for getting.
static const void *
_conf_to_memberp(TSOverridableConfigKey conf, const OverridableHttpConfigParams *overridableHttpConfig, MgmtConverter const *&conv)
{
  return _conf_to_memberp(conf, const_cast<OverridableHttpConfigParams *>(overridableHttpConfig), conv);
}

// 3rd little helper function to find and eval MgmtConverter
static TSReturnCode
_eval_conv(OverridableHttpConfigParams *target, TSOverridableConfigKey conf, const char *value, int length)
{
  MgmtConverter const *conv;
  void                *dest = _conf_to_memberp(conf, target, conv);
  if (dest != nullptr && conv != nullptr && conv->store_string) {
    conv->store_string(dest, std::string_view(value, length));
  } else {
    return TS_ERROR;
  }
  return TS_SUCCESS;
}

/* APIs to manipulate the overridable configuration options.
 */
TSReturnCode
TSHttpTxnConfigIntSet(TSHttpTxn txnp, TSOverridableConfigKey conf, TSMgmtInt value)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM              *s = reinterpret_cast<HttpSM *>(txnp);
  MgmtConverter const *conv;

  s->t_state.setup_per_txn_configs();

  void *dest = _conf_to_memberp(conf, &(s->t_state.my_txn_conf()), conv);

  if (!dest || !conv->store_int) {
    return TS_ERROR;
  }

  conv->store_int(dest, value);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnConfigIntGet(TSHttpTxn txnp, TSOverridableConfigKey conf, TSMgmtInt *value)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)value) == TS_SUCCESS);

  HttpSM              *s = reinterpret_cast<HttpSM *>(txnp);
  MgmtConverter const *conv;
  const void          *src = _conf_to_memberp(conf, s->t_state.txn_conf, conv);

  if (!src || !conv->load_int) {
    return TS_ERROR;
  }

  *value = conv->load_int(src);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnConfigFloatSet(TSHttpTxn txnp, TSOverridableConfigKey conf, TSMgmtFloat value)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM              *s = reinterpret_cast<HttpSM *>(txnp);
  MgmtConverter const *conv;

  s->t_state.setup_per_txn_configs();

  void *dest = _conf_to_memberp(conf, &(s->t_state.my_txn_conf()), conv);

  if (!dest || !conv->store_float) {
    return TS_ERROR;
  }

  conv->store_float(dest, value);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnConfigFloatGet(TSHttpTxn txnp, TSOverridableConfigKey conf, TSMgmtFloat *value)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr(static_cast<void *>(value)) == TS_SUCCESS);

  MgmtConverter const *conv;
  const void          *src = _conf_to_memberp(conf, reinterpret_cast<HttpSM *>(txnp)->t_state.txn_conf, conv);

  if (!src || !conv->load_float) {
    return TS_ERROR;
  }
  *value = conv->load_float(src);

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnConfigStringSet(TSHttpTxn txnp, TSOverridableConfigKey conf, const char *value, int length)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  if (length == -1) {
    length = strlen(value);
  }

  HttpSM *s = reinterpret_cast<HttpSM *>(txnp);

  s->t_state.setup_per_txn_configs();

  switch (conf) {
  case TS_CONFIG_HTTP_RESPONSE_SERVER_STR:
    if (value && length > 0) {
      s->t_state.my_txn_conf().proxy_response_server_string     = const_cast<char *>(value); // The "core" likes non-const char*
      s->t_state.my_txn_conf().proxy_response_server_string_len = length;
    } else {
      s->t_state.my_txn_conf().proxy_response_server_string     = nullptr;
      s->t_state.my_txn_conf().proxy_response_server_string_len = 0;
    }
    break;
  case TS_CONFIG_HTTP_GLOBAL_USER_AGENT_HEADER:
    if (value && length > 0) {
      s->t_state.my_txn_conf().global_user_agent_header      = const_cast<char *>(value); // The "core" likes non-const char*
      s->t_state.my_txn_conf().global_user_agent_header_size = length;
    } else {
      s->t_state.my_txn_conf().global_user_agent_header      = nullptr;
      s->t_state.my_txn_conf().global_user_agent_header_size = 0;
    }
    break;
  case TS_CONFIG_BODY_FACTORY_TEMPLATE_BASE:
    if (value && length > 0) {
      s->t_state.my_txn_conf().body_factory_template_base     = const_cast<char *>(value);
      s->t_state.my_txn_conf().body_factory_template_base_len = length;
    } else {
      s->t_state.my_txn_conf().body_factory_template_base     = nullptr;
      s->t_state.my_txn_conf().body_factory_template_base_len = 0;
    }
    break;
  case TS_CONFIG_HTTP_INSERT_FORWARDED:
    if (value && length > 0) {
      auto &parsed                              = ParsedConfigCache::lookup(conf, std::string_view(value, length));
      s->t_state.my_txn_conf().insert_forwarded = std::get<HttpForwarded::OptionBitSet>(parsed.parsed);
    }
    break;
  case TS_CONFIG_HTTP_SERVER_SESSION_SHARING_MATCH:
    if (value && length > 0) {
      auto &parsed                                              = ParsedConfigCache::lookup(conf, std::string_view(value, length));
      s->t_state.my_txn_conf().server_session_sharing_match     = std::get<MgmtByte>(parsed.parsed);
      s->t_state.my_txn_conf().server_session_sharing_match_str = const_cast<char *>(parsed.conf_value_storage.data());
    }
    break;
  case TS_CONFIG_SSL_CLIENT_VERIFY_SERVER_POLICY:
    if (value && length > 0) {
      s->t_state.my_txn_conf().ssl_client_verify_server_policy = const_cast<char *>(value);
    }
    break;
  case TS_CONFIG_SSL_CLIENT_VERIFY_SERVER_PROPERTIES:
    if (value && length > 0) {
      s->t_state.my_txn_conf().ssl_client_verify_server_properties = const_cast<char *>(value);
    }
    break;
  case TS_CONFIG_SSL_CLIENT_SNI_POLICY:
    if (value && length > 0) {
      s->t_state.my_txn_conf().ssl_client_sni_policy = const_cast<char *>(value);
    }
    break;
  case TS_CONFIG_SSL_CLIENT_CERT_FILENAME:
    if (value && length > 0) {
      s->t_state.my_txn_conf().ssl_client_cert_filename = const_cast<char *>(value);
    }
    break;
  case TS_CONFIG_SSL_CLIENT_PRIVATE_KEY_FILENAME:
    if (value && length > 0) {
      s->t_state.my_txn_conf().ssl_client_private_key_filename = const_cast<char *>(value);
    }
    break;
  case TS_CONFIG_SSL_CLIENT_CA_CERT_FILENAME:
    if (value && length > 0) {
      s->t_state.my_txn_conf().ssl_client_ca_cert_filename = const_cast<char *>(value);
    }
    break;
  case TS_CONFIG_SSL_CLIENT_ALPN_PROTOCOLS:
    if (value && length > 0) {
      s->t_state.my_txn_conf().ssl_client_alpn_protocols = const_cast<char *>(value);
    }
    break;
  case TS_CONFIG_SSL_CERT_FILEPATH:
    /* noop */
    break;
  case TS_CONFIG_HTTP_NEGATIVE_CACHING_LIST:
    if (value && length > 0) {
      auto &parsed                                   = ParsedConfigCache::lookup(conf, std::string_view(value, length));
      s->t_state.my_txn_conf().negative_caching_list = std::get<HttpStatusCodeList>(parsed.parsed);
    }
    break;
  case TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_LIST:
    if (value && length > 0) {
      auto &parsed                                        = ParsedConfigCache::lookup(conf, std::string_view(value, length));
      s->t_state.my_txn_conf().negative_revalidating_list = std::get<HttpStatusCodeList>(parsed.parsed);
    }
    break;
  case TS_CONFIG_HTTP_HOST_RESOLUTION_PREFERENCE:
    if (value && length > 0) {
      auto &parsed                           = ParsedConfigCache::lookup(conf, std::string_view(value, length));
      s->t_state.my_txn_conf().host_res_data = std::get<HostResData>(parsed.parsed);
    }
    break;
  case TS_CONFIG_HTTP_CACHE_TARGETED_CACHE_CONTROL_HEADERS:
    if (value && length > 0) {
      auto &parsed = ParsedConfigCache::lookup(conf, std::string_view(value, length));
      // This is intentionally a non-owning copy of the parsed representation.
      // ParsedConfigCache::ParsedValue owns the backing string in conf_value_storage,
      // and TargetedCacheControlHeaders stores string_view entries into that stable
      // storage. The per-transaction override struct in HttpTransact::State is raw
      // storage (not an owning/destructed HttpConfigParams object), so this path
      // does not free conf_value. Reusing the cached parsed object avoids reparsing
      // and avoids allocating/duplicating a second backing string on every txn
      // override update, while preserving valid lifetimes for all string_view data.
      s->t_state.my_txn_conf().targeted_cache_control_headers = std::get<TargetedCacheControlHeaders>(parsed.parsed);
    } else {
      s->t_state.my_txn_conf().targeted_cache_control_headers = TargetedCacheControlHeaders{};
    }
    break;
  default: {
    if (value && length > 0) {
      return _eval_conv(&(s->t_state.my_txn_conf()), conf, value, length);
    }
    break;
  }
  }

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnConfigStringGet(TSHttpTxn txnp, TSOverridableConfigKey conf, const char **value, int *length)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void **)value) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)length) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  switch (conf) {
  case TS_CONFIG_HTTP_RESPONSE_SERVER_STR:
    *value  = sm->t_state.txn_conf->proxy_response_server_string;
    *length = sm->t_state.txn_conf->proxy_response_server_string_len;
    break;
  case TS_CONFIG_HTTP_GLOBAL_USER_AGENT_HEADER:
    *value  = sm->t_state.txn_conf->global_user_agent_header;
    *length = sm->t_state.txn_conf->global_user_agent_header_size;
    break;
  case TS_CONFIG_BODY_FACTORY_TEMPLATE_BASE:
    *value  = sm->t_state.txn_conf->body_factory_template_base;
    *length = sm->t_state.txn_conf->body_factory_template_base_len;
    break;
  case TS_CONFIG_HTTP_SERVER_SESSION_SHARING_MATCH:
    *value  = sm->t_state.txn_conf->server_session_sharing_match_str;
    *length = *value ? strlen(*value) : 0;
    break;
  default: {
    MgmtConverter const *conv;
    const void          *src = _conf_to_memberp(conf, sm->t_state.txn_conf, conv);
    if (src != nullptr && conv != nullptr && conv->load_string) {
      auto sv = conv->load_string(src);
      *value  = sv.data();
      *length = sv.size();
    } else {
      return TS_ERROR;
    }
    break;
  }
  }

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnConfigFind(const char *name, int length, TSOverridableConfigKey *conf, TSRecordDataType *type)
{
  sdk_assert(sdk_sanity_check_null_ptr(name) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr(conf) == TS_SUCCESS);

  std::string_view name_sv(name, length < 0 ? strlen(name) : length);
  if (auto config = ts::Overridable_Txn_Vars.find(name_sv); config != ts::Overridable_Txn_Vars.end()) {
    std::tie(*conf, *type) = config->second;
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSHttpTxnPrivateSessionSet(TSHttpTxn txnp, int private_session)
{
  if (sdk_sanity_check_txn(txnp) != TS_SUCCESS) {
    return TS_ERROR;
  }
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  if (sm->set_server_session_private(private_session)) {
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

// APIs to register new Mgmt (records) entries.
TSReturnCode
TSMgmtStringCreate(TSRecordType rec_type, const char *name, const TSMgmtString data_default, TSRecordUpdateType update_type,
                   TSRecordCheckType check_type, const char *check_regex, TSRecordAccessType access_type)
{
  if (check_regex == nullptr && check_type != TS_RECORDCHECK_NULL) {
    return TS_ERROR;
  }
  if (REC_ERR_OKAY != RecRegisterConfigString(static_cast<enum RecT>(rec_type), name, data_default,
                                              static_cast<enum RecUpdateT>(update_type), static_cast<enum RecCheckT>(check_type),
                                              check_regex, REC_SOURCE_PLUGIN, static_cast<enum RecAccessT>(access_type))) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSMgmtIntCreate(TSRecordType rec_type, const char *name, TSMgmtInt data_default, TSRecordUpdateType update_type,
                TSRecordCheckType check_type, const char *check_regex, TSRecordAccessType access_type)
{
  if (check_regex == nullptr && check_type != TS_RECORDCHECK_NULL) {
    return TS_ERROR;
  }
  if (REC_ERR_OKAY != RecRegisterConfigInt(static_cast<enum RecT>(rec_type), name, static_cast<RecInt>(data_default),
                                           static_cast<enum RecUpdateT>(update_type), static_cast<enum RecCheckT>(check_type),
                                           check_regex, REC_SOURCE_PLUGIN, static_cast<enum RecAccessT>(access_type))) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnCloseAfterResponse(TSHttpTxn txnp, int should_close)
{
  if (sdk_sanity_check_txn(txnp) != TS_SUCCESS) {
    return TS_ERROR;
  }

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  if (should_close) {
    sm->t_state.client_info.keep_alive = HTTPKeepAlive::NO_KEEPALIVE;
    if (sm->get_ua_txn()) {
      sm->set_ua_half_close_flag();
    }
  }
  // Don't change if PIPELINE is set...
  else if (sm->t_state.client_info.keep_alive == HTTPKeepAlive::NO_KEEPALIVE) {
    sm->t_state.client_info.keep_alive = HTTPKeepAlive::KEEPALIVE;
  }

  return TS_SUCCESS;
}

// Parse a port descriptor for the proxy.config.http.server_ports descriptor format.
TSPortDescriptor
TSPortDescriptorParse(const char *descriptor)
{
  HttpProxyPort *port = new HttpProxyPort();

  if (descriptor && port->processOptions(descriptor)) {
    return reinterpret_cast<TSPortDescriptor>(port);
  }

  delete port;
  return nullptr;
}

TSReturnCode
TSPortDescriptorAccept(TSPortDescriptor descp, TSCont contp)
{
  Action                     *action = nullptr;
  HttpProxyPort              *port   = reinterpret_cast<HttpProxyPort *>(descp);
  NetProcessor::AcceptOptions net(make_net_accept_options(port, -1 /* nthreads */));

  if (port->isSSL()) {
    action = sslNetProcessor.main_accept(reinterpret_cast<INKContInternal *>(contp), port->m_fd, net);
  } else {
    action = netProcessor.main_accept(reinterpret_cast<INKContInternal *>(contp), port->m_fd, net);
  }

  return action ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSPluginDescriptorAccept(TSCont contp)
{
  Action *action = nullptr;

  HttpProxyPort::Group &proxy_ports = HttpProxyPort::global();
  for (auto &port : proxy_ports) {
    if (port.isPlugin()) {
      NetProcessor::AcceptOptions net(make_net_accept_options(&port, -1 /* nthreads */));
      action = netProcessor.main_accept(reinterpret_cast<INKContInternal *>(contp), port.m_fd, net);
    }
  }
  return action ? TS_SUCCESS : TS_ERROR;
}

int
TSHttpTxnBackgroundFillStarted(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *s = reinterpret_cast<HttpSM *>(txnp);

  return (s->background_fill == BackgroundFill_t::STARTED);
}

int
TSHttpTxnIsCacheable(TSHttpTxn txnp, TSMBuffer request, TSMBuffer response)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM  *sm = reinterpret_cast<HttpSM *>(txnp);
  HTTPHdr *req, *resp;

  // We allow for either request or response to be empty (or both), in
  // which case we default to the transactions request or response.
  if (request) {
    sdk_assert(sdk_sanity_check_mbuffer(request) == TS_SUCCESS);
    req = reinterpret_cast<HTTPHdr *>(request);
  } else {
    req = &(sm->t_state.hdr_info.client_request);
  }
  if (response) {
    sdk_assert(sdk_sanity_check_mbuffer(response) == TS_SUCCESS);
    resp = reinterpret_cast<HTTPHdr *>(response);
  } else {
    resp = &(sm->t_state.hdr_info.server_response);
  }

  // Make sure these are valid response / requests, then verify if it's cacheable.
  return (req->valid() && resp->valid() && HttpTransact::is_response_cacheable(&(sm->t_state), req, resp)) ? 1 : 0;
}

int
TSHttpTxnGetMaxAge(TSHttpTxn txnp, TSMBuffer response)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM  *sm = reinterpret_cast<HttpSM *>(txnp);
  HTTPHdr *resp;

  if (response) {
    // Make sure the response we got as a parameter is valid
    sdk_assert(sdk_sanity_check_mbuffer(response) == TS_SUCCESS);
    resp = reinterpret_cast<HTTPHdr *>(response);
  } else {
    // Use the transactions origin response if the user passed null
    resp = &(sm->t_state.hdr_info.server_response);
  }

  if (!resp || !resp->valid()) {
    return -1;
  }

  // We have a valid response, return max_age
  return HttpTransact::get_max_age(resp);
}

// Lookup various debug names for common HTTP types.
const char *
TSHttpServerStateNameLookup(TSServerState state)
{
  return HttpDebugNames::get_server_state_name(static_cast<HttpTransact::ServerState_t>(state));
}

const char *
TSHttpHookNameLookup(TSHttpHookID hook)
{
  return HttpDebugNames::get_api_hook_name(static_cast<TSHttpHookID>(hook));
}

const char *
TSHttpEventNameLookup(TSEvent event)
{
  return HttpDebugNames::get_event_name(static_cast<int>(event));
}

/// Re-enable NetVC that has TLSEventSupport.
class TSSslCallback : public Continuation
{
public:
  TSSslCallback(TLSEventSupport *tes, TSEvent event) : Continuation(tes->getMutexForTLSEvents().get()), m_tes(tes), m_event(event)
  {
    SET_HANDLER(&TSSslCallback::event_handler);
  }
  int
  event_handler(int /* event ATS_UNUSED */, void *)
  {
    m_tes->reenable(m_event);
    delete this;
    return 0;
  }

private:
  TLSEventSupport *m_tes;
  TSEvent          m_event;
};

/// SSL Hooks
TSReturnCode
TSVConnTunnel(TSVConn sslp)
{
  NetVConnection    *vc     = reinterpret_cast<NetVConnection *>(sslp);
  SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc);
  TSReturnCode       zret   = TS_SUCCESS;
  if (nullptr != ssl_vc) {
    ssl_vc->hookOpRequested = SslVConnOp::SSL_HOOK_OP_TUNNEL;
  } else {
    zret = TS_ERROR;
  }
  return zret;
}

TSSslConnection
TSVConnSslConnectionGet(TSVConn sslp)
{
  TSSslConnection ssl   = nullptr;
  NetVConnection *netvc = reinterpret_cast<NetVConnection *>(sslp);
  if (auto tbs = netvc->get_service<TLSBasicSupport>(); tbs) {
    ssl = reinterpret_cast<TSSslConnection>(tbs->get_tls_handle());
  }
  return ssl;
}

int
TSVConnFdGet(TSVConn vconnp)
{
  sdk_assert(sdk_sanity_check_null_ptr(vconnp) == TS_SUCCESS);
  NetVConnection *vc = reinterpret_cast<NetVConnection *>(vconnp);
  return vc->get_socket();
}

const char *
TSVConnSslSniGet(TSVConn sslp, int *length)
{
  if (sslp == nullptr) {
    if (length) {
      *length = 0;
    }
    return nullptr;
  }

  char const     *server_name = nullptr;
  NetVConnection *vc          = reinterpret_cast<NetVConnection *>(sslp);
  if (auto snis = vc->get_service<TLSSNISupport>(); snis) {
    server_name = snis->get_sni_server_name();
    if (length) {
      *length = server_name ? strlen(server_name) : 0;
    }
  }

  return server_name;
}

TSClientHello
TSVConnClientHelloGet(TSVConn sslp)
{
  NetVConnection *netvc = reinterpret_cast<NetVConnection *>(sslp);
  if (netvc == nullptr) {
    return nullptr;
  }

  if (auto snis = netvc->get_service<TLSSNISupport>(); snis) {
    TLSSNISupport::ClientHello *client_hello = snis->get_client_hello();
    if (client_hello == nullptr) {
      return nullptr;
    }

    // Wrap the raw object in the accessor and return
    return TSClientHello(client_hello);
  }

  return nullptr;
}

TSReturnCode
TSClientHelloExtensionGet(TSClientHello ch, unsigned int type, const unsigned char **out, size_t *outlen)
{
  if (static_cast<TLSSNISupport::ClientHello *>(ch._get_internal())->getExtension(type, out, outlen) == 1) {
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSSslVerifyCTX
TSVConnSslVerifyCTXGet(TSVConn sslp)
{
  NetVConnection  *vc    = reinterpret_cast<NetVConnection *>(sslp);
  TLSBasicSupport *tlsbs = vc->get_service<TLSBasicSupport>();
  if (tlsbs != nullptr) {
    return reinterpret_cast<TSSslVerifyCTX>(tlsbs->get_tls_cert_to_verify());
  }
  return nullptr;
}

TSSslContext
TSSslContextFindByName(const char *name)
{
  if (nullptr == name || 0 == strlen(name)) {
    // an empty name is an invalid input
    return nullptr;
  }
  TSSslContext   ret    = nullptr;
  SSLCertLookup *lookup = SSLCertificateConfig::acquire();
  if (lookup != nullptr) {
    SSLCertContext *cc = lookup->find(name);
    if (cc) {
      shared_SSL_CTX ctx = cc->getCtx();
      if (ctx) {
        ret = reinterpret_cast<TSSslContext>(ctx.get());
      }
    }
    SSLCertificateConfig::release(lookup);
  }
  return ret;
}
TSSslContext
TSSslContextFindByAddr(struct sockaddr const *addr)
{
  TSSslContext   ret    = nullptr;
  SSLCertLookup *lookup = SSLCertificateConfig::acquire();
  if (lookup != nullptr) {
    IpEndpoint ip;
    ip.assign(addr);
    SSLCertContext *cc = lookup->find(ip);
    if (cc) {
      shared_SSL_CTX ctx = cc->getCtx();
      if (ctx) {
        ret = reinterpret_cast<TSSslContext>(ctx.get());
      }
    }
    SSLCertificateConfig::release(lookup);
  }
  return ret;
}

/**
 * This function sets the secret cache value for a given secret name.  This allows
 * plugins to load cert/key PEM information on for use by the TLS core
 */
TSReturnCode
TSSslSecretSet(const char *secret_name, int secret_name_length, const char *secret_data, int secret_data_len)
{
  TSReturnCode      retval = TS_SUCCESS;
  std::string const secret_name_str{secret_name, static_cast<unsigned>(secret_name_length)};
  SSLConfigParams  *load_params = SSLConfig::load_acquire();
  SSLConfigParams  *params      = SSLConfig::acquire();
  if (load_params != nullptr) { // Update the current data structure
    Dbg(dbg_ctl_ssl_cert_update, "Setting secrets in SSLConfig load for: %.*s", secret_name_length, secret_name);
    load_params->secrets.setSecret(secret_name_str, std::string_view(secret_data, secret_data_len));
    load_params->updateCTX(secret_name_str);
    SSLConfig::load_release(load_params);
  }
  if (params != nullptr) {
    Dbg(dbg_ctl_ssl_cert_update, "Setting secrets in SSLConfig for: %.*s", secret_name_length, secret_name);
    params->secrets.setSecret(secret_name_str, std::string_view(secret_data, secret_data_len));
    params->updateCTX(secret_name_str);
    SSLConfig::release(params);
  }
  return retval;
}

TSReturnCode
TSSslSecretUpdate(const char *secret_name, int secret_name_length)
{
  TSReturnCode     retval = TS_SUCCESS;
  SSLConfigParams *params = SSLConfig::acquire();
  if (params != nullptr) {
    params->updateCTX(std::string(secret_name, secret_name_length));
  }
  SSLConfig::release(params);
  return retval;
}

char *
TSSslSecretGet(const char *secret_name, int secret_name_length, int *secret_data_length)
{
  sdk_assert(secret_name != nullptr);
  sdk_assert(secret_data_length != nullptr);

  bool             loading = true;
  SSLConfigParams *params  = SSLConfig::load_acquire();
  if (params == nullptr) {
    params  = SSLConfig::acquire();
    loading = false;
  }
  std::string const secret_data = params->secrets.getSecret(std::string(secret_name, secret_name_length));
  char             *data{nullptr};
  if (secret_data.empty()) {
    *secret_data_length = 0;

  } else {
    data = static_cast<char *>(ats_malloc(secret_data.size()));
    memcpy(data, secret_data.data(), secret_data.size());
    *secret_data_length = secret_data.size();
  }
  if (loading) {
    SSLConfig::load_release(params);
  } else {
    SSLConfig::release(params);
  }
  return data;
}

/**
 * This function retrieves an array of lookup keys for client contexts loaded in
 * traffic server. Given a 2-level mapping for client contexts, every 2 lookup keys
 * can be used to locate and identify 1 context.
 * @param n Allocated size for result array.
 * @param result Const char pointer arrays to be filled with lookup keys.
 * @param actual Total number of lookup keys.
 */
TSReturnCode
TSSslClientContextsNamesGet(int n, const char **result, int *actual)
{
  sdk_assert(n == 0 || result != nullptr);
  int              idx = 0, count = 0;
  SSLConfigParams *params = SSLConfig::acquire();

  if (params) {
    auto &ctx_map_lock = params->ctxMapLock;
    auto &ca_map       = params->top_level_ctx_map;
    auto  mem          = static_cast<std::string_view *>(alloca(sizeof(std::string_view) * n));
    ink_mutex_acquire(&ctx_map_lock);
    for (auto &ca_pair : ca_map) {
      // Populate mem array with 2 strings each time
      for (auto &ctx_pair : ca_pair.second) {
        if (idx + 1 < n) {
          mem[idx++] = ca_pair.first;
          mem[idx++] = ctx_pair.first;
        }
        count += 2;
      }
    }
    ink_mutex_release(&ctx_map_lock);
    for (int i = 0; i < idx; i++) {
      result[i] = mem[i].data();
    }
  }
  if (actual) {
    *actual = count;
  }
  SSLConfig::release(params);
  return TS_SUCCESS;
}

/**
 * This function returns the client context corresponding to the lookup keys provided.
 * User should call TSSslClientContextsGet() first to determine which lookup keys are
 * present before querying for them. User will need to release the context returned
 * from this function.
 * Returns valid TSSslContext on success and nullptr on failure.
 * @param first_key Key string for the top level.
 * @param second_key Key string for the second level.
 */
TSSslContext
TSSslClientContextFindByName(const char *ca_paths, const char *ck_paths)
{
  if (!ca_paths || !ck_paths || ca_paths[0] == '\0' || ck_paths[0] == '\0') {
    return nullptr;
  }
  SSLConfigParams *params = SSLConfig::acquire();
  TSSslContext     retval = nullptr;
  if (params) {
    ink_mutex_acquire(&params->ctxMapLock);
    auto ca_iter = params->top_level_ctx_map.find(ca_paths);
    if (ca_iter != params->top_level_ctx_map.end()) {
      auto ctx_iter = ca_iter->second.find(ck_paths);
      if (ctx_iter != ca_iter->second.end()) {
        SSL_CTX_up_ref(ctx_iter->second.get());
        retval = reinterpret_cast<TSSslContext>(ctx_iter->second.get());
      }
    }
    ink_mutex_release(&params->ctxMapLock);
  }
  SSLConfig::release(params);
  return retval;
}

TSSslContext
TSSslServerContextCreate(TSSslX509 cert, const char *certname, const char *rsp_file)
{
  TSSslContext     ret    = nullptr;
  SSLConfigParams *config = SSLConfig::acquire();
  if (config != nullptr) {
    ret = reinterpret_cast<TSSslContext>(SSLCreateServerContext(config, nullptr));
    if (ret && SSLConfigParams::ssl_ocsp_enabled && cert && certname) {
      if (SSL_CTX_set_tlsext_status_cb(reinterpret_cast<SSL_CTX *>(ret), ssl_callback_ocsp_stapling)) {
        if (!ssl_stapling_init_cert(reinterpret_cast<SSL_CTX *>(ret), reinterpret_cast<X509 *>(cert), certname, rsp_file)) {
          Warning("failed to configure SSL_CTX for OCSP Stapling info for certificate at %s", certname);
        }
      }
    }
    SSLConfig::release(config);
  }
  return ret;
}

void
TSSslContextDestroy(TSSslContext ctx)
{
  SSLReleaseContext(reinterpret_cast<SSL_CTX *>(ctx));
}

TSReturnCode
TSSslClientCertUpdate(const char *cert_path, const char *key_path)
{
  if (nullptr == cert_path) {
    return TS_ERROR;
  }

  std::string      key;
  shared_SSL_CTX   client_ctx = nullptr;
  SSLConfigParams *params     = SSLConfig::acquire();

  // Generate second level key for client context lookup
  swoc::bwprint(key, "{}:{}", cert_path, key_path);
  Dbg(dbg_ctl_ssl_cert_update, "TSSslClientCertUpdate(): Use %.*s as key for lookup", static_cast<int>(key.size()), key.data());

  if (nullptr != params) {
    // Try to update client contexts maps
    auto       &ca_paths_map = params->top_level_ctx_map;
    auto       &map_lock     = params->ctxMapLock;
    std::string ca_paths_key;
    // First try to locate the client context and its CA path (by top level)
    ink_mutex_acquire(&map_lock);
    for (auto &ca_paths_pair : ca_paths_map) {
      auto &ctx_map = ca_paths_pair.second;
      auto  iter    = ctx_map.find(key);
      if (iter != ctx_map.end() && iter->second != nullptr) {
        ca_paths_key = ca_paths_pair.first;
        break;
      }
    }
    ink_mutex_release(&map_lock);

    // Only update on existing
    if (ca_paths_key.empty()) {
      return TS_ERROR;
    }

    // Extract CA related paths
    size_t      sep            = ca_paths_key.find(':');
    std::string ca_bundle_file = ca_paths_key.substr(0, sep);
    std::string ca_bundle_path = ca_paths_key.substr(sep + 1);

    // Build new client context
    client_ctx =
      shared_SSL_CTX(SSLCreateClientContext(params, ca_bundle_path.empty() ? nullptr : ca_bundle_path.c_str(),
                                            ca_bundle_file.empty() ? nullptr : ca_bundle_file.c_str(), cert_path, key_path),
                     SSL_CTX_free);

    // Successfully generates a client context, update in the map
    ink_mutex_acquire(&map_lock);
    auto iter = ca_paths_map.find(ca_paths_key);
    if (iter != ca_paths_map.end() && iter->second.count(key)) {
      iter->second[key] = client_ctx;
    } else {
      client_ctx = nullptr;
    }
    ink_mutex_release(&map_lock);
  }

  return client_ctx ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSSslServerCertUpdate(const char *cert_path, const char *key_path)
{
  if (nullptr == cert_path) {
    return TS_ERROR;
  }

  if (!key_path || key_path[0] == '\0') {
    key_path = cert_path;
  }

  SSLCertContext       *cc       = nullptr;
  shared_SSL_CTX        test_ctx = nullptr;
  std::shared_ptr<X509> cert     = nullptr;

  SSLConfig::scoped_config            config;
  SSLCertificateConfig::scoped_config lookup;

  if (lookup && config) {
    // Read cert from path to extract lookup key (common name)
    scoped_BIO bio(BIO_new_file(cert_path, "r"));
    if (bio) {
      cert = std::shared_ptr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr), X509_free);
    }
    if (!bio || !cert) {
      SSLError("Failed to load certificate/key from %s", cert_path);
      return TS_ERROR;
    }

    // Extract common name
    int              pos              = X509_NAME_get_index_by_NID(X509_get_subject_name(cert.get()), NID_commonName, -1);
    X509_NAME_ENTRY *common_name      = X509_NAME_get_entry(X509_get_subject_name(cert.get()), pos);
    ASN1_STRING     *common_name_asn1 = X509_NAME_ENTRY_get_data(common_name);
    char *common_name_str = reinterpret_cast<char *>(const_cast<unsigned char *>(ASN1_STRING_get0_data(common_name_asn1)));
    if (ASN1_STRING_length(common_name_asn1) != static_cast<int>(strlen(common_name_str))) {
      // Embedded null char
      return TS_ERROR;
    }
    Dbg(dbg_ctl_ssl_cert_update, "Updating from %s with common name %s", cert_path, common_name_str);

    // Update context to use cert
    cc = lookup->find(common_name_str);
    if (cc && cc->getCtx()) {
      test_ctx = shared_SSL_CTX(SSLCreateServerContext(config, cc->userconfig.get(), cert_path, key_path), SSLReleaseContext);
      if (!test_ctx) {
        return TS_ERROR;
      }
      // Atomic Swap
      cc->setCtx(test_ctx);
      return TS_SUCCESS;
    }
  }

  return TS_ERROR;
}

TSReturnCode
TSSslTicketKeyUpdate(char *ticketData, int ticketDataLen)
{
  return SSLTicketKeyConfig::reconfigure_data(ticketData, ticketDataLen) ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSVConnProtocolEnable(TSVConn connp, const char *protocol_name)
{
  TSReturnCode retval       = TS_ERROR;
  int          protocol_idx = globalSessionProtocolNameRegistry.toIndexConst(std::string_view{protocol_name});
  auto         net_vc       = reinterpret_cast<UnixNetVConnection *>(connp);
  if (auto alpn = net_vc->get_service<ALPNSupport>(); alpn) {
    alpn->enableProtocol(protocol_idx);
    retval = TS_SUCCESS;
  }
  return retval;
}

TSReturnCode
TSVConnProtocolDisable(TSVConn connp, const char *protocol_name)
{
  TSReturnCode retval       = TS_ERROR;
  int          protocol_idx = globalSessionProtocolNameRegistry.toIndexConst(std::string_view{protocol_name});
  auto         net_vc       = reinterpret_cast<UnixNetVConnection *>(connp);
  if (auto alpn = net_vc->get_service<ALPNSupport>(); alpn) {
    alpn->disableProtocol(protocol_idx);
    retval = TS_SUCCESS;
  }
  return retval;
}

TSAcceptor
TSAcceptorGet(TSVConn sslp)
{
  NetVConnection    *vc     = reinterpret_cast<NetVConnection *>(sslp);
  SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc);
  return ssl_vc ? reinterpret_cast<TSAcceptor>(ssl_vc->accept_object) : nullptr;
}

TSAcceptor
TSAcceptorGetbyID(int ID)
{
  SCOPED_MUTEX_LOCK(lock, naVecMutex, this_ethread());
  auto ret = naVec.at(ID);
  Dbg(dbg_ctl_ssl, "getNetAccept in INK API.cc %p", ret);
  return reinterpret_cast<TSAcceptor>(ret);
}

int
TSAcceptorIDGet(TSAcceptor acceptor)
{
  NetAccept *na = reinterpret_cast<NetAccept *>(acceptor);
  return na ? na->id : -1;
}

int
TSAcceptorCount()
{
  SCOPED_MUTEX_LOCK(lock, naVecMutex, this_ethread());
  return naVec.size();
}

int
TSVConnIsSsl(TSVConn sslp)
{
  NetVConnection    *vc     = reinterpret_cast<NetVConnection *>(sslp);
  SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc);
  return ssl_vc != nullptr;
}

int
TSVConnProvidedSslCert(TSVConn sslp)
{
  NetVConnection *vc = reinterpret_cast<NetVConnection *>(sslp);
  return vc->provided_cert();
}

void
TSVConnReenable(TSVConn vconn)
{
  TSVConnReenableEx(vconn, TS_EVENT_CONTINUE);
}

void
TSVConnReenableEx(TSVConn vconn, TSEvent event)
{
  NetVConnection *vc = reinterpret_cast<NetVConnection *>(vconn);

  if (auto tes = vc->get_service<TLSEventSupport>(); tes) {
    EThread *eth = this_ethread();

    // We use the mutex of VC's NetHandler so we can put the VC into ready_list by reenable()
    Ptr<ProxyMutex> m = tes->getMutexForTLSEvents();
    MUTEX_TRY_LOCK(trylock, m, eth);
    if (trylock.is_locked()) {
      tes->reenable(event);
    } else {
      // We schedule the reenable to the home thread of ssl_vc.
      tes->getThreadForTLSEvents()->schedule_imm(new TSSslCallback(tes, event));
    }
  }
}

TSReturnCode
TSVConnPPInfoGet(TSVConn vconn, uint16_t key, const char **value, int *length)
{
  NetVConnection *vc = reinterpret_cast<NetVConnection *>(vconn);

  if (key < 0x100) {
    auto &tlv = vc->get_proxy_protocol_info().tlv;
    if (auto ite = tlv.find(key); ite != tlv.end()) {
      *value  = ite->second.data();
      *length = ite->second.length();
    } else {
      return TS_ERROR;
    }
  } else {
    switch (key) {
    case TS_PP_INFO_SRC_ADDR:
      *value = reinterpret_cast<const char *>(vc->get_proxy_protocol_src_addr());
      if (*value == nullptr) {
        return TS_ERROR;
      }
      *length = ats_ip_size(reinterpret_cast<const sockaddr *>(*value));
      break;
    case TS_PP_INFO_DST_ADDR:
      *value = reinterpret_cast<const char *>(vc->get_proxy_protocol_dst_addr());
      if (*value == nullptr) {
        return TS_ERROR;
      }
      *length = ats_ip_size(reinterpret_cast<const sockaddr *>(*value));
      break;
    default:
      return TS_ERROR;
    }
  }

  return TS_SUCCESS;
}

TSReturnCode
TSVConnPPInfoIntGet(TSVConn vconn, uint16_t key, TSMgmtInt *value)
{
  NetVConnection *vc = reinterpret_cast<NetVConnection *>(vconn);

  if (key < 0x100) {
    // Unknown type value cannot be returned as an integer
    return TS_ERROR;
  } else {
    switch (key) {
    case TS_PP_INFO_VERSION:
      *value = static_cast<TSMgmtInt>(vc->get_proxy_protocol_version());
      break;
    case TS_PP_INFO_SRC_PORT:
      *value = static_cast<TSMgmtInt>(vc->get_proxy_protocol_src_port());
      break;
    case TS_PP_INFO_DST_PORT:
      *value = static_cast<TSMgmtInt>(vc->get_proxy_protocol_dst_port());
      break;
    case TS_PP_INFO_PROTOCOL:
      *value = static_cast<TSMgmtInt>(vc->get_proxy_protocol_info().ip_family);
      break;
    case TS_PP_INFO_SOCK_TYPE:
      *value = static_cast<TSMgmtInt>(vc->get_proxy_protocol_info().type);
      break;
    default:
      return TS_ERROR;
    }
  }

  return TS_SUCCESS;
}

// APIs for managing and using UUIDs.
TSUuid
TSUuidCreate()
{
  ATSUuid *uuid = new ATSUuid();
  return reinterpret_cast<TSUuid>(uuid);
}

void
TSUuidDestroy(TSUuid uuid)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)uuid) == TS_SUCCESS);
  delete reinterpret_cast<ATSUuid *>(uuid);
}

TSReturnCode
TSUuidCopy(TSUuid dest, const TSUuid src)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)dest) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)src) == TS_SUCCESS);
  ATSUuid *d = reinterpret_cast<ATSUuid *>(dest);
  ATSUuid *s = reinterpret_cast<ATSUuid *>(src);

  if (s->valid()) {
    *d = *s;
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSReturnCode
TSUuidInitialize(TSUuid uuid, TSUuidVersion v)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)uuid) == TS_SUCCESS);
  ATSUuid *u = reinterpret_cast<ATSUuid *>(uuid);

  u->initialize(v);
  return u->valid() ? TS_SUCCESS : TS_ERROR;
}

TSUuid
TSProcessUuidGet()
{
  Machine *machine = Machine::instance();
  return reinterpret_cast<TSUuid>(&machine->process_uuid);
}

const char *
TSUuidStringGet(const TSUuid uuid)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)uuid) == TS_SUCCESS);
  ATSUuid *u = reinterpret_cast<ATSUuid *>(uuid);

  if (u->valid()) {
    return u->getString();
  }

  return nullptr;
}

TSReturnCode
TSClientRequestUuidGet(TSHttpTxn txnp, char *uuid_str)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)uuid_str) == TS_SUCCESS);

  HttpSM     *sm      = reinterpret_cast<HttpSM *>(txnp);
  const char *machine = const_cast<char *>(Machine::instance()->process_uuid.getString());
  int         len;

  len = snprintf(uuid_str, TS_CRUUID_STRING_LEN + 1, "%s-%" PRId64 "", machine, sm->sm_id);
  if (len > TS_CRUUID_STRING_LEN) {
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSUuidStringParse(TSUuid uuid, const char *str)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)uuid) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void *)str) == TS_SUCCESS);
  ATSUuid *u = reinterpret_cast<ATSUuid *>(uuid);

  if (u->parseString(str)) {
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

TSUuidVersion
TSUuidVersionGet(TSUuid uuid)
{
  sdk_assert(sdk_sanity_check_null_ptr((void *)uuid) == TS_SUCCESS);
  ATSUuid *u = reinterpret_cast<ATSUuid *>(uuid);

  return u->version();
}

// Expose the HttpSM's sequence number (ID)
uint64_t
TSHttpTxnIdGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  return static_cast<uint64_t>(sm->sm_id);
}

// Returns unique client session identifier
int64_t
TSHttpSsnIdGet(TSHttpSsn ssnp)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  ProxySession const *cs = reinterpret_cast<ProxySession *>(ssnp);
  return cs->connection_id();
}

// Return information about the protocols used by the client
TSReturnCode
TSHttpTxnClientProtocolStackGet(TSHttpTxn txnp, int count, const char **result, int *actual)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(count == 0 || result != nullptr);
  HttpSM *sm        = reinterpret_cast<HttpSM *>(txnp);
  int     new_count = 0;
  if (sm && count > 0) {
    auto mem  = static_cast<std::string_view *>(alloca(sizeof(std::string_view) * count));
    new_count = sm->populate_client_protocol(mem, count);
    for (int i = 0; i < new_count; ++i) {
      result[i] = mem[i].data();
    }
  }
  if (actual) {
    *actual = new_count;
  }
  return TS_SUCCESS;
}

TSReturnCode
TSHttpSsnClientProtocolStackGet(TSHttpSsn ssnp, int count, const char **result, int *actual)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  sdk_assert(count == 0 || result != nullptr);
  auto const *cs        = reinterpret_cast<ProxySession *>(ssnp);
  int         new_count = 0;
  if (cs && count > 0) {
    auto mem  = static_cast<std::string_view *>(alloca(sizeof(std::string_view) * count));
    new_count = cs->populate_protocol(mem, count);
    for (int i = 0; i < new_count; ++i) {
      result[i] = mem[i].data();
    }
  }
  if (actual) {
    *actual = new_count;
  }
  return TS_SUCCESS;
}

// Return information about the protocols used by the server
TSReturnCode
TSHttpTxnServerProtocolStackGet(TSHttpTxn txnp, int count, const char **result, int *actual)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(count == 0 || result != nullptr);
  HttpSM *sm        = reinterpret_cast<HttpSM *>(txnp);
  int     new_count = 0;
  if (sm && count > 0) {
    auto mem  = static_cast<std::string_view *>(alloca(sizeof(std::string_view) * count));
    new_count = sm->populate_server_protocol(mem, count);
    for (int i = 0; i < new_count; ++i) {
      result[i] = mem[i].data();
    }
  }
  if (actual) {
    *actual = new_count;
  }
  return TS_SUCCESS;
}

const char *
TSNormalizedProtocolTag(const char *tag)
{
  return RecNormalizeProtoTag(tag);
}

const char *
TSHttpTxnClientProtocolStackContains(TSHttpTxn txnp, const char *tag)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->client_protocol_contains(std::string_view{tag});
}

const char *
TSHttpSsnClientProtocolStackContains(TSHttpSsn ssnp, const char *tag)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  ProxySession *cs = reinterpret_cast<ProxySession *>(ssnp);
  return cs->protocol_contains(std::string_view{tag});
}

const char *
TSHttpTxnServerProtocolStackContains(TSHttpTxn txnp, const char *tag)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return sm->server_protocol_contains(std::string_view{tag});
}

const char *
TSRegisterProtocolTag(const char * /* tag ATS_UNUSED */)
{
  return nullptr;
}

TSReturnCode
TSHttpTxnRedoCacheLookup(TSHttpTxn txnp, const char *url, int length)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM              *sm = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::State *s  = &(sm->t_state);
  sdk_assert(s->next_action == HttpTransact::StateMachineAction_t::CACHE_LOOKUP);

  // Because of where this is in the state machine, the storage for the cache_info URL must
  // have already been initialized and @a lookup_url must be valid.
  auto result = s->cache_info.lookup_url->parse(url, length < 0 ? strlen(url) : length);
  if (ParseResult::DONE == result) {
    s->transact_return_point = nullptr;
    sm->rewind_state_machine();
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

namespace
{
// Function that contains the common logic for TSRemapFrom/ToUrlGet().
//
TSReturnCode
remapUrlGet(TSHttpTxn txnp, TSMLoc *urlLocp, URL *(UrlMappingContainer::*mfp)() const)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr(urlLocp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);

  URL *url = (sm->t_state.url_map.*mfp)();
  if (url == nullptr) {
    return TS_ERROR;
  }

  auto urlImpl = url->m_url_impl;
  if (urlImpl == nullptr) {
    return TS_ERROR;
  }

  *urlLocp = reinterpret_cast<TSMLoc>(urlImpl);

  return TS_SUCCESS;
}

} // end anonymous namespace

TSReturnCode
TSRemapFromUrlGet(TSHttpTxn txnp, TSMLoc *urlLocp)
{
  return remapUrlGet(txnp, urlLocp, &UrlMappingContainer::getFromURL);
}

TSReturnCode
TSRemapToUrlGet(TSHttpTxn txnp, TSMLoc *urlLocp)
{
  return remapUrlGet(txnp, urlLocp, &UrlMappingContainer::getToURL);
}

void *
TSRemapDLHandleGet(TSRemapPluginInfo plugin_info)
{
  sdk_assert(sdk_sanity_check_null_ptr(plugin_info) == TS_SUCCESS);
  RemapPluginInfo *info = reinterpret_cast<RemapPluginInfo *>(plugin_info);

  return info->dlh();
}

TSReturnCode
TSHostnameIsSelf(const char *hostname, size_t hostname_len)
{
  return Machine::instance()->is_self(std::string_view{hostname, hostname_len}) ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSHostStatusGet(const char *hostname, const size_t hostname_len, TSHostStatus *status, unsigned int *reason)
{
  HostStatRec *hst = HostStatus::instance().getHostStatus(std::string_view(hostname, hostname_len));
  if (hst == nullptr) {
    return TS_ERROR;
  }
  if (status != nullptr) {
    *status = hst->status;
  }
  if (reason != nullptr) {
    *reason = hst->reasons;
  }
  return TS_SUCCESS;
}

void
TSHostStatusSet(const char *hostname, const size_t hostname_len, TSHostStatus status, const unsigned int down_time,
                const unsigned int reason)
{
  HostStatus::instance().setHostStatus(std::string_view(hostname, hostname_len), status, down_time, reason);
}

// TSHttpTxnResponseActionSet takes a ResponseAction and sets it as the behavior for finding the next parent.
// Be aware ATS will never change this outside a plugin. Therefore, plugins which set the ResponseAction
// to retry must also un-set it after the subsequent success or failure, or ATS will retry forever!
//
// The passed *action must not be null, and is copied and may be destroyed after this call returns.
// Callers must maintain owernship of action.hostname, and its lifetime must exceed the transaction.
void
TSHttpTxnResponseActionSet(TSHttpTxn txnp, TSResponseAction *action)
{
  HttpSM              *sm    = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::State *s     = &(sm->t_state);
  s->response_action.handled = true;
  s->response_action.action  = *action;
}

// Get the ResponseAction set by a plugin.
//
// The action is an out-param and must point to a valid location.
// The returned action.hostname must not be modified, and is owned by some plugin if not null.
//
// The action members will always be zero, if no plugin has called TSHttpTxnResponseActionSet.
//
void
TSHttpTxnResponseActionGet(TSHttpTxn txnp, TSResponseAction *action)
{
  HttpSM              *sm = reinterpret_cast<HttpSM *>(txnp);
  HttpTransact::State *s  = &(sm->t_state);
  if (!s->response_action.handled) {
    memset(action, 0, sizeof(TSResponseAction)); // because {0} gives a C++ warning. Ugh.
  } else {
    *action = s->response_action.action;
  }
}

TSIOBufferReader
TSHttpTxnPostBufferReaderGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return reinterpret_cast<TSIOBufferReader>(sm->get_postbuf_clone_reader());
}

TSRPCProviderHandle
TSRPCRegister(const char *provider_name, size_t provider_len, const char *yaml_version, size_t yamlcpp_lib_len)
{
  sdk_assert(sdk_sanity_check_null_ptr(yaml_version) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr(provider_name) == TS_SUCCESS);

  // We want to make sure that plugins are using the same yaml library version as we use internally. Plugins have to cast the
  // TSYaml to the YAML::Node, in order for them to make sure the version compatibility they need to register here and make sure
  // the version is the same.
  if (std::string_view{yaml_version, yamlcpp_lib_len} != YAMLCPP_LIB_VERSION) {
    Dbg(dbg_ctl_rpc_api, "[%.*s] YAML version check failed. Passed='%.*s', expected='%s'", static_cast<int>(provider_len),
        provider_name, static_cast<int>(yamlcpp_lib_len), yaml_version, YAMLCPP_LIB_VERSION);

    return nullptr;
  }

  ::rpc::RPCRegistryInfo *info = new ::rpc::RPCRegistryInfo();
  info->provider               = {provider_name, provider_len};

  return reinterpret_cast<TSRPCProviderHandle>(info);
}

TSReturnCode
TSRPCRegisterMethodHandler(const char *name, size_t name_len, TSRPCMethodCb callback, TSRPCProviderHandle info,
                           const TSRPCHandlerOptions *opt)
{
  sdk_assert(sdk_sanity_check_rpc_handler_options(opt) == TS_SUCCESS);

  if (!::rpc::add_method_handler_from_plugin(
        {name, name_len},
        [callback](std::string_view const &id, const YAML::Node &params) -> void {
          std::string msgId{id.data(), id.size()};
          callback(msgId.c_str(), reinterpret_cast<TSYaml>(const_cast<YAML::Node *>(&params)));
        },
        reinterpret_cast<const ::rpc::RPCRegistryInfo *>(info), *opt)) {
    return TS_ERROR;
  }
  return TS_SUCCESS;
}

TSReturnCode
TSRPCRegisterNotificationHandler(const char *name, size_t name_len, TSRPCNotificationCb callback, TSRPCProviderHandle info,
                                 const TSRPCHandlerOptions *opt)
{
  sdk_assert(sdk_sanity_check_rpc_handler_options(opt) == TS_SUCCESS);

  if (!::rpc::add_notification_handler(
        {name, name_len},
        [callback](const YAML::Node &params) -> void { callback(reinterpret_cast<TSYaml>(const_cast<YAML::Node *>(&params))); },
        reinterpret_cast<const ::rpc::RPCRegistryInfo *>(info), *opt)) {
    return TS_ERROR;
  }
  return TS_SUCCESS;
}

TSReturnCode
TSRPCHandlerDone(TSYaml resp)
{
  Dbg(dbg_ctl_rpc_api, ">> Handler seems to be done");
  std::lock_guard<std::mutex> lock(::rpc::g_rpcHandlingMutex);
  auto                        data       = *reinterpret_cast<YAML::Node *>(resp);
  ::rpc::g_rpcHandlerResponseData        = data;
  ::rpc::g_rpcHandlerProcessingCompleted = true;
  ::rpc::g_rpcHandlingCompletion.notify_one();
  Dbg(dbg_ctl_rpc_api, ">> all set.");
  return TS_SUCCESS;
}

TSReturnCode
TSRPCHandlerError(int ec, const char *descr, size_t descr_len)
{
  Dbg(dbg_ctl_rpc_api, ">> Handler seems to be done with an error");
  std::lock_guard<std::mutex> lock(rpc::g_rpcHandlingMutex);
  ::rpc::g_rpcHandlerResponseData        = swoc::Errata(ts::make_errno_code(ec), "{}", swoc::TextView{descr, descr_len});
  ::rpc::g_rpcHandlerProcessingCompleted = true;
  ::rpc::g_rpcHandlingCompletion.notify_one();
  Dbg(dbg_ctl_rpc_api, ">> error  flagged.");
  return TS_SUCCESS;
}

TSReturnCode
TSRecYAMLConfigParse(TSYaml node, TSYAMLRecNodeHandler handler, void *data)
{
  swoc::Errata err;
  try {
    err = ParseRecordsFromYAML(
      *reinterpret_cast<YAML::Node *>(node),
      [handler, data](const CfgNode &field, swoc::Errata &) -> void {
        // Errors from the handler should be reported and handled by the handler.
        // RecYAMLConfigFileParse will report any YAML parsing error.
        TSYAMLRecCfgFieldData cfg;
        auto const           &field_str = field.node.as<std::string>();
        cfg.field_name                  = field_str.c_str();
        cfg.record_name                 = field.get_record_name().data();
        cfg.value_node                  = reinterpret_cast<TSYaml>(const_cast<YAML::Node *>(&field.value_node));
        handler(&cfg, data);
      },
      true /* lock */);
  } catch (std::exception const &ex) {
    err.note(ERRATA_ERROR, "RecYAMLConfigParse error cought: {}", ex.what());
  }
  // Drop API logs in case of an error.
  if (!err.empty()) {
    std::string buf;
    Dbg(dbg_ctl_plugin, "%s", swoc::bwprint(buf, "{}", err).c_str());
  }

  return err.empty() ? TS_SUCCESS : TS_ERROR;
}

TSTxnType
TSHttpTxnTypeGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM   *sm     = reinterpret_cast<HttpSM *>(txnp);
  TSTxnType retval = TS_TXN_TYPE_UNKNOWN;
  if (sm != nullptr) {
    if (sm->t_state.transparent_passthrough) {
      retval = TS_TXN_TYPE_TR_PASS_TUNNEL;
    } else if (sm->t_state.client_info.port_attribute == HttpProxyPort::TRANSPORT_BLIND_TUNNEL) {
      retval = TS_TXN_TYPE_EXPLICIT_TUNNEL;
    } else {
      retval = TS_TXN_TYPE_HTTP;
    }
  }
  return retval;
}

TSReturnCode
TSConnectionLimitExemptListAdd(std::string_view ip_ranges)
{
  swoc::TextView ip_ranges_tv{ip_ranges};

  while (auto ip_range_tv = ip_ranges_tv.take_prefix_at(',')) {
    swoc::IPRange ip_range;

    if (!ip_range.load(ip_range_tv)) {
      return TS_ERROR;
    }
    bool success = ConnectionTracker::add_client_exempt_range(ip_range);

    if (!success) {
      return TS_ERROR;
    }
  }
  return TS_SUCCESS;
}

TSReturnCode
TSConnectionLimitExemptListRemove(std::string_view ip_ranges)
{
  swoc::TextView ip_ranges_tv{ip_ranges};

  while (auto ip_range_tv = ip_ranges_tv.take_prefix_at(',')) {
    swoc::IPRange ip_range;

    if (!ip_range.load(ip_range_tv)) {
      return TS_ERROR;
    }
    bool success = ConnectionTracker::remove_client_exempt_range(ip_range);

    if (!success) {
      return TS_ERROR;
    }
  }
  return TS_SUCCESS;
}

void
TSConnectionLimitExemptListClear()
{
  ConnectionTracker::clear_client_exempt_list();
}

TSReturnCode
TSLogFieldRegister(std::string_view name, std::string_view symbol, TSLogType type, TSLogMarshalCallback marshal_cb,
                   TSLogUnmarshalCallback unmarshal_cb, bool replace)
{
  if (auto ite = Log::field_symbol_hash.find(symbol.data()); ite != Log::field_symbol_hash.end()) {
    if (replace) {
      // Symbol is registered and the plugin wants to replace it.
      // Need to unregister the existing entry first.
      Log::global_field_list.remove(ite->second);
      Log::field_symbol_hash.erase(ite);
    } else {
      // Symbol conflict.
      return TS_ERROR;
    }
  }

  LogField *field = new LogField(name.data(), symbol.data(), static_cast<LogField::Type>(type),
                                 reinterpret_cast<LogField::CustomMarshalFunc>(marshal_cb), unmarshal_cb);
  Log::global_field_list.add(field, false);
  Log::field_symbol_hash.emplace(symbol.data(), field);

  return TS_SUCCESS;
}

int
TSLogStringMarshal(char *buf, std::string_view str)
{
  if (buf) {
    ink_strlcpy(buf, str.data(), str.length() + 1);
  }
  return str.length() + 1;
}

std::tuple<int, int>
TSLogStringUnmarshal(char **buf, char *dest, int len)
{
  // We cannot use LogAccess::unmarshal_str, etc. here because those internal
  // functions take care of log buffer alignment. This function needs to be
  // implemented as if it's a piece of code in plugin code, which is unaware
  // of the alignment.
  if (int l = strlen(*buf); l < len) {
    memcpy(dest, *buf, l);
    return {l, l};
  } else {
    return {-1, -1};
  }
}

int
TSLogIntMarshal(char *buf, int64_t value)
{
  if (buf) {
    *(reinterpret_cast<int64_t *>(buf)) = value;
  }
  return sizeof(int64_t);
}

std::tuple<int, int>
TSLogIntUnmarshal(char **buf, char *dest, int len)
{
  int64_t val     = *(reinterpret_cast<int64_t *>(*buf));
  auto [end, err] = std::to_chars(dest, dest + len, val);
  if (err == std::errc()) {
    *end = '\0';
    return {sizeof(uint64_t), end - dest};
  }

  return {-1, -1};
}

int
TSLogAddrMarshal(char *buf, sockaddr *addr)
{
  LogFieldIpStorage data;
  int               len = sizeof(data._ip);

  if (nullptr == addr) {
    data._ip._family = AF_UNSPEC;
  } else if (ats_is_ip4(addr)) {
    if (buf) {
      data._ip4._family = AF_INET;
      data._ip4._addr   = ats_ip4_addr_cast(addr);
    }
    len = sizeof(data._ip4);
  } else if (ats_is_ip6(addr)) {
    if (buf) {
      data._ip6._family = AF_INET6;
      data._ip6._addr   = ats_ip6_addr_cast(addr);
    }
    len = sizeof(data._ip6);
  } else if (ats_is_unix(addr)) {
    if (buf) {
      data._un._family = AF_UNIX;
      strncpy(data._un._path, ats_unix_cast(addr)->sun_path, TS_UNIX_SIZE);
    }
    len = sizeof(data._un);
  } else {
    data._ip._family = AF_UNSPEC;
  }

  if (buf) {
    memcpy(buf, &data, len);
  }
  return len;
}

std::tuple<int, int>
TSLogAddrUnmarshal(char **buf, char *dest, int len)
{
  IpEndpoint endpoint;
  int        read_len = sizeof(LogFieldIp);

  LogFieldIp *raw = reinterpret_cast<LogFieldIp *>(*buf);
  if (AF_INET == raw->_family) {
    LogFieldIp4 *ip4 = static_cast<LogFieldIp4 *>(raw);
    ats_ip4_set(&endpoint, ip4->_addr);
    read_len = sizeof(*ip4);
  } else if (AF_INET6 == raw->_family) {
    LogFieldIp6 *ip6 = static_cast<LogFieldIp6 *>(raw);
    ats_ip6_set(&endpoint, ip6->_addr);
    read_len = sizeof(*ip6);
  } else if (AF_UNIX == raw->_family) {
    LogFieldUn *un = static_cast<LogFieldUn *>(raw);
    ats_unix_set(&endpoint, un->_path, TS_UNIX_SIZE);
    read_len = sizeof(*un);
  } else {
    ats_ip_invalidate(&endpoint);
  }

  if (!ats_is_ip(&endpoint) && !ats_is_unix(&endpoint)) {
    dest[0] = '0';
    dest[1] = '\0';
    return {-1, 1};
  } else if (ats_ip_ntop(&endpoint, dest, len)) {
    return {read_len, static_cast<int>(::strlen(dest))};
  }

  return {-1, -1};
}

bool
TSClientHello::is_available() const
{
  return static_cast<bool>(*this);
}

uint16_t
TSClientHello::get_version() const
{
  return static_cast<TLSSNISupport::ClientHello *>(_client_hello)->getVersion();
}

const uint8_t *
TSClientHello::get_cipher_suites() const
{
  return reinterpret_cast<const uint8_t *>(static_cast<TLSSNISupport::ClientHello *>(_client_hello)->getCipherSuites().data());
}

size_t
TSClientHello::get_cipher_suites_len() const
{
  return static_cast<TLSSNISupport::ClientHello *>(_client_hello)->getCipherSuites().length();
}

TSClientHello::TSExtensionTypeList::Iterator::Iterator(const void *ite)
{
  static_assert(sizeof(_real_iterator) >= sizeof(TLSSNISupport::ClientHello::ExtensionIdIterator));

  ink_assert(_real_iterator);
  ink_assert(ite);
  memcpy(_real_iterator, ite, sizeof(TLSSNISupport::ClientHello::ExtensionIdIterator));
}

TSClientHello::TSExtensionTypeList::Iterator
TSClientHello::TSExtensionTypeList::begin()
{
  ink_assert(_ch);
  auto ch  = static_cast<TLSSNISupport::ClientHello *>(_ch);
  auto ite = ch->begin();
  // The temporal pointer is for the memcpy in the constructor. It's only used in the constructor.
  return TSClientHello::TSExtensionTypeList::Iterator(&ite);
}

TSClientHello::TSExtensionTypeList::Iterator
TSClientHello::TSExtensionTypeList::end()
{
  auto ite = static_cast<TLSSNISupport::ClientHello *>(_ch)->end();
  // The temporal pointer is for the memcpy in the constructor. It's only used in the constructor.
  return TSClientHello::TSExtensionTypeList::Iterator(&ite);
}

TSClientHello::TSExtensionTypeList::Iterator &
TSClientHello::TSExtensionTypeList::Iterator::operator++()
{
  ++(*reinterpret_cast<TLSSNISupport::ClientHello::ExtensionIdIterator *>(_real_iterator));
  return *this;
}

bool
TSClientHello::TSExtensionTypeList::Iterator::operator==(const TSClientHello::TSExtensionTypeList::Iterator &b) const
{
  return memcmp(_real_iterator, b._real_iterator, sizeof(_real_iterator)) == 0;
}
int
TSClientHello::TSExtensionTypeList::Iterator::operator*() const
{
  return *(*reinterpret_cast<const TLSSNISupport::ClientHello::ExtensionIdIterator *>(_real_iterator));
}
