/** @file

  Implements callin functions for TSAPI plugins.

  @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.
 */

// Avoid complaining about the deprecated APIs.
// #define TS_DEPRECATED

#include <stdio.h>

#include "libts.h"
#include "I_Layout.h"

#include "ts.h"
#include "InkAPIInternal.h"
#include "Log.h"
#include "URL.h"
#include "MIME.h"
#include "HTTP.h"
#include "HttpClientSession.h"
#include "HttpServerSession.h"
#include "HttpSM.h"
#include "HttpConfig.h"
#include "P_Net.h"
#include "P_UDPNet.h"
#include "P_HostDB.h"
#include "StatSystem.h"
#include "P_Cache.h"
#include "I_RecCore.h"
#include "I_RecSignals.h"
#include "ProxyConfig.h"
#include "Plugin.h"
#include "LogObject.h"
#include "LogConfig.h"
//#include "UserNameCache.h"
#include "PluginVC.h"
#include "api/ts/experimental.h"
#include "ICP.h"
#include "HttpAccept.h"
#include "PluginVC.h"
#include "FetchSM.h"
#include "HttpDebugNames.h"
#include "I_AIO.h"
#include "I_Tasks.h"

#include "I_RecDefs.h"
#include "I_RecCore.h"
#include "HttpProxyServerMain.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 trys 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;

// Globals for new librecords stats
volatile int top_stat = 0;
RecRawStatBlock *api_rsb;

// Globals for the Sessions/Transaction index registry
volatile int next_argv_index = 0;

struct _STATE_ARG_TABLE {
  char* name;
  size_t name_len;
  char* description;
} state_arg_table[HTTP_SSN_TXN_MAX_USER_ARG];


/* URL schemes */
tsapi const char *TS_URL_SCHEME_FILE;
tsapi const char *TS_URL_SCHEME_FTP;
tsapi const char *TS_URL_SCHEME_GOPHER;
tsapi const char *TS_URL_SCHEME_HTTP;
tsapi const char *TS_URL_SCHEME_HTTPS;
tsapi const char *TS_URL_SCHEME_MAILTO;
tsapi const char *TS_URL_SCHEME_NEWS;
tsapi const char *TS_URL_SCHEME_NNTP;
tsapi const char *TS_URL_SCHEME_PROSPERO;
tsapi const char *TS_URL_SCHEME_TELNET;
tsapi const char *TS_URL_SCHEME_TUNNEL;
tsapi const char *TS_URL_SCHEME_WAIS;
tsapi const char *TS_URL_SCHEME_PNM;
tsapi const char *TS_URL_SCHEME_RTSP;
tsapi const char *TS_URL_SCHEME_RTSPU;
tsapi const char *TS_URL_SCHEME_MMS;
tsapi const char *TS_URL_SCHEME_MMSU;
tsapi const char *TS_URL_SCHEME_MMST;

/* URL schemes string lengths */
tsapi int TS_URL_LEN_FILE;
tsapi int TS_URL_LEN_FTP;
tsapi int TS_URL_LEN_GOPHER;
tsapi int TS_URL_LEN_HTTP;
tsapi int TS_URL_LEN_HTTPS;
tsapi int TS_URL_LEN_MAILTO;
tsapi int TS_URL_LEN_NEWS;
tsapi int TS_URL_LEN_NNTP;
tsapi int TS_URL_LEN_PROSPERO;
tsapi int TS_URL_LEN_TELNET;
tsapi int TS_URL_LEN_TUNNEL;
tsapi int TS_URL_LEN_WAIS;
tsapi int TS_URL_LEN_PNM;
tsapi int TS_URL_LEN_RTSP;
tsapi int TS_URL_LEN_RTSPU;
tsapi int TS_URL_LEN_MMS;
tsapi int TS_URL_LEN_MMSU;
tsapi int TS_URL_LEN_MMST;

/* MIME fields */
tsapi const char *TS_MIME_FIELD_ACCEPT;
tsapi const char *TS_MIME_FIELD_ACCEPT_CHARSET;
tsapi const char *TS_MIME_FIELD_ACCEPT_ENCODING;
tsapi const char *TS_MIME_FIELD_ACCEPT_LANGUAGE;
tsapi const char *TS_MIME_FIELD_ACCEPT_RANGES;
tsapi const char *TS_MIME_FIELD_AGE;
tsapi const char *TS_MIME_FIELD_ALLOW;
tsapi const char *TS_MIME_FIELD_APPROVED;
tsapi const char *TS_MIME_FIELD_AUTHORIZATION;
tsapi const char *TS_MIME_FIELD_BYTES;
tsapi const char *TS_MIME_FIELD_CACHE_CONTROL;
tsapi const char *TS_MIME_FIELD_CLIENT_IP;
tsapi const char *TS_MIME_FIELD_CONNECTION;
tsapi const char *TS_MIME_FIELD_CONTENT_BASE;
tsapi const char *TS_MIME_FIELD_CONTENT_ENCODING;
tsapi const char *TS_MIME_FIELD_CONTENT_LANGUAGE;
tsapi const char *TS_MIME_FIELD_CONTENT_LENGTH;
tsapi const char *TS_MIME_FIELD_CONTENT_LOCATION;
tsapi const char *TS_MIME_FIELD_CONTENT_MD5;
tsapi const char *TS_MIME_FIELD_CONTENT_RANGE;
tsapi const char *TS_MIME_FIELD_CONTENT_TYPE;
tsapi const char *TS_MIME_FIELD_CONTROL;
tsapi const char *TS_MIME_FIELD_COOKIE;
tsapi const char *TS_MIME_FIELD_DATE;
tsapi const char *TS_MIME_FIELD_DISTRIBUTION;
tsapi const char *TS_MIME_FIELD_ETAG;
tsapi const char *TS_MIME_FIELD_EXPECT;
tsapi const char *TS_MIME_FIELD_EXPIRES;
tsapi const char *TS_MIME_FIELD_FOLLOWUP_TO;
tsapi const char *TS_MIME_FIELD_FROM;
tsapi const char *TS_MIME_FIELD_HOST;
tsapi const char *TS_MIME_FIELD_IF_MATCH;
tsapi const char *TS_MIME_FIELD_IF_MODIFIED_SINCE;
tsapi const char *TS_MIME_FIELD_IF_NONE_MATCH;
tsapi const char *TS_MIME_FIELD_IF_RANGE;
tsapi const char *TS_MIME_FIELD_IF_UNMODIFIED_SINCE;
tsapi const char *TS_MIME_FIELD_KEEP_ALIVE;
tsapi const char *TS_MIME_FIELD_KEYWORDS;
tsapi const char *TS_MIME_FIELD_LAST_MODIFIED;
tsapi const char *TS_MIME_FIELD_LINES;
tsapi const char *TS_MIME_FIELD_LOCATION;
tsapi const char *TS_MIME_FIELD_MAX_FORWARDS;
tsapi const char *TS_MIME_FIELD_MESSAGE_ID;
tsapi const char *TS_MIME_FIELD_NEWSGROUPS;
tsapi const char *TS_MIME_FIELD_ORGANIZATION;
tsapi const char *TS_MIME_FIELD_PATH;
tsapi const char *TS_MIME_FIELD_PRAGMA;
tsapi const char *TS_MIME_FIELD_PROXY_AUTHENTICATE;
tsapi const char *TS_MIME_FIELD_PROXY_AUTHORIZATION;
tsapi const char *TS_MIME_FIELD_PROXY_CONNECTION;
tsapi const char *TS_MIME_FIELD_PUBLIC;
tsapi const char *TS_MIME_FIELD_RANGE;
tsapi const char *TS_MIME_FIELD_REFERENCES;
tsapi const char *TS_MIME_FIELD_REFERER;
tsapi const char *TS_MIME_FIELD_REPLY_TO;
tsapi const char *TS_MIME_FIELD_RETRY_AFTER;
tsapi const char *TS_MIME_FIELD_SENDER;
tsapi const char *TS_MIME_FIELD_SERVER;
tsapi const char *TS_MIME_FIELD_SET_COOKIE;
tsapi const char *TS_MIME_FIELD_SUBJECT;
tsapi const char *TS_MIME_FIELD_SUMMARY;
tsapi const char *TS_MIME_FIELD_TE;
tsapi const char *TS_MIME_FIELD_TRANSFER_ENCODING;
tsapi const char *TS_MIME_FIELD_UPGRADE;
tsapi const char *TS_MIME_FIELD_USER_AGENT;
tsapi const char *TS_MIME_FIELD_VARY;
tsapi const char *TS_MIME_FIELD_VIA;
tsapi const char *TS_MIME_FIELD_WARNING;
tsapi const char *TS_MIME_FIELD_WWW_AUTHENTICATE;
tsapi const char *TS_MIME_FIELD_XREF;
tsapi const char *TS_MIME_FIELD_X_FORWARDED_FOR;

/* MIME fields string lengths */
tsapi int TS_MIME_LEN_ACCEPT;
tsapi int TS_MIME_LEN_ACCEPT_CHARSET;
tsapi int TS_MIME_LEN_ACCEPT_ENCODING;
tsapi int TS_MIME_LEN_ACCEPT_LANGUAGE;
tsapi int TS_MIME_LEN_ACCEPT_RANGES;
tsapi int TS_MIME_LEN_AGE;
tsapi int TS_MIME_LEN_ALLOW;
tsapi int TS_MIME_LEN_APPROVED;
tsapi int TS_MIME_LEN_AUTHORIZATION;
tsapi int TS_MIME_LEN_BYTES;
tsapi int TS_MIME_LEN_CACHE_CONTROL;
tsapi int TS_MIME_LEN_CLIENT_IP;
tsapi int TS_MIME_LEN_CONNECTION;
tsapi int TS_MIME_LEN_CONTENT_BASE;
tsapi int TS_MIME_LEN_CONTENT_ENCODING;
tsapi int TS_MIME_LEN_CONTENT_LANGUAGE;
tsapi int TS_MIME_LEN_CONTENT_LENGTH;
tsapi int TS_MIME_LEN_CONTENT_LOCATION;
tsapi int TS_MIME_LEN_CONTENT_MD5;
tsapi int TS_MIME_LEN_CONTENT_RANGE;
tsapi int TS_MIME_LEN_CONTENT_TYPE;
tsapi int TS_MIME_LEN_CONTROL;
tsapi int TS_MIME_LEN_COOKIE;
tsapi int TS_MIME_LEN_DATE;
tsapi int TS_MIME_LEN_DISTRIBUTION;
tsapi int TS_MIME_LEN_ETAG;
tsapi int TS_MIME_LEN_EXPECT;
tsapi int TS_MIME_LEN_EXPIRES;
tsapi int TS_MIME_LEN_FOLLOWUP_TO;
tsapi int TS_MIME_LEN_FROM;
tsapi int TS_MIME_LEN_HOST;
tsapi int TS_MIME_LEN_IF_MATCH;
tsapi int TS_MIME_LEN_IF_MODIFIED_SINCE;
tsapi int TS_MIME_LEN_IF_NONE_MATCH;
tsapi int TS_MIME_LEN_IF_RANGE;
tsapi int TS_MIME_LEN_IF_UNMODIFIED_SINCE;
tsapi int TS_MIME_LEN_KEEP_ALIVE;
tsapi int TS_MIME_LEN_KEYWORDS;
tsapi int TS_MIME_LEN_LAST_MODIFIED;
tsapi int TS_MIME_LEN_LINES;
tsapi int TS_MIME_LEN_LOCATION;
tsapi int TS_MIME_LEN_MAX_FORWARDS;
tsapi int TS_MIME_LEN_MESSAGE_ID;
tsapi int TS_MIME_LEN_NEWSGROUPS;
tsapi int TS_MIME_LEN_ORGANIZATION;
tsapi int TS_MIME_LEN_PATH;
tsapi int TS_MIME_LEN_PRAGMA;
tsapi int TS_MIME_LEN_PROXY_AUTHENTICATE;
tsapi int TS_MIME_LEN_PROXY_AUTHORIZATION;
tsapi int TS_MIME_LEN_PROXY_CONNECTION;
tsapi int TS_MIME_LEN_PUBLIC;
tsapi int TS_MIME_LEN_RANGE;
tsapi int TS_MIME_LEN_REFERENCES;
tsapi int TS_MIME_LEN_REFERER;
tsapi int TS_MIME_LEN_REPLY_TO;
tsapi int TS_MIME_LEN_RETRY_AFTER;
tsapi int TS_MIME_LEN_SENDER;
tsapi int TS_MIME_LEN_SERVER;
tsapi int TS_MIME_LEN_SET_COOKIE;
tsapi int TS_MIME_LEN_SUBJECT;
tsapi int TS_MIME_LEN_SUMMARY;
tsapi int TS_MIME_LEN_TE;
tsapi int TS_MIME_LEN_TRANSFER_ENCODING;
tsapi int TS_MIME_LEN_UPGRADE;
tsapi int TS_MIME_LEN_USER_AGENT;
tsapi int TS_MIME_LEN_VARY;
tsapi int TS_MIME_LEN_VIA;
tsapi int TS_MIME_LEN_WARNING;
tsapi int TS_MIME_LEN_WWW_AUTHENTICATE;
tsapi int TS_MIME_LEN_XREF;
tsapi int TS_MIME_LEN_X_FORWARDED_FOR;


/* HTTP miscellaneous values */
tsapi const char *TS_HTTP_VALUE_BYTES;
tsapi const char *TS_HTTP_VALUE_CHUNKED;
tsapi const char *TS_HTTP_VALUE_CLOSE;
tsapi const char *TS_HTTP_VALUE_COMPRESS;
tsapi const char *TS_HTTP_VALUE_DEFLATE;
tsapi const char *TS_HTTP_VALUE_GZIP;
tsapi const char *TS_HTTP_VALUE_IDENTITY;
tsapi const char *TS_HTTP_VALUE_KEEP_ALIVE;
tsapi const char *TS_HTTP_VALUE_MAX_AGE;
tsapi const char *TS_HTTP_VALUE_MAX_STALE;
tsapi const char *TS_HTTP_VALUE_MIN_FRESH;
tsapi const char *TS_HTTP_VALUE_MUST_REVALIDATE;
tsapi const char *TS_HTTP_VALUE_NONE;
tsapi const char *TS_HTTP_VALUE_NO_CACHE;
tsapi const char *TS_HTTP_VALUE_NO_STORE;
tsapi const char *TS_HTTP_VALUE_NO_TRANSFORM;
tsapi const char *TS_HTTP_VALUE_ONLY_IF_CACHED;
tsapi const char *TS_HTTP_VALUE_PRIVATE;
tsapi const char *TS_HTTP_VALUE_PROXY_REVALIDATE;
tsapi const char *TS_HTTP_VALUE_PUBLIC;
tsapi const char *TS_HTTP_VALUE_S_MAXAGE;

/* HTTP miscellaneous values string lengths */
tsapi int TS_HTTP_LEN_BYTES;
tsapi int TS_HTTP_LEN_CHUNKED;
tsapi int TS_HTTP_LEN_CLOSE;
tsapi int TS_HTTP_LEN_COMPRESS;
tsapi int TS_HTTP_LEN_DEFLATE;
tsapi int TS_HTTP_LEN_GZIP;
tsapi int TS_HTTP_LEN_IDENTITY;
tsapi int TS_HTTP_LEN_KEEP_ALIVE;
tsapi int TS_HTTP_LEN_MAX_AGE;
tsapi int TS_HTTP_LEN_MAX_STALE;
tsapi int TS_HTTP_LEN_MIN_FRESH;
tsapi int TS_HTTP_LEN_MUST_REVALIDATE;
tsapi int TS_HTTP_LEN_NONE;
tsapi int TS_HTTP_LEN_NO_CACHE;
tsapi int TS_HTTP_LEN_NO_STORE;
tsapi int TS_HTTP_LEN_NO_TRANSFORM;
tsapi int TS_HTTP_LEN_ONLY_IF_CACHED;
tsapi int TS_HTTP_LEN_PRIVATE;
tsapi int TS_HTTP_LEN_PROXY_REVALIDATE;
tsapi int TS_HTTP_LEN_PUBLIC;
tsapi int TS_HTTP_LEN_S_MAXAGE;

/* HTTP methods */
tsapi const char *TS_HTTP_METHOD_CONNECT;
tsapi const char *TS_HTTP_METHOD_DELETE;
tsapi const char *TS_HTTP_METHOD_GET;
tsapi const char *TS_HTTP_METHOD_HEAD;
tsapi const char *TS_HTTP_METHOD_ICP_QUERY;
tsapi const char *TS_HTTP_METHOD_OPTIONS;
tsapi const char *TS_HTTP_METHOD_POST;
tsapi const char *TS_HTTP_METHOD_PURGE;
tsapi const char *TS_HTTP_METHOD_PUT;
tsapi const char *TS_HTTP_METHOD_TRACE;

/* HTTP methods string lengths */
tsapi int TS_HTTP_LEN_CONNECT;
tsapi int TS_HTTP_LEN_DELETE;
tsapi int TS_HTTP_LEN_GET;
tsapi int TS_HTTP_LEN_HEAD;
tsapi int TS_HTTP_LEN_ICP_QUERY;
tsapi int TS_HTTP_LEN_OPTIONS;
tsapi int TS_HTTP_LEN_POST;
tsapi int TS_HTTP_LEN_PURGE;
tsapi int TS_HTTP_LEN_PUT;
tsapi int TS_HTTP_LEN_TRACE;

/* TLS Next Protocol well-known protocol names. */

tsapi const char * TS_NPN_PROTOCOL_HTTP_1_0 = "http/1.0";
tsapi const char * TS_NPN_PROTOCOL_HTTP_1_1 = "http/1.1";
tsapi const char * TS_NPN_PROTOCOL_SPDY_1   = "spdy/1";   // obsolete
tsapi const char * TS_NPN_PROTOCOL_SPDY_2   = "spdy/2";   // shipping
tsapi const char * TS_NPN_PROTOCOL_SPDY_3   = "spdy/3";   // upcoming

/* MLoc Constants */
tsapi const TSMLoc TS_NULL_MLOC = (TSMLoc)NULL;

HttpAPIHooks *http_global_hooks = NULL;
LifecycleAPIHooks* lifecycle_hooks = NULL;
ConfigUpdateCbTable *global_config_cbs = NULL;

static char traffic_server_version[128] = "";
static int ts_major_version = 0;
static int ts_minor_version = 0;
static int ts_patch_version = 0;

static ClassAllocator<APIHook> apiHookAllocator("apiHookAllocator");
static ClassAllocator<INKContInternal> INKContAllocator("INKContAllocator");
static ClassAllocator<INKVConnInternal> INKVConnAllocator("INKVConnAllocator");
static ClassAllocator<MIMEFieldSDKHandle> mHandleAllocator("MIMEFieldSDKHandle");


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

  if (is_action_tag_set("deft") || is_action_tag_set("sdk_vbos_errors")) {
    va_start(args, fmt);
    diags->print_va(NULL, DL_Error, NULL, fmt, args);
    va_end(args);
  }
  va_start(args, fmt);
  Log::va_error((char *) 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);
#else
_TSAssert(const char *, const char *, int)
{
#endif
 return 0;
}

// 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


////////////////////////////////////////////////////////////////////
//
// 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 (obj->m_type == HDR_HEAP_OBJ_HTTP_HEADER)
    impl = ((HTTPHdrImpl *) obj)->m_fields_impl;
  else if (obj->m_type == HDR_HEAP_OBJ_MIME_HEADER)
    impl = (MIMEHdrImpl *) obj;
  else {
    ink_release_assert(!"mloc not a header type");
    impl = NULL;                /* gcc does not know about 'ink_release_assert' - make him happy */
  }
  return impl;
}

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

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

  MIMEFieldSDKHandle *field_handle = (MIMEFieldSDKHandle *) field;
  if (field_handle->m_type != HDR_HEAP_OBJ_FIELD_SDK_HANDLE)
    return TS_ERROR;

  if (parent_hdr != NULL) {
    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 = (HdrHeapSDKHandle *) bufp;
  if ((handle == NULL) || (handle->m_heap == NULL) || (handle->m_heap->m_magic != HDR_BUF_MAGIC_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 = (MIMEFieldSDKHandle *) field;
  if (field_handle->m_type != HDR_HEAP_OBJ_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 = (MIMEFieldSDKHandle *) field;
  if (field_handle->m_type != HDR_HEAP_OBJ_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 = (HTTPHdrImpl *) field;
  if (field_handle->m_type != HDR_HEAP_OBJ_HTTP_HEADER)
    return TS_ERROR;

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_continuation(TSCont cont)
{
  if ((cont == NULL) || (((INKContInternal *) cont)->m_free_magic == INKCONT_INTERN_MAGIC_DEAD))
    return TS_ERROR;

  return TS_SUCCESS;
}

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

  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_txn(TSHttpTxn txnp)
{
  if ((txnp != NULL) && (((HttpSM *) txnp)->magic == HTTP_SM_MAGIC_ALIVE))
    return TS_SUCCESS;
  return TS_ERROR;
}

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

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

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

TSReturnCode
sdk_sanity_check_hook_id(TSHttpHookID id)
{
  if (id<TS_HTTP_READ_REQUEST_HDR_HOOK || id> TS_HTTP_LAST_HOOK)
    return TS_ERROR;
  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_lifecycle_hook_id(TSLifecycleHookID id)
{
  if (id<TS_LIFECYCLE_PORTS_INITIALIZED_HOOK || id> TS_LIFECYCLE_LAST_HOOK)
    return TS_ERROR;
  return TS_SUCCESS;
}

TSReturnCode
sdk_sanity_check_null_ptr(void *ptr)
{
  if (ptr == NULL)
    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 != NULL) {
    return ((HdrHeapSDKHandle *) bufp)->m_heap->m_writeable;
  }
  return false;
}


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

  // 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, HDR_HEAP_OBJ_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) {
    mHandleAllocator.free(field_handle);
  }
}


////////////////////////////////////////////////////////////////////
//
// FileImpl
//
////////////////////////////////////////////////////////////////////
FileImpl::FileImpl()
  : m_fd(-1), m_mode(CLOSED), m_buf(NULL), m_bufsize(0), m_bufpos(0)
{ }

FileImpl::~FileImpl()
{
  fclose();
}

int
FileImpl::fopen(const char *filename, const char *mode)
{
  if (mode[0] == '\0') {
    return 0;
  } else if (mode[0] == 'r') {
    if (mode[1] != '\0') {
      return 0;
    }
    m_mode = READ;
    m_fd = open(filename, O_RDONLY | _O_ATTRIB_NORMAL);
  } else if (mode[0] == 'w') {
    if (mode[1] != '\0') {
      return 0;
    }
    m_mode = WRITE;
    m_fd = open(filename, O_WRONLY | O_CREAT | _O_ATTRIB_NORMAL, 0644);
  } else if (mode[0] == 'a') {
    if (mode[1] != '\0') {
      return 0;
    }
    m_mode = WRITE;
    m_fd = open(filename, O_WRONLY | O_CREAT | O_APPEND | _O_ATTRIB_NORMAL, 0644);
  }

  if (m_fd < 0) {
    m_mode = CLOSED;
    return 0;
  } else {
    return 1;
  }
}

void
FileImpl::fclose()
{
  if (m_fd != -1) {
    fflush();

    close(m_fd);
    m_fd = -1;
    m_mode = CLOSED;
  }

  if (m_buf) {
    ats_free(m_buf);
    m_buf = NULL;
    m_bufsize = 0;
    m_bufpos = 0;
  }
}

int
FileImpl::fread(void *buf, int length)
{
  int64_t amount;
  int64_t err;

  if ((m_mode != READ) || (m_fd == -1)) {
    return -1;
  }

  if (!m_buf) {
    m_bufpos = 0;
    m_bufsize = 1024;
    m_buf = (char *)ats_malloc(m_bufsize);
  }

  if (m_bufpos < length) {
    amount = length;
    if (amount < 1024) {
      amount = 1024;
    }
    if (amount > (m_bufsize - m_bufpos)) {
      while (amount > (m_bufsize - m_bufpos)) {
        m_bufsize *= 2;
      }
      m_buf = (char *)ats_realloc(m_buf, m_bufsize);
    }

    do {
      err = read(m_fd, &m_buf[m_bufpos], amount);
    } while ((err < 0) && (errno == EINTR));

    if (err < 0) {
      return -1;
    }

    m_bufpos += err;
  }

  if (buf) {
    amount = length;
    if (amount > m_bufpos) {
      amount = m_bufpos;
    }
    memcpy(buf, m_buf, amount);
    memmove(m_buf, &m_buf[amount], m_bufpos - amount);
    m_bufpos -= amount;
    return amount;
  } else {
    return m_bufpos;
  }
}

int
FileImpl::fwrite(const void *buf, int length)
{
  const char *p, *e;
  int64_t avail;

  if ((m_mode != WRITE) || (m_fd == -1)) {
    return -1;
  }

  if (!m_buf) {
    m_bufpos = 0;
    m_bufsize = 1024;
    m_buf = (char *)ats_malloc(m_bufsize);
  }

  p = (const char *) buf;
  e = p + length;

  while (p != e) {
    avail = m_bufsize - m_bufpos;
    if (avail > length) {
      avail = length;
    }
    memcpy(&m_buf[m_bufpos], p, avail);

    m_bufpos += avail;
    p += avail;
    length -= avail;

    if ((length > 0) && (m_bufpos > 0)) {
      if (fflush() <= 0) {
        break;
      }
    }
  }

  return (p - (const char *) buf);
}

int
FileImpl::fflush()
{
  char *p, *e;
  int err = 0;

  if ((m_mode != WRITE) || (m_fd == -1)) {
    return -1;
  }

  if (m_buf) {
    p = m_buf;
    e = &m_buf[m_bufpos];

    while (p != e) {
      do {
        err = write(m_fd, p, e - p);
      } while ((err < 0) && (errno == EINTR));

      if (err < 0) {
        break;
      }

      p += err;
    }

    err = p - m_buf;
    memmove(m_buf, &m_buf[err], m_bufpos - err);
    m_bufpos -= err;
  }

  return err;
}

char *
FileImpl::fgets(char *buf, int length)
{
  char *e;
  int pos;

  if (length == 0) {
    return NULL;
  }

  if (!m_buf || (m_bufpos < (length - 1))) {
    pos = m_bufpos;

    fread(NULL, length - 1);

    if (!m_bufpos && (pos == m_bufpos)) {
      return NULL;
    }
  }

  e = (char *) memchr(m_buf, '\n', m_bufpos);
  if (e) {
    e += 1;
    if (length > (e - m_buf + 1)) {
      length = e - m_buf + 1;
    }
  }

  pos = fread(buf, length - 1);
  buf[pos] = '\0';

  return buf;
}

////////////////////////////////////////////////////////////////////
//
// INKContInternal
//
////////////////////////////////////////////////////////////////////

INKContInternal::INKContInternal()
  : DummyVConnection(NULL), mdata(NULL), m_event_func(NULL), m_event_count(0), m_closed(1), m_deletable(0),
    m_deleted(0), m_free_magic(INKCONT_INTERN_MAGIC_ALIVE)
{ }

INKContInternal::INKContInternal(TSEventFunc funcp, TSMutex mutexp)
  : DummyVConnection((ProxyMutex *) mutexp),
    mdata(NULL), m_event_func(funcp), m_event_count(0), m_closed(1), m_deletable(0), m_deleted(0),
    m_free_magic(INKCONT_INTERN_MAGIC_ALIVE)
{
  SET_HANDLER(&INKContInternal::handle_event);
}

void
INKContInternal::init(TSEventFunc funcp, TSMutex mutexp)
{
  SET_HANDLER(&INKContInternal::handle_event);

  mutex = (ProxyMutex *) mutexp;
  m_event_func = funcp;
}

void
INKContInternal::destroy()
{
  if (m_free_magic == INKCONT_INTERN_MAGIC_DEAD) {
    ink_release_assert(!"Plugin tries to use a continuation which is deleted");
  }
  m_deleted = 1;
  if (m_deletable) {
    this->mutex = NULL;
    m_free_magic = INKCONT_INTERN_MAGIC_DEAD;
    INKContAllocator.free(this);
  } else {
    // TODO: Should this schedule on some other "thread" ?
    // TODO: we don't care about the return action?
    TSContSchedule((TSCont)this, 0, TS_THREAD_POOL_DEFAULT);
  }
}

void
INKContInternal::handle_event_count(int event)
{
  if ((event == EVENT_IMMEDIATE) || (event == EVENT_INTERVAL)) {
    int val;

    m_deletable = (m_closed != 0);

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

    m_deletable = m_deletable && (val == 1);
  }
}

int
INKContInternal::handle_event(int event, void *edata)
{
  if (m_free_magic == INKCONT_INTERN_MAGIC_DEAD) {
    ink_release_assert(!"Plugin tries to use a continuation which is deleted");
  }
  handle_event_count(event);
  if (m_deleted) {
    if (m_deletable) {
      this->mutex = NULL;
      m_free_magic = INKCONT_INTERN_MAGIC_DEAD;
      INKContAllocator.free(this);
    }
  } else {
    return m_event_func((TSCont) this, (TSEvent) event, edata);
  }
  return EVENT_DONE;
}


////////////////////////////////////////////////////////////////////
//
// INKVConnInternal
//
////////////////////////////////////////////////////////////////////

INKVConnInternal::INKVConnInternal()
:INKContInternal(), m_read_vio(), m_write_vio(), m_output_vc(NULL)
{
  m_closed = 0;
}

INKVConnInternal::INKVConnInternal(TSEventFunc funcp, TSMutex mutexp)
:INKContInternal(funcp, mutexp), m_read_vio(), m_write_vio(), m_output_vc(NULL)
{
  m_closed = 0;
  SET_HANDLER(&INKVConnInternal::handle_event);
}

void
INKVConnInternal::init(TSEventFunc funcp, TSMutex mutexp)
{
  INKContInternal::init(funcp, mutexp);
  SET_HANDLER(&INKVConnInternal::handle_event);
}

void
INKVConnInternal::destroy()
{
  m_deleted = 1;
  if (m_deletable) {
    this->mutex = NULL;
    m_read_vio.set_continuation(NULL);
    m_write_vio.set_continuation(NULL);
    INKVConnAllocator.free(this);
  }
}

int
INKVConnInternal::handle_event(int event, void *edata)
{
  handle_event_count(event);
  if (m_deleted) {
    if (m_deletable) {
      this->mutex = NULL;
      m_read_vio.set_continuation(NULL);
      m_write_vio.set_continuation(NULL);
      INKVConnAllocator.free(this);
    }
  } else {
    return m_event_func((TSCont) this, (TSEvent) event, edata);
  }
  return EVENT_DONE;
}

VIO *
INKVConnInternal::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf)
{
  m_read_vio.buffer.writer_for(buf);
  m_read_vio.op = VIO::READ;
  m_read_vio.set_continuation(c);
  m_read_vio.nbytes = nbytes;
  m_read_vio.ndone = 0;
  m_read_vio.vc_server = this;

  if (ink_atomic_increment((int *) &m_event_count, 1) < 0) {
    ink_assert(!"not reached");
  }
  eventProcessor.schedule_imm(this, ET_NET);

  return &m_read_vio;
}

VIO *
INKVConnInternal::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner)
{
  ink_assert(!owner);
  m_write_vio.buffer.reader_for(buf);
  m_write_vio.op = VIO::WRITE;
  m_write_vio.set_continuation(c);
  m_write_vio.nbytes = nbytes;
  m_write_vio.ndone = 0;
  m_write_vio.vc_server = this;

  if (m_write_vio.buffer.reader()->read_avail() > 0) {
    if (ink_atomic_increment((int *) &m_event_count, 1) < 0) {
      ink_assert(!"not reached");
    }
    eventProcessor.schedule_imm(this, ET_NET);
  }

  return &m_write_vio;
}

void
INKVConnInternal::do_io_transform(VConnection *vc)
{
  m_output_vc = vc;
}

void
INKVConnInternal::do_io_close(int error)
{
  if (ink_atomic_increment((int *) &m_event_count, 1) < 0) {
    ink_assert(!"not reached");
  }

  INK_WRITE_MEMORY_BARRIER;

  if (error != -1) {
    lerrno = error;
    m_closed = TS_VC_CLOSE_ABORT;
  } else {
    m_closed = TS_VC_CLOSE_NORMAL;
  }

  m_read_vio.op = VIO::NONE;
  m_read_vio.buffer.clear();

  m_write_vio.op = VIO::NONE;
  m_write_vio.buffer.clear();

  if (m_output_vc) {
    m_output_vc->do_io_close(error);
  }

  eventProcessor.schedule_imm(this, ET_NET);
}

void
INKVConnInternal::do_io_shutdown(ShutdownHowTo_t howto)
{
  if ((howto == IO_SHUTDOWN_READ) || (howto == IO_SHUTDOWN_READWRITE)) {
    m_read_vio.op = VIO::NONE;
    m_read_vio.buffer.clear();
  }

  if ((howto == IO_SHUTDOWN_WRITE) || (howto == IO_SHUTDOWN_READWRITE)) {
    m_write_vio.op = VIO::NONE;
    m_write_vio.buffer.clear();
  }

  if (ink_atomic_increment((int *) &m_event_count, 1) < 0) {
    ink_assert(!"not reached");
  }
  eventProcessor.schedule_imm(this, ET_NET);
}

void
INKVConnInternal::reenable(VIO */* vio ATS_UNUSED */)
{
  if (ink_atomic_increment((int *) &m_event_count, 1) < 0) {
    ink_assert(!"not reached");
  }
  eventProcessor.schedule_imm(this, ET_NET);
}

void
INKVConnInternal::retry(unsigned int delay)
{
  if (ink_atomic_increment((int *) &m_event_count, 1) < 0) {
    ink_assert(!"not reached");
  }
  mutex->thread_holding->schedule_in(this, HRTIME_MSECONDS(delay));
}

bool
INKVConnInternal::get_data(int id, void *data)
{
  switch (id) {
  case TS_API_DATA_READ_VIO:
    *((TSVIO *) data) = reinterpret_cast<TSVIO>(&m_read_vio);
    return true;
  case TS_API_DATA_WRITE_VIO:
    *((TSVIO *) data) = reinterpret_cast<TSVIO>(&m_write_vio);
    return true;
  case TS_API_DATA_OUTPUT_VC:
    *((TSVConn *) data) = reinterpret_cast<TSVConn>(m_output_vc);
    return true;
  case TS_API_DATA_CLOSED:
    *((int *) data) = m_closed;
    return true;
  default:
    return INKContInternal::get_data(id, data);
  }
}

bool
INKVConnInternal::set_data(int id, void *data)
{
  switch (id) {
  case TS_API_DATA_OUTPUT_VC:
    m_output_vc = (VConnection *) data;
    return true;
  default:
    return INKContInternal::set_data(id, data);
  }
}

////////////////////////////////////////////////////////////////////
//
// APIHook, APIHooks, HttpAPIHooks
//
////////////////////////////////////////////////////////////////////

int
APIHook::invoke(int event, void *edata)
{
  if ((event == EVENT_IMMEDIATE) || (event == EVENT_INTERVAL)) {
    if (ink_atomic_increment((int *) &m_cont->m_event_count, 1) < 0) {
      ink_assert(!"not reached");
    }
  }
  return m_cont->handleEvent(event, edata);
}

APIHook *
APIHook::next() const
{
  return m_link.next;
}


void
APIHooks::prepend(INKContInternal *cont)
{
  APIHook *api_hook;

  api_hook = apiHookAllocator.alloc();
  api_hook->m_cont = cont;

  m_hooks.push(api_hook);
}

void
APIHooks::append(INKContInternal *cont)
{
  APIHook *api_hook;

  api_hook = apiHookAllocator.alloc();
  api_hook->m_cont = cont;

  m_hooks.enqueue(api_hook);
}

APIHook *
APIHooks::get()
{
  return m_hooks.head;
}

void
APIHooks::clear()
{
  APIHook* hook;
  while (0 != (hook = m_hooks.pop())) {
    apiHookAllocator.free(hook);
  }
}

////////////////////////////////////////////////////////////////////
//
// ConfigUpdateCbTable
//
////////////////////////////////////////////////////////////////////

ConfigUpdateCbTable::ConfigUpdateCbTable()
{
  cb_table = ink_hash_table_create(InkHashTableKeyType_String);
}

ConfigUpdateCbTable::~ConfigUpdateCbTable()
{
  ink_assert(cb_table != NULL);

  ink_hash_table_destroy(cb_table);
}

void
ConfigUpdateCbTable::insert(INKContInternal *contp, const char *name)
{
  ink_assert(cb_table != NULL);

  if (contp && name)
    ink_hash_table_insert(cb_table, (InkHashTableKey) name, (InkHashTableValue) contp);
}

void
ConfigUpdateCbTable::invoke(const char *name)
{
  ink_assert(cb_table != NULL);

  InkHashTableIteratorState ht_iter;
  InkHashTableEntry *ht_entry;
  INKContInternal *contp;

  if (name != NULL) {
    if (strcmp(name, "*") == 0) {
      ht_entry = ink_hash_table_iterator_first(cb_table, &ht_iter);
      while (ht_entry != NULL) {
        contp = (INKContInternal *)ink_hash_table_entry_value(cb_table, ht_entry);
        ink_assert(contp != NULL);
        invoke(contp);
        ht_entry = ink_hash_table_iterator_next(cb_table, &ht_iter);
      }
    } else {
      ht_entry = ink_hash_table_lookup_entry(cb_table, (InkHashTableKey) name);
      if (ht_entry != NULL) {
        contp = (INKContInternal *) ink_hash_table_entry_value(cb_table, ht_entry);
        ink_assert(contp != NULL);
        invoke(contp);
      }
    }
  }
}

void
ConfigUpdateCbTable::invoke(INKContInternal *contp)
{
  eventProcessor.schedule_imm(NEW(new ConfigUpdateCallback(contp)), ET_TASK);
}

////////////////////////////////////////////////////////////////////
//
// api_init
//
////////////////////////////////////////////////////////////////////

void
api_init()
{
  // HDR FIX ME

  static int init = 1;

  if (init) {
    init = 0;

#ifndef UNSAFE_FORCE_MUTEX
    ink_mutex_init(&big_mux, "APIMongoMutex");
#endif

    /* URL schemes */
    TS_URL_SCHEME_FILE = URL_SCHEME_FILE;
    TS_URL_SCHEME_FTP = URL_SCHEME_FTP;
    TS_URL_SCHEME_GOPHER = URL_SCHEME_GOPHER;
    TS_URL_SCHEME_HTTP = URL_SCHEME_HTTP;
    TS_URL_SCHEME_HTTPS = URL_SCHEME_HTTPS;
    TS_URL_SCHEME_MAILTO = URL_SCHEME_MAILTO;
    TS_URL_SCHEME_NEWS = URL_SCHEME_NEWS;
    TS_URL_SCHEME_NNTP = URL_SCHEME_NNTP;
    TS_URL_SCHEME_PROSPERO = URL_SCHEME_PROSPERO;
    TS_URL_SCHEME_TELNET = URL_SCHEME_TELNET;
    TS_URL_SCHEME_WAIS = URL_SCHEME_WAIS;

    TS_URL_LEN_FILE = URL_LEN_FILE;
    TS_URL_LEN_FTP = URL_LEN_FTP;
    TS_URL_LEN_GOPHER = URL_LEN_GOPHER;
    TS_URL_LEN_HTTP = URL_LEN_HTTP;
    TS_URL_LEN_HTTPS = URL_LEN_HTTPS;
    TS_URL_LEN_MAILTO = URL_LEN_MAILTO;
    TS_URL_LEN_NEWS = URL_LEN_NEWS;
    TS_URL_LEN_NNTP = URL_LEN_NNTP;
    TS_URL_LEN_PROSPERO = URL_LEN_PROSPERO;
    TS_URL_LEN_TELNET = URL_LEN_TELNET;
    TS_URL_LEN_WAIS = URL_LEN_WAIS;

    /* MIME fields */
    TS_MIME_FIELD_ACCEPT = MIME_FIELD_ACCEPT;
    TS_MIME_FIELD_ACCEPT_CHARSET = MIME_FIELD_ACCEPT_CHARSET;
    TS_MIME_FIELD_ACCEPT_ENCODING = MIME_FIELD_ACCEPT_ENCODING;
    TS_MIME_FIELD_ACCEPT_LANGUAGE = MIME_FIELD_ACCEPT_LANGUAGE;
    TS_MIME_FIELD_ACCEPT_RANGES = MIME_FIELD_ACCEPT_RANGES;
    TS_MIME_FIELD_AGE = MIME_FIELD_AGE;
    TS_MIME_FIELD_ALLOW = MIME_FIELD_ALLOW;
    TS_MIME_FIELD_APPROVED = MIME_FIELD_APPROVED;
    TS_MIME_FIELD_AUTHORIZATION = MIME_FIELD_AUTHORIZATION;
    TS_MIME_FIELD_BYTES = MIME_FIELD_BYTES;
    TS_MIME_FIELD_CACHE_CONTROL = MIME_FIELD_CACHE_CONTROL;
    TS_MIME_FIELD_CLIENT_IP = MIME_FIELD_CLIENT_IP;
    TS_MIME_FIELD_CONNECTION = MIME_FIELD_CONNECTION;
    TS_MIME_FIELD_CONTENT_BASE = MIME_FIELD_CONTENT_BASE;
    TS_MIME_FIELD_CONTENT_ENCODING = MIME_FIELD_CONTENT_ENCODING;
    TS_MIME_FIELD_CONTENT_LANGUAGE = MIME_FIELD_CONTENT_LANGUAGE;
    TS_MIME_FIELD_CONTENT_LENGTH = MIME_FIELD_CONTENT_LENGTH;
    TS_MIME_FIELD_CONTENT_LOCATION = MIME_FIELD_CONTENT_LOCATION;
    TS_MIME_FIELD_CONTENT_MD5 = MIME_FIELD_CONTENT_MD5;
    TS_MIME_FIELD_CONTENT_RANGE = MIME_FIELD_CONTENT_RANGE;
    TS_MIME_FIELD_CONTENT_TYPE = MIME_FIELD_CONTENT_TYPE;
    TS_MIME_FIELD_CONTROL = MIME_FIELD_CONTROL;
    TS_MIME_FIELD_COOKIE = MIME_FIELD_COOKIE;
    TS_MIME_FIELD_DATE = MIME_FIELD_DATE;
    TS_MIME_FIELD_DISTRIBUTION = MIME_FIELD_DISTRIBUTION;
    TS_MIME_FIELD_ETAG = MIME_FIELD_ETAG;
    TS_MIME_FIELD_EXPECT = MIME_FIELD_EXPECT;
    TS_MIME_FIELD_EXPIRES = MIME_FIELD_EXPIRES;
    TS_MIME_FIELD_FOLLOWUP_TO = MIME_FIELD_FOLLOWUP_TO;
    TS_MIME_FIELD_FROM = MIME_FIELD_FROM;
    TS_MIME_FIELD_HOST = MIME_FIELD_HOST;
    TS_MIME_FIELD_IF_MATCH = MIME_FIELD_IF_MATCH;
    TS_MIME_FIELD_IF_MODIFIED_SINCE = MIME_FIELD_IF_MODIFIED_SINCE;
    TS_MIME_FIELD_IF_NONE_MATCH = MIME_FIELD_IF_NONE_MATCH;
    TS_MIME_FIELD_IF_RANGE = MIME_FIELD_IF_RANGE;
    TS_MIME_FIELD_IF_UNMODIFIED_SINCE = MIME_FIELD_IF_UNMODIFIED_SINCE;
    TS_MIME_FIELD_KEEP_ALIVE = MIME_FIELD_KEEP_ALIVE;
    TS_MIME_FIELD_KEYWORDS = MIME_FIELD_KEYWORDS;
    TS_MIME_FIELD_LAST_MODIFIED = MIME_FIELD_LAST_MODIFIED;
    TS_MIME_FIELD_LINES = MIME_FIELD_LINES;
    TS_MIME_FIELD_LOCATION = MIME_FIELD_LOCATION;
    TS_MIME_FIELD_MAX_FORWARDS = MIME_FIELD_MAX_FORWARDS;
    TS_MIME_FIELD_MESSAGE_ID = MIME_FIELD_MESSAGE_ID;
    TS_MIME_FIELD_NEWSGROUPS = MIME_FIELD_NEWSGROUPS;
    TS_MIME_FIELD_ORGANIZATION = MIME_FIELD_ORGANIZATION;
    TS_MIME_FIELD_PATH = MIME_FIELD_PATH;
    TS_MIME_FIELD_PRAGMA = MIME_FIELD_PRAGMA;
    TS_MIME_FIELD_PROXY_AUTHENTICATE = MIME_FIELD_PROXY_AUTHENTICATE;
    TS_MIME_FIELD_PROXY_AUTHORIZATION = MIME_FIELD_PROXY_AUTHORIZATION;
    TS_MIME_FIELD_PROXY_CONNECTION = MIME_FIELD_PROXY_CONNECTION;
    TS_MIME_FIELD_PUBLIC = MIME_FIELD_PUBLIC;
    TS_MIME_FIELD_RANGE = MIME_FIELD_RANGE;
    TS_MIME_FIELD_REFERENCES = MIME_FIELD_REFERENCES;
    TS_MIME_FIELD_REFERER = MIME_FIELD_REFERER;
    TS_MIME_FIELD_REPLY_TO = MIME_FIELD_REPLY_TO;
    TS_MIME_FIELD_RETRY_AFTER = MIME_FIELD_RETRY_AFTER;
    TS_MIME_FIELD_SENDER = MIME_FIELD_SENDER;
    TS_MIME_FIELD_SERVER = MIME_FIELD_SERVER;
    TS_MIME_FIELD_SET_COOKIE = MIME_FIELD_SET_COOKIE;
    TS_MIME_FIELD_SUBJECT = MIME_FIELD_SUBJECT;
    TS_MIME_FIELD_SUMMARY = MIME_FIELD_SUMMARY;
    TS_MIME_FIELD_TE = MIME_FIELD_TE;
    TS_MIME_FIELD_TRANSFER_ENCODING = MIME_FIELD_TRANSFER_ENCODING;
    TS_MIME_FIELD_UPGRADE = MIME_FIELD_UPGRADE;
    TS_MIME_FIELD_USER_AGENT = MIME_FIELD_USER_AGENT;
    TS_MIME_FIELD_VARY = MIME_FIELD_VARY;
    TS_MIME_FIELD_VIA = MIME_FIELD_VIA;
    TS_MIME_FIELD_WARNING = MIME_FIELD_WARNING;
    TS_MIME_FIELD_WWW_AUTHENTICATE = MIME_FIELD_WWW_AUTHENTICATE;
    TS_MIME_FIELD_XREF = MIME_FIELD_XREF;
    TS_MIME_FIELD_X_FORWARDED_FOR = MIME_FIELD_X_FORWARDED_FOR;


    TS_MIME_LEN_ACCEPT = MIME_LEN_ACCEPT;
    TS_MIME_LEN_ACCEPT_CHARSET = MIME_LEN_ACCEPT_CHARSET;
    TS_MIME_LEN_ACCEPT_ENCODING = MIME_LEN_ACCEPT_ENCODING;
    TS_MIME_LEN_ACCEPT_LANGUAGE = MIME_LEN_ACCEPT_LANGUAGE;
    TS_MIME_LEN_ACCEPT_RANGES = MIME_LEN_ACCEPT_RANGES;
    TS_MIME_LEN_AGE = MIME_LEN_AGE;
    TS_MIME_LEN_ALLOW = MIME_LEN_ALLOW;
    TS_MIME_LEN_APPROVED = MIME_LEN_APPROVED;
    TS_MIME_LEN_AUTHORIZATION = MIME_LEN_AUTHORIZATION;
    TS_MIME_LEN_BYTES = MIME_LEN_BYTES;
    TS_MIME_LEN_CACHE_CONTROL = MIME_LEN_CACHE_CONTROL;
    TS_MIME_LEN_CLIENT_IP = MIME_LEN_CLIENT_IP;
    TS_MIME_LEN_CONNECTION = MIME_LEN_CONNECTION;
    TS_MIME_LEN_CONTENT_BASE = MIME_LEN_CONTENT_BASE;
    TS_MIME_LEN_CONTENT_ENCODING = MIME_LEN_CONTENT_ENCODING;
    TS_MIME_LEN_CONTENT_LANGUAGE = MIME_LEN_CONTENT_LANGUAGE;
    TS_MIME_LEN_CONTENT_LENGTH = MIME_LEN_CONTENT_LENGTH;
    TS_MIME_LEN_CONTENT_LOCATION = MIME_LEN_CONTENT_LOCATION;
    TS_MIME_LEN_CONTENT_MD5 = MIME_LEN_CONTENT_MD5;
    TS_MIME_LEN_CONTENT_RANGE = MIME_LEN_CONTENT_RANGE;
    TS_MIME_LEN_CONTENT_TYPE = MIME_LEN_CONTENT_TYPE;
    TS_MIME_LEN_CONTROL = MIME_LEN_CONTROL;
    TS_MIME_LEN_COOKIE = MIME_LEN_COOKIE;
    TS_MIME_LEN_DATE = MIME_LEN_DATE;
    TS_MIME_LEN_DISTRIBUTION = MIME_LEN_DISTRIBUTION;
    TS_MIME_LEN_ETAG = MIME_LEN_ETAG;
    TS_MIME_LEN_EXPECT = MIME_LEN_EXPECT;
    TS_MIME_LEN_EXPIRES = MIME_LEN_EXPIRES;
    TS_MIME_LEN_FOLLOWUP_TO = MIME_LEN_FOLLOWUP_TO;
    TS_MIME_LEN_FROM = MIME_LEN_FROM;
    TS_MIME_LEN_HOST = MIME_LEN_HOST;
    TS_MIME_LEN_IF_MATCH = MIME_LEN_IF_MATCH;
    TS_MIME_LEN_IF_MODIFIED_SINCE = MIME_LEN_IF_MODIFIED_SINCE;
    TS_MIME_LEN_IF_NONE_MATCH = MIME_LEN_IF_NONE_MATCH;
    TS_MIME_LEN_IF_RANGE = MIME_LEN_IF_RANGE;
    TS_MIME_LEN_IF_UNMODIFIED_SINCE = MIME_LEN_IF_UNMODIFIED_SINCE;
    TS_MIME_LEN_KEEP_ALIVE = MIME_LEN_KEEP_ALIVE;
    TS_MIME_LEN_KEYWORDS = MIME_LEN_KEYWORDS;
    TS_MIME_LEN_LAST_MODIFIED = MIME_LEN_LAST_MODIFIED;
    TS_MIME_LEN_LINES = MIME_LEN_LINES;
    TS_MIME_LEN_LOCATION = MIME_LEN_LOCATION;
    TS_MIME_LEN_MAX_FORWARDS = MIME_LEN_MAX_FORWARDS;
    TS_MIME_LEN_MESSAGE_ID = MIME_LEN_MESSAGE_ID;
    TS_MIME_LEN_NEWSGROUPS = MIME_LEN_NEWSGROUPS;
    TS_MIME_LEN_ORGANIZATION = MIME_LEN_ORGANIZATION;
    TS_MIME_LEN_PATH = MIME_LEN_PATH;
    TS_MIME_LEN_PRAGMA = MIME_LEN_PRAGMA;
    TS_MIME_LEN_PROXY_AUTHENTICATE = MIME_LEN_PROXY_AUTHENTICATE;
    TS_MIME_LEN_PROXY_AUTHORIZATION = MIME_LEN_PROXY_AUTHORIZATION;
    TS_MIME_LEN_PROXY_CONNECTION = MIME_LEN_PROXY_CONNECTION;
    TS_MIME_LEN_PUBLIC = MIME_LEN_PUBLIC;
    TS_MIME_LEN_RANGE = MIME_LEN_RANGE;
    TS_MIME_LEN_REFERENCES = MIME_LEN_REFERENCES;
    TS_MIME_LEN_REFERER = MIME_LEN_REFERER;
    TS_MIME_LEN_REPLY_TO = MIME_LEN_REPLY_TO;
    TS_MIME_LEN_RETRY_AFTER = MIME_LEN_RETRY_AFTER;
    TS_MIME_LEN_SENDER = MIME_LEN_SENDER;
    TS_MIME_LEN_SERVER = MIME_LEN_SERVER;
    TS_MIME_LEN_SET_COOKIE = MIME_LEN_SET_COOKIE;
    TS_MIME_LEN_SUBJECT = MIME_LEN_SUBJECT;
    TS_MIME_LEN_SUMMARY = MIME_LEN_SUMMARY;
    TS_MIME_LEN_TE = MIME_LEN_TE;
    TS_MIME_LEN_TRANSFER_ENCODING = MIME_LEN_TRANSFER_ENCODING;
    TS_MIME_LEN_UPGRADE = MIME_LEN_UPGRADE;
    TS_MIME_LEN_USER_AGENT = MIME_LEN_USER_AGENT;
    TS_MIME_LEN_VARY = MIME_LEN_VARY;
    TS_MIME_LEN_VIA = MIME_LEN_VIA;
    TS_MIME_LEN_WARNING = MIME_LEN_WARNING;
    TS_MIME_LEN_WWW_AUTHENTICATE = MIME_LEN_WWW_AUTHENTICATE;
    TS_MIME_LEN_XREF = MIME_LEN_XREF;
    TS_MIME_LEN_X_FORWARDED_FOR = MIME_LEN_X_FORWARDED_FOR;


    /* HTTP methods */
    TS_HTTP_METHOD_CONNECT = HTTP_METHOD_CONNECT;
    TS_HTTP_METHOD_DELETE = HTTP_METHOD_DELETE;
    TS_HTTP_METHOD_GET = HTTP_METHOD_GET;
    TS_HTTP_METHOD_HEAD = HTTP_METHOD_HEAD;
    TS_HTTP_METHOD_ICP_QUERY = HTTP_METHOD_ICP_QUERY;
    TS_HTTP_METHOD_OPTIONS = HTTP_METHOD_OPTIONS;
    TS_HTTP_METHOD_POST = HTTP_METHOD_POST;
    TS_HTTP_METHOD_PURGE = HTTP_METHOD_PURGE;
    TS_HTTP_METHOD_PUT = HTTP_METHOD_PUT;
    TS_HTTP_METHOD_TRACE = HTTP_METHOD_TRACE;

    TS_HTTP_LEN_CONNECT = HTTP_LEN_CONNECT;
    TS_HTTP_LEN_DELETE = HTTP_LEN_DELETE;
    TS_HTTP_LEN_GET = HTTP_LEN_GET;
    TS_HTTP_LEN_HEAD = HTTP_LEN_HEAD;
    TS_HTTP_LEN_ICP_QUERY = HTTP_LEN_ICP_QUERY;
    TS_HTTP_LEN_OPTIONS = HTTP_LEN_OPTIONS;
    TS_HTTP_LEN_POST = HTTP_LEN_POST;
    TS_HTTP_LEN_PURGE = HTTP_LEN_PURGE;
    TS_HTTP_LEN_PUT = HTTP_LEN_PUT;
    TS_HTTP_LEN_TRACE = HTTP_LEN_TRACE;

    /* HTTP miscellaneous values */
    TS_HTTP_VALUE_BYTES = HTTP_VALUE_BYTES;
    TS_HTTP_VALUE_CHUNKED = HTTP_VALUE_CHUNKED;
    TS_HTTP_VALUE_CLOSE = HTTP_VALUE_CLOSE;
    TS_HTTP_VALUE_COMPRESS = HTTP_VALUE_COMPRESS;
    TS_HTTP_VALUE_DEFLATE = HTTP_VALUE_DEFLATE;
    TS_HTTP_VALUE_GZIP = HTTP_VALUE_GZIP;
    TS_HTTP_VALUE_IDENTITY = HTTP_VALUE_IDENTITY;
    TS_HTTP_VALUE_KEEP_ALIVE = HTTP_VALUE_KEEP_ALIVE;
    TS_HTTP_VALUE_MAX_AGE = HTTP_VALUE_MAX_AGE;
    TS_HTTP_VALUE_MAX_STALE = HTTP_VALUE_MAX_STALE;
    TS_HTTP_VALUE_MIN_FRESH = HTTP_VALUE_MIN_FRESH;
    TS_HTTP_VALUE_MUST_REVALIDATE = HTTP_VALUE_MUST_REVALIDATE;
    TS_HTTP_VALUE_NONE = HTTP_VALUE_NONE;
    TS_HTTP_VALUE_NO_CACHE = HTTP_VALUE_NO_CACHE;
    TS_HTTP_VALUE_NO_STORE = HTTP_VALUE_NO_STORE;
    TS_HTTP_VALUE_NO_TRANSFORM = HTTP_VALUE_NO_TRANSFORM;
    TS_HTTP_VALUE_ONLY_IF_CACHED = HTTP_VALUE_ONLY_IF_CACHED;
    TS_HTTP_VALUE_PRIVATE = HTTP_VALUE_PRIVATE;
    TS_HTTP_VALUE_PROXY_REVALIDATE = HTTP_VALUE_PROXY_REVALIDATE;
    TS_HTTP_VALUE_PUBLIC = HTTP_VALUE_PUBLIC;
    TS_HTTP_VALUE_S_MAXAGE = HTTP_VALUE_S_MAXAGE;

    TS_HTTP_LEN_BYTES = HTTP_LEN_BYTES;
    TS_HTTP_LEN_CHUNKED = HTTP_LEN_CHUNKED;
    TS_HTTP_LEN_CLOSE = HTTP_LEN_CLOSE;
    TS_HTTP_LEN_COMPRESS = HTTP_LEN_COMPRESS;
    TS_HTTP_LEN_DEFLATE = HTTP_LEN_DEFLATE;
    TS_HTTP_LEN_GZIP = HTTP_LEN_GZIP;
    TS_HTTP_LEN_IDENTITY = HTTP_LEN_IDENTITY;
    TS_HTTP_LEN_KEEP_ALIVE = HTTP_LEN_KEEP_ALIVE;
    TS_HTTP_LEN_MAX_AGE = HTTP_LEN_MAX_AGE;
    TS_HTTP_LEN_MAX_STALE = HTTP_LEN_MAX_STALE;
    TS_HTTP_LEN_MIN_FRESH = HTTP_LEN_MIN_FRESH;
    TS_HTTP_LEN_MUST_REVALIDATE = HTTP_LEN_MUST_REVALIDATE;
    TS_HTTP_LEN_NONE = HTTP_LEN_NONE;
    TS_HTTP_LEN_NO_CACHE = HTTP_LEN_NO_CACHE;
    TS_HTTP_LEN_NO_STORE = HTTP_LEN_NO_STORE;
    TS_HTTP_LEN_NO_TRANSFORM = HTTP_LEN_NO_TRANSFORM;
    TS_HTTP_LEN_ONLY_IF_CACHED = HTTP_LEN_ONLY_IF_CACHED;
    TS_HTTP_LEN_PRIVATE = HTTP_LEN_PRIVATE;
    TS_HTTP_LEN_PROXY_REVALIDATE = HTTP_LEN_PROXY_REVALIDATE;
    TS_HTTP_LEN_PUBLIC = HTTP_LEN_PUBLIC;
    TS_HTTP_LEN_S_MAXAGE = HTTP_LEN_S_MAXAGE;

    http_global_hooks = NEW(new HttpAPIHooks);
    lifecycle_hooks = NEW(new LifecycleAPIHooks);
    global_config_cbs = NEW(new ConfigUpdateCbTable);

    if (TS_MAX_API_STATS > 0) {
      api_rsb = RecAllocateRawStatBlock(TS_MAX_API_STATS);
      if (NULL == api_rsb) {
        Warning("Can't allocate API stats block");
      } else {
        Debug("sdk", "initialized SDK stats APIs with %d slots", TS_MAX_API_STATS);
      }
    } else {
      api_rsb = NULL;
    }

    memset(state_arg_table, 0, sizeof(state_arg_table));

    // Setup the version string for returning to plugins
    ink_strlcpy(traffic_server_version, appVersionInfo.VersionStr, sizeof(traffic_server_version));
    // Extract the elements.
    // coverity[secure_coding]
    if (sscanf(traffic_server_version, "%d.%d.%d", &ts_major_version, &ts_minor_version, &ts_patch_version) != 3) {
      Warning("Unable to parse traffic server version string '%s'\n", traffic_server_version);
    }

  }
}

////////////////////////////////////////////////////////////////////
//
// 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
//
////////////////////////////////////////////////////////////////////

unsigned int
TSrandom()
{
  return this_ethread()->generator.random();
}

double
TSdrandom()
{
  return this_ethread()->generator.drandom();
}

ink_hrtime
TShrtime()
{
  return ink_get_based_hrtime();
}

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

const char *
TSInstallDirGet(void)
{
  return system_root_dir;
}

const char *
TSConfigDirGet(void)
{
  return system_config_directory;
}

const char *
TSTrafficServerVersionGet(void)
{
  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(void)
{
  static char path[PATH_NAME_MAX + 1] = "";

  if (*path == '\0') {
    char *plugin_dir = NULL;
    RecGetRecordString_Xmalloc("proxy.config.plugin.plugin_dir", &plugin_dir);
    if (!plugin_dir) {
      Error("Unable to read proxy.config.plugin.plugin_dir");
      return NULL;
    }
    Layout::relative_to(path, sizeof(path),
                        Layout::get()->prefix, plugin_dir);
    ats_free(plugin_dir);
  }

  return path;
}

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

TSReturnCode
TSPluginRegister(TSSDKVersion sdk_version, TSPluginRegistrationInfo *plugin_info)
{
  PluginSDKVersion version = (PluginSDKVersion)sdk_version;

  if (!plugin_reg_current)
    return TS_ERROR;

  sdk_assert(sdk_sanity_check_null_ptr((void*) plugin_info) == TS_SUCCESS);

  plugin_reg_current->plugin_registered = true;

  // We're compatible only within the 3.x release
  if (version >= PLUGIN_SDK_VERSION_3_0 && version < PLUGIN_SDK_VERSION_4_0) {
    plugin_reg_current->sdk_version = version;
  } else {
    plugin_reg_current->sdk_version = PLUGIN_SDK_VERSION_UNKNOWN;
  }

  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;
}

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

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

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

  return (TSFile)file;
}

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

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

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

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

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

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

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

  if (mloc == TS_NULL_MLOC)
    return TS_SUCCESS;

  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);

  switch (obj->m_type) {
  case HDR_HEAP_OBJ_URL:
  case HDR_HEAP_OBJ_HTTP_HEADER:
  case HDR_HEAP_OBJ_MIME_HEADER:
    return TS_SUCCESS;

  case HDR_HEAP_OBJ_FIELD_SDK_HANDLE:
    field_handle = (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(void)
{
  TSMBuffer bufp;
  HdrHeapSDKHandle *new_heap = NEW(new HdrHeapSDKHandle);

  new_heap->m_heap = new_HdrHeap();
  bufp = (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 = (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 = ((HdrHeapSDKHandle *) bufp)->m_heap;
    *locp = (TSMLoc)url_create(heap);
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

TSReturnCode
TSUrlDestroy(TSMBuffer /* bufp ATS_UNUSED */, TSMLoc /* url_loc ATS_UNUSED */)
{
  return TS_SUCCESS;
}

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 = ((HdrHeapSDKHandle *) src_bufp)->m_heap;
  d_heap = ((HdrHeapSDKHandle *) dest_bufp)->m_heap;
  s_url = (URLImpl *) src_url;

  d_url = url_copy(s_url, s_heap, d_heap, (s_heap != d_heap));
  *locp = (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 = ((HdrHeapSDKHandle *) src_bufp)->m_heap;
  d_heap = ((HdrHeapSDKHandle *) dest_bufp)->m_heap;
  s_url = (URLImpl *) src_obj;
  d_url = (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 = (MIOBuffer *) iobufp;
  IOBufferBlock *blk;
  int bufindex;
  int tmp, dumpoffset;
  int done;
  URL u;

  u.m_heap = ((HdrHeapSDKHandle *) bufp)->m_heap;
  u.m_url_impl = (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 = ((HdrHeapSDKHandle *) bufp)->m_heap;
  u.m_url_impl = (URLImpl *) obj;
  url_clear(u.m_url_impl);
  return (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 = (URLImpl *) obj;
  return url_length_get(url_impl);
}

char *
TSUrlStringGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  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 = (URLImpl *) obj;
  return url_string_get(url_impl, NULL, length, NULL);
}

typedef const char *(URL::*URLPartGetF) (int *length);
typedef void (URL::*URLPartSetF) (const char *value, int length);

static const char *
URLPartGet(TSMBuffer bufp, TSMLoc obj, int *length, URLPartGetF url_f)
{
  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);

  URL u;

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

  return (u.*url_f)(length);
}

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 = ((HdrHeapSDKHandle *) bufp)->m_heap;
  u.m_url_impl = (URLImpl *) obj;

  if (!value)
    length = 0;
  else if (length < 0)
    length = strlen(value);
  (u.*url_f)(value, length);

  return TS_SUCCESS;
}

const char *
TSUrlSchemeGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  return URLPartGet(bufp, obj, length, &URL::scheme_get);
}

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)
{
  return URLPartGet(bufp, obj, length, &URL::user_get);
}

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)
{
  return URLPartGet(bufp, obj, length, &URL::password_get);
}

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)
{
  return URLPartGet(bufp, obj, length, &URL::host_get);
}

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 = ((HdrHeapSDKHandle *) bufp)->m_heap;
  u.m_url_impl = (URLImpl *) obj;

  return u.port_get();
}

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 = ((HdrHeapSDKHandle *) bufp)->m_heap;
  u.m_url_impl = (URLImpl *) obj;
  u.port_set(port);
  return TS_SUCCESS;
}

/* FTP and HTTP specific URLs  */

const char *
TSUrlPathGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  return URLPartGet(bufp, obj, length, &URL::path_get);
}

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 = ((HdrHeapSDKHandle *) bufp)->m_heap;
  u.m_url_impl = (URLImpl *) obj;
  return u.type_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 = ((HdrHeapSDKHandle *) bufp)->m_heap;
    u.m_url_impl = (URLImpl *) obj;
    u.type_set(type);
    return TS_SUCCESS;
  }

  return TS_ERROR;
}

/* HTTP specific URLs */

const char *
TSUrlHttpParamsGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  return URLPartGet(bufp, obj, length, &URL::params_get);
}

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

const char *
TSUrlHttpQueryGet(TSMBuffer bufp, TSMLoc obj, int *length)
{
  return URLPartGet(bufp, obj, length, &URL::query_get);
}

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)
{
  return URLPartGet(bufp, obj, length, &URL::fragment_get);
}

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...
  if (NULL == LogUtils::escapify_url(NULL, 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);
  *buffer = '\0';
  if (length)
    *length = (buffer - dst);

  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 = (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, NULL, &url_len, NULL);
  ret = TSStringPercentEncode(url, url_len, dst, dst_size, length, map);
  ats_free(url);

  return ret;
}


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

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

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

  mime_parser_init((MIMEParser *) parser);
  return parser;
}

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

  mime_parser_clear((MIMEParser *) parser);
}

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

  mime_parser_clear((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, return NULL.
  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(((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(((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, return NULL.
  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 = ((HdrHeapSDKHandle *) src_bufp)->m_heap;
  d_heap = ((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 = (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 = ((HdrHeapSDKHandle *) src_bufp)->m_heap;
  d_heap = ((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(TSMBuffer bufp, TSMLoc obj, TSIOBuffer iobufp)
{
  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_iocore_structure(iobufp) == TS_SUCCESS);

  HdrHeap *heap = ((HdrHeapSDKHandle *) bufp)->m_heap;
  MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(obj);
  MIOBuffer *b = (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(heap, 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 (TSParseResult)mime_parser_parse((MIMEParser *) parser, ((HdrHeapSDKHandle *) bufp)->m_heap, mh,
                                          start, end, 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(((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.
const char *
TSMimeFieldValueGet(TSMBuffer /* bufp ATS_UNUSED */, TSMLoc field_obj, int idx, int *value_len_ptr)
{
  MIMEFieldSDKHandle *handle = (MIMEFieldSDKHandle *) field_obj;

  if (idx >= 0) {
    return mime_field_value_get_comma_val(handle->field_ptr, value_len_ptr, idx);
  } else {
    return mime_field_value_get(handle->field_ptr, value_len_ptr);
  }

  *value_len_ptr = 0;
  return NULL;
}

void
TSMimeFieldValueSet(TSMBuffer bufp, TSMLoc field_obj, int idx, const char *value, int length)
{
  MIMEFieldSDKHandle *handle = (MIMEFieldSDKHandle *) field_obj;
  HdrHeap *heap = ((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, value, length);
  else
    mime_field_value_set(heap, handle->mh, handle->field_ptr, value, length, true);
}

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

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

  mime_field_value_insert_comma_val(heap, handle->mh, handle->field_ptr, idx, value, length);
}


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

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

int
TSMimeHdrFieldEqual(TSMBuffer bufp, TSMLoc hdr_obj, TSMLoc field1_obj, TSMLoc field2_obj)
{
  sdk_assert(sdk_sanity_check_mbuffer(bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_field_handle(field1_obj, hdr_obj) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_field_handle(field2_obj, hdr_obj) == TS_SUCCESS);

  MIMEFieldSDKHandle *field1_handle = (MIMEFieldSDKHandle *) field1_obj;
  MIMEFieldSDKHandle *field2_handle = (MIMEFieldSDKHandle *) field2_obj;

  if ((field1_handle == NULL) || (field2_handle == NULL))
    return (field1_handle == field2_handle);
  return (field1_handle->field_ptr == field2_handle->field_ptr);
}

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 == NULL)
    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, name, length);

  if (f == NULL)
    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 = (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 == NULL) {
    HdrHeap *heap = (HdrHeap *) (((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, NULL);
  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 = (MIMEFieldSDKHandle *) field_mloc;

  if (field_handle->mh != NULL) {
    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 = (MIMEFieldSDKHandle *) field_mloc;

  if (field_handle->mh == NULL) { // NOT SUPPORTED!!
    ink_release_assert(!"Failed MH");
  } else {
    MIMEHdrImpl *mh = _hdr_mloc_to_mime_hdr_impl(mh_mloc);
    HdrHeap *heap = (HdrHeap *) (((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, return NULL.
  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 = (HdrHeap *) (((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 = (HdrHeap *) (((HdrHeapSDKHandle *) bufp)->m_heap);
  MIMEFieldSDKHandle *h = sdk_alloc_field_handle(bufp, mh);
  h->field_ptr = mime_field_create_named(heap, mh, name, 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 = (MIMEFieldSDKHandle *) src_field;
  MIMEFieldSDKHandle *d_handle = (MIMEFieldSDKHandle *) dest_field;
  HdrHeap *d_heap = ((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,
                            s_handle->field_ptr->m_ptr_name,
                            s_handle->field_ptr->m_len_name,
                            s_handle->field_ptr->m_ptr_value, 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, NULL);
  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, return NULL.
  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 = (MIMEFieldSDKHandle *) src_field;
  MIMEFieldSDKHandle *d_handle = (MIMEFieldSDKHandle *) dest_field;
  HdrHeap *d_heap = ((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, s_field->m_ptr_value, s_field->m_len_value, true);
  return TS_SUCCESS;
}

// TODO: This is implemented horribly slowly, but who's using it anyway?
//       If we threaded all the MIMEFields, this function could be easier,
//       but we'd have to print dups in order and we'd need a flag saying
//       end of dup list or dup follows.
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);

  MIMEFieldSDKHandle *handle = (MIMEFieldSDKHandle *) field;

  if (handle->mh == NULL)
    return TS_NULL_MLOC;

  int slotnum = mime_hdr_field_slotnum(handle->mh, handle->field_ptr);
  if (slotnum == -1)
    return TS_NULL_MLOC;

  while (1) {
    ++slotnum;
    MIMEField *f = mime_hdr_field_get_slotnum(handle->mh, slotnum);

    if (f == NULL)
      return TS_NULL_MLOC;
    if (f->is_live()) {
      MIMEFieldSDKHandle *h = sdk_alloc_field_handle(bufp, handle->mh);
      
      h->field_ptr = f;
      return reinterpret_cast<TSMLoc>(h);
    }
  }
  return TS_NULL_MLOC; // Shouldn't happen.
}

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 = (MIMEFieldSDKHandle *) field;
  MIMEField *next = field_handle->field_ptr->m_next_dup;
  if (next == NULL)
    return TS_NULL_MLOC;

  MIMEFieldSDKHandle *next_handle = sdk_alloc_field_handle(bufp, mh);
  next_handle->field_ptr = next;
  return (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 = (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 = (MIMEFieldSDKHandle *) field;
  return mime_field_name_get(handle->field_ptr, length);
}

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 = (MIMEFieldSDKHandle *) field;
  HdrHeap *heap = ((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, name, length);

  if (attached)
    mime_hdr_field_attach(handle->mh, handle->field_ptr, 1, NULL);
  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 = (MIMEFieldSDKHandle *) field;
  HdrHeap *heap = ((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, NULL, 0, 1);
  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 = (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 == NULL)
    return (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 == NULL)
    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 == NULL)
    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 == NULL)
    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
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 = (MIMEFieldSDKHandle *) field;
  HdrHeap *heap = ((HdrHeapSDKHandle *) bufp)->m_heap;

  if (length == -1)
    length = strlen(value);
  mime_field_value_extend_comma_val(heap, handle->mh, handle->field_ptr, idx, value, 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 exisiting 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 = (MIMEFieldSDKHandle *) field;
  HdrHeap *heap = ((HdrHeapSDKHandle *) bufp)->m_heap;

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

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

  return parser;
}

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

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

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


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

  HTTPHdr h;
  h.m_heap = ((HdrHeapSDKHandle *) bufp)->m_heap;
  h.create(HTTP_TYPE_UNKNOWN);
  return (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, return NULL.
  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 = ((HdrHeapSDKHandle *) src_bufp)->m_heap;
  d_heap = ((HdrHeapSDKHandle *) dest_bufp)->m_heap;
  s_hh = (HTTPHdrImpl *) src_hdr;

  if (s_hh->m_type != HDR_HEAP_OBJ_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 = (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 = ((HdrHeapSDKHandle *) src_bufp)->m_heap;
  d_heap = ((HdrHeapSDKHandle *) dest_bufp)->m_heap;
  s_hh = (HTTPHdrImpl *) src_obj;
  d_hh = (HTTPHdrImpl *) dest_obj;

  if ((s_hh->m_type != HDR_HEAP_OBJ_HTTP_HEADER) || (d_hh->m_type != HDR_HEAP_OBJ_HTTP_HEADER))
    return TS_ERROR;

  inherit_strs = (s_heap != d_heap ? true : false);
  TSHttpHdrTypeSet(dest_bufp, dest_obj, (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 = (MIOBuffer *) iobufp;
  IOBufferBlock *blk;
  HTTPHdr h;
  int bufindex;
  int tmp, dumpoffset;
  int done;

  SET_HTTP_HDR(h, bufp, obj);
  ink_assert(h.m_http->m_type == HDR_HEAP_OBJ_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(h.m_http->m_type == HDR_HEAP_OBJ_HTTP_HEADER);
  TSHttpHdrTypeSet(bufp, obj, TS_HTTP_TYPE_REQUEST);
  return (TSParseResult)h.parse_req((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(h.m_http->m_type == HDR_HEAP_OBJ_HTTP_HEADER);
  TSHttpHdrTypeSet(bufp, obj, TS_HTTP_TYPE_RESPONSE);
  return (TSParseResult)h.parse_resp((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(h.m_http->m_type == HDR_HEAP_OBJ_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 == HDR_HEAP_OBJ_HTTP_HEADER);
   */
  return (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(h.m_http->m_type == HDR_HEAP_OBJ_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 == HTTP_TYPE_UNKNOWN) {
    if (type == (TSHttpType) HTTP_TYPE_REQUEST) {
      h.m_http->u.req.m_url_impl = url_create(h.m_heap);
      h.m_http->m_polarity = (HTTPType) type;
    } else if (type == (TSHttpType) HTTP_TYPE_RESPONSE) {
      h.m_http->m_polarity = (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.m_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(h.m_http->m_type == HDR_HEAP_OBJ_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);
  return h.method_get(length);
}

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(value, length);
  return TS_SUCCESS;
}

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 = (HTTPHdrImpl *) obj;

  if (hh->m_polarity != HTTP_TYPE_REQUEST)
    return TS_ERROR;

  *locp = ((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 = ((HdrHeapSDKHandle *) bufp)->m_heap;
  HTTPHdrImpl *hh = (HTTPHdrImpl *) obj;

  if (hh->m_type != HDR_HEAP_OBJ_HTTP_HEADER)
    return TS_ERROR;

  URLImpl *url_impl = (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 (TSHttpStatus)h.status_get();
}

TSReturnCode
TSHttpHdrStatusSet(TSMBuffer bufp, TSMLoc obj, TSHttpStatus status)
{
  // 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(h.m_http->m_type == HDR_HEAP_OBJ_HTTP_HEADER);
  h.status_set((HTTPStatus) status);
  return TS_SUCCESS;
}

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);
  return h.reason_get(length);
}

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 == HDR_HEAP_OBJ_HTTP_HEADER);
  */

  if (length < 0)
    length = strlen(value);
  h.reason_set(value, length);
  return TS_SUCCESS;
}

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


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

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

  return TS_SUCCESS;
}

TSCacheKey
TSCacheKeyCreate(void)
{
  TSCacheKey key = (TSCacheKey)NEW(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);
  
  if (((CacheInfo *) key)->magic != CACHE_INFO_MAGIC_ALIVE)
    return TS_ERROR;

  ((CacheInfo *) key)->cache_key.encodeBuffer((char *) input, length);
  return TS_SUCCESS;
}

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

  if (((CacheInfo *) key)->magic != CACHE_INFO_MAGIC_ALIVE)
    return TS_ERROR;

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

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

  if (((CacheInfo *) key)->magic != CACHE_INFO_MAGIC_ALIVE)
    return TS_ERROR;

  switch (type) {
  case TS_CACHE_DATA_TYPE_NONE:
    ((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:
    ((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 (((CacheInfo *) key)->magic != CACHE_INFO_MAGIC_ALIVE)
    return TS_ERROR;

  CacheInfo *i = (CacheInfo *) key;
  /* need to make a copy of the hostname. The caller
     might deallocate it anytime in the future */
  i->hostname = (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 (((CacheInfo *) key)->magic != CACHE_INFO_MAGIC_ALIVE)
    return TS_ERROR;

  CacheInfo *i = (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 (((CacheInfo *) key)->magic != CACHE_INFO_MAGIC_ALIVE)
    return TS_ERROR;

  CacheInfo *i = (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(new CacheHTTPInfo);

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

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

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


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

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

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

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

int64_t
TSCacheHttpInfoSizeGet(TSCacheHttpInfo infop)
{
  CacheHTTPInfo *info = (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 = (CacheHTTPInfo *) infop;
  info->request_set(&h);
}


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

  SET_HTTP_HDR(h, bufp, obj);

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


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

  vector.insert(info);

  int size = vector.marshal_length();

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

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


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

TSCacheHttpInfo
TSCacheHttpInfoCreate(void)
{
  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(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, (ConfigInfo *) configp);
}

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

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

void
TSMgmtUpdateRegister(TSCont contp, const char *plugin_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((INKContInternal *)contp, plugin_name);
}

TSReturnCode
TSMgmtIntGet(const char *var_name, TSMgmtInt *result)
{
  return RecGetRecordInt((char *) var_name, (RecInt *) result) == REC_ERR_OKAY ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSMgmtCounterGet(const char *var_name, TSMgmtCounter *result)
{
  return RecGetRecordCounter((char *) var_name, (RecCounter *) result) == REC_ERR_OKAY ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSMgmtFloatGet(const char *var_name, TSMgmtFloat *result)
{
  return RecGetRecordFloat((char *) var_name, (RecFloat *) result) == REC_ERR_OKAY ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSMgmtStringGet(const char *var_name, TSMgmtString *result)
{
  RecString tmp = 0;
  (void) RecGetRecordString_Xmalloc((char *) var_name, &tmp);

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

  return TS_ERROR;
}

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

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

  INKContInternal *i = INKContAllocator.alloc();

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

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

  INKContInternal *i = (INKContInternal *) contp;

  i->destroy();
}

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

  INKContInternal *i = (INKContInternal *) contp;

  i->mdata = data;
}

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

  INKContInternal *i = (INKContInternal *) contp;

  return i->mdata;
}

TSAction
TSContSchedule(TSCont contp, ink_hrtime timeout, TSThreadPool tp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  FORCE_PLUGIN_MUTEX(contp);

  INKContInternal *i = (INKContInternal *) contp;
  TSAction action;

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

  EventType etype;

  switch (tp) {
  case TS_THREAD_POOL_NET:
  case TS_THREAD_POOL_DEFAULT:
    etype = ET_NET;
    break;
  case TS_THREAD_POOL_TASK:
      etype = ET_TASK;
      break;
  case TS_THREAD_POOL_SSL:
    etype = ET_TASK; // Should be ET_SSL
    break;
  case TS_THREAD_POOL_DNS:
    etype = ET_DNS;
    break;
  case TS_THREAD_POOL_REMAP:
    etype = ET_TASK; // Should be ET_REMAP
    break;
  case TS_THREAD_POOL_CLUSTER:
    etype = ET_CLUSTER;
    break;
  case TS_THREAD_POOL_UDP:
    etype = ET_UDP;
    break;
  default:
    etype = ET_TASK;
    break;
  }

  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 = (TSAction) ((uintptr_t) action | 0x1);
  return action;
}

TSAction
TSContScheduleEvery(TSCont contp, ink_hrtime every, TSThreadPool tp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(contp) == TS_SUCCESS);

  FORCE_PLUGIN_MUTEX(contp);

  INKContInternal *i = (INKContInternal *) contp;
  TSAction action;

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

  EventType etype;

  switch (tp) {
  case TS_THREAD_POOL_NET:
  case TS_THREAD_POOL_DEFAULT:
    etype = ET_NET;
    break;
  case TS_THREAD_POOL_TASK:
    etype = ET_TASK;
    break;
  default:
    etype = ET_TASK;
    break;
  }

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

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

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

  FORCE_PLUGIN_MUTEX(contp);

  INKContInternal *i = (INKContInternal *) contp;

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

  TSAction action;
  Continuation *cont  = (Continuation*)contp;
  HttpSM *sm = (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 = (TSAction) ((uintptr_t) action | 0x1);
  return action;
}

int
TSContCall(TSCont contp, TSEvent event, void *edata)
{
  Continuation *c = (Continuation *) contp;
  return c->handleEvent((int) event, edata);
}

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

  Continuation *c = (Continuation *)contp;
  return (TSMutex) ((ProxyMutex *)c->mutex);
}


/* HTTP hooks */

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

  http_global_hooks->append(id, (INKContInternal *)contp);
}

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);

  lifecycle_hooks->append(id, (INKContInternal *)contp);
}

void
TSHttpIcpDynamicSet(int value)
{
  int32_t old_value, new_value;

  new_value = (value == 0) ? 0 : 1;
  old_value = icp_dynamic_enabled;
  while (old_value != new_value) {
    if (ink_atomic_cas(&icp_dynamic_enabled, old_value, new_value))
      break;
    old_value = icp_dynamic_enabled;
  }
}

/* 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);

  HttpClientSession *cs = (HttpClientSession *) ssnp;
  cs->ssn_hook_append(id, (INKContInternal *) contp);
}

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

  HttpClientSession* cs = (HttpClientSession*)ssnp;
  return cs->get_transact_count();
}

class TSHttpSsnCallback : public Continuation
{
public:
  TSHttpSsnCallback(HttpClientSession *cs, TSEvent event)
    : Continuation(cs->mutex), m_cs(cs), m_event(event)
  {
    SET_HANDLER(&TSHttpSsnCallback::event_handler);
  }

  int event_handler(int, void*)
  {
    m_cs->handleEvent((int) m_event, 0);
    delete this;
    return 0;
  }

private:
  HttpClientSession *m_cs;
  TSEvent m_event;
};


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

  HttpClientSession *cs = (HttpClientSession *) 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.
  if (eth->tt != REGULAR) {
    eventProcessor.schedule_imm(NEW(new TSHttpSsnCallback(cs, event)), ET_NET);
  } else {
    MUTEX_TRY_LOCK(trylock, cs->mutex, eth);
    if (!trylock) {
      eventProcessor.schedule_imm(NEW(new TSHttpSsnCallback(cs, event)), ET_NET);
    } else {
      cs->handleEvent((int) event, 0);
    }
  }
}


/* 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 = (HttpSM *) txnp;
  sm->txn_hook_append(id, (INKContInternal *) contp);
}


// Private api function for gzip plugin.
//  This function should only appear in TsapiPrivate.h
TSReturnCode
TSHttpTxnHookRegisteredFor(TSHttpTxn txnp, TSHttpHookID id, TSEventFunc funcp)
{
  HttpSM *sm = (HttpSM *) txnp;
  APIHook *hook = sm->txn_hook_get(id);

  while (hook != NULL) {
    if (hook->m_cont && hook->m_cont->m_event_func == funcp) {
      return TS_SUCCESS;
    }
    hook = hook->m_link.next;
  }

  return TS_ERROR;
}

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

  HttpSM *sm = (HttpSM *) txnp;
  return (TSHttpSsn)sm->ua_session;
}

// TODO: Is this still necessary ??
void
TSHttpTxnClientKeepaliveSet(TSHttpTxn txnp, int set)
{
  HttpSM *sm = (HttpSM *) txnp;
  HttpTransact::State *s = &(sm->t_state);

  s->hdr_info.trust_response_cl = (set != 0) ? true : false;
}

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 = (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 = (HttpSM*) txnp;
  HTTPHdr *hptr = &(sm->t_state.hdr_info.client_request);

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

    if ((sdk_sanity_check_mbuffer(*bufp) == TS_SUCCESS) && (*url_loc))
      return TS_SUCCESS;
  }
  return TS_ERROR;
}

// Shortcut to just get the URL.
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(0, length);
}

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 = (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_sanity_check_mbuffer(*bufp);
    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 = (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_sanity_check_mbuffer(*bufp);
    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 = (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_sanity_check_mbuffer(*bufp);
    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 = (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 == NULL) {
    *handle = (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_sanity_check_mbuffer(*bufp);

  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 = (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 == NULL) {
    *handle = (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_sanity_check_mbuffer(*bufp);

  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 = (HttpSM *) txnp;
  HttpTransact::State *s = &(sm->t_state);
  HTTPHdr *c_resp = NULL;
  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 == NULL || !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 != NULL && c_resp->valid());
  *(reinterpret_cast<HTTPHdr**>(bufp)) = c_resp;
  *obj = reinterpret_cast<TSMLoc>(c_resp->m_http);
  sdk_sanity_check_mbuffer(*bufp);

  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 = (HttpSM *) txnp;

  switch (sm->t_state.cache_lookup_result) {
  case HttpTransact::CACHE_LOOKUP_MISS:
  case HttpTransact::CACHE_LOOKUP_DOC_BUSY:
    *lookup_status = TS_CACHE_LOOKUP_MISS;
    break;
  case HttpTransact::CACHE_LOOKUP_HIT_STALE:
    *lookup_status = TS_CACHE_LOOKUP_HIT_STALE;
    break;
  case HttpTransact::CACHE_LOOKUP_HIT_WARNING:
  case HttpTransact::CACHE_LOOKUP_HIT_FRESH:
    *lookup_status = TS_CACHE_LOOKUP_HIT_FRESH;
    break;
  case HttpTransact::CACHE_LOOKUP_SKIPPED:
    *lookup_status = TS_CACHE_LOOKUP_SKIPPED;
    break;
  case HttpTransact::CACHE_LOOKUP_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 = (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 = (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::CACHE_LOOKUP_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::CACHE_LOOKUP_MISS) {
    sm->t_state.api_cleanup_cache_read = true;
    ink_assert(sm->t_state.transact_return_point != NULL);
    sm->t_state.transact_return_point = HttpTransact::HandleCacheOpenRead;
  }

  switch (cachelookup) {
  case TS_CACHE_LOOKUP_MISS:
    *sm_status = HttpTransact::CACHE_LOOKUP_MISS;
    break;
  case TS_CACHE_LOOKUP_HIT_STALE:
    *sm_status = HttpTransact::CACHE_LOOKUP_HIT_STALE;
    break;
  case TS_CACHE_LOOKUP_HIT_FRESH:
    *sm_status = HttpTransact::CACHE_LOOKUP_HIT_FRESH;
    break;
  default:
    return TS_ERROR;
  }

  return TS_SUCCESS;
}

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 = (HttpSM *) txnp;
  URL u, *l_url;

  u.m_heap = ((HdrHeapSDKHandle *) bufp)->m_heap;
  u.m_url_impl = (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;
}

// TS-1996: This API will be removed after v3.4.0 is cut. Do not use it!
TSReturnCode
TSHttpTxnNewCacheLookupDo(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc url_loc)
{
  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(url_loc) == TS_SUCCESS);

  URL new_url, *client_url, *l_url, *o_url;
  INK_MD5 md51, md52;

  new_url.m_heap = ((HdrHeapSDKHandle *) bufp)->m_heap;
  new_url.m_url_impl = (URLImpl *) url_loc;
  if (!new_url.valid())
    return TS_ERROR;

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

  client_url = s->hdr_info.client_request.url_get();
  if (!(client_url->valid()))
    return TS_ERROR;

  // if l_url is not valid, then no cache lookup has been done yet
  // so we shouldn't be calling TSHttpTxnNewCacheLookupDo right now
  l_url = s->cache_info.lookup_url;
  if (!l_url || !l_url->valid()) {
    s->cache_info.lookup_url_storage.create(NULL);
    s->cache_info.lookup_url = &(s->cache_info.lookup_url_storage);
    l_url = s->cache_info.lookup_url;
  } else {
    l_url->MD5_get(&md51);
    new_url.MD5_get(&md52);
    if (md51 == md52)
      return TS_ERROR;
    o_url = &(s->cache_info.original_url);
    if (!o_url->valid()) {
      o_url->create(NULL);
      o_url->copy(l_url);
    }
  }

  // copy the new_url to lookup_url
  l_url->copy(&new_url);

  // bypass HttpTransact::HandleFiltering
  s->transact_return_point = HttpTransact::DecideCacheLookup;
  s->cache_info.action = HttpTransact::CACHE_DO_LOOKUP;
  sm->add_cache_sm();
  s->api_cleanup_cache_read = true;

  return TS_SUCCESS;
}

// TS-1996: This API will be removed after v3.4.0 is cut. Do not use it!
TSReturnCode
TSHttpTxnSecondUrlTryLock(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM *) txnp;
  HttpTransact::State *s = &(sm->t_state);
  // TSHttpTxnNewCacheLookupDo didn't continue
  if (!s->cache_info.original_url.valid())
    return TS_ERROR;
  sm->add_cache_sm();
  s->api_lock_url = HttpTransact::LOCK_URL_SECOND;

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnFollowRedirect(TSHttpTxn txnp, int on)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM *) txnp;

  sm->api_enable_redirection = (on ? true : false);
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnRedirectRequest(TSHttpTxn txnp, TSMBuffer bufp, TSMLoc url_loc)
{
  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(url_loc) == TS_SUCCESS);

  URL u, *o_url, *r_url, *client_url;
  HttpSM *sm = (HttpSM *) txnp;
  HttpTransact::State *s = &(sm->t_state);

  u.m_heap = ((HdrHeapSDKHandle *) bufp)->m_heap;
  u.m_url_impl = (URLImpl *) url_loc;
  if (!u.valid())
    return TS_ERROR;

  client_url = s->hdr_info.client_request.url_get();
  if (!(client_url->valid()))
    return TS_ERROR;

  s->redirect_info.redirect_in_process = true;
  o_url = &(s->redirect_info.original_url);
  if (!o_url->valid()) {
    o_url->create(NULL);
    o_url->copy(client_url);
  }
  client_url->copy(&u);

  r_url = &(s->redirect_info.redirect_url);
  if (!r_url->valid())
    r_url->create(NULL);
  r_url->copy(&u);

  s->hdr_info.server_request.destroy();
  // we want to close the server session
  s->api_release_server_session = true;

  s->request_sent_time = 0;
  s->response_received_time = 0;
  s->cache_info.write_lock_state = HttpTransact::CACHE_WL_INIT;
  s->next_action = HttpTransact::REDIRECT_READ;

  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 = &(((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 = &(((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 = &(((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 = &(((HttpSM *) txnp)->t_state);
  s->api_txn_no_activity_timeout_value = timeout;
}


// TS-2196: TSHttpTxnCacheLookupSkip will be removed in the 5.x release.
TSReturnCode
TSHttpTxnCacheLookupSkip(TSHttpTxn txnp)
{
  return TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_CACHE_HTTP, 0);
}

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

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

  return TS_SUCCESS;
}

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

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

  if (cached_obj == NULL || !cached_obj->valid())
    return TS_ERROR;

  cached_resp = cached_obj->response_get();
  if (cached_resp == NULL || !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 = &(((HttpSM *) txnp)->t_state);
  s->api_http_sm_shutdown = true;

  return TS_SUCCESS;
}

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

  HttpSM *sm = (HttpSM *) txnp;
  switch (sm->t_state.squid_codes.log_code) {
  case SQUID_LOG_ERR_CLIENT_ABORT:
  case SQUID_LOG_TCP_SWAPFAIL:
    // check for client abort and cache read error
    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 = (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 = (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 = (HttpSM *) txnp;
  return (sm->t_state.hdr_info.client_req_is_server_style ? 1 : 0);
}

void
TSHttpTxnOverwriteExpireTime(TSHttpTxn txnp, time_t expire_time)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpTransact::State *s = &(((HttpSM *) txnp)->t_state);
  s->plugin_set_expire_time = expire_time;
}

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

  HttpSM *sm = (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::CACHE_WL_READ_RETRY)
    return TS_ERROR;

  s->api_update_cached_object = HttpTransact::UPDATE_CACHED_OBJECT_PREPARE;
  return TS_SUCCESS;
}

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

  HttpSM *sm = (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)
{
  HttpClientSession *cs = reinterpret_cast<HttpClientSession *>(ssnp);

  if (cs == NULL) return 0;

  NetVConnection *vc = cs->get_netvc();
  if (vc == NULL) return 0;

  return vc->get_remote_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)
{
  HttpClientSession *cs = reinterpret_cast<HttpClientSession *>(ssnp);

  if (cs == NULL) return 0;

  NetVConnection *vc = cs->get_netvc();
  if (vc == NULL) return 0;

  return vc->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*
TSHttpTxnServerAddrGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
  return &sm->t_state.server_info.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 (ats_ip_copy(&sm->t_state.server_info.addr.sa, addr)) {
    sm->t_state.api_server_addr_set = true;
    return TS_SUCCESS;
  } else {
    return TS_ERROR;
  }
}

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

  HttpSM *sm = (HttpSM *) txnp;
  sm->t_state.client_info.port = 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 = (HttpSM *) txnp;

  sm->ua_session->outbound_port = ats_ip_port_host_order(addr);

  if (ats_is_ip4(addr)) {
    sm->ua_session->outbound_ip4.assign(addr);
  } else if (ats_is_ip6(addr)) {
    sm->ua_session->outbound_ip6.assign(addr);
  } else {
    sm->ua_session->outbound_ip4.invalidate();
    sm->ua_session->outbound_ip6.invalidate();
  }
  return TS_ERROR;
}

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 == NULL)
    return NULL;

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

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

# if ! TS_USE_TPROXY
  if (flag) return TS_ERROR; // can't enable if it's not configured.
# endif

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

  sm->ua_session->f_outbound_transparent = flag;
  return TS_SUCCESS;
}

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

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

  vc->options.packet_mark = (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 = (HttpSM *) txnp;

  // change the mark on an active server session
  if (NULL != sm->ua_session) {
    HttpServerSession *ssn = sm->ua_session->get_server_session();
    if (NULL != ssn) {
      NetVConnection *vc = ssn->get_netvc();
      if (vc != NULL) {
        vc->options.packet_mark = (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
TSHttpTxnClientPacketTosSet(TSHttpTxn txnp, int tos)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = (HttpSM *) txnp;
  if (NULL == sm->ua_session) {
    return TS_ERROR;
  }

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

  vc->options.packet_tos = (uint32_t)tos;
  vc->apply_options();
  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnServerPacketTosSet(TSHttpTxn txnp, int tos)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  HttpSM *sm = (HttpSM *) txnp;

  // change the tos on an active server session
  if (NULL != sm->ua_session) {
    HttpServerSession *ssn = sm->ua_session->get_server_session();
    if (NULL != ssn) {
      NetVConnection *vc = ssn->get_netvc();
      if (vc != NULL) {
        vc->options.packet_tos = (uint32_t)tos;
        vc->apply_options();
      }
    }
  }

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

void
TSHttpTxnErrorBodySet(TSHttpTxn txnp, char *buf, int buflength, char *mimetype)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void*)buf) == TS_SUCCESS);
  sdk_assert(buflength > 0);

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

  if (s->internal_msg_buffer)
    HttpTransact::free_internal_msg_buffer(s->internal_msg_buffer, s->internal_msg_buffer_fast_allocator_size);

  ats_free_null(s->internal_msg_buffer_type);

  s->internal_msg_buffer = buf;
  s->internal_msg_buffer_type = mimetype;
  s->internal_msg_buffer_size = buflength;
  s->internal_msg_buffer_fast_allocator_size = -1;
}

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

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

  if (s->method != HTTP_WKSIDX_GET)
    return;

  if (s->internal_msg_buffer)
    HttpTransact::free_internal_msg_buffer(s->internal_msg_buffer, s->internal_msg_buffer_fast_allocator_size);

  s->api_server_request_body_set = true;
  s->internal_msg_buffer = buf;
  s->internal_msg_buffer_size = buflength;
  s->internal_msg_buffer_fast_allocator_size = -1;
}

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

  HttpSM *sm = (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, 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 = (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;
}

void
TSHttpTxnUntransformedRespCache(TSHttpTxn txnp, int on)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (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 = (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((int) m_event, 0);
    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 = (HttpSM *) txnp;
  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.
  if (eth->tt != REGULAR) {
    eventProcessor.schedule_imm(NEW(new TSHttpSMCallback(sm, event)), ET_NET);
  } else {
    MUTEX_TRY_LOCK(trylock, sm->mutex, eth);
    if (!trylock) {
      eventProcessor.schedule_imm(NEW(new TSHttpSMCallback(sm, event)), ET_NET);
    } else {
      sm->state_api_callback((int) event, 0);
    }
  }
}

TSReturnCode
TSHttpArgIndexReserve(const char* name, const char* description, int *arg_idx)
{
  sdk_assert(sdk_sanity_check_null_ptr(arg_idx) == TS_SUCCESS);

  int volatile ix = ink_atomic_increment(&next_argv_index, 1);

  if (ix < HTTP_SSN_TXN_MAX_USER_ARG) {
    state_arg_table[ix].name = ats_strdup(name);
    state_arg_table[ix].name_len = strlen(state_arg_table[ix].name);
    if (description)
      state_arg_table[ix].description = ats_strdup(description);
    *arg_idx = ix;

    return TS_SUCCESS;
  }
  return TS_ERROR;
}

TSReturnCode
TSHttpArgIndexLookup(int arg_idx, const char** name, const char** description)
{
  if (sdk_sanity_check_null_ptr(name) == TS_SUCCESS) {
    if (state_arg_table[arg_idx].name) {
      *name = state_arg_table[arg_idx].name;
      if (description)
        *description = state_arg_table[arg_idx].description;
      return TS_SUCCESS;
    }
  }
  return TS_ERROR;
}

// Not particularly efficient, but good enough for now.
TSReturnCode
TSHttpArgIndexNameLookup(const char* name, int *arg_idx, const char **description)
{
  sdk_assert(sdk_sanity_check_null_ptr(arg_idx) == TS_SUCCESS);

  size_t len = strlen(name);

  for (int ix = 0; ix <  next_argv_index; ++ix) {
    if ((len == state_arg_table[ix].name_len) && (0 == strcmp(name, state_arg_table[ix].name))) {
      if (description)
        *description = state_arg_table[ix].description;
      *arg_idx = ix;
      return TS_SUCCESS;
    }
  }
  return TS_ERROR;
}

void
TSHttpTxnArgSet(TSHttpTxn txnp, int arg_idx, void *arg)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(arg_idx >= 0 && arg_idx < HTTP_SSN_TXN_MAX_USER_ARG);

  HttpSM *sm = (HttpSM *) txnp;
  sm->t_state.user_args[arg_idx] = arg;
}

void *
TSHttpTxnArgGet(TSHttpTxn txnp, int arg_idx)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(arg_idx >= 0 && arg_idx < HTTP_SSN_TXN_MAX_USER_ARG);

  HttpSM *sm = (HttpSM *) txnp;
  return sm->t_state.user_args[arg_idx];
}

void
TSHttpSsnArgSet(TSHttpSsn ssnp, int arg_idx, void *arg)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  sdk_assert(arg_idx >= 0 && arg_idx < HTTP_SSN_TXN_MAX_USER_ARG);

  HttpClientSession *cs = (HttpClientSession *)ssnp;

  cs->set_user_arg(arg_idx, arg);
}

void *
TSHttpSsnArgGet(TSHttpSsn ssnp, int arg_idx)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  sdk_assert(arg_idx >= 0 && arg_idx < HTTP_SSN_TXN_MAX_USER_ARG);

  HttpClientSession *cs = (HttpClientSession *)ssnp;
  return cs->get_user_arg(arg_idx);
}

void
TSHttpTxnSetHttpRetStatus(TSHttpTxn txnp, TSHttpStatus http_retstatus)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM *) txnp;
  sm->t_state.http_return_code = (HTTPStatus) http_retstatus;
}

int
TSHttpTxnGetMaxHttpRetBodySize(void)
{
  return HTTP_TRANSACT_STATE_MAX_XBUF_SIZE;
}

void
TSHttpTxnSetHttpRetBody(TSHttpTxn txnp, const char *body_msg, int plain_msg_flag)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

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

  s->return_xbuf_size = 0;
  s->return_xbuf[0] = 0;
  s->return_xbuf_plain = false;
  if (body_msg) {
    ink_strlcpy(s->return_xbuf, body_msg, HTTP_TRANSACT_STATE_MAX_XBUF_SIZE);
    s->return_xbuf_size = strlen(s->return_xbuf);
    s->return_xbuf_plain = plain_msg_flag;
  }
}

/* control channel for HTTP */
TSReturnCode
TSHttpTxnCntl(TSHttpTxn txnp, TSHttpCntlType cntl, void *data)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM *) txnp;

  switch (cntl) {
  case TS_HTTP_CNTL_GET_LOGGING_MODE:
    {
      if (data == NULL)
        return TS_ERROR;

      intptr_t *rptr = (intptr_t *) data;

      if (sm->t_state.api_info.logging_enabled) {
        *rptr = (intptr_t) TS_HTTP_CNTL_ON;
      } else {
        *rptr = (intptr_t) TS_HTTP_CNTL_OFF;
      }

      return TS_SUCCESS;
    }

  case TS_HTTP_CNTL_SET_LOGGING_MODE:
    if (data != TS_HTTP_CNTL_ON && data != TS_HTTP_CNTL_OFF) {
      return TS_ERROR;
    } else {
      sm->t_state.api_info.logging_enabled = (bool) data;
      return TS_SUCCESS;
    }
    break;

  case TS_HTTP_CNTL_GET_INTERCEPT_RETRY_MODE:
    {
      if (data == NULL)
        return TS_ERROR;

      intptr_t *rptr = (intptr_t *) data;

      if (sm->t_state.api_info.retry_intercept_failures) {
        *rptr = (intptr_t) TS_HTTP_CNTL_ON;
      } else {
        *rptr = (intptr_t) TS_HTTP_CNTL_OFF;
      }

      return TS_SUCCESS;
    }

  case TS_HTTP_CNTL_SET_INTERCEPT_RETRY_MODE:
    if (data != TS_HTTP_CNTL_ON && data != TS_HTTP_CNTL_OFF) {
      return TS_ERROR;
    } else {
      sm->t_state.api_info.retry_intercept_failures = (bool) data;
      return TS_SUCCESS;
    }
  default:
    return TS_ERROR;
  }

  return TS_ERROR;
}

/* 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 = &(((HttpSM *) txnp)->t_state);
  return (TSServerState)s->current.state;
}

void
TSHttpTxnDebugSet(TSHttpTxn txnp, int on)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  ((HttpSM *)txnp)->debug_on = on;
}

int
TSHttpTxnDebugGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  return ((HttpSM *)txnp)->debug_on;
}
void
TSHttpSsnDebugSet(TSHttpSsn ssnp, int on)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  ((HttpClientSession *)ssnp)->debug_on = on;
}
int
TSHttpSsnDebugGet(TSHttpSsn ssnp)
{
  sdk_assert(sdk_sanity_check_http_ssn(ssnp) == TS_SUCCESS);
  return ((HttpClientSession *)ssnp)->debug_on;
}

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

  HttpSM *sm = (HttpSM *) txnp;
  return sm->client_request_hdr_bytes;
}

int64_t
TSHttpTxnClientReqBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM *) txnp;
  return sm->client_request_body_bytes;
}

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

  HttpSM *sm = (HttpSM *) txnp;
  return sm->server_request_hdr_bytes;
}

int64_t
TSHttpTxnServerReqBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM *) txnp;
  return sm->server_request_body_bytes;
}

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

  HttpSM *sm = (HttpSM *) txnp;
  return sm->server_response_hdr_bytes;
}

int64_t
TSHttpTxnServerRespBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM *) txnp;
  return sm->server_response_body_bytes;
}

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

  HttpSM *sm = (HttpSM *) txnp;
  return sm->client_response_hdr_bytes;
}

int64_t
TSHttpTxnClientRespBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM *) txnp;
  return sm->client_response_body_bytes;
}

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

  HttpSM *sm = (HttpSM *) txnp;
  return sm->pushed_response_hdr_bytes;
}

int64_t
TSHttpTxnPushedRespBodyBytesGet(TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (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 = (HttpSM *) txnp;
  TSReturnCode ret = TS_SUCCESS;

  switch(milestone) {
  case TS_MILESTONE_UA_BEGIN:
    *time = sm->milestones.ua_begin;
    break;
  case TS_MILESTONE_UA_READ_HEADER_DONE:
    *time = sm->milestones.ua_read_header_done;
    break;
  case TS_MILESTONE_UA_BEGIN_WRITE:
    *time = sm->milestones.ua_begin_write;
    break;
  case TS_MILESTONE_UA_CLOSE:
    *time = sm->milestones.ua_close;
    break;
  case TS_MILESTONE_SERVER_FIRST_CONNECT:
    *time = sm->milestones.server_first_connect;
    break;
  case TS_MILESTONE_SERVER_CONNECT:
    *time = sm->milestones.server_connect;
    break;
  case TS_MILESTONE_SERVER_CONNECT_END:
    *time = sm->milestones.server_connect_end;
    break;
  case TS_MILESTONE_SERVER_BEGIN_WRITE:
    *time = sm->milestones.server_begin_write;
    break;
  case TS_MILESTONE_SERVER_FIRST_READ:
    *time = sm->milestones.server_first_read;
    break;
  case TS_MILESTONE_SERVER_READ_HEADER_DONE:
    *time = sm->milestones.server_read_header_done;
    break;
  case TS_MILESTONE_SERVER_CLOSE:
    *time = sm->milestones.server_close;
    break;
  case TS_MILESTONE_CACHE_OPEN_READ_BEGIN:
    *time = sm->milestones.cache_open_read_begin;
    break;
  case TS_MILESTONE_CACHE_OPEN_READ_END:
    *time = sm->milestones.cache_open_read_end;
    break;
  case TS_MILESTONE_CACHE_OPEN_WRITE_BEGIN:
    *time = sm->milestones.cache_open_write_begin;
    break;
  case TS_MILESTONE_CACHE_OPEN_WRITE_END:
    *time = sm->milestones.cache_open_write_end;
    break;
  case TS_MILESTONE_DNS_LOOKUP_BEGIN:
    *time = sm->milestones.dns_lookup_begin;
    break;
  case TS_MILESTONE_DNS_LOOKUP_END:
    *time = sm->milestones.dns_lookup_end;
    break;
  case TS_MILESTONE_SM_START:
    *time = sm->milestones.sm_start;
    break;
  case TS_MILESTONE_SM_FINISH:
    *time = sm->milestones.sm_finish;
    break;
  default:
    *time = -1;
    ret = TS_ERROR;
    break;
  }

  return ret;
}

TSReturnCode
TSHttpTxnCachedRespTimeGet(TSHttpTxn txnp, time_t *resp_time)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

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

  if (cached_obj == NULL || !cached_obj->valid())
    return TS_ERROR;

  *resp_time = cached_obj->response_received_time_get();
  return TS_SUCCESS;
}

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

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

  return (int)(s->current.request_to);
}

int
TSHttpCurrentClientConnectionsGet(void)
{
  int64_t S;

  HTTP_READ_DYN_SUM(http_current_client_connections_stat, S);
  return (int)S;
}

int
TSHttpCurrentActiveClientConnectionsGet(void)
{
  int64_t S;

  HTTP_READ_DYN_SUM(http_current_active_client_connections_stat, S);
  return (int)S;
}

int
TSHttpCurrentIdleClientConnectionsGet(void)
{
  int64_t total = 0;
  int64_t active = 0;

  HTTP_READ_DYN_SUM(http_current_client_connections_stat, total);
  HTTP_READ_DYN_SUM(http_current_active_client_connections_stat, active);

  if (total >= active)
    return (int)(total - active);

  return 0;
}

int
TSHttpCurrentCacheConnectionsGet(void)
{
  int64_t S;

  HTTP_READ_DYN_SUM(http_current_cache_connections_stat, S);
  return (int)S;
}

int
TSHttpCurrentServerConnectionsGet(void)
{
  int64_t S;

  HTTP_READ_GLOBAL_DYN_SUM(http_current_server_connections_stat, S);
  return (int)S;
}


/* HTTP alternate selection */
TSReturnCode
TSHttpAltInfoClientReqGet(TSHttpAltInfo infop, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_alt_info(infop) == TS_SUCCESS);

  HttpAltInfo *info = (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 = (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 = (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 = (HttpAltInfo *) infop;
  info->m_qvalue = quality;
}

extern HttpAccept *plugin_http_accept;
extern HttpAccept *plugin_http_transparent_accept;

TSVConn
TSHttpConnect(sockaddr const* addr)
{
  sdk_assert(addr);

  sdk_assert(ats_is_ip(addr));
  sdk_assert(ats_ip_port_cast(addr));

  if (plugin_http_accept) {
    PluginVCCore *new_pvc = PluginVCCore::alloc();

    new_pvc->set_active_addr(addr);
    new_pvc->set_accept_cont(plugin_http_accept);

    PluginVC *return_vc = new_pvc->connect();

    if (return_vc != NULL) {
      PluginVC* other_side = return_vc->get_other_side();

      if(other_side != NULL) {
        other_side->set_is_internal_request(true);
      }
    }

    return reinterpret_cast<TSVConn>(return_vc);
  }

  return NULL;
}

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();

    // 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);
    new_pvc->set_accept_cont(plugin_http_transparent_accept);

    PluginVC *return_vc = new_pvc->connect();

    if (return_vc != NULL) {
      PluginVC* other_side = return_vc->get_other_side();

      if(other_side != NULL) {
        other_side->set_is_internal_request(true);
      }
    }

    return reinterpret_cast<TSVConn>(return_vc);
  }

  return NULL;
}

/* Actions */
void
TSActionCancel(TSAction actionp)
{
  Action *a;
  INKContInternal *i;

/* This is a hack. SHould be handled in ink_types */
  if ((uintptr_t) actionp & 0x1) {
    a = (Action *) ((uintptr_t) actionp - 1);
    i = (INKContInternal *) a->continuation;
    i->handle_event_count(EVENT_IMMEDIATE);
  } else {
    a = (Action *) actionp;
  }

  a->cancel();
}

// Currently no error handling necessary, actionp can be anything.
int
TSActionDone(TSAction actionp)
{
  return ((Action *)actionp == ACTION_RESULT_DONE) ? 1 : 0;
}

/* Connections */

/* Deprectated.
   Do not use this API.
   The reason is even if VConn is created using this API, it is still useless.
   For example, if we do TSVConnRead, the read operation returns read_vio, if
   we do TSVIOReenable (read_vio), it actually calls:
   void VIO::reenable()
   {
       if (vc_server) vc_server->reenable(this);
   }
   vc_server->reenable calls:
   VConnection::reenable(VIO)

   this function is virtual in VConnection.h. It is defined separately for
   UnixNet, NTNet and CacheVConnection.

   Thus, unless VConn is either NetVConnection or CacheVConnection, it can't
   be instantiated for functions like reenable.

   Meanwhile, this function has never been used.
   */
TSVConn
TSVConnCreate(TSEventFunc event_funcp, TSMutex mutexp)
{
  if (mutexp == NULL)
    mutexp = (TSMutex) new_ProxyMutex();

  // TODO: probably don't need this if memory allocations fails properly
  sdk_assert(sdk_sanity_check_mutex(mutexp) == TS_SUCCESS);

  INKVConnInternal *i = INKVConnAllocator.alloc();

  sdk_assert(sdk_sanity_check_null_ptr((void*)i) == TS_SUCCESS);

  i->init(event_funcp, mutexp);
  return reinterpret_cast<TSVConn>(i);
}

TSVIO
TSVConnReadVIOGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = (VConnection *)connp;
  TSVIO data;

  if (vc->get_data(TS_API_DATA_READ_VIO, &data)) {
    return data;
  }

  return NULL;
}

TSVIO
TSVConnWriteVIOGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = (VConnection *) connp;
  TSVIO data;

  if (vc->get_data(TS_API_DATA_WRITE_VIO, &data)) {
    return data;
  }

  return NULL;
}

int
TSVConnClosedGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = (VConnection *) connp;
  int data;

  vc->get_data(TS_API_DATA_CLOSED, &data); // Can not fail for this case
  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_MUTEX(contp);
  VConnection *vc = (VConnection *) connp;

  return reinterpret_cast<TSVIO>(vc->do_io(VIO::READ, (INKContInternal *) contp, nbytes, (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_MUTEX(contp);
  VConnection *vc = (VConnection *) connp;

  return reinterpret_cast<TSVIO>(vc->do_io_write((INKContInternal *) contp, nbytes, (IOBufferReader *) readerp));
}

void
TSVConnClose(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = (VConnection *) connp;
  vc->do_io_close();
}

void
TSVConnAbort(TSVConn connp, int error)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = (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 = (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 = (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 = (CacheVC *) connp;
  if (vc->base_stat == cache_scan_active_stat)
    vc->set_http_info((CacheHTTPInfo *) infop);
}

/* Transformations */

TSVConn
TSTransformCreate(TSEventFunc event_funcp, TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  // TODO: This is somewhat of a leap of faith, but I think a TSHttpTxn is just another
  // fancy continuation?
  return TSVConnCreate(event_funcp, TSContMutexGet(reinterpret_cast<TSCont>(txnp)));
}

TSVConn
TSTransformOutputVConnGet(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  VConnection *vc = (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)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);

  HttpSM *http_sm = (HttpSM *)txnp;
  INKContInternal *i = (INKContInternal *)contp;

  // Must have a mutex
  sdk_assert(sdk_sanity_check_null_ptr((void*)i->mutex) == TS_SUCCESS);

  http_sm->plugin_tunnel_type = HTTP_PLUGIN_AS_SERVER;
  http_sm->plugin_tunnel = PluginVCCore::alloc();
  http_sm->plugin_tunnel->set_accept_cont(i);
}

void
TSHttpTxnIntercept(TSCont contp, TSHttpTxn txnp)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);

  HttpSM *http_sm = (HttpSM *) txnp;
  INKContInternal *i = (INKContInternal *) contp;

  // Must have a mutex
  sdk_assert(sdk_sanity_check_null_ptr((void*)i->mutex) == TS_SUCCESS);

  http_sm->plugin_tunnel_type = HTTP_PLUGIN_AS_INTERCEPT;
  http_sm->plugin_tunnel = PluginVCCore::alloc();
  http_sm->plugin_tunnel->set_accept_cont(i);
}

/* Net VConnections */
void
TSVConnInactivityTimeoutSet(TSVConn connp, TSHRTime timeout)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  NetVConnection *vc = (NetVConnection *) connp;
  vc->set_inactivity_timeout(timeout);
}

void
TSVConnInactivityTimeoutCancel(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  NetVConnection *vc = (NetVConnection *) connp;
  vc->cancel_inactivity_timeout();
}

void
TSVConnActiveTimeoutSet(TSVConn connp, TSHRTime timeout)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  NetVConnection *vc = (NetVConnection *) connp;
  vc->set_active_timeout(timeout);
}

void
TSVConnActiveTimeoutCancel(TSVConn connp)
{
  sdk_assert(sdk_sanity_check_iocore_structure(connp) == TS_SUCCESS);

  NetVConnection *vc = (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();
}

TSAction
TSNetConnect(TSCont contp, sockaddr const* addr)
{
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(ats_is_ip(addr));

  FORCE_PLUGIN_MUTEX(contp);

  return reinterpret_cast<TSAction>(
    netProcessor.connect_re(reinterpret_cast<INKContInternal*>(contp), addr)
  );
}

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_MUTEX(contp);

  return reinterpret_cast<TSAction>(
    netProcessor.connect_re(reinterpret_cast<INKContInternal*>(contp), server_addr, &opt)
  );
}

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_MUTEX(contp);

  // If it's not IPv6, force to IPv4.
  opt.ip_family = domain == AF_INET6 ? AF_INET6 : AF_INET;
  opt.accept_threads = accept_threads;
  opt.local_port = port;
  opt.frequent_accept = false;

  INKContInternal *i = (INKContInternal *) contp;
  return (TSAction)netProcessor.accept(i, opt);
}

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

TSReturnCode
#if TS_USE_TLS_NPN
TSNetAcceptNamedProtocol(TSCont contp, const char * protocol)
{
  sdk_assert(protocol != NULL);
  sdk_assert(contp != NULL);
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);

  if (!ssl_register_protocol(protocol, (INKContInternal *)contp)) {
    ssl_unregister_protocol(protocol, (INKContInternal *)contp);
    return TS_ERROR;
  }

  return TS_SUCCESS;
}
#else /* TS_USE_TLS_NPN */
TSNetAcceptNamedProtocol(TSCont, const char *)
{
  return TS_ERROR;
}
#endif /* TS_USE_TLS_NPN */

/* DNS Lookups */
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_MUTEX(contp);

  INKContInternal *i = (INKContInternal *) contp;
  return (TSAction)hostDBProcessor.getbyname_re(i, hostname, namelen);
}

sockaddr const*
TSHostLookupResultAddrGet(TSHostLookupResult lookup_result)
{
  sdk_assert(sdk_sanity_check_hostlookup_structure(lookup_result) == TS_SUCCESS);
  HostDBInfo* di = reinterpret_cast<HostDBInfo*>(lookup_result);
  return di->ip();
}

/*
 * checks if the cache is ready
 */

/* Only TSCacheReady exposed in SDK. No need of TSCacheDataTypeReady */
/* because SDK cache API supports only the data type: NONE */
TSReturnCode
TSCacheReady(int *is_ready)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)is_ready) == TS_SUCCESS);
  return TSCacheDataTypeReady(TS_CACHE_DATA_TYPE_NONE, is_ready);
}

/* Private API (used by Mixt) */
TSReturnCode
TSCacheDataTypeReady(TSCacheDataType type, int *is_ready)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)is_ready) == TS_SUCCESS);

  CacheFragType frag_type;

  switch (type) {
  case TS_CACHE_DATA_TYPE_NONE:
    frag_type = CACHE_FRAG_TYPE_NONE;
    break;
  case TS_CACHE_DATA_TYPE_OTHER:      /* other maps to http */
  case TS_CACHE_DATA_TYPE_HTTP:
    frag_type = CACHE_FRAG_TYPE_HTTP;
    break;
  default:
    *is_ready = 0;
    return TS_ERROR;
  }

  *is_ready = cacheProcessor.IsCacheReady(frag_type);
  return TS_SUCCESS;
}

/* 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_MUTEX(contp);

  CacheInfo *info = (CacheInfo *) key;
  Continuation *i = (INKContInternal *) contp;

  return (TSAction)cacheProcessor.open_read(i, &info->cache_key, true, info->frag_type, info->hostname, 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_MUTEX(contp);

  CacheInfo *info = (CacheInfo *) key;
  Continuation *i = (INKContInternal *) contp;

  return (TSAction)cacheProcessor.open_write(i, &info->cache_key, true, info->frag_type, 0, false, info->pin_in_cache,
                                             info->hostname, 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_MUTEX(contp);

  CacheInfo *info = (CacheInfo *) key;
  INKContInternal *i = (INKContInternal *) contp;

  return (TSAction)cacheProcessor.remove(i, &info->cache_key, true, info->frag_type, true, false, info->hostname, 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_MUTEX(contp);

  INKContInternal *i = (INKContInternal *) contp;

  if (key) {
    CacheInfo *info = (CacheInfo *) key;
    return (TSAction)cacheProcessor.scan(i, info->hostname, info->len, KB_per_second);
  }
  return reinterpret_cast<TSAction>(cacheProcessor.scan(i, 0, 0, KB_per_second));
}


/************************   REC Stats API    **************************/
int
TSStatCreate(const char *the_name, TSRecordDataType the_type, TSStatPersistence persist, TSStatSync sync)
{
  int id = ink_atomic_increment(&top_stat, 1);
  RecRawStatSyncCb syncer = RecRawStatSyncCount;

  // TODO: This only supports "int" data types at this point, since the "Raw" stats
  // interfaces only supports integers. Going forward, we could extend either the "Raw"
  // stats APIs, or make non-int use the direct (synchronous) stats APIs (slower).
  if ((sdk_sanity_check_null_ptr((void*)the_name) != TS_SUCCESS) ||
      (sdk_sanity_check_null_ptr((void*)api_rsb) != TS_SUCCESS) ||
      (id >= api_rsb->max_stats))
    return TS_ERROR;

  switch (sync) {
  case TS_STAT_SYNC_SUM:
    syncer = RecRawStatSyncSum;
    break;
  case TS_STAT_SYNC_AVG:
    syncer = RecRawStatSyncAvg;
    break;
  case TS_STAT_SYNC_TIMEAVG:
    syncer = RecRawStatSyncHrTimeAvg;
    break;
  default:
    syncer = RecRawStatSyncCount;
    break;
  }
  RecRegisterRawStat(api_rsb, RECT_PLUGIN, the_name, (RecDataT)the_type, (RecPersistT)persist, id, syncer);

  return id;
}

void
TSStatIntIncrement(int the_stat, TSMgmtInt amount)
{
  RecIncrRawStat(api_rsb, NULL, the_stat, amount);
}

void
TSStatIntDecrement(int the_stat, TSMgmtInt amount)
{
  RecDecrRawStat(api_rsb, NULL, the_stat, amount);
}

TSMgmtInt
TSStatIntGet(int the_stat)
{
  TSMgmtInt value;

  RecGetGlobalRawStatSum(api_rsb, the_stat, &value);
  return value;
}

void
TSStatIntSet(int the_stat, TSMgmtInt value)
{
  RecSetGlobalRawStatSum(api_rsb, the_stat, value);
}

TSReturnCode
TSStatFindName(const char* name, int *idp)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)name) == TS_SUCCESS);

  if (RecGetRecordOrderAndId(name, NULL, idp) == REC_ERR_OKAY)
    return TS_SUCCESS;

  return TS_ERROR;
}


/**************************    Stats API    ****************************/
// THESE APIS ARE DEPRECATED, USE THE REC APIs INSTEAD
// #define ink_sanity_check_stat_structure(_x) TS_SUCCESS

inline TSReturnCode
ink_sanity_check_stat_structure(void *obj)
{
  if (obj == NULL)
    return TS_ERROR;

  return TS_SUCCESS;
}

/**************************   Tracing API   ****************************/
// returns 1 or 0 to indicate whether TS is being run with a debug tag.
int
TSIsDebugTagSet(const char *t)
{
  return (diags->on(t, DiagsTagType_Debug)) ? 1 : 0;
}

void
TSDebugSpecific(int debug_flag, const char *tag, const char *format_str, ...)
{
  if (diags->on(tag, DiagsTagType_Debug) || (debug_flag  && diags->on())) {
    va_list ap;

    va_start(ap, format_str);
    diags->print_va(tag, DL_Diag, NULL, format_str, ap);
    va_end(ap);
  }
}

// Plugins would use TSDebug just as the TS internal uses Debug
// e.g. TSDebug("plugin-cool", "Snoopy is a cool guy even after %d requests.\n", num_reqs);
void
TSDebug(const char *tag, const char *format_str, ...)
{
  if (diags->on(tag, DiagsTagType_Debug)) {
    va_list ap;

    va_start(ap, format_str);
    diags->print_va(tag, DL_Diag, NULL, format_str, ap);
    va_end(ap);
  }
}

/**************************   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 = NULL;
    return TS_ERROR;
  }

  TextLogObject *tlog = NEW(new TextLogObject(filename, Log::config->logfile_dir,
                                              (bool) mode & TS_LOG_MODE_ADD_TIMESTAMP,
                                              NULL,
                                              Log::config->rolling_enabled,
                                              Log::config->rolling_interval_sec,
                                              Log::config->rolling_offset_hr,
                                              Log::config->rolling_size_mb));
  if (tlog) {
    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 = NULL;
      return TS_ERROR;
    }
  } else {
    *new_object = NULL;
    return TS_ERROR;
  }
  *new_object = (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 (((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);

  ((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((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);

  ((TextLogObject *) the_object)->set_log_file_header(header);
}

void
TSTextLogObjectRollingEnabledSet(TSTextLogObject the_object, int rolling_enabled)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  ((TextLogObject *) the_object)->set_rolling_enabled(rolling_enabled);
}

void
TSTextLogObjectRollingIntervalSecSet(TSTextLogObject the_object, int rolling_interval_sec)
{
  sdk_assert(sdk_sanity_check_iocore_structure(the_object) == TS_SUCCESS);

  ((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);

  ((TextLogObject *) the_object)->set_rolling_offset_hr(rolling_offset_hr);
}

TSReturnCode
TSHttpSsnClientFdGet(TSHttpSsn ssnp, int *fdp)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)fdp) == TS_SUCCESS);

  HttpClientSession *cs = (HttpClientSession *) ssnp;

  if (cs == NULL)
    return TS_ERROR;

  NetVConnection *vc = cs->get_netvc();
  if (vc == NULL)
    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);
}

/* Matcher Utils */
char *
TSMatcherReadIntoBuffer(char *file_name, int *file_len)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)file_name) == TS_SUCCESS);
  return readIntoBuffer((char *) file_name, "TSMatcher", file_len);
}

char *
TSMatcherTokLine(char *buffer, char **last)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)buffer) == TS_SUCCESS);
  return tokLine(buffer, last);
}

char *
TSMatcherExtractIPRange(char *match_str, uint32_t *addr1, uint32_t *addr2)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)match_str) == TS_SUCCESS);
  return (char*)ExtractIpRange(match_str, addr1, addr2);
}
// Conflict in header due to overload (must be C compatible).
char *
TSMatcherExtractIPRange(char *match_str, sockaddr* addr1, sockaddr* addr2)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)match_str) == TS_SUCCESS);
  return (char*)ExtractIpRange(match_str, addr1, addr2);
}

TSMatcherLine
TSMatcherLineCreate(void)
{
  return reinterpret_cast<TSMatcherLine>(ats_malloc(sizeof(matcher_line)));
}

void
TSMatcherLineDestroy(TSMatcherLine ml)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)ml) == TS_SUCCESS);
  ats_free(ml);
}

const char *
TSMatcherParseSrcIPConfigLine(char *line, TSMatcherLine ml)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)line) == TS_SUCCESS);
  return parseConfigLine(line, (matcher_line *) ml, &ip_allow_tags);
}

char *
TSMatcherLineName(TSMatcherLine ml, int element)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)ml) == TS_SUCCESS);
  return (((matcher_line *) ml)->line)[0][element];
}

char *
TSMatcherLineValue(TSMatcherLine ml, int element)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)ml) == TS_SUCCESS);
  return (((matcher_line *) ml)->line)[1][element];
}

/* Configuration Setting */
TSReturnCode
TSMgmtConfigIntSet(const char *var_name, TSMgmtInt value)
{
  TSMgmtInt result;
  char *buffer;

  // is this a valid integer?
  if (TSMgmtIntGet(var_name, &result) != TS_SUCCESS)
    return TS_ERROR;

  // construct a buffer
  int buffer_size = strlen(var_name) + 1 + 32 + 1 + 64 + 1;

  buffer = (char *) alloca(buffer_size);
  snprintf(buffer, buffer_size, "%s %d %" PRId64 "", var_name, MGMT_INT, value);

  // tell manager to set the configuration; note that this is not
  // transactional (e.g. we return control to the plugin before the
  // value is commited to disk by the manager)
  RecSignalManager(MGMT_SIGNAL_PLUGIN_SET_CONFIG, buffer);

  return TS_SUCCESS;
}

void
TSICPFreshnessFuncSet(TSPluginFreshnessCalcFunc funcp)
{
  pluginFreshnessCalcFunc = (PluginFreshnessCalcFunc) funcp;
}

TSReturnCode
TSICPCachedReqGet(TSCont contp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void*)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void*)obj) == TS_SUCCESS);

  ICPPeerReadCont *sm = (ICPPeerReadCont *)contp;
  HTTPInfo *cached_obj;

  cached_obj = sm->_object_read;
  if (cached_obj == NULL || !cached_obj->valid())
    return TS_ERROR;

  HTTPHdr *cached_hdr = cached_obj->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->_cache_req_hdr_heap_handle);

  if (*handle == NULL) {
    *handle = (HdrHeapSDKHandle *)ats_malloc(sizeof(HdrHeapSDKHandle));
    (*handle)->m_heap = cached_hdr->m_heap;
  }

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

  return sdk_sanity_check_mbuffer(*bufp);
}

TSReturnCode
TSICPCachedRespGet(TSCont contp, TSMBuffer *bufp, TSMLoc *obj)
{
  sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void*)bufp) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void*)obj) == TS_SUCCESS);

  ICPPeerReadCont *sm = (ICPPeerReadCont *) contp;
  HTTPInfo *cached_obj;

  cached_obj = sm->_object_read;
  if (cached_obj == NULL || !cached_obj->valid())
    return TS_ERROR;

  HTTPHdr *cached_hdr = cached_obj->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->_cache_resp_hdr_heap_handle);

  if (*handle == NULL) {
    *handle = (HdrHeapSDKHandle *)ats_malloc(sizeof(HdrHeapSDKHandle));
    (*handle)->m_heap = cached_hdr->m_heap;
  }

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

  return sdk_sanity_check_mbuffer(*bufp);
}

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

  HttpSM *sm = (HttpSM *) txnp;
  Debug("cache_url", "[TSCacheUrlSet]");

  if (sm->t_state.cache_info.lookup_url == NULL) {
    Debug("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(NULL);
    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 = (CacheHTTPInfo *) infop;
  INK_MD5 *key = (INK_MD5 *)keyp;

  info->object_key_set(*key);
}

void
TSCacheHttpInfoSizeSet(TSCacheHttpInfo infop, int64_t size)
{
  // TODO: Check input ?
  CacheHTTPInfo *info = (CacheHTTPInfo *) infop;

  info->object_size_set(size);
}

// this function should be called at TS_EVENT_HTTP_READ_RESPONSE_HDR
void
TSRedirectUrlSet(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 = (HttpSM*) txnp;

  if (sm->redirect_url != NULL) {
    ats_free(sm->redirect_url);
    sm->redirect_url = NULL;
    sm->redirect_url_len = 0;
  }

  sm->redirect_url = (char*)ats_malloc(url_len + 1);
  ink_strlcpy(sm->redirect_url, (char*)url, url_len + 1);
  sm->redirect_url_len = url_len;
  // have to turn redirection on for this transaction if user wants to redirect to another URL
  if (sm->enable_redirection == false) {
    sm->enable_redirection = true;
    // max-out "redirection_tries" to avoid the regular redirection being turned on in
    // this transaction improperly. This variable doesn't affect the custom-redirection
    sm->redirection_tries = HttpConfig::m_master.number_of_redirections;
  }
}

const char*
TSRedirectUrlGet(TSHttpTxn txnp, int *url_len_ptr)
{
  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

  HttpSM *sm = (HttpSM*)txnp;

  *url_len_ptr = sm->redirect_url_len;
  return (const char*)sm->redirect_url;
}

char*
TSFetchRespGet(TSHttpTxn txnp, int *length)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)length) == TS_SUCCESS);
  FetchSM *fetch_sm = (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 = (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;
}

// Fetchpages SM
extern ClassAllocator<FetchSM> FetchSMAllocator;

void
TSFetchPages(TSFetchUrlParams_t *params)
{
  TSFetchUrlParams_t *myparams = params;

  while (myparams != NULL) {
    FetchSM *fetch_sm =  FetchSMAllocator.alloc();
    sockaddr* addr = ats_ip_sa_cast(&myparams->ip);
    in_addr_t ip = ats_ip4_addr_cast(addr);
    uint16_t port = ats_ip_port_host_order(addr);

    fetch_sm->init((Continuation*)myparams->contp, myparams->options,myparams->events, myparams->request, myparams->request_len, ip, port);
    fetch_sm->httpConnect();
    myparams= myparams->next;
  }
}

void
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);
  }
  sdk_assert(ats_is_ip4(ip));

  FetchSM *fetch_sm =  FetchSMAllocator.alloc();
  in_addr_t addr = ats_ip4_addr_cast(ip);
  unsigned short port = ats_ip_port_cast(ip);

  fetch_sm->init((Continuation*)contp, callback_options, events, headers, request_len, addr, port);
  fetch_sm->httpConnect();
}

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

  TSHttpSsn ssnp = TSHttpTxnSsnGet(txnp);
  HttpClientSession *cs = (HttpClientSession *) ssnp;
  if (!cs)
    return TS_ERROR;

  NetVConnection *vc = cs->get_netvc();
  if (!vc)
    return TS_ERROR;

  return vc->get_is_internal_request() ? TS_SUCCESS : TS_ERROR;
}


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 = (Continuation*)contp;
  AIOCallback* pAIO = new_AIOCallback();

  if (pAIO == NULL)
    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 = ((ProxyMutex*) pCont->mutex)->thread_holding;

  if (ink_aio_read(pAIO, 1) == 1)
    return TS_SUCCESS;

  return TS_ERROR;
}

char*
TSAIOBufGet(TSAIOCallback data)
{
  AIOCallback* pAIO = (AIOCallback*)data;
  return (char*)pAIO->aiocb.aio_buf;
}

int
TSAIONBytesGet(TSAIOCallback data)
{
  AIOCallback* pAIO = (AIOCallback*)data;
  return (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 = (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 = ((ProxyMutex*) pCont->mutex)->thread_holding;

  if (ink_aio_write(pAIO, 1) == 1)
    return TS_SUCCESS;

  return TS_ERROR;
}

TSReturnCode
TSAIOThreadNumSet(int thread_num)
{
#if AIO_MODE == AIO_MODE_NATIVE
  (void)thread_num;
  return TS_SUCCESS;
#else
  if (ink_aio_thread_num_set(thread_num))
    return TS_SUCCESS;

  return TS_ERROR;
#endif
}

void
TSRecordDump(TSRecordType rec_type, TSRecordDumpCb callback, void *edata)
{
  RecDumpRecords((RecT)rec_type, (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 = (HttpSM*) txnp;
  sm->t_state.api_skip_all_remapping = (flag != 0);
}

// Little helper function to find the struct member
void*
_conf_to_memberp(TSOverridableConfigKey conf, HttpSM* sm, OverridableDataType *typep)
{
  // The default is "Byte", make sure to override that for those configs which are "Int".
  OverridableDataType typ = OVERRIDABLE_TYPE_BYTE;
  void* ret = NULL;

  switch (conf) {
  case TS_CONFIG_URL_REMAP_PRISTINE_HOST_HDR:
    ret = &sm->t_state.txn_conf->maintain_pristine_host_hdr;
    break;
  case TS_CONFIG_HTTP_CHUNKING_ENABLED:
    ret = &sm->t_state.txn_conf->chunking_enabled;
    break;
  case TS_CONFIG_HTTP_NEGATIVE_CACHING_ENABLED:
    ret = &sm->t_state.txn_conf->negative_caching_enabled;
    break;
  case TS_CONFIG_HTTP_NEGATIVE_CACHING_LIFETIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->negative_caching_lifetime;
    break;
  case TS_CONFIG_HTTP_CACHE_WHEN_TO_REVALIDATE:
    ret = &sm->t_state.txn_conf->cache_when_to_revalidate;
    break;
  case TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_IN:
    ret = &sm->t_state.txn_conf->keep_alive_enabled_in;
    break;
  case TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_OUT:
    ret = &sm->t_state.txn_conf->keep_alive_enabled_out;
    break;
  case TS_CONFIG_HTTP_KEEP_ALIVE_POST_OUT:
    ret = &sm->t_state.txn_conf->keep_alive_post_out;
    break;
  case TS_CONFIG_HTTP_SHARE_SERVER_SESSIONS:
    ret = &sm->t_state.txn_conf->share_server_sessions;
    break;
  case TS_CONFIG_NET_SOCK_RECV_BUFFER_SIZE_OUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->sock_recv_buffer_size_out;
    break;
  case TS_CONFIG_NET_SOCK_SEND_BUFFER_SIZE_OUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->sock_send_buffer_size_out;
    break;
  case TS_CONFIG_NET_SOCK_OPTION_FLAG_OUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->sock_option_flag_out;
    break;
  case TS_CONFIG_HTTP_FORWARD_PROXY_AUTH_TO_PARENT:
    ret = &sm->t_state.txn_conf->fwd_proxy_auth_to_parent;
    break;
  case TS_CONFIG_HTTP_ANONYMIZE_REMOVE_FROM:
    ret = &sm->t_state.txn_conf->anonymize_remove_from;
    break;
  case TS_CONFIG_HTTP_ANONYMIZE_REMOVE_REFERER:
    ret = &sm->t_state.txn_conf->anonymize_remove_referer;
    break;
  case TS_CONFIG_HTTP_ANONYMIZE_REMOVE_USER_AGENT:
    ret = &sm->t_state.txn_conf->anonymize_remove_user_agent;
    break;
  case TS_CONFIG_HTTP_ANONYMIZE_REMOVE_COOKIE:
    ret = &sm->t_state.txn_conf->anonymize_remove_cookie;
    break;
  case TS_CONFIG_HTTP_ANONYMIZE_REMOVE_CLIENT_IP:
    ret = &sm->t_state.txn_conf->anonymize_remove_client_ip;
    break;
  case TS_CONFIG_HTTP_ANONYMIZE_INSERT_CLIENT_IP:
    ret = &sm->t_state.txn_conf->anonymize_insert_client_ip;
    break;
  case TS_CONFIG_HTTP_RESPONSE_SERVER_ENABLED:
    ret = &sm->t_state.txn_conf->proxy_response_server_enabled;
    break;
  case TS_CONFIG_HTTP_INSERT_SQUID_X_FORWARDED_FOR:
    ret = &sm->t_state.txn_conf->insert_squid_x_forwarded_for;
    break;
  case TS_CONFIG_HTTP_SERVER_TCP_INIT_CWND:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->server_tcp_init_cwnd;
    break;
  case TS_CONFIG_HTTP_SEND_HTTP11_REQUESTS:
    ret = &sm->t_state.txn_conf->send_http11_requests;
    break;
  case TS_CONFIG_HTTP_CACHE_HTTP:
    ret = &sm->t_state.txn_conf->cache_http;
    break;
  case TS_CONFIG_HTTP_CACHE_CLUSTER_CACHE_LOCAL:
    ret = &sm->t_state.txn_conf->cache_cluster_cache_local;
    break;
  case TS_CONFIG_HTTP_CACHE_IGNORE_CLIENT_NO_CACHE:
    ret = &sm->t_state.txn_conf->cache_ignore_client_no_cache;
    break;
  case TS_CONFIG_HTTP_CACHE_IGNORE_CLIENT_CC_MAX_AGE:
    ret = &sm->t_state.txn_conf->cache_ignore_client_cc_max_age;
    break;
  case TS_CONFIG_HTTP_CACHE_IMS_ON_CLIENT_NO_CACHE:
    ret = &sm->t_state.txn_conf->cache_ims_on_client_no_cache;
    break;
  case TS_CONFIG_HTTP_CACHE_IGNORE_SERVER_NO_CACHE:
    ret = &sm->t_state.txn_conf->cache_ignore_server_no_cache;
    break;
  case TS_CONFIG_HTTP_CACHE_CACHE_RESPONSES_TO_COOKIES:
    ret = &sm->t_state.txn_conf->cache_responses_to_cookies;
    break;
  case TS_CONFIG_HTTP_CACHE_IGNORE_AUTHENTICATION:
    ret = &sm->t_state.txn_conf->cache_ignore_auth;
    break;
  case TS_CONFIG_HTTP_CACHE_CACHE_URLS_THAT_LOOK_DYNAMIC:
    ret = &sm->t_state.txn_conf->cache_urls_that_look_dynamic;
    break;
  case TS_CONFIG_HTTP_CACHE_REQUIRED_HEADERS:
    ret = &sm->t_state.txn_conf->cache_required_headers;
    break;
  case TS_CONFIG_HTTP_INSERT_REQUEST_VIA_STR:
    ret = &sm->t_state.txn_conf->insert_request_via_string;
    break;
  case TS_CONFIG_HTTP_INSERT_RESPONSE_VIA_STR:
    ret = &sm->t_state.txn_conf->insert_response_via_string;
    break;
  case TS_CONFIG_HTTP_CACHE_HEURISTIC_MIN_LIFETIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->cache_heuristic_min_lifetime;
    break;
  case TS_CONFIG_HTTP_CACHE_HEURISTIC_MAX_LIFETIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->cache_heuristic_max_lifetime;
    break;
  case TS_CONFIG_HTTP_CACHE_GUARANTEED_MIN_LIFETIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->cache_guaranteed_min_lifetime;
    break;
  case TS_CONFIG_HTTP_CACHE_GUARANTEED_MAX_LIFETIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->cache_guaranteed_max_lifetime;
    break;
  case TS_CONFIG_HTTP_CACHE_MAX_STALE_AGE:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->cache_max_stale_age;
    break;
  case TS_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_IN:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->keep_alive_no_activity_timeout_in;
    break;
  case TS_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_OUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->keep_alive_no_activity_timeout_out;
    break;
  case TS_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_IN:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->transaction_no_activity_timeout_in;
    break;
  case TS_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_OUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->transaction_no_activity_timeout_out;
    break;
  case TS_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_OUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->transaction_active_timeout_out;
    break;
  case TS_CONFIG_HTTP_ORIGIN_MAX_CONNECTIONS:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->origin_max_connections;
    break;
  case TS_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->connect_attempts_max_retries;
    break;
  case TS_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES_DEAD_SERVER:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->connect_attempts_max_retries_dead_server;
    break;
  case TS_CONFIG_HTTP_CONNECT_ATTEMPTS_RR_RETRIES:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->connect_attempts_rr_retries;
    break;
  case TS_CONFIG_HTTP_CONNECT_ATTEMPTS_TIMEOUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->connect_attempts_timeout;
    break;
  case TS_CONFIG_HTTP_POST_CONNECT_ATTEMPTS_TIMEOUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->post_connect_attempts_timeout;
    break;
  case TS_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->down_server_timeout;
    break;
  case TS_CONFIG_HTTP_DOWN_SERVER_ABORT_THRESHOLD:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->client_abort_threshold;
    break;
  case TS_CONFIG_HTTP_CACHE_FUZZ_TIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->freshness_fuzz_time;
    break;
  case TS_CONFIG_HTTP_CACHE_FUZZ_MIN_TIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->freshness_fuzz_min_time;
    break;
  case TS_CONFIG_HTTP_DOC_IN_CACHE_SKIP_DNS:
    ret = &sm->t_state.txn_conf->doc_in_cache_skip_dns;
    break;
  case TS_CONFIG_HTTP_BACKGROUND_FILL_ACTIVE_TIMEOUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->background_fill_active_timeout;
    break;
  case TS_CONFIG_HTTP_RESPONSE_SERVER_STR:
    typ = OVERRIDABLE_TYPE_STRING;
    ret = &sm->t_state.txn_conf->proxy_response_server_string;
    break;
  case TS_CONFIG_HTTP_CACHE_HEURISTIC_LM_FACTOR:
    typ = OVERRIDABLE_TYPE_FLOAT;
    ret = &sm->t_state.txn_conf->cache_heuristic_lm_factor;
    break;
  case TS_CONFIG_HTTP_CACHE_FUZZ_PROBABILITY:
    typ = OVERRIDABLE_TYPE_FLOAT;
    ret = &sm->t_state.txn_conf->freshness_fuzz_prob;
    break;
  case TS_CONFIG_HTTP_BACKGROUND_FILL_COMPLETED_THRESHOLD:
    typ = OVERRIDABLE_TYPE_FLOAT;
    ret = &sm->t_state.txn_conf->background_fill_threshold;
    break;
  case TS_CONFIG_NET_SOCK_PACKET_MARK_OUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->sock_packet_mark_out;
    break;
  case TS_CONFIG_NET_SOCK_PACKET_TOS_OUT:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->sock_packet_tos_out;
    break;
  case TS_CONFIG_HTTP_INSERT_AGE_IN_RESPONSE:
    ret = &sm->t_state.txn_conf->insert_age_in_response;
    break;
  case TS_CONFIG_HTTP_CHUNKING_SIZE:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->http_chunking_size;
    break;
  case TS_CONFIG_HTTP_FLOW_CONTROL_ENABLED:
    ret = &sm->t_state.txn_conf->flow_control_enabled;
    break;
  case TS_CONFIG_HTTP_FLOW_CONTROL_LOW_WATER_MARK:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->flow_low_water_mark;
    break;
  case TS_CONFIG_HTTP_FLOW_CONTROL_HIGH_WATER_MARK:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->flow_high_water_mark;
    break;
  case TS_CONFIG_HTTP_CACHE_RANGE_LOOKUP:
    ret = &sm->t_state.txn_conf->cache_range_lookup;
    break;
  case TS_CONFIG_HTTP_NORMALIZE_AE_GZIP:
    ret = &sm->t_state.txn_conf->normalize_ae_gzip;
    break;
  case TS_CONFIG_HTTP_DEFAULT_BUFFER_SIZE:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->default_buffer_size_index;
    break;
  case TS_CONFIG_HTTP_DEFAULT_BUFFER_WATER_MARK:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->default_buffer_water_mark;
    break;
  case TS_CONFIG_HTTP_REQUEST_HEADER_MAX_SIZE:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->request_hdr_max_size;
    break;
  case TS_CONFIG_HTTP_RESPONSE_HEADER_MAX_SIZE:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->response_hdr_max_size;
    break;
  case TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_ENABLED:
    ret = &sm->t_state.txn_conf->negative_revalidating_enabled;
    break;
  case TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_LIFETIME:
    typ = OVERRIDABLE_TYPE_INT;
    ret = &sm->t_state.txn_conf->negative_revalidating_lifetime;
    break;
  case TS_CONFIG_HTTP_ACCEPT_ENCODING_FILTER_ENABLED:
    ret = &sm->t_state.txn_conf->accept_encoding_filter_enabled;
    break;

    // This helps avoiding compiler warnings, yet detect unhandled enum members.
  case TS_CONFIG_NULL:
  case TS_CONFIG_LAST_ENTRY:
    typ = OVERRIDABLE_TYPE_NULL;
    ret = NULL;
    break;
  }

  *typep = typ;

  return ret;
}

/* 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);
  OverridableDataType type;

  s->t_state.setup_per_txn_configs();

  void *dest = _conf_to_memberp(conf, s, &type);

  if (!dest)
    return TS_ERROR;

  switch (type) {
  case OVERRIDABLE_TYPE_INT:
    *(static_cast<TSMgmtInt*>(dest)) = value;
    break;
  case OVERRIDABLE_TYPE_BYTE:
    *(static_cast<TSMgmtByte*>(dest)) = static_cast<TSMgmtByte>(value);
    break;
  default:
    return TS_ERROR;
  }

  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);

  OverridableDataType type;
  void* src = _conf_to_memberp(conf, (HttpSM*)txnp, &type);

  if (!src)
    return TS_ERROR;

  switch (type) {
  case OVERRIDABLE_TYPE_INT:
    *value = *(static_cast<TSMgmtInt*>(src));
    break;
  case OVERRIDABLE_TYPE_BYTE:
    *value = *(static_cast<TSMgmtByte*>(src));
    break;
  default:
    return TS_ERROR;
  }

  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);
  OverridableDataType type;

  s->t_state.setup_per_txn_configs();

  TSMgmtFloat* dest = static_cast<TSMgmtFloat*>(_conf_to_memberp(conf, s, &type));

  if (type != OVERRIDABLE_TYPE_FLOAT)
    return TS_ERROR;

  if (dest) {
    *dest = value;
    return TS_SUCCESS;
  }

  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((void*)value) == TS_SUCCESS);

  OverridableDataType type;
  TSMgmtFloat* dest = static_cast<TSMgmtFloat*>(_conf_to_memberp(conf, (HttpSM*)txnp, &type));

  if (type != OVERRIDABLE_TYPE_FLOAT)
    return TS_ERROR;

  if (dest) {
    *value = *dest;
    return TS_SUCCESS;
  }

  return TS_SUCCESS;
}

TSReturnCode
TSHttpTxnConfigStringSet(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);

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

  HttpSM *s = (HttpSM*) txnp;

  s->t_state.setup_per_txn_configs();

  switch (conf) {
  case TS_CONFIG_HTTP_RESPONSE_SERVER_STR:
    s->t_state.txn_conf->proxy_response_server_string = const_cast<char*>(value); // The "core" likes non-const char*
    s->t_state.txn_conf->proxy_response_server_string_len = length;
    break;
  default:
    return TS_ERROR;
    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 = (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;
  default:
    return TS_ERROR;
    break;
  }

  return TS_SUCCESS;
}


// This is pretty suboptimal, and should only be used outside the critical path.
TSReturnCode
TSHttpTxnConfigFind(const char* name, int length, TSOverridableConfigKey *conf, TSRecordDataType *type)
{
  sdk_assert(sdk_sanity_check_null_ptr((void*)name) == TS_SUCCESS);
  sdk_assert(sdk_sanity_check_null_ptr((void*)conf) == TS_SUCCESS);

  TSOverridableConfigKey cnf = TS_CONFIG_NULL;
  TSRecordDataType typ = TS_RECORDDATATYPE_INT;

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

  // Lots of string comparisons here, but we avoid quite a few by checking lengths
  switch (length) {
  case 28:
    if (!strncmp(name, "proxy.config.http.cache.http", length))
      cnf = TS_CONFIG_HTTP_CACHE_HTTP;
    break;

  case 31:
    if (!strncmp(name, "proxy.config.http.chunking.size", length))
      cnf = TS_CONFIG_HTTP_CHUNKING_SIZE;
    break;

  case 33:
    if (!strncmp(name, "proxy.config.http.cache.fuzz.time", length))
      cnf = TS_CONFIG_HTTP_CACHE_FUZZ_TIME;
    break;

  case 34:
    if (!strncmp(name, "proxy.config.http.chunking_enabled", length))
      cnf = TS_CONFIG_HTTP_CHUNKING_ENABLED;
    break;

  case 35:
    if (!strncmp(name, "proxy.config.http.normalize_ae_gzip", length))
      cnf = TS_CONFIG_HTTP_NORMALIZE_AE_GZIP;
    break;

  case 36:
    switch (name[length-1]) {
    case 'p':
      if (!strncmp(name, "proxy.config.http.cache.range.lookup", length))
        cnf = TS_CONFIG_HTTP_CACHE_RANGE_LOOKUP;
      break;
    case 't':
      if (!strncmp(name, "proxy.config.net.sock_packet_tos_out", length))
        cnf = TS_CONFIG_NET_SOCK_PACKET_TOS_OUT;
      break;
    }
    break;

  case 37:
    switch (name[length-1]) {
    case 'e':
      if (!strncmp(name, "proxy.config.http.cache.max_stale_age", length))
        cnf = TS_CONFIG_HTTP_CACHE_MAX_STALE_AGE;
      else if (!strncmp(name, "proxy.config.http.cache.fuzz.min_time", length))
        cnf = TS_CONFIG_HTTP_CACHE_FUZZ_MIN_TIME;
      else if (!strncmp(name, "proxy.config.http.default_buffer_size", length))
        cnf = TS_CONFIG_HTTP_DEFAULT_BUFFER_SIZE;
      break;
    case 'r':
      if (!strncmp(name, "proxy.config.http.response_server_str", length)) {
        cnf = TS_CONFIG_HTTP_RESPONSE_SERVER_STR;
        typ = TS_RECORDDATATYPE_STRING;
      }
      break;
    case 't':
      if (!strncmp(name, "proxy.config.http.keep_alive_post_out", length))
        cnf = TS_CONFIG_HTTP_KEEP_ALIVE_POST_OUT;
      else if (!strncmp(name, "proxy.config.net.sock_option_flag_out", length))
        cnf = TS_CONFIG_NET_SOCK_OPTION_FLAG_OUT;
      else if (!strncmp(name, "proxy.config.net.sock_packet_mark_out", length))
        cnf = TS_CONFIG_NET_SOCK_PACKET_MARK_OUT;
      break;
    }
    break;

  case 38:
    switch (name[length-1]) {
    case 'd':
      if (!strncmp(name, "proxy.config.http.server_tcp_init_cwnd", length))
        cnf = TS_CONFIG_HTTP_SERVER_TCP_INIT_CWND;
      else if (!strncmp(name, "proxy.config.http.flow_control.enabled", length))
        cnf = TS_CONFIG_HTTP_FLOW_CONTROL_ENABLED;
      break;
      break;
    case 's':
      if (!strncmp(name, "proxy.config.http.send_http11_requests", length))
        cnf = TS_CONFIG_HTTP_SEND_HTTP11_REQUESTS;
      break;
    }
    break;

  case 39:
    switch (name[length-1]) {
    case 'm':
      if (!strncmp(name, "proxy.config.http.anonymize_remove_from", length))
        cnf = TS_CONFIG_HTTP_ANONYMIZE_REMOVE_FROM;
      break;
    case 'n':
      if (!strncmp(name, "proxy.config.http.keep_alive_enabled_in", length))
        cnf = TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_IN;
      break;
    case 's':
      if (!strncmp(name, "proxy.config.http.doc_in_cache_skip_dns", length))
        cnf = TS_CONFIG_HTTP_DOC_IN_CACHE_SKIP_DNS;
      else if (!strncmp(name, "proxy.config.http.share_server_sessions", length))
        cnf = TS_CONFIG_HTTP_SHARE_SERVER_SESSIONS;
      break;
    }
    break;

  case 40:
    switch (name[length-1]) {
    case 'e':
      if (!strncmp(name, "proxy.config.http.down_server.cache_time", length))
        cnf = TS_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME;
      else if (!strncmp(name, "proxy.config.http.insert_age_in_response", length))
        cnf = TS_CONFIG_HTTP_INSERT_AGE_IN_RESPONSE;
      break;
    case 'r':
      if (!strncmp(name, "proxy.config.url_remap.pristine_host_hdr", length))
        cnf = TS_CONFIG_URL_REMAP_PRISTINE_HOST_HDR;
      else if (!strncmp(name, "proxy.config.http.insert_request_via_str", length))
        cnf = TS_CONFIG_HTTP_INSERT_REQUEST_VIA_STR;
      else if (!strncmp(name, "proxy.config.http.flow_control.low_water", length))
        cnf = TS_CONFIG_HTTP_FLOW_CONTROL_LOW_WATER_MARK;
      break;
    case 's':
      if (!strncmp(name, "proxy.config.http.origin_max_connections", length))
        cnf = TS_CONFIG_HTTP_ORIGIN_MAX_CONNECTIONS;
      else if (!strncmp(name, "proxy.config.http.cache.required_headers", length))
        cnf = TS_CONFIG_HTTP_CACHE_REQUIRED_HEADERS;
      break;
    case 't':
      if (!strncmp(name, "proxy.config.http.keep_alive_enabled_out", length))
        cnf = TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_OUT;
      break;
    case 'y':
      if (!strncmp(name, "proxy.config.http.cache.fuzz.probability", length)) {
        typ = TS_RECORDDATATYPE_FLOAT;
        cnf = TS_CONFIG_HTTP_CACHE_FUZZ_PROBABILITY;
      }
      break;
    }
    break;

  case 41:
    switch (name[length-1]) {
    case 'd':
      if (!strncmp(name, "proxy.config.http.response_server_enabled", length))
        cnf = TS_CONFIG_HTTP_RESPONSE_SERVER_ENABLED;
      break;
    case 'e':
      if (!strncmp(name, "proxy.config.http.anonymize_remove_cookie", length))
        cnf = TS_CONFIG_HTTP_ANONYMIZE_REMOVE_COOKIE;
      else if (!strncmp(name, "proxy.config.http.request_header_max_size", length))
        cnf = TS_CONFIG_HTTP_REQUEST_HEADER_MAX_SIZE;
      break;
    case 'r':
      if (!strncmp(name, "proxy.config.http.insert_response_via_str", length))
        cnf = TS_CONFIG_HTTP_INSERT_RESPONSE_VIA_STR;
      else if (!strncmp(name, "proxy.config.http.flow_control.high_water", length))
        cnf = TS_CONFIG_HTTP_FLOW_CONTROL_HIGH_WATER_MARK;
      break;
    }
    break;

  case 42:
    switch (name[length-1]) {
    case 'd':
      if (!strncmp(name, "proxy.config.http.negative_caching_enabled", length))
        cnf = TS_CONFIG_HTTP_NEGATIVE_CACHING_ENABLED;
      break;
    case 'e':
      if (!strncmp(name, "proxy.config.http.cache.when_to_revalidate", length))
        cnf = TS_CONFIG_HTTP_CACHE_WHEN_TO_REVALIDATE;
      else if (!strncmp(name, "proxy.config.http.response_header_max_size", length))
        cnf = TS_CONFIG_HTTP_RESPONSE_HEADER_MAX_SIZE;
      break;
    case 'r':
      if (!strncmp(name, "proxy.config.http.anonymize_remove_referer", length))
        cnf = TS_CONFIG_HTTP_ANONYMIZE_REMOVE_REFERER;
      break;
    case 't':
      if (!strncmp(name, "proxy.config.net.sock_recv_buffer_size_out", length))
        cnf = TS_CONFIG_NET_SOCK_RECV_BUFFER_SIZE_OUT;
      else if (!strncmp(name, "proxy.config.net.sock_send_buffer_size_out", length))
        cnf = TS_CONFIG_NET_SOCK_SEND_BUFFER_SIZE_OUT;
      else if (!strncmp(name, "proxy.config.http.connect_attempts_timeout", length))
        cnf = TS_CONFIG_HTTP_CONNECT_ATTEMPTS_TIMEOUT;
      break;
    }
    break;

  case 43:
    switch (name[length-1]) {
    case 'e':
      if (!strncmp(name, "proxy.config.http.negative_caching_lifetime", length))
        cnf = TS_CONFIG_HTTP_NEGATIVE_CACHING_LIFETIME;
      break;
    case 'k':
      if (!strncmp(name, "proxy.config.http.default_buffer_water_mark", length))
        cnf = TS_CONFIG_HTTP_DEFAULT_BUFFER_WATER_MARK;
      break;
    case 'l':
      if (!strncmp(name, "proxy.config.http.cache.cluster_cache_local", length))
        cnf = TS_CONFIG_HTTP_CACHE_CLUSTER_CACHE_LOCAL;
      break;
    case 'r':
      if (!strncmp(name, "proxy.config.http.cache.heuristic_lm_factor", length)) {
        typ = TS_RECORDDATATYPE_FLOAT;
        cnf = TS_CONFIG_HTTP_CACHE_HEURISTIC_LM_FACTOR;
      }
      break;
    }
    break;

  case 44:
    if (!strncmp(name, "proxy.config.http.anonymize_remove_client_ip", length))
      cnf = TS_CONFIG_HTTP_ANONYMIZE_REMOVE_CLIENT_IP;
    else if (!strncmp(name, "proxy.config.http.anonymize_insert_client_ip", length))
      cnf = TS_CONFIG_HTTP_ANONYMIZE_INSERT_CLIENT_IP;
    break;

  case 45:
    switch (name[length-1]) {
    case 'd':
      if (!strncmp(name, "proxy.config.http.down_server.abort_threshold", length))
        cnf = TS_CONFIG_HTTP_DOWN_SERVER_ABORT_THRESHOLD;
      break;
    case 'n':
      if (!strncmp(name, "proxy.config.http.cache.ignore_authentication", length))
        cnf = TS_CONFIG_HTTP_CACHE_IGNORE_AUTHENTICATION;
      break;
    case 't':
      if (!strncmp(name, "proxy.config.http.anonymize_remove_user_agent", length))
        cnf = TS_CONFIG_HTTP_ANONYMIZE_REMOVE_USER_AGENT;
      break;
    case 's':
      if (!strncmp(name, "proxy.config.http.connect_attempts_rr_retries", length))
        cnf = TS_CONFIG_HTTP_CONNECT_ATTEMPTS_RR_RETRIES;
      break;
    }
    break;

  case 46:
    switch (name[length-1]) {
    case 'e':
      if (!strncmp(name, "proxy.config.http.cache.ignore_client_no_cache", length))
        cnf = TS_CONFIG_HTTP_CACHE_IGNORE_CLIENT_NO_CACHE;
      else if (!strncmp(name, "proxy.config.http.cache.ims_on_client_no_cache", length))
        cnf = TS_CONFIG_HTTP_CACHE_IMS_ON_CLIENT_NO_CACHE;
      else if (!strncmp(name, "proxy.config.http.cache.ignore_server_no_cache", length))
        cnf = TS_CONFIG_HTTP_CACHE_IGNORE_SERVER_NO_CACHE;
      else if (!strncmp(name, "proxy.config.http.cache.heuristic_min_lifetime", length))
        cnf = TS_CONFIG_HTTP_CACHE_HEURISTIC_MIN_LIFETIME;
      else if (!strncmp(name, "proxy.config.http.cache.heuristic_max_lifetime", length))
        cnf = TS_CONFIG_HTTP_CACHE_HEURISTIC_MAX_LIFETIME;
      break;
    case 'r':
      if (!strncmp(name, "proxy.config.http.insert_squid_x_forwarded_for", length))
        cnf = TS_CONFIG_HTTP_INSERT_SQUID_X_FORWARDED_FOR;
      break;
    case 's':
      if (!strncmp(name, "proxy.config.http.connect_attempts_max_retries", length))
        cnf = TS_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES;
      break;
    case 't':
      if (!strncmp(name, "proxy.config.http.forward.proxy_auth_to_parent", length))
        cnf = TS_CONFIG_HTTP_FORWARD_PROXY_AUTH_TO_PARENT;
      break;
    }
    break;

  case 47:
    switch (name[length-1]) {
    case 'd':
      if (!strncmp(name, "proxy.config.http.negative_revalidating_enabled", length))
        cnf = TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_ENABLED;
      break;
    case 'e':
      if (!strncmp(name, "proxy.config.http.cache.guaranteed_min_lifetime", length))
        cnf = TS_CONFIG_HTTP_CACHE_GUARANTEED_MIN_LIFETIME;
      else if (!strncmp(name, "proxy.config.http.cache.guaranteed_max_lifetime", length))
        cnf = TS_CONFIG_HTTP_CACHE_GUARANTEED_MAX_LIFETIME;
      break;
    case 't':
      if (!strncmp(name, "proxy.config.http.post_connect_attempts_timeout", length))
        cnf = TS_CONFIG_HTTP_POST_CONNECT_ATTEMPTS_TIMEOUT;
      break;
    }
    break;

  case 48:
    switch (name[length-1]) {
    case 'd':
      if (!strncmp(name, "proxy.config.http.accept_encoding_filter_enabled", length))
        cnf = TS_CONFIG_HTTP_ACCEPT_ENCODING_FILTER_ENABLED;
      break;
    case 'e':
      if (!strncmp(name, "proxy.config.http.cache.ignore_client_cc_max_age", length))
        cnf = TS_CONFIG_HTTP_CACHE_IGNORE_CLIENT_CC_MAX_AGE;
      else if (!strncmp(name, "proxy.config.http.negative_revalidating_lifetime", length))
        cnf = TS_CONFIG_HTTP_NEGATIVE_REVALIDATING_LIFETIME;
      break;
    case 't':
      switch (name[length-4]) {
      case '_':
        if (!strncmp(name, "proxy.config.http.transaction_active_timeout_out", length))
          cnf = TS_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_OUT;
        break;
      case 'e':
          if (!strncmp(name, "proxy.config.http.background_fill_active_timeout", length)) {
            cnf = TS_CONFIG_HTTP_BACKGROUND_FILL_ACTIVE_TIMEOUT;
          }
          break;
      }
      break;
    }
    break;

  case 50:
    if (!strncmp(name, "proxy.config.http.cache.cache_responses_to_cookies", length))
      cnf = TS_CONFIG_HTTP_CACHE_CACHE_RESPONSES_TO_COOKIES;
    break;

  case 51:
    if (!strncmp(name, "proxy.config.http.keep_alive_no_activity_timeout_in", length))
      cnf = TS_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_IN;
    break;

  case 52:
    switch (name[length-1]) {
    case 'c':
      if (!strncmp(name, "proxy.config.http.cache.cache_urls_that_look_dynamic", length))
        cnf = TS_CONFIG_HTTP_CACHE_CACHE_URLS_THAT_LOOK_DYNAMIC;
      break;
    case 'n':
      if (!strncmp(name, "proxy.config.http.transaction_no_activity_timeout_in", length))
        cnf = TS_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_IN;
      break;
    case 't':
      if (!strncmp(name, "proxy.config.http.keep_alive_no_activity_timeout_out", length))
        cnf = TS_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_OUT;
      break;
    }
    break;

  case 53:
    switch (name[length-1]) {
      case 't':
      if (!strncmp(name, "proxy.config.http.transaction_no_activity_timeout_out", length))
        cnf = TS_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_OUT;
      break;
      case 'd':
        if (!strncmp(name, "proxy.config.http.background_fill_completed_threshold", length)) {
          typ = TS_RECORDDATATYPE_FLOAT;
          cnf = TS_CONFIG_HTTP_BACKGROUND_FILL_COMPLETED_THRESHOLD;
        }
      break;
    }
    break;

  case 58:
   if (!strncmp(name, "proxy.config.http.connect_attempts_max_retries_dead_server", length))
     cnf = TS_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES_DEAD_SERVER;
   break;
  }

  *conf = cnf;
  if (type)
    *type = typ;

  return ((cnf != TS_CONFIG_NULL) ? TS_SUCCESS: TS_ERROR);
}

TSReturnCode
TSHttpTxnPrivateSessionSet(TSHttpTxn txnp, int private_session)
{
  if (sdk_sanity_check_txn(txnp) != TS_SUCCESS) {
    return TS_ERROR;
  }
  HttpSM *sm = (HttpSM *) txnp;
  if (sm->set_server_session_private(private_session)) {
    return TS_SUCCESS;
  }
  return TS_ERROR;
}

// APIs to register new Mgmt (records.config) 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 == NULL && check_type != TS_RECORDCHECK_NULL)
      return TS_ERROR;
  if (REC_ERR_OKAY != RecRegisterConfigString((enum RecT)rec_type, name, data_default, (enum RecUpdateT)update_type,
                                              (enum RecCheckT)check_type, check_regex, (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 == NULL && check_type != TS_RECORDCHECK_NULL)
      return TS_ERROR;
  if (REC_ERR_OKAY != RecRegisterConfigInt((enum RecT)rec_type, name, (RecInt)data_default, (enum RecUpdateT)update_type,
                                           (enum RecCheckT)check_type, check_regex, (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 = (HttpSM*)txnp;
    if (should_close) {
        sm->t_state.client_info.keep_alive = HTTP_NO_KEEPALIVE;
        if (sm->ua_session) sm->set_ua_half_close_flag();
    }
    // Don't change if PIPELINE is set...
    else if (sm->t_state.client_info.keep_alive == HTTP_NO_KEEPALIVE) {
        sm->t_state.client_info.keep_alive = HTTP_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(new HttpProxyPort());

  if (descriptor && port->processOptions(descriptor)) {
    return (TSPortDescriptor)port;
  }

  delete port;
  return NULL;
}

TSReturnCode
TSPortDescriptorAccept(TSPortDescriptor descp, TSCont contp)
{
  Action * action = NULL;
  HttpProxyPort * port = (HttpProxyPort *)descp;
  NetProcessor::AcceptOptions net(make_net_accept_options(*port, 0 /* nthreads */));

  if (port->isSSL()) {
    action = sslNetProcessor.main_accept((INKContInternal *)contp, port->m_fd, net);
  } else {
    action = netProcessor.main_accept((INKContInternal *)contp, port->m_fd, net);
  }

  return action ? TS_SUCCESS : TS_ERROR;
}

TSReturnCode
TSPluginDescriptorAccept(TSCont contp)
{
  Action * action = NULL;

  HttpProxyPort::Group& proxy_ports = HttpProxyPort::global();
  for ( int i = 0 , n = proxy_ports.length() ; i < n ; ++i ) {
    HttpProxyPort& port = proxy_ports[i];
    if (port.isPlugin()) {
      NetProcessor::AcceptOptions net(make_net_accept_options(port, 0 /* nthreads */));
      action = netProcessor.main_accept((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 = (HttpSM*) txnp;

  return (s->background_fill == BACKGROUND_FILL_STARTED);
}
