This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 7d6248e  Moves traffic_server to cmd/traffic_server
7d6248e is described below

commit 7d6248ea44da16d1e263f0f332c74b1e5f753fc8
Author: Leif Hedstrom <[email protected]>
AuthorDate: Tue Jun 5 13:51:20 2018 +0200

    Moves traffic_server to cmd/traffic_server
---
 .gitignore                                         |    4 +-
 CMakeLists.txt                                     |   31 +-
 Makefile.am                                        |    3 +-
 cmd/Makefile.am                                    |    1 +
 {proxy => cmd/traffic_server}/CoreUtils.cc         |    0
 {proxy => cmd/traffic_server}/CoreUtils.h          |    0
 {proxy => cmd/traffic_server}/Crash.cc             |    0
 {proxy => cmd/traffic_server}/EventName.cc         |    0
 {proxy => cmd/traffic_server}/EventName.h          |    0
 {proxy => cmd/traffic_server}/FetchSM.cc           |    0
 {proxy => cmd/traffic_server}/FetchSM.h            |    0
 {proxy => cmd/traffic_server}/HostStatus.cc        |    0
 {proxy => cmd/traffic_server}/InkAPI.cc            |    0
 {proxy => cmd/traffic_server}/InkAPITest.cc        | 1092 ++++++++++++++++++-
 {proxy => cmd/traffic_server}/InkIOCoreAPI.cc      |    0
 cmd/traffic_server/Makefile.am                     |  111 ++
 {proxy => cmd/traffic_server}/SocksProxy.cc        |    0
 .../traffic_server/traffic_server.cc               |    0
 configure.ac                                       |    3 +-
 proxy/CompletionUtil.h                             |   44 -
 proxy/InkAPITestTool.cc                            | 1103 --------------------
 proxy/Makefile.am                                  |  167 +--
 proxy/UnixCompletionUtil.h                         |  102 --
 23 files changed, 1264 insertions(+), 1397 deletions(-)

diff --git a/.gitignore b/.gitignore
index f4518df..937a7d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,6 +57,7 @@ cmd/traffic_layout/traffic_layout
 cmd/traffic_logcat/traffic_logcat
 cmd/traffic_logstats/traffic_logstats
 cmd/traffic_manager/traffic_manager
+cmd/traffic_server/traffic_server
 cmd/traffic_top/traffic_top
 cmd/traffic_via/traffic_via
 cmd/traffic_wccp/traffic_wccp
@@ -130,9 +131,6 @@ mgmt/api/api_cli_remote
 mgmt/tools/shmem_clean
 mgmt/utils/test_marshall
 
-proxy/traffic_server
-proxy/test_xml_parser
-
 libtool
 m4/libtool.m4
 m4/ltoptions.m4
diff --git a/CMakeLists.txt b/CMakeLists.txt
index edcf8d0..5188e0b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,6 +94,22 @@ add_executable(traffic_manager
         cmd/traffic_manager/traffic_manager.cc
 )
 
+add_executable(traffic_server
+        cmd/traffic_server/CoreUtils.cc
+        cmd/traffic_server/CoreUtils.h
+        cmd/traffic_server/Crash.cc
+        cmd/traffic_server/EventName.cc
+        cmd/traffic_server/EventName.h
+        cmd/traffic_server/FetchSM.cc
+        cmd/traffic_server/FetchSM.h
+        cmd/traffic_server/HostStatus.cc
+        cmd/traffic_server/InkAPI.cc
+        cmd/traffic_server/InkAPITest.cc
+        cmd/traffic_server/InkIOCoreAPI.cc
+        cmd/traffic_server/SocksProxy.cc
+        cmd/traffic_server/traffic_server.cc
+)
+
 add_executable(ats
         cmd/traffic_via/traffic_via.cc
         cmd/traffic_wccp/wccp_client.cc
@@ -1054,26 +1070,13 @@ add_executable(ats
         proxy/shared/UglyLogStubs.cc
         proxy/CacheControl.cc
         proxy/CacheControl.h
-        proxy/CompletionUtil.h
         proxy/ControlBase.cc
         proxy/ControlBase.h
         proxy/ControlMatcher.cc
         proxy/ControlMatcher.h
-        proxy/CoreUtils.cc
-        proxy/CoreUtils.h
-        proxy/Crash.cc
-        proxy/EventName.cc
-        proxy/EventName.h
-        proxy/FetchSM.cc
-        proxy/FetchSM.h
-        proxy/InkAPI.cc
         proxy/InkAPIInternal.h
-        proxy/InkAPITest.cc
-        proxy/InkAPITestTool.cc
-        proxy/InkIOCoreAPI.cc
         proxy/IPAllow.cc
         proxy/IPAllow.h
-        proxy/Main.cc
         proxy/Main.h
         proxy/Milestones.h
         proxy/ParentConsistentHash.cc
@@ -1098,14 +1101,12 @@ add_executable(ats
         proxy/ReverseProxy.cc
         proxy/ReverseProxy.h
         proxy/Show.h
-        proxy/SocksProxy.cc
         proxy/StatPages.cc
         proxy/StatPages.h
         proxy/TimeTrace.h
         proxy/Transform.cc
         proxy/Transform.h
         proxy/TransformInternal.h
-        proxy/UnixCompletionUtil.h
         tests/gold_tests/tls/ssl-post.c
         tests/include/catch.hpp
         tests/tools/plugins/continuations_verify.cc
diff --git a/Makefile.am b/Makefile.am
index 19b3116..221e6fa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -28,13 +28,12 @@ export CCACHE_BASEDIR
 
 # proxy/api/ts has to be built first, since so much of libraries and "core
 # depends on the generates ts/ts.h include file.
+SUBDIRS = proxy/api/ts lib iocore proxy mgmt cmd plugins tools example rc
 
-SUBDIRS = proxy/api/ts lib iocore proxy/hdrs proxy/shared mgmt proxy cmd 
plugins tools example rc
 if BUILD_DOCS
 SUBDIRS += doc
 endif
 
-
 DIST_BUILD_USER=`id -nu`
 DIST_BUILD_USER_GROUP=`id -ng`
 DISTCHECK_CONFIGURE_FLAGS=--with-user=${DIST_BUILD_USER} 
--with-group=${DIST_BUILD_USER_GROUP}
diff --git a/cmd/Makefile.am b/cmd/Makefile.am
index d66468f..3370dfb 100644
--- a/cmd/Makefile.am
+++ b/cmd/Makefile.am
@@ -23,6 +23,7 @@ SUBDIRS = \
        traffic_logcat \
        traffic_logstats \
        traffic_manager \
+       traffic_server \
        traffic_top \
        traffic_via
 
diff --git a/proxy/CoreUtils.cc b/cmd/traffic_server/CoreUtils.cc
similarity index 100%
rename from proxy/CoreUtils.cc
rename to cmd/traffic_server/CoreUtils.cc
diff --git a/proxy/CoreUtils.h b/cmd/traffic_server/CoreUtils.h
similarity index 100%
rename from proxy/CoreUtils.h
rename to cmd/traffic_server/CoreUtils.h
diff --git a/proxy/Crash.cc b/cmd/traffic_server/Crash.cc
similarity index 100%
rename from proxy/Crash.cc
rename to cmd/traffic_server/Crash.cc
diff --git a/proxy/EventName.cc b/cmd/traffic_server/EventName.cc
similarity index 100%
rename from proxy/EventName.cc
rename to cmd/traffic_server/EventName.cc
diff --git a/proxy/EventName.h b/cmd/traffic_server/EventName.h
similarity index 100%
rename from proxy/EventName.h
rename to cmd/traffic_server/EventName.h
diff --git a/proxy/FetchSM.cc b/cmd/traffic_server/FetchSM.cc
similarity index 100%
rename from proxy/FetchSM.cc
rename to cmd/traffic_server/FetchSM.cc
diff --git a/proxy/FetchSM.h b/cmd/traffic_server/FetchSM.h
similarity index 100%
rename from proxy/FetchSM.h
rename to cmd/traffic_server/FetchSM.h
diff --git a/proxy/HostStatus.cc b/cmd/traffic_server/HostStatus.cc
similarity index 100%
rename from proxy/HostStatus.cc
rename to cmd/traffic_server/HostStatus.cc
diff --git a/proxy/InkAPI.cc b/cmd/traffic_server/InkAPI.cc
similarity index 100%
rename from proxy/InkAPI.cc
rename to cmd/traffic_server/InkAPI.cc
diff --git a/proxy/InkAPITest.cc b/cmd/traffic_server/InkAPITest.cc
similarity index 91%
rename from proxy/InkAPITest.cc
rename to cmd/traffic_server/InkAPITest.cc
index 8fae375..688cbe3 100644
--- a/proxy/InkAPITest.cc
+++ b/cmd/traffic_server/InkAPITest.cc
@@ -27,29 +27,1107 @@
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #endif
 
-#include "ts/ink_config.h"
-#include "ts/ink_sprintf.h"
-#include "ts/ink_file.h"
 #include <sys/types.h>
+#include <arpa/inet.h> /* For htonl */
 
 #include <cerrno>
-// extern int errno;
-
 #include <pthread.h>
 #include <unistd.h>
 #include <cstdio>
 #include <cstring>
 
+#include "ts/ink_config.h"
+#include "ts/ink_sprintf.h"
+#include "ts/ink_file.h"
 #include "ts/Regression.h"
 #include "api/ts/ts.h"
 #include "api/ts/experimental.h"
 #include "I_RecCore.h"
-#include <sys/types.h>
 
-#include "InkAPITestTool.cc"
+#include "P_Net.h"
+#include "records/I_RecHttp.h"
+
 #include "http/HttpSM.h"
 #include "ts/TestBox.h"
 
+// This used to be in InkAPITestTool.cc, which we'd just #include here... But 
that seemed silly.
+#define SDBG_TAG "SockServer"
+#define CDBG_TAG "SockClient"
+
+#define IP(a, b, c, d) htonl((a) << 24 | (b) << 16 | (c) << 8 | (d))
+
+#define SET_TEST_HANDLER(_d, _s) \
+  {                              \
+    _d = _s;                     \
+  }
+
+#define MAGIC_ALIVE 0xfeedbaba
+#define MAGIC_DEAD 0xdeadbeef
+
+#define SYNSERVER_LISTEN_PORT 3300
+#define SYNSERVER_DUMMY_PORT -1
+
+#define PROXY_CONFIG_NAME_HTTP_PORT "proxy.config.http.server_port"
+#define PROXY_HTTP_DEFAULT_PORT 8080
+
+#define REQUEST_MAX_SIZE 4095
+#define RESPONSE_MAX_SIZE 4095
+
+#define HTTP_REQUEST_END "\r\n\r\n"
+
+// each request/response includes an identifier as a Mime field
+#define X_REQUEST_ID "X-Request-ID"
+#define X_RESPONSE_ID "X-Response-ID"
+
+#define ERROR_BODY "TESTING ERROR PAGE"
+#define TRANSFORM_APPEND_STRING "This is a transformed response"
+
+//////////////////////////////////////////////////////////////////////////////
+// STRUCTURES
+//////////////////////////////////////////////////////////////////////////////
+
+typedef int (*TxnHandler)(TSCont contp, TSEvent event, void *data);
+
+/* Server transaction structure */
+typedef struct {
+  TSVConn vconn;
+
+  TSVIO read_vio;
+  TSIOBuffer req_buffer;
+  TSIOBufferReader req_reader;
+
+  TSVIO write_vio;
+  TSIOBuffer resp_buffer;
+  TSIOBufferReader resp_reader;
+
+  char request[REQUEST_MAX_SIZE + 1];
+  int request_len;
+
+  TxnHandler current_handler;
+  unsigned int magic;
+} ServerTxn;
+
+/* Server structure */
+typedef struct {
+  int accept_port;
+  TSAction accept_action;
+  TSCont accept_cont;
+  unsigned int magic;
+} SocketServer;
+
+typedef enum {
+  REQUEST_SUCCESS,
+  REQUEST_INPROGRESS,
+  REQUEST_FAILURE,
+} RequestStatus;
+
+/* Client structure */
+typedef struct {
+  TSVConn vconn;
+
+  TSVIO read_vio;
+  TSIOBuffer req_buffer;
+  TSIOBufferReader req_reader;
+
+  TSVIO write_vio;
+  TSIOBuffer resp_buffer;
+  TSIOBufferReader resp_reader;
+
+  char *request;
+  char response[RESPONSE_MAX_SIZE + 1];
+  int response_len;
+
+  RequestStatus status;
+
+  int connect_port;
+  int local_port;
+  uint64_t connect_ip;
+  TSAction connect_action;
+
+  TxnHandler current_handler;
+
+  unsigned int magic;
+} ClientTxn;
+
+//////////////////////////////////////////////////////////////////////////////
+// DECLARATIONS
+//////////////////////////////////////////////////////////////////////////////
+
+/* utility */
+static char *get_body_ptr(const char *request);
+static char *generate_request(int test_case);
+static char *generate_response(const char *request);
+static int get_request_id(TSHttpTxn txnp);
+
+/* client side */
+static ClientTxn *synclient_txn_create(void);
+static int synclient_txn_delete(ClientTxn *txn);
+static void synclient_txn_close(ClientTxn *txn);
+static int synclient_txn_send_request(ClientTxn *txn, char *request);
+static int synclient_txn_send_request_to_vc(ClientTxn *txn, char *request, 
TSVConn vc);
+static int synclient_txn_read_response(TSCont contp);
+static int synclient_txn_read_response_handler(TSCont contp, TSEvent event, 
void *data);
+static int synclient_txn_write_request(TSCont contp);
+static int synclient_txn_write_request_handler(TSCont contp, TSEvent event, 
void *data);
+static int synclient_txn_connect_handler(TSCont contp, TSEvent event, void 
*data);
+static int synclient_txn_main_handler(TSCont contp, TSEvent event, void *data);
+
+/* Server side */
+SocketServer *synserver_create(int port);
+static int synserver_start(SocketServer *s);
+static int synserver_stop(SocketServer *s);
+static int synserver_delete(SocketServer *s);
+static int synserver_vc_accept(TSCont contp, TSEvent event, void *data);
+static int synserver_vc_refuse(TSCont contp, TSEvent event, void *data);
+static int synserver_txn_close(TSCont contp);
+static int synserver_txn_write_response(TSCont contp);
+static int synserver_txn_write_response_handler(TSCont contp, TSEvent event, 
void *data);
+static int synserver_txn_read_request(TSCont contp);
+static int synserver_txn_read_request_handler(TSCont contp, TSEvent event, 
void *data);
+static int synserver_txn_main_handler(TSCont contp, TSEvent event, void *data);
+
+//////////////////////////////////////////////////////////////////////////////
+// REQUESTS/RESPONSES GENERATION
+//////////////////////////////////////////////////////////////////////////////
+
+static char *
+get_body_ptr(const char *request)
+{
+  char *ptr = (char *)strstr((const char *)request, (const char *)"\r\n\r\n");
+  return (ptr != nullptr) ? (ptr + 4) : nullptr;
+}
+
+/* Caller must free returned request */
+static char *
+generate_request(int test_case)
+{
+// We define request formats.
+// Each format has an X-Request-ID field that contains the id of the testcase
+#define HTTP_REQUEST_DEFAULT_FORMAT                   \
+  "GET http://127.0.0.1:%d/default.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                              \
+  "\r\n"
+
+#define HTTP_REQUEST_FORMAT1                          \
+  "GET http://127.0.0.1:%d/format1.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                              \
+  "\r\n"
+
+#define HTTP_REQUEST_FORMAT2                          \
+  "GET http://127.0.0.1:%d/format2.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                              \
+  "Content-Type: text/html\r\n"                       \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT3                          \
+  "GET http://127.0.0.1:%d/format3.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                              \
+  "Response: Error\r\n"                               \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT4                          \
+  "GET http://127.0.0.1:%d/format4.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                              \
+  "Request:%d\r\n"                                    \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT5                          \
+  "GET http://127.0.0.1:%d/format5.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                              \
+  "Request:%d\r\n"                                    \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT6                         \
+  "GET http://127.0.0.1:%d/format.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                             \
+  "Accept-Language: English\r\n"                     \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT7                         \
+  "GET http://127.0.0.1:%d/format.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                             \
+  "Accept-Language: French\r\n"                      \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT8                         \
+  "GET http://127.0.0.1:%d/format.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                             \
+  "Accept-Language: English,French\r\n"              \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT9                                      \
+  "GET http://trafficserver.apache.org/format9.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                                          \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT10                                      \
+  "GET http://trafficserver.apache.org/format10.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                                           \
+  "\r\n"
+#define HTTP_REQUEST_FORMAT11                                      \
+  "GET http://trafficserver.apache.org/format11.html HTTP/1.0\r\n" \
+  "X-Request-ID: %d\r\n"                                           \
+  "\r\n"
+  char *request = (char *)TSmalloc(REQUEST_MAX_SIZE + 1);
+
+  switch (test_case) {
+  case 1:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT1, 
SYNSERVER_LISTEN_PORT, test_case);
+    break;
+  case 2:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT2, 
SYNSERVER_LISTEN_PORT, test_case);
+    break;
+  case 3:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT3, 
SYNSERVER_LISTEN_PORT, test_case);
+    break;
+  case 4:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT4, 
SYNSERVER_LISTEN_PORT, test_case, 1);
+    break;
+  case 5:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT5, 
SYNSERVER_LISTEN_PORT, test_case, 2);
+    break;
+  case 6:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT6, 
SYNSERVER_LISTEN_PORT, test_case);
+    break;
+  case 7:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT7, 
SYNSERVER_LISTEN_PORT, test_case - 1);
+    break;
+  case 8:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT8, 
SYNSERVER_LISTEN_PORT, test_case - 2);
+    break;
+  case 9:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT9, test_case);
+    break;
+  case 10:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT10, test_case);
+    break;
+  case 11:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT11, test_case);
+    break;
+  default:
+    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_DEFAULT_FORMAT, 
SYNSERVER_LISTEN_PORT, test_case);
+    break;
+  }
+
+  return request;
+}
+
+/* Caller must free returned response */
+static char *
+generate_response(const char *request)
+{
+// define format for response
+// Each response contains a field X-Response-ID that contains the id of the 
testcase
+#define HTTP_REQUEST_TESTCASE_FORMAT \
+  "GET %1024s HTTP/1.%d\r\n"         \
+  "X-Request-ID: %d\r\n"
+
+#define HTTP_RESPONSE_DEFAULT_FORMAT \
+  "HTTP/1.0 200 OK\r\n"              \
+  "X-Response-ID: %d\r\n"            \
+  "Cache-Control: max-age=86400\r\n" \
+  "Content-Type: text/html\r\n"      \
+  "\r\n"                             \
+  "Default body"
+
+#define HTTP_RESPONSE_FORMAT1   \
+  "HTTP/1.0 200 OK\r\n"         \
+  "X-Response-ID: %d\r\n"       \
+  "Content-Type: text/html\r\n" \
+  "Cache-Control: no-cache\r\n" \
+  "\r\n"                        \
+  "Body for response 1"
+
+#define HTTP_RESPONSE_FORMAT2        \
+  "HTTP/1.0 200 OK\r\n"              \
+  "X-Response-ID: %d\r\n"            \
+  "Cache-Control: max-age=86400\r\n" \
+  "Content-Type: text/html\r\n"      \
+  "\r\n"                             \
+  "Body for response 2"
+#define HTTP_RESPONSE_FORMAT4        \
+  "HTTP/1.0 200 OK\r\n"              \
+  "X-Response-ID: %d\r\n"            \
+  "Cache-Control: max-age=86400\r\n" \
+  "Content-Type: text/html\r\n"      \
+  "\r\n"                             \
+  "Body for response 4"
+#define HTTP_RESPONSE_FORMAT5   \
+  "HTTP/1.0 200 OK\r\n"         \
+  "X-Response-ID: %d\r\n"       \
+  "Content-Type: text/html\r\n" \
+  "\r\n"                        \
+  "Body for response 5"
+#define HTTP_RESPONSE_FORMAT6        \
+  "HTTP/1.0 200 OK\r\n"              \
+  "X-Response-ID: %d\r\n"            \
+  "Cache-Control: max-age=86400\r\n" \
+  "Content-Language: English\r\n"    \
+  "\r\n"                             \
+  "Body for response 6"
+#define HTTP_RESPONSE_FORMAT7        \
+  "HTTP/1.0 200 OK\r\n"              \
+  "X-Response-ID: %d\r\n"            \
+  "Cache-Control: max-age=86400\r\n" \
+  "Content-Language: French\r\n"     \
+  "\r\n"                             \
+  "Body for response 7"
+
+#define HTTP_RESPONSE_FORMAT8             \
+  "HTTP/1.0 200 OK\r\n"                   \
+  "X-Response-ID: %d\r\n"                 \
+  "Cache-Control: max-age=86400\r\n"      \
+  "Content-Language: French, English\r\n" \
+  "\r\n"                                  \
+  "Body for response 8"
+
+#define HTTP_RESPONSE_FORMAT9        \
+  "HTTP/1.0 200 OK\r\n"              \
+  "Cache-Control: max-age=86400\r\n" \
+  "X-Response-ID: %d\r\n"            \
+  "\r\n"                             \
+  "Body for response 9"
+
+#define HTTP_RESPONSE_FORMAT10       \
+  "HTTP/1.0 200 OK\r\n"              \
+  "Cache-Control: max-age=86400\r\n" \
+  "X-Response-ID: %d\r\n"            \
+  "\r\n"                             \
+  "Body for response 10"
+
+#define HTTP_RESPONSE_FORMAT11          \
+  "HTTP/1.0 200 OK\r\n"                 \
+  "Cache-Control: private,no-store\r\n" \
+  "X-Response-ID: %d\r\n"               \
+  "\r\n"                                \
+  "Body for response 11"
+
+  int test_case, match, http_version;
+
+  char *response = (char *)TSmalloc(RESPONSE_MAX_SIZE + 1);
+  char url[1025];
+
+  // coverity[secure_coding]
+  match = sscanf(request, HTTP_REQUEST_TESTCASE_FORMAT, url, &http_version, 
&test_case);
+  if (match == 3) {
+    switch (test_case) {
+    case 1:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT1, 
test_case);
+      break;
+    case 2:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT2, 
test_case);
+      break;
+    case 4:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT4, 
test_case);
+      break;
+    case 5:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT5, 
test_case);
+      break;
+    case 6:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT6, 
test_case);
+      break;
+    case 7:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT7, 
test_case);
+      break;
+    case 8:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT8, 
test_case);
+      break;
+    case 9:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT9, 
test_case);
+      break;
+    case 10:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT10, 
test_case);
+      break;
+    case 11:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT11, 
test_case);
+      break;
+    default:
+      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_DEFAULT_FORMAT, 
test_case);
+      break;
+    }
+  } else {
+    /* Didin't recognize a testcase request. send the default response */
+    snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_DEFAULT_FORMAT, 
test_case);
+  }
+
+  return response;
+}
+
+static int
+get_request_id_value(const char *name, TSMBuffer buf, TSMLoc hdr)
+{
+  int id = -1;
+  TSMLoc field;
+
+  field = TSMimeHdrFieldFind(buf, hdr, name, -1);
+  if (field != TS_NULL_MLOC) {
+    id = TSMimeHdrFieldValueIntGet(buf, hdr, field, 0);
+  }
+
+  TSHandleMLocRelease(buf, hdr, field);
+  return id;
+}
+
+// This routine can be called by tests, from the READ_REQUEST_HDR_HOOK
+// to figure out the id of a test message
+// Returns id/-1 in case of error
+static int
+get_request_id(TSHttpTxn txnp)
+{
+  TSMBuffer bufp;
+  TSMLoc hdr_loc;
+  int id = -1;
+
+  if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
+    return -1;
+  }
+
+  id = get_request_id_value(X_REQUEST_ID, bufp, hdr_loc);
+  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+  return id;
+}
+
+// This routine can be called by tests, from the READ_RESPONSE_HDR_HOOK
+// to figure out the id of a test message
+// Returns id/-1 in case of error
+static int
+get_response_id(TSHttpTxn txnp)
+{
+  TSMBuffer bufp;
+  TSMLoc hdr_loc;
+  int id = -1;
+
+  if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
+    return -1;
+  }
+
+  id = get_request_id_value(X_RESPONSE_ID, bufp, hdr_loc);
+  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
+  return id;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// SOCKET CLIENT
+//////////////////////////////////////////////////////////////////////////////
+
+static ClientTxn *
+synclient_txn_create(void)
+{
+  const HttpProxyPort *proxy_port;
+
+  ClientTxn *txn = (ClientTxn *)TSmalloc(sizeof(ClientTxn));
+
+  ink_zero(*txn);
+
+  if (nullptr == (proxy_port = HttpProxyPort::findHttp(AF_INET))) {
+    txn->connect_port = PROXY_HTTP_DEFAULT_PORT;
+  } else {
+    txn->connect_port = proxy_port->m_port;
+  }
+
+  txn->connect_ip = IP(127, 0, 0, 1);
+  txn->status     = REQUEST_INPROGRESS;
+  txn->magic      = MAGIC_ALIVE;
+
+  TSDebug(CDBG_TAG, "Connecting to proxy 127.0.0.1 on port %d", 
txn->connect_port);
+  return txn;
+}
+
+static int
+synclient_txn_delete(ClientTxn *txn)
+{
+  TSAssert(txn->magic == MAGIC_ALIVE);
+  if (txn->connect_action && !TSActionDone(txn->connect_action)) {
+    TSActionCancel(txn->connect_action);
+    txn->connect_action = nullptr;
+  }
+
+  ats_free(txn->request);
+  txn->magic = MAGIC_DEAD;
+  TSfree(txn);
+  return 1;
+}
+
+static void
+synclient_txn_close(ClientTxn *txn)
+{
+  if (txn) {
+    if (txn->vconn != nullptr) {
+      TSVConnClose(txn->vconn);
+      txn->vconn = nullptr;
+    }
+
+    if (txn->req_buffer != nullptr) {
+      TSIOBufferDestroy(txn->req_buffer);
+      txn->req_buffer = nullptr;
+    }
+
+    if (txn->resp_buffer != nullptr) {
+      TSIOBufferDestroy(txn->resp_buffer);
+      txn->resp_buffer = nullptr;
+    }
+
+    TSDebug(CDBG_TAG, "Client Txn destroyed");
+  }
+}
+
+static int
+synclient_txn_send_request(ClientTxn *txn, char *request)
+{
+  TSCont cont;
+  sockaddr_in addr;
+
+  TSAssert(txn->magic == MAGIC_ALIVE);
+  txn->request = ats_strdup(request);
+  SET_TEST_HANDLER(txn->current_handler, synclient_txn_connect_handler);
+
+  cont = TSContCreate(synclient_txn_main_handler, TSMutexCreate());
+  TSContDataSet(cont, txn);
+
+  ats_ip4_set(&addr, txn->connect_ip, htons(txn->connect_port));
+  TSNetConnect(cont, ats_ip_sa_cast(&addr));
+  return 1;
+}
+
+/* This can be used to send a request to a specific VC */
+static int
+synclient_txn_send_request_to_vc(ClientTxn *txn, char *request, TSVConn vc)
+{
+  TSCont cont;
+  TSAssert(txn->magic == MAGIC_ALIVE);
+  txn->request = ats_strdup(request);
+  SET_TEST_HANDLER(txn->current_handler, synclient_txn_connect_handler);
+
+  cont = TSContCreate(synclient_txn_main_handler, TSMutexCreate());
+  TSContDataSet(cont, txn);
+
+  TSContCall(cont, TS_EVENT_NET_CONNECT, vc);
+  return 1;
+}
+
+static int
+synclient_txn_read_response(TSCont contp)
+{
+  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  TSIOBufferBlock block = TSIOBufferReaderStart(txn->resp_reader);
+  while (block != nullptr) {
+    int64_t blocklen;
+    const char *blockptr = TSIOBufferBlockReadStart(block, txn->resp_reader, 
&blocklen);
+
+    if (txn->response_len + blocklen <= RESPONSE_MAX_SIZE) {
+      memcpy((char *)(txn->response + txn->response_len), blockptr, blocklen);
+      txn->response_len += blocklen;
+    } else {
+      TSError("Error: Response length %" PRId64 " > response buffer size %d", 
txn->response_len + blocklen, RESPONSE_MAX_SIZE);
+    }
+
+    block = TSIOBufferBlockNext(block);
+  }
+
+  txn->response[txn->response_len] = '\0';
+  TSDebug(CDBG_TAG, "Response = |%s|, req len = %d", txn->response, 
txn->response_len);
+
+  return 1;
+}
+
+static int
+synclient_txn_read_response_handler(TSCont contp, TSEvent event, void * /* 
data ATS_UNUSED */)
+{
+  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  int64_t avail;
+
+  switch (event) {
+  case TS_EVENT_VCONN_READ_READY:
+  case TS_EVENT_VCONN_READ_COMPLETE:
+    if (event == TS_EVENT_VCONN_READ_READY) {
+      TSDebug(CDBG_TAG, "READ_READY");
+    } else {
+      TSDebug(CDBG_TAG, "READ_COMPLETE");
+    }
+
+    avail = TSIOBufferReaderAvail(txn->resp_reader);
+    TSDebug(CDBG_TAG, "%" PRId64 " bytes available in buffer", avail);
+
+    if (avail > 0) {
+      synclient_txn_read_response(contp);
+      TSIOBufferReaderConsume(txn->resp_reader, avail);
+    }
+
+    TSVIOReenable(txn->read_vio);
+    break;
+
+  case TS_EVENT_VCONN_EOS:
+    TSDebug(CDBG_TAG, "READ_EOS");
+    // Connection closed. In HTTP/1.0 it means we're done for this request.
+    txn->status = REQUEST_SUCCESS;
+    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
+    TSContDestroy(contp);
+    return 1;
+
+  case TS_EVENT_ERROR:
+    TSDebug(CDBG_TAG, "READ_ERROR");
+    txn->status = REQUEST_FAILURE;
+    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
+    TSContDestroy(contp);
+    return 1;
+
+  default:
+    TSAssert(!"Invalid event");
+    break;
+  }
+  return 1;
+}
+
+static int
+synclient_txn_write_request(TSCont contp)
+{
+  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  TSIOBufferBlock block;
+  char *ptr_block;
+  int64_t len, ndone, ntodo, towrite, avail;
+
+  len = strlen(txn->request);
+
+  ndone = 0;
+  ntodo = len;
+  while (ntodo > 0) {
+    block     = TSIOBufferStart(txn->req_buffer);
+    ptr_block = TSIOBufferBlockWriteStart(block, &avail);
+    towrite   = std::min(ntodo, avail);
+    memcpy(ptr_block, txn->request + ndone, towrite);
+    TSIOBufferProduce(txn->req_buffer, towrite);
+    ntodo -= towrite;
+    ndone += towrite;
+  }
+
+  /* Start writing the response */
+  TSDebug(CDBG_TAG, "Writing |%s| (%" PRId64 ") bytes", txn->request, len);
+  txn->write_vio = TSVConnWrite(txn->vconn, contp, txn->req_reader, len);
+
+  return 1;
+}
+
+static int
+synclient_txn_write_request_handler(TSCont contp, TSEvent event, void * /* 
data ATS_UNUSED */)
+{
+  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  switch (event) {
+  case TS_EVENT_VCONN_WRITE_READY:
+    TSDebug(CDBG_TAG, "WRITE_READY");
+    TSVIOReenable(txn->write_vio);
+    break;
+
+  case TS_EVENT_VCONN_WRITE_COMPLETE:
+    TSDebug(CDBG_TAG, "WRITE_COMPLETE");
+    // Weird: synclient should not close the write part of vconn.
+    // Otherwise some strangeness...
+
+    /* Start reading */
+    SET_TEST_HANDLER(txn->current_handler, 
synclient_txn_read_response_handler);
+    txn->read_vio = TSVConnRead(txn->vconn, contp, txn->resp_buffer, 
INT64_MAX);
+    break;
+
+  case TS_EVENT_VCONN_EOS:
+    TSDebug(CDBG_TAG, "WRITE_EOS");
+    txn->status = REQUEST_FAILURE;
+    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
+    TSContDestroy(contp);
+    break;
+
+  case TS_EVENT_ERROR:
+    TSDebug(CDBG_TAG, "WRITE_ERROR");
+    txn->status = REQUEST_FAILURE;
+    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
+    TSContDestroy(contp);
+    break;
+
+  default:
+    TSAssert(!"Invalid event");
+    break;
+  }
+  return TS_EVENT_IMMEDIATE;
+}
+
+static int
+synclient_txn_connect_handler(TSCont contp, TSEvent event, void *data)
+{
+  TSAssert((event == TS_EVENT_NET_CONNECT) || (event == 
TS_EVENT_NET_CONNECT_FAILED));
+
+  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  if (event == TS_EVENT_NET_CONNECT) {
+    TSDebug(CDBG_TAG, "NET_CONNECT");
+
+    txn->req_buffer  = TSIOBufferCreate();
+    txn->req_reader  = TSIOBufferReaderAlloc(txn->req_buffer);
+    txn->resp_buffer = TSIOBufferCreate();
+    txn->resp_reader = TSIOBufferReaderAlloc(txn->resp_buffer);
+
+    txn->response[0]  = '\0';
+    txn->response_len = 0;
+
+    txn->vconn      = (TSVConn)data;
+    txn->local_port = (int)((NetVConnection *)data)->get_local_port();
+
+    txn->write_vio = nullptr;
+    txn->read_vio  = nullptr;
+
+    /* start writing */
+    SET_TEST_HANDLER(txn->current_handler, 
synclient_txn_write_request_handler);
+    synclient_txn_write_request(contp);
+
+    return TS_EVENT_IMMEDIATE;
+  } else {
+    TSDebug(CDBG_TAG, "NET_CONNECT_FAILED");
+    txn->status = REQUEST_FAILURE;
+    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
+    TSContDestroy(contp);
+  }
+
+  return TS_EVENT_IMMEDIATE;
+}
+
+static int
+synclient_txn_main_handler(TSCont contp, TSEvent event, void *data)
+{
+  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  TxnHandler handler = txn->current_handler;
+  return (*handler)(contp, event, data);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// SOCKET SERVER
+//////////////////////////////////////////////////////////////////////////////
+
+SocketServer *
+synserver_create(int port, TSCont cont)
+{
+  if (port != SYNSERVER_DUMMY_PORT) {
+    TSAssert(port > 0);
+    TSAssert(port < INT16_MAX);
+  }
+
+  SocketServer *s  = (SocketServer *)TSmalloc(sizeof(SocketServer));
+  s->magic         = MAGIC_ALIVE;
+  s->accept_port   = port;
+  s->accept_action = nullptr;
+  s->accept_cont   = cont;
+  TSContDataSet(s->accept_cont, s);
+  return s;
+}
+
+SocketServer *
+synserver_create(int port)
+{
+  return synserver_create(port, TSContCreate(synserver_vc_accept, 
TSMutexCreate()));
+}
+
+static int
+synserver_start(SocketServer *s)
+{
+  TSAssert(s->magic == MAGIC_ALIVE);
+  TSAssert(s->accept_action == nullptr);
+
+  if (s->accept_port != SYNSERVER_DUMMY_PORT) {
+    TSAssert(s->accept_port > 0);
+    TSAssert(s->accept_port < INT16_MAX);
+
+    s->accept_action = TSNetAccept(s->accept_cont, s->accept_port, AF_INET, 0);
+  }
+
+  return 1;
+}
+
+static int
+synserver_stop(SocketServer *s)
+{
+  TSAssert(s->magic == MAGIC_ALIVE);
+  if (s->accept_action && !TSActionDone(s->accept_action)) {
+    TSActionCancel(s->accept_action);
+    s->accept_action = nullptr;
+    TSDebug(SDBG_TAG, "Had to cancel action");
+  }
+  TSDebug(SDBG_TAG, "stopped");
+  return 1;
+}
+
+static int
+synserver_delete(SocketServer *s)
+{
+  if (s != nullptr) {
+    TSAssert(s->magic == MAGIC_ALIVE);
+    synserver_stop(s);
+
+    if (s->accept_cont) {
+      TSContDestroy(s->accept_cont);
+      s->accept_cont = nullptr;
+      TSDebug(SDBG_TAG, "destroyed accept cont");
+    }
+
+    s->magic = MAGIC_DEAD;
+    TSfree(s);
+    TSDebug(SDBG_TAG, "deleted server");
+  }
+
+  return 1;
+}
+
+static int
+synserver_vc_refuse(TSCont contp, TSEvent event, void *data)
+{
+  TSAssert((event == TS_EVENT_NET_ACCEPT) || (event == 
TS_EVENT_NET_ACCEPT_FAILED));
+
+  SocketServer *s = (SocketServer *)TSContDataGet(contp);
+  TSAssert(s->magic == MAGIC_ALIVE);
+
+  TSDebug(SDBG_TAG, "%s: NET_ACCEPT", __func__);
+
+  if (event == TS_EVENT_NET_ACCEPT_FAILED) {
+    Warning("Synserver failed to bind to port %d.", ntohs(s->accept_port));
+    ink_release_assert(!"Synserver must be able to bind to a port, check 
system netstat");
+    TSDebug(SDBG_TAG, "%s: NET_ACCEPT_FAILED", __func__);
+    return TS_EVENT_IMMEDIATE;
+  }
+
+  TSVConnClose((TSVConn)data);
+  return TS_EVENT_IMMEDIATE;
+}
+
+static int
+synserver_vc_accept(TSCont contp, TSEvent event, void *data)
+{
+  TSAssert((event == TS_EVENT_NET_ACCEPT) || (event == 
TS_EVENT_NET_ACCEPT_FAILED));
+
+  SocketServer *s = (SocketServer *)TSContDataGet(contp);
+  TSAssert(s->magic == MAGIC_ALIVE);
+
+  if (event == TS_EVENT_NET_ACCEPT_FAILED) {
+    Warning("Synserver failed to bind to port %d.", ntohs(s->accept_port));
+    ink_release_assert(!"Synserver must be able to bind to a port, check 
system netstat");
+    TSDebug(SDBG_TAG, "%s: NET_ACCEPT_FAILED", __func__);
+    return TS_EVENT_IMMEDIATE;
+  }
+
+  TSDebug(SDBG_TAG, "%s: NET_ACCEPT", __func__);
+
+  /* Create a new transaction */
+  ServerTxn *txn = (ServerTxn *)TSmalloc(sizeof(ServerTxn));
+  txn->magic     = MAGIC_ALIVE;
+
+  SET_TEST_HANDLER(txn->current_handler, synserver_txn_read_request_handler);
+
+  TSCont txn_cont = TSContCreate(synserver_txn_main_handler, TSMutexCreate());
+  TSContDataSet(txn_cont, txn);
+
+  txn->req_buffer = TSIOBufferCreate();
+  txn->req_reader = TSIOBufferReaderAlloc(txn->req_buffer);
+
+  txn->resp_buffer = TSIOBufferCreate();
+  txn->resp_reader = TSIOBufferReaderAlloc(txn->resp_buffer);
+
+  txn->request[0]  = '\0';
+  txn->request_len = 0;
+
+  txn->vconn = (TSVConn)data;
+
+  txn->write_vio = nullptr;
+
+  /* start reading */
+  txn->read_vio = TSVConnRead(txn->vconn, txn_cont, txn->req_buffer, 
INT64_MAX);
+
+  return TS_EVENT_IMMEDIATE;
+}
+
+static int
+synserver_txn_close(TSCont contp)
+{
+  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  if (txn->vconn != nullptr) {
+    TSVConnClose(txn->vconn);
+  }
+  if (txn->req_buffer) {
+    TSIOBufferDestroy(txn->req_buffer);
+  }
+  if (txn->resp_buffer) {
+    TSIOBufferDestroy(txn->resp_buffer);
+  }
+
+  txn->magic = MAGIC_DEAD;
+  TSfree(txn);
+  TSContDestroy(contp);
+
+  TSDebug(SDBG_TAG, "Server Txn destroyed");
+  return TS_EVENT_IMMEDIATE;
+}
+
+static int
+synserver_txn_write_response(TSCont contp)
+{
+  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  SET_TEST_HANDLER(txn->current_handler, synserver_txn_write_response_handler);
+
+  TSIOBufferBlock block;
+  char *ptr_block;
+  int64_t len, ndone, ntodo, towrite, avail;
+  char *response;
+
+  response = generate_response(txn->request);
+  len      = strlen(response);
+
+  ndone = 0;
+  ntodo = len;
+  while (ntodo > 0) {
+    block     = TSIOBufferStart(txn->resp_buffer);
+    ptr_block = TSIOBufferBlockWriteStart(block, &avail);
+    towrite   = std::min(ntodo, avail);
+    memcpy(ptr_block, response + ndone, towrite);
+    TSIOBufferProduce(txn->resp_buffer, towrite);
+    ntodo -= towrite;
+    ndone += towrite;
+  }
+
+  /* Start writing the response */
+  TSDebug(SDBG_TAG, "Writing response: |%s| (%" PRId64 ") bytes)", response, 
len);
+  txn->write_vio = TSVConnWrite(txn->vconn, contp, txn->resp_reader, len);
+
+  /* Now that response is in IOBuffer, free up response */
+  TSfree(response);
+
+  return TS_EVENT_IMMEDIATE;
+}
+
+static int
+synserver_txn_write_response_handler(TSCont contp, TSEvent event, void * /* 
data ATS_UNUSED */)
+{
+  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  switch (event) {
+  case TS_EVENT_VCONN_WRITE_READY:
+    TSDebug(SDBG_TAG, "WRITE_READY");
+    TSVIOReenable(txn->write_vio);
+    break;
+
+  case TS_EVENT_VCONN_WRITE_COMPLETE:
+    TSDebug(SDBG_TAG, "WRITE_COMPLETE");
+    TSVConnShutdown(txn->vconn, 0, 1);
+    return synserver_txn_close(contp);
+    break;
+
+  case TS_EVENT_VCONN_EOS:
+    TSDebug(SDBG_TAG, "WRITE_EOS");
+    return synserver_txn_close(contp);
+    break;
+
+  case TS_EVENT_ERROR:
+    TSDebug(SDBG_TAG, "WRITE_ERROR");
+    return synserver_txn_close(contp);
+    break;
+
+  default:
+    TSAssert(!"Invalid event");
+    break;
+  }
+  return TS_EVENT_IMMEDIATE;
+}
+
+static int
+synserver_txn_read_request(TSCont contp)
+{
+  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  int end;
+  TSIOBufferBlock block = TSIOBufferReaderStart(txn->req_reader);
+
+  while (block != nullptr) {
+    int64_t blocklen;
+    const char *blockptr = TSIOBufferBlockReadStart(block, txn->req_reader, 
&blocklen);
+
+    if (txn->request_len + blocklen <= REQUEST_MAX_SIZE) {
+      memcpy((char *)(txn->request + txn->request_len), blockptr, blocklen);
+      txn->request_len += blocklen;
+    } else {
+      TSError("Error: Request length %" PRId64 " > request buffer size %d", 
txn->request_len + blocklen, REQUEST_MAX_SIZE);
+    }
+
+    block = TSIOBufferBlockNext(block);
+  }
+
+  txn->request[txn->request_len] = '\0';
+  TSDebug(SDBG_TAG, "Request = |%s|, req len = %d", txn->request, 
txn->request_len);
+
+  end = (strstr(txn->request, HTTP_REQUEST_END) != nullptr);
+  TSDebug(SDBG_TAG, "End of request = %d", end);
+
+  return end;
+}
+
+static int
+synserver_txn_read_request_handler(TSCont contp, TSEvent event, void * /* data 
ATS_UNUSED */)
+{
+  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  int64_t avail;
+  int end_of_request;
+
+  switch (event) {
+  case TS_EVENT_VCONN_READ_READY:
+  case TS_EVENT_VCONN_READ_COMPLETE:
+    TSDebug(SDBG_TAG, (event == TS_EVENT_VCONN_READ_READY) ? "READ_READY" : 
"READ_COMPLETE");
+    avail = TSIOBufferReaderAvail(txn->req_reader);
+    TSDebug(SDBG_TAG, "%" PRId64 " bytes available in buffer", avail);
+
+    if (avail > 0) {
+      end_of_request = synserver_txn_read_request(contp);
+      TSIOBufferReaderConsume(txn->req_reader, avail);
+
+      if (end_of_request) {
+        TSVConnShutdown(txn->vconn, 1, 0);
+        return synserver_txn_write_response(contp);
+      }
+    }
+
+    TSVIOReenable(txn->read_vio);
+    break;
+
+  case TS_EVENT_VCONN_EOS:
+    TSDebug(SDBG_TAG, "READ_EOS");
+    return synserver_txn_close(contp);
+    break;
+
+  case TS_EVENT_ERROR:
+    TSDebug(SDBG_TAG, "READ_ERROR");
+    return synserver_txn_close(contp);
+    break;
+
+  default:
+    TSAssert(!"Invalid event");
+    break;
+  }
+  return TS_EVENT_IMMEDIATE;
+}
+
+static int
+synserver_txn_main_handler(TSCont contp, TSEvent event, void *data)
+{
+  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
+  TSAssert(txn->magic == MAGIC_ALIVE);
+
+  TxnHandler handler = txn->current_handler;
+  return (*handler)(contp, event, data);
+}
+
+// End of the previous #include "InkAPITestTool.cc"
+
 #define TC_PASS 1
 #define TC_FAIL 0
 
diff --git a/proxy/InkIOCoreAPI.cc b/cmd/traffic_server/InkIOCoreAPI.cc
similarity index 100%
rename from proxy/InkIOCoreAPI.cc
rename to cmd/traffic_server/InkIOCoreAPI.cc
diff --git a/cmd/traffic_server/Makefile.am b/cmd/traffic_server/Makefile.am
new file mode 100644
index 0000000..dd5f4c0
--- /dev/null
+++ b/cmd/traffic_server/Makefile.am
@@ -0,0 +1,111 @@
+#
+# Makefile.am for the Enterprise Management module.
+#
+#  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.
+
+AM_CPPFLAGS += \
+       $(iocore_include_dirs) \
+       -I$(abs_top_srcdir)/lib/records \
+       -I$(abs_top_srcdir)/proxy \
+       -I$(abs_top_srcdir)/proxy/http \
+       -I$(abs_top_srcdir)/proxy/http2 \
+       -I$(abs_top_srcdir)/proxy/logging \
+       -I$(abs_top_srcdir)/proxy/http/remap \
+       -I$(abs_top_srcdir)/proxy/hdrs \
+       -I$(abs_top_srcdir)/proxy/shared \
+       -I$(abs_top_srcdir)/mgmt \
+       -I$(abs_top_srcdir)/mgmt/utils \
+       $(TS_INCLUDES) \
+       @OPENSSL_INCLUDES@
+
+bin_PROGRAMS = traffic_server
+
+traffic_server_SOURCES = \
+       CoreUtils.cc \
+       CoreUtils.h \
+       Crash.cc \
+       EventName.cc \
+       EventName.h \
+       FetchSM.cc \
+       FetchSM.h \
+       HostStatus.cc \
+       InkAPI.cc \
+       InkIOCoreAPI.cc \
+       SocksProxy.cc \
+       traffic_server.cc
+
+if BUILD_TESTS
+traffic_server_SOURCES += \
+       InkAPITest.cc
+endif
+
+traffic_server_LDADD = \
+       $(top_builddir)/proxy/http/libhttp.a \
+       $(top_builddir)/proxy/http/remap/libhttp_remap.a \
+       $(top_builddir)/proxy/http/remap/libhttp_remap.a \
+       $(top_builddir)/proxy/http2/libhttp2.a \
+       $(top_builddir)/proxy/logging/liblogging.a \
+       $(top_builddir)/proxy/logging/liblogcollation.a \
+       $(top_builddir)/proxy/hdrs/libhdrs.a \
+       $(top_builddir)/proxy/shared/libdiagsconfig.a \
+       $(top_builddir)/mgmt/libmgmt_p.la \
+       $(top_builddir)/iocore/utils/libinkutils.a \
+       $(top_builddir)/iocore/dns/libinkdns.a \
+       $(top_builddir)/iocore/hostdb/libinkhostdb.a \
+       $(top_builddir)/iocore/dns/libinkdns.a \
+       $(top_builddir)/iocore/cache/libinkcache.a \
+       $(top_builddir)/iocore/aio/libinkaio.a \
+       $(top_builddir)/lib/ts/libtsutil.la \
+       $(top_builddir)/lib/bindings/libbindings.la \
+       $(top_builddir)/proxy/libproxy.a
+
+# ToDo: When we remove this, we hould merge the two _LDADD rules here
+if BUILD_LUAJIT
+traffic_server_LDADD += \
+       $(top_builddir)/lib/luajit/src/libluajit.a
+endif
+
+traffic_server_LDADD += \
+       $(top_builddir)/iocore/net/libinknet.a \
+       $(top_builddir)/iocore/eventsystem/libinkevent.a \
+       $(top_builddir)/lib/records/librecords_p.a \
+       $(top_builddir)/iocore/eventsystem/libinkevent.a \
+       $(top_builddir)/lib/tsconfig/libtsconfig.la \
+       @HWLOC_LIBS@ \
+       @LIBPCRE@ \
+       @LIBTCL@ \
+       @LIBRESOLV@ \
+       @LIBZ@ \
+       @LIBLZMA@ \
+       @LIBPROFILER@ \
+       @OPENSSL_LIBS@ \
+       -lm
+
+if BUILD_LUAJIT
+traffic_server_LDADD += $(LUAJIT:%=$(top_builddir)/lib/luajit/src/%)
+endif
+
+if SYSTEM_LUAJIT
+traffic_server_LDADD += @LIBLUAJIT@
+endif
+
+versiondir = $(pkgsysconfdir)
+
+include $(top_srcdir)/build/tidy.mk
+
+clang-tidy-local: $(noinst_HEADERS) $(traffic_server_SOURCES)
+       $(CXX_Clang_Tidy)
diff --git a/proxy/SocksProxy.cc b/cmd/traffic_server/SocksProxy.cc
similarity index 100%
rename from proxy/SocksProxy.cc
rename to cmd/traffic_server/SocksProxy.cc
diff --git a/proxy/Main.cc b/cmd/traffic_server/traffic_server.cc
similarity index 100%
rename from proxy/Main.cc
rename to cmd/traffic_server/traffic_server.cc
diff --git a/configure.ac b/configure.ac
index f110e61..f8c378a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,7 +38,7 @@ m4_define([TS_VERSION_N],[9000000])
 AC_INIT([Apache Traffic Server], TS_VERSION_S(), 
[[email protected]], 
[trafficserver],[http://trafficserver.apache.org])
 AC_PREREQ([2.59])
 AC_CONFIG_AUX_DIR([build/_aux])
-AC_CONFIG_SRCDIR([proxy/Main.cc])
+AC_CONFIG_SRCDIR([cmd/traffic_server/traffic_server.cc])
 AC_CONFIG_MACRO_DIR([build])
 
 # NOTE: we turn off portability warnings because the clang-tidy targets use
@@ -2035,6 +2035,7 @@ AC_CONFIG_FILES([
   cmd/traffic_logcat/Makefile
   cmd/traffic_logstats/Makefile
   cmd/traffic_manager/Makefile
+  cmd/traffic_server/Makefile
   cmd/traffic_top/Makefile
   cmd/traffic_via/Makefile
   cmd/traffic_wccp/Makefile
diff --git a/proxy/CompletionUtil.h b/proxy/CompletionUtil.h
deleted file mode 100644
index 18b7d68..0000000
--- a/proxy/CompletionUtil.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-#pragma once
-// interface
-class completionUtil
-{
-public:
-  static Event *create();
-  static void destroy(Event *e);
-  static void setThread(Event *e, EThread *t);
-  static void setContinuation(Event *e, Continuation *c);
-  static void *getHandle(Event *e);
-  static void setHandle(Event *e, void *handle);
-  static void setInfo(Event *e, int fd, IOBufferBlock *buf, int actual, int 
errno_);
-  static void setInfo(Event *e, int fd, struct msghdr *msg, int actual, int 
errno_);
-  static int getBytesTransferred(Event *e);
-  static IOBufferBlock *getIOBufferBlock(Event *e);
-  static Continuation *getContinuation(Event *e);
-  static int getError(Event *e);
-  static void releaseReferences(Event *e);
-};
-
-#include "UnixCompletionUtil.h"
diff --git a/proxy/InkAPITestTool.cc b/proxy/InkAPITestTool.cc
deleted file mode 100644
index fabc430..0000000
--- a/proxy/InkAPITestTool.cc
+++ /dev/null
@@ -1,1103 +0,0 @@
-/** @file
-
-  Implements unit test for SDK APIs
-
-  @section license License
-
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
- */
-
-#include "ts/Regression.h"
-#include "api/ts/ts.h"
-
-#include <arpa/inet.h> /* For htonl */
-#include "P_Net.h"
-#include <records/I_RecHttp.h>
-
-#define SDBG_TAG "SockServer"
-#define CDBG_TAG "SockClient"
-
-#define IP(a, b, c, d) htonl((a) << 24 | (b) << 16 | (c) << 8 | (d))
-
-#define SET_TEST_HANDLER(_d, _s) \
-  {                              \
-    _d = _s;                     \
-  }
-
-#define MAGIC_ALIVE 0xfeedbaba
-#define MAGIC_DEAD 0xdeadbeef
-
-#define SYNSERVER_LISTEN_PORT 3300
-#define SYNSERVER_DUMMY_PORT -1
-
-#define PROXY_HTTP_DEFAULT_PORT 8080
-
-#define REQUEST_MAX_SIZE 4095
-#define RESPONSE_MAX_SIZE 4095
-
-#define HTTP_REQUEST_END "\r\n\r\n"
-
-// each request/response includes an identifier as a Mime field
-#define X_REQUEST_ID "X-Request-ID"
-#define X_RESPONSE_ID "X-Response-ID"
-
-#define ERROR_BODY "TESTING ERROR PAGE"
-#define TRANSFORM_APPEND_STRING "This is a transformed response"
-
-//////////////////////////////////////////////////////////////////////////////
-// STRUCTURES
-//////////////////////////////////////////////////////////////////////////////
-
-typedef int (*TxnHandler)(TSCont contp, TSEvent event, void *data);
-
-/* Server transaction structure */
-typedef struct {
-  TSVConn vconn;
-
-  TSVIO read_vio;
-  TSIOBuffer req_buffer;
-  TSIOBufferReader req_reader;
-
-  TSVIO write_vio;
-  TSIOBuffer resp_buffer;
-  TSIOBufferReader resp_reader;
-
-  char request[REQUEST_MAX_SIZE + 1];
-  int request_len;
-
-  TxnHandler current_handler;
-  unsigned int magic;
-} ServerTxn;
-
-/* Server structure */
-typedef struct {
-  int accept_port;
-  TSAction accept_action;
-  TSCont accept_cont;
-  unsigned int magic;
-} SocketServer;
-
-typedef enum {
-  REQUEST_SUCCESS,
-  REQUEST_INPROGRESS,
-  REQUEST_FAILURE,
-} RequestStatus;
-
-/* Client structure */
-typedef struct {
-  TSVConn vconn;
-
-  TSVIO read_vio;
-  TSIOBuffer req_buffer;
-  TSIOBufferReader req_reader;
-
-  TSVIO write_vio;
-  TSIOBuffer resp_buffer;
-  TSIOBufferReader resp_reader;
-
-  char *request;
-  char response[RESPONSE_MAX_SIZE + 1];
-  int response_len;
-
-  RequestStatus status;
-
-  int connect_port;
-  int local_port;
-  uint64_t connect_ip;
-  TSAction connect_action;
-
-  TxnHandler current_handler;
-
-  unsigned int magic;
-} ClientTxn;
-
-//////////////////////////////////////////////////////////////////////////////
-// DECLARATIONS
-//////////////////////////////////////////////////////////////////////////////
-
-/* utility */
-static char *get_body_ptr(const char *request);
-static char *generate_request(int test_case);
-static char *generate_response(const char *request);
-static int get_request_id(TSHttpTxn txnp);
-
-/* client side */
-static ClientTxn *synclient_txn_create(void);
-static int synclient_txn_delete(ClientTxn *txn);
-static void synclient_txn_close(ClientTxn *txn);
-static int synclient_txn_send_request(ClientTxn *txn, char *request);
-static int synclient_txn_send_request_to_vc(ClientTxn *txn, char *request, 
TSVConn vc);
-static int synclient_txn_read_response(TSCont contp);
-static int synclient_txn_read_response_handler(TSCont contp, TSEvent event, 
void *data);
-static int synclient_txn_write_request(TSCont contp);
-static int synclient_txn_write_request_handler(TSCont contp, TSEvent event, 
void *data);
-static int synclient_txn_connect_handler(TSCont contp, TSEvent event, void 
*data);
-static int synclient_txn_main_handler(TSCont contp, TSEvent event, void *data);
-
-/* Server side */
-SocketServer *synserver_create(int port);
-static int synserver_start(SocketServer *s);
-static int synserver_stop(SocketServer *s);
-static int synserver_delete(SocketServer *s);
-static int synserver_vc_accept(TSCont contp, TSEvent event, void *data);
-static int synserver_vc_refuse(TSCont contp, TSEvent event, void *data);
-static int synserver_txn_close(TSCont contp);
-static int synserver_txn_write_response(TSCont contp);
-static int synserver_txn_write_response_handler(TSCont contp, TSEvent event, 
void *data);
-static int synserver_txn_read_request(TSCont contp);
-static int synserver_txn_read_request_handler(TSCont contp, TSEvent event, 
void *data);
-static int synserver_txn_main_handler(TSCont contp, TSEvent event, void *data);
-
-//////////////////////////////////////////////////////////////////////////////
-// REQUESTS/RESPONSES GENERATION
-//////////////////////////////////////////////////////////////////////////////
-
-static char *
-get_body_ptr(const char *request)
-{
-  char *ptr = (char *)strstr((const char *)request, (const char *)"\r\n\r\n");
-  return (ptr != nullptr) ? (ptr + 4) : nullptr;
-}
-
-/* Caller must free returned request */
-static char *
-generate_request(int test_case)
-{
-// We define request formats.
-// Each format has an X-Request-ID field that contains the id of the testcase
-#define HTTP_REQUEST_DEFAULT_FORMAT                   \
-  "GET http://127.0.0.1:%d/default.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                              \
-  "\r\n"
-
-#define HTTP_REQUEST_FORMAT1                          \
-  "GET http://127.0.0.1:%d/format1.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                              \
-  "\r\n"
-
-#define HTTP_REQUEST_FORMAT2                          \
-  "GET http://127.0.0.1:%d/format2.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                              \
-  "Content-Type: text/html\r\n"                       \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT3                          \
-  "GET http://127.0.0.1:%d/format3.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                              \
-  "Response: Error\r\n"                               \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT4                          \
-  "GET http://127.0.0.1:%d/format4.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                              \
-  "Request:%d\r\n"                                    \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT5                          \
-  "GET http://127.0.0.1:%d/format5.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                              \
-  "Request:%d\r\n"                                    \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT6                         \
-  "GET http://127.0.0.1:%d/format.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                             \
-  "Accept-Language: English\r\n"                     \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT7                         \
-  "GET http://127.0.0.1:%d/format.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                             \
-  "Accept-Language: French\r\n"                      \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT8                         \
-  "GET http://127.0.0.1:%d/format.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                             \
-  "Accept-Language: English,French\r\n"              \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT9                                      \
-  "GET http://trafficserver.apache.org/format9.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                                          \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT10                                      \
-  "GET http://trafficserver.apache.org/format10.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                                           \
-  "\r\n"
-#define HTTP_REQUEST_FORMAT11                                      \
-  "GET http://trafficserver.apache.org/format11.html HTTP/1.0\r\n" \
-  "X-Request-ID: %d\r\n"                                           \
-  "\r\n"
-  char *request = (char *)TSmalloc(REQUEST_MAX_SIZE + 1);
-
-  switch (test_case) {
-  case 1:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT1, 
SYNSERVER_LISTEN_PORT, test_case);
-    break;
-  case 2:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT2, 
SYNSERVER_LISTEN_PORT, test_case);
-    break;
-  case 3:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT3, 
SYNSERVER_LISTEN_PORT, test_case);
-    break;
-  case 4:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT4, 
SYNSERVER_LISTEN_PORT, test_case, 1);
-    break;
-  case 5:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT5, 
SYNSERVER_LISTEN_PORT, test_case, 2);
-    break;
-  case 6:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT6, 
SYNSERVER_LISTEN_PORT, test_case);
-    break;
-  case 7:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT7, 
SYNSERVER_LISTEN_PORT, test_case - 1);
-    break;
-  case 8:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT8, 
SYNSERVER_LISTEN_PORT, test_case - 2);
-    break;
-  case 9:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT9, test_case);
-    break;
-  case 10:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT10, test_case);
-    break;
-  case 11:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_FORMAT11, test_case);
-    break;
-  default:
-    snprintf(request, REQUEST_MAX_SIZE + 1, HTTP_REQUEST_DEFAULT_FORMAT, 
SYNSERVER_LISTEN_PORT, test_case);
-    break;
-  }
-
-  return request;
-}
-
-/* Caller must free returned response */
-static char *
-generate_response(const char *request)
-{
-// define format for response
-// Each response contains a field X-Response-ID that contains the id of the 
testcase
-#define HTTP_REQUEST_TESTCASE_FORMAT \
-  "GET %1024s HTTP/1.%d\r\n"         \
-  "X-Request-ID: %d\r\n"
-
-#define HTTP_RESPONSE_DEFAULT_FORMAT \
-  "HTTP/1.0 200 OK\r\n"              \
-  "X-Response-ID: %d\r\n"            \
-  "Cache-Control: max-age=86400\r\n" \
-  "Content-Type: text/html\r\n"      \
-  "\r\n"                             \
-  "Default body"
-
-#define HTTP_RESPONSE_FORMAT1   \
-  "HTTP/1.0 200 OK\r\n"         \
-  "X-Response-ID: %d\r\n"       \
-  "Content-Type: text/html\r\n" \
-  "Cache-Control: no-cache\r\n" \
-  "\r\n"                        \
-  "Body for response 1"
-
-#define HTTP_RESPONSE_FORMAT2        \
-  "HTTP/1.0 200 OK\r\n"              \
-  "X-Response-ID: %d\r\n"            \
-  "Cache-Control: max-age=86400\r\n" \
-  "Content-Type: text/html\r\n"      \
-  "\r\n"                             \
-  "Body for response 2"
-#define HTTP_RESPONSE_FORMAT4        \
-  "HTTP/1.0 200 OK\r\n"              \
-  "X-Response-ID: %d\r\n"            \
-  "Cache-Control: max-age=86400\r\n" \
-  "Content-Type: text/html\r\n"      \
-  "\r\n"                             \
-  "Body for response 4"
-#define HTTP_RESPONSE_FORMAT5   \
-  "HTTP/1.0 200 OK\r\n"         \
-  "X-Response-ID: %d\r\n"       \
-  "Content-Type: text/html\r\n" \
-  "\r\n"                        \
-  "Body for response 5"
-#define HTTP_RESPONSE_FORMAT6        \
-  "HTTP/1.0 200 OK\r\n"              \
-  "X-Response-ID: %d\r\n"            \
-  "Cache-Control: max-age=86400\r\n" \
-  "Content-Language: English\r\n"    \
-  "\r\n"                             \
-  "Body for response 6"
-#define HTTP_RESPONSE_FORMAT7        \
-  "HTTP/1.0 200 OK\r\n"              \
-  "X-Response-ID: %d\r\n"            \
-  "Cache-Control: max-age=86400\r\n" \
-  "Content-Language: French\r\n"     \
-  "\r\n"                             \
-  "Body for response 7"
-
-#define HTTP_RESPONSE_FORMAT8             \
-  "HTTP/1.0 200 OK\r\n"                   \
-  "X-Response-ID: %d\r\n"                 \
-  "Cache-Control: max-age=86400\r\n"      \
-  "Content-Language: French, English\r\n" \
-  "\r\n"                                  \
-  "Body for response 8"
-
-#define HTTP_RESPONSE_FORMAT9        \
-  "HTTP/1.0 200 OK\r\n"              \
-  "Cache-Control: max-age=86400\r\n" \
-  "X-Response-ID: %d\r\n"            \
-  "\r\n"                             \
-  "Body for response 9"
-
-#define HTTP_RESPONSE_FORMAT10       \
-  "HTTP/1.0 200 OK\r\n"              \
-  "Cache-Control: max-age=86400\r\n" \
-  "X-Response-ID: %d\r\n"            \
-  "\r\n"                             \
-  "Body for response 10"
-
-#define HTTP_RESPONSE_FORMAT11          \
-  "HTTP/1.0 200 OK\r\n"                 \
-  "Cache-Control: private,no-store\r\n" \
-  "X-Response-ID: %d\r\n"               \
-  "\r\n"                                \
-  "Body for response 11"
-
-  int test_case, match, http_version;
-
-  char *response = (char *)TSmalloc(RESPONSE_MAX_SIZE + 1);
-  char url[1025];
-
-  // coverity[secure_coding]
-  match = sscanf(request, HTTP_REQUEST_TESTCASE_FORMAT, url, &http_version, 
&test_case);
-  if (match == 3) {
-    switch (test_case) {
-    case 1:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT1, 
test_case);
-      break;
-    case 2:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT2, 
test_case);
-      break;
-    case 4:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT4, 
test_case);
-      break;
-    case 5:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT5, 
test_case);
-      break;
-    case 6:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT6, 
test_case);
-      break;
-    case 7:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT7, 
test_case);
-      break;
-    case 8:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT8, 
test_case);
-      break;
-    case 9:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT9, 
test_case);
-      break;
-    case 10:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT10, 
test_case);
-      break;
-    case 11:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_FORMAT11, 
test_case);
-      break;
-    default:
-      snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_DEFAULT_FORMAT, 
test_case);
-      break;
-    }
-  } else {
-    /* Didin't recognize a testcase request. send the default response */
-    snprintf(response, RESPONSE_MAX_SIZE + 1, HTTP_RESPONSE_DEFAULT_FORMAT, 
test_case);
-  }
-
-  return response;
-}
-
-static int
-get_request_id_value(const char *name, TSMBuffer buf, TSMLoc hdr)
-{
-  int id = -1;
-  TSMLoc field;
-
-  field = TSMimeHdrFieldFind(buf, hdr, name, -1);
-  if (field != TS_NULL_MLOC) {
-    id = TSMimeHdrFieldValueIntGet(buf, hdr, field, 0);
-  }
-
-  TSHandleMLocRelease(buf, hdr, field);
-  return id;
-}
-
-// This routine can be called by tests, from the READ_REQUEST_HDR_HOOK
-// to figure out the id of a test message
-// Returns id/-1 in case of error
-static int
-get_request_id(TSHttpTxn txnp)
-{
-  TSMBuffer bufp;
-  TSMLoc hdr_loc;
-  int id = -1;
-
-  if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
-    return -1;
-  }
-
-  id = get_request_id_value(X_REQUEST_ID, bufp, hdr_loc);
-  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
-  return id;
-}
-
-// This routine can be called by tests, from the READ_RESPONSE_HDR_HOOK
-// to figure out the id of a test message
-// Returns id/-1 in case of error
-static int
-get_response_id(TSHttpTxn txnp)
-{
-  TSMBuffer bufp;
-  TSMLoc hdr_loc;
-  int id = -1;
-
-  if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
-    return -1;
-  }
-
-  id = get_request_id_value(X_RESPONSE_ID, bufp, hdr_loc);
-  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
-  return id;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// SOCKET CLIENT
-//////////////////////////////////////////////////////////////////////////////
-
-static ClientTxn *
-synclient_txn_create(void)
-{
-  const HttpProxyPort *proxy_port;
-
-  ClientTxn *txn = (ClientTxn *)TSmalloc(sizeof(ClientTxn));
-
-  ink_zero(*txn);
-
-  if (nullptr == (proxy_port = HttpProxyPort::findHttp(AF_INET))) {
-    txn->connect_port = PROXY_HTTP_DEFAULT_PORT;
-  } else {
-    txn->connect_port = proxy_port->m_port;
-  }
-
-  txn->connect_ip = IP(127, 0, 0, 1);
-  txn->status     = REQUEST_INPROGRESS;
-  txn->magic      = MAGIC_ALIVE;
-
-  TSDebug(CDBG_TAG, "Connecting to proxy 127.0.0.1 on port %d", 
txn->connect_port);
-  return txn;
-}
-
-static int
-synclient_txn_delete(ClientTxn *txn)
-{
-  TSAssert(txn->magic == MAGIC_ALIVE);
-  if (txn->connect_action && !TSActionDone(txn->connect_action)) {
-    TSActionCancel(txn->connect_action);
-    txn->connect_action = nullptr;
-  }
-
-  ats_free(txn->request);
-  txn->magic = MAGIC_DEAD;
-  TSfree(txn);
-  return 1;
-}
-
-static void
-synclient_txn_close(ClientTxn *txn)
-{
-  if (txn) {
-    if (txn->vconn != nullptr) {
-      TSVConnClose(txn->vconn);
-      txn->vconn = nullptr;
-    }
-
-    if (txn->req_buffer != nullptr) {
-      TSIOBufferDestroy(txn->req_buffer);
-      txn->req_buffer = nullptr;
-    }
-
-    if (txn->resp_buffer != nullptr) {
-      TSIOBufferDestroy(txn->resp_buffer);
-      txn->resp_buffer = nullptr;
-    }
-
-    TSDebug(CDBG_TAG, "Client Txn destroyed");
-  }
-}
-
-static int
-synclient_txn_send_request(ClientTxn *txn, char *request)
-{
-  TSCont cont;
-  sockaddr_in addr;
-
-  TSAssert(txn->magic == MAGIC_ALIVE);
-  txn->request = ats_strdup(request);
-  SET_TEST_HANDLER(txn->current_handler, synclient_txn_connect_handler);
-
-  cont = TSContCreate(synclient_txn_main_handler, TSMutexCreate());
-  TSContDataSet(cont, txn);
-
-  ats_ip4_set(&addr, txn->connect_ip, htons(txn->connect_port));
-  TSNetConnect(cont, ats_ip_sa_cast(&addr));
-  return 1;
-}
-
-/* This can be used to send a request to a specific VC */
-static int
-synclient_txn_send_request_to_vc(ClientTxn *txn, char *request, TSVConn vc)
-{
-  TSCont cont;
-  TSAssert(txn->magic == MAGIC_ALIVE);
-  txn->request = ats_strdup(request);
-  SET_TEST_HANDLER(txn->current_handler, synclient_txn_connect_handler);
-
-  cont = TSContCreate(synclient_txn_main_handler, TSMutexCreate());
-  TSContDataSet(cont, txn);
-
-  TSContCall(cont, TS_EVENT_NET_CONNECT, vc);
-  return 1;
-}
-
-static int
-synclient_txn_read_response(TSCont contp)
-{
-  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  TSIOBufferBlock block = TSIOBufferReaderStart(txn->resp_reader);
-  while (block != nullptr) {
-    int64_t blocklen;
-    const char *blockptr = TSIOBufferBlockReadStart(block, txn->resp_reader, 
&blocklen);
-
-    if (txn->response_len + blocklen <= RESPONSE_MAX_SIZE) {
-      memcpy((char *)(txn->response + txn->response_len), blockptr, blocklen);
-      txn->response_len += blocklen;
-    } else {
-      TSError("Error: Response length %" PRId64 " > response buffer size %d", 
txn->response_len + blocklen, RESPONSE_MAX_SIZE);
-    }
-
-    block = TSIOBufferBlockNext(block);
-  }
-
-  txn->response[txn->response_len] = '\0';
-  TSDebug(CDBG_TAG, "Response = |%s|, req len = %d", txn->response, 
txn->response_len);
-
-  return 1;
-}
-
-static int
-synclient_txn_read_response_handler(TSCont contp, TSEvent event, void * /* 
data ATS_UNUSED */)
-{
-  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  int64_t avail;
-
-  switch (event) {
-  case TS_EVENT_VCONN_READ_READY:
-  case TS_EVENT_VCONN_READ_COMPLETE:
-    if (event == TS_EVENT_VCONN_READ_READY) {
-      TSDebug(CDBG_TAG, "READ_READY");
-    } else {
-      TSDebug(CDBG_TAG, "READ_COMPLETE");
-    }
-
-    avail = TSIOBufferReaderAvail(txn->resp_reader);
-    TSDebug(CDBG_TAG, "%" PRId64 " bytes available in buffer", avail);
-
-    if (avail > 0) {
-      synclient_txn_read_response(contp);
-      TSIOBufferReaderConsume(txn->resp_reader, avail);
-    }
-
-    TSVIOReenable(txn->read_vio);
-    break;
-
-  case TS_EVENT_VCONN_EOS:
-    TSDebug(CDBG_TAG, "READ_EOS");
-    // Connection closed. In HTTP/1.0 it means we're done for this request.
-    txn->status = REQUEST_SUCCESS;
-    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
-    TSContDestroy(contp);
-    return 1;
-
-  case TS_EVENT_ERROR:
-    TSDebug(CDBG_TAG, "READ_ERROR");
-    txn->status = REQUEST_FAILURE;
-    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
-    TSContDestroy(contp);
-    return 1;
-
-  default:
-    TSAssert(!"Invalid event");
-    break;
-  }
-  return 1;
-}
-
-static int
-synclient_txn_write_request(TSCont contp)
-{
-  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  TSIOBufferBlock block;
-  char *ptr_block;
-  int64_t len, ndone, ntodo, towrite, avail;
-
-  len = strlen(txn->request);
-
-  ndone = 0;
-  ntodo = len;
-  while (ntodo > 0) {
-    block     = TSIOBufferStart(txn->req_buffer);
-    ptr_block = TSIOBufferBlockWriteStart(block, &avail);
-    towrite   = std::min(ntodo, avail);
-    memcpy(ptr_block, txn->request + ndone, towrite);
-    TSIOBufferProduce(txn->req_buffer, towrite);
-    ntodo -= towrite;
-    ndone += towrite;
-  }
-
-  /* Start writing the response */
-  TSDebug(CDBG_TAG, "Writing |%s| (%" PRId64 ") bytes", txn->request, len);
-  txn->write_vio = TSVConnWrite(txn->vconn, contp, txn->req_reader, len);
-
-  return 1;
-}
-
-static int
-synclient_txn_write_request_handler(TSCont contp, TSEvent event, void * /* 
data ATS_UNUSED */)
-{
-  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  switch (event) {
-  case TS_EVENT_VCONN_WRITE_READY:
-    TSDebug(CDBG_TAG, "WRITE_READY");
-    TSVIOReenable(txn->write_vio);
-    break;
-
-  case TS_EVENT_VCONN_WRITE_COMPLETE:
-    TSDebug(CDBG_TAG, "WRITE_COMPLETE");
-    // Weird: synclient should not close the write part of vconn.
-    // Otherwise some strangeness...
-
-    /* Start reading */
-    SET_TEST_HANDLER(txn->current_handler, 
synclient_txn_read_response_handler);
-    txn->read_vio = TSVConnRead(txn->vconn, contp, txn->resp_buffer, 
INT64_MAX);
-    break;
-
-  case TS_EVENT_VCONN_EOS:
-    TSDebug(CDBG_TAG, "WRITE_EOS");
-    txn->status = REQUEST_FAILURE;
-    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
-    TSContDestroy(contp);
-    break;
-
-  case TS_EVENT_ERROR:
-    TSDebug(CDBG_TAG, "WRITE_ERROR");
-    txn->status = REQUEST_FAILURE;
-    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
-    TSContDestroy(contp);
-    break;
-
-  default:
-    TSAssert(!"Invalid event");
-    break;
-  }
-  return TS_EVENT_IMMEDIATE;
-}
-
-static int
-synclient_txn_connect_handler(TSCont contp, TSEvent event, void *data)
-{
-  TSAssert((event == TS_EVENT_NET_CONNECT) || (event == 
TS_EVENT_NET_CONNECT_FAILED));
-
-  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  if (event == TS_EVENT_NET_CONNECT) {
-    TSDebug(CDBG_TAG, "NET_CONNECT");
-
-    txn->req_buffer  = TSIOBufferCreate();
-    txn->req_reader  = TSIOBufferReaderAlloc(txn->req_buffer);
-    txn->resp_buffer = TSIOBufferCreate();
-    txn->resp_reader = TSIOBufferReaderAlloc(txn->resp_buffer);
-
-    txn->response[0]  = '\0';
-    txn->response_len = 0;
-
-    txn->vconn      = (TSVConn)data;
-    txn->local_port = (int)((NetVConnection *)data)->get_local_port();
-
-    txn->write_vio = nullptr;
-    txn->read_vio  = nullptr;
-
-    /* start writing */
-    SET_TEST_HANDLER(txn->current_handler, 
synclient_txn_write_request_handler);
-    synclient_txn_write_request(contp);
-
-    return TS_EVENT_IMMEDIATE;
-  } else {
-    TSDebug(CDBG_TAG, "NET_CONNECT_FAILED");
-    txn->status = REQUEST_FAILURE;
-    synclient_txn_close((ClientTxn *)TSContDataGet(contp));
-    TSContDestroy(contp);
-  }
-
-  return TS_EVENT_IMMEDIATE;
-}
-
-static int
-synclient_txn_main_handler(TSCont contp, TSEvent event, void *data)
-{
-  ClientTxn *txn = (ClientTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  TxnHandler handler = txn->current_handler;
-  return (*handler)(contp, event, data);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// SOCKET SERVER
-//////////////////////////////////////////////////////////////////////////////
-
-SocketServer *
-synserver_create(int port, TSCont cont)
-{
-  if (port != SYNSERVER_DUMMY_PORT) {
-    TSAssert(port > 0);
-    TSAssert(port < INT16_MAX);
-  }
-
-  SocketServer *s  = (SocketServer *)TSmalloc(sizeof(SocketServer));
-  s->magic         = MAGIC_ALIVE;
-  s->accept_port   = port;
-  s->accept_action = nullptr;
-  s->accept_cont   = cont;
-  TSContDataSet(s->accept_cont, s);
-  return s;
-}
-
-SocketServer *
-synserver_create(int port)
-{
-  return synserver_create(port, TSContCreate(synserver_vc_accept, 
TSMutexCreate()));
-}
-
-static int
-synserver_start(SocketServer *s)
-{
-  TSAssert(s->magic == MAGIC_ALIVE);
-  TSAssert(s->accept_action == nullptr);
-
-  if (s->accept_port != SYNSERVER_DUMMY_PORT) {
-    TSAssert(s->accept_port > 0);
-    TSAssert(s->accept_port < INT16_MAX);
-
-    s->accept_action = TSNetAccept(s->accept_cont, s->accept_port, AF_INET, 0);
-  }
-
-  return 1;
-}
-
-static int
-synserver_stop(SocketServer *s)
-{
-  TSAssert(s->magic == MAGIC_ALIVE);
-  if (s->accept_action && !TSActionDone(s->accept_action)) {
-    TSActionCancel(s->accept_action);
-    s->accept_action = nullptr;
-    TSDebug(SDBG_TAG, "Had to cancel action");
-  }
-  TSDebug(SDBG_TAG, "stopped");
-  return 1;
-}
-
-static int
-synserver_delete(SocketServer *s)
-{
-  if (s != nullptr) {
-    TSAssert(s->magic == MAGIC_ALIVE);
-    synserver_stop(s);
-
-    if (s->accept_cont) {
-      TSContDestroy(s->accept_cont);
-      s->accept_cont = nullptr;
-      TSDebug(SDBG_TAG, "destroyed accept cont");
-    }
-
-    s->magic = MAGIC_DEAD;
-    TSfree(s);
-    TSDebug(SDBG_TAG, "deleted server");
-  }
-
-  return 1;
-}
-
-static int
-synserver_vc_refuse(TSCont contp, TSEvent event, void *data)
-{
-  TSAssert((event == TS_EVENT_NET_ACCEPT) || (event == 
TS_EVENT_NET_ACCEPT_FAILED));
-
-  SocketServer *s = (SocketServer *)TSContDataGet(contp);
-  TSAssert(s->magic == MAGIC_ALIVE);
-
-  TSDebug(SDBG_TAG, "%s: NET_ACCEPT", __func__);
-
-  if (event == TS_EVENT_NET_ACCEPT_FAILED) {
-    Warning("Synserver failed to bind to port %d.", ntohs(s->accept_port));
-    ink_release_assert(!"Synserver must be able to bind to a port, check 
system netstat");
-    TSDebug(SDBG_TAG, "%s: NET_ACCEPT_FAILED", __func__);
-    return TS_EVENT_IMMEDIATE;
-  }
-
-  TSVConnClose((TSVConn)data);
-  return TS_EVENT_IMMEDIATE;
-}
-
-static int
-synserver_vc_accept(TSCont contp, TSEvent event, void *data)
-{
-  TSAssert((event == TS_EVENT_NET_ACCEPT) || (event == 
TS_EVENT_NET_ACCEPT_FAILED));
-
-  SocketServer *s = (SocketServer *)TSContDataGet(contp);
-  TSAssert(s->magic == MAGIC_ALIVE);
-
-  if (event == TS_EVENT_NET_ACCEPT_FAILED) {
-    Warning("Synserver failed to bind to port %d.", ntohs(s->accept_port));
-    ink_release_assert(!"Synserver must be able to bind to a port, check 
system netstat");
-    TSDebug(SDBG_TAG, "%s: NET_ACCEPT_FAILED", __func__);
-    return TS_EVENT_IMMEDIATE;
-  }
-
-  TSDebug(SDBG_TAG, "%s: NET_ACCEPT", __func__);
-
-  /* Create a new transaction */
-  ServerTxn *txn = (ServerTxn *)TSmalloc(sizeof(ServerTxn));
-  txn->magic     = MAGIC_ALIVE;
-
-  SET_TEST_HANDLER(txn->current_handler, synserver_txn_read_request_handler);
-
-  TSCont txn_cont = TSContCreate(synserver_txn_main_handler, TSMutexCreate());
-  TSContDataSet(txn_cont, txn);
-
-  txn->req_buffer = TSIOBufferCreate();
-  txn->req_reader = TSIOBufferReaderAlloc(txn->req_buffer);
-
-  txn->resp_buffer = TSIOBufferCreate();
-  txn->resp_reader = TSIOBufferReaderAlloc(txn->resp_buffer);
-
-  txn->request[0]  = '\0';
-  txn->request_len = 0;
-
-  txn->vconn = (TSVConn)data;
-
-  txn->write_vio = nullptr;
-
-  /* start reading */
-  txn->read_vio = TSVConnRead(txn->vconn, txn_cont, txn->req_buffer, 
INT64_MAX);
-
-  return TS_EVENT_IMMEDIATE;
-}
-
-static int
-synserver_txn_close(TSCont contp)
-{
-  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  if (txn->vconn != nullptr) {
-    TSVConnClose(txn->vconn);
-  }
-  if (txn->req_buffer) {
-    TSIOBufferDestroy(txn->req_buffer);
-  }
-  if (txn->resp_buffer) {
-    TSIOBufferDestroy(txn->resp_buffer);
-  }
-
-  txn->magic = MAGIC_DEAD;
-  TSfree(txn);
-  TSContDestroy(contp);
-
-  TSDebug(SDBG_TAG, "Server Txn destroyed");
-  return TS_EVENT_IMMEDIATE;
-}
-
-static int
-synserver_txn_write_response(TSCont contp)
-{
-  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  SET_TEST_HANDLER(txn->current_handler, synserver_txn_write_response_handler);
-
-  TSIOBufferBlock block;
-  char *ptr_block;
-  int64_t len, ndone, ntodo, towrite, avail;
-  char *response;
-
-  response = generate_response(txn->request);
-  len      = strlen(response);
-
-  ndone = 0;
-  ntodo = len;
-  while (ntodo > 0) {
-    block     = TSIOBufferStart(txn->resp_buffer);
-    ptr_block = TSIOBufferBlockWriteStart(block, &avail);
-    towrite   = std::min(ntodo, avail);
-    memcpy(ptr_block, response + ndone, towrite);
-    TSIOBufferProduce(txn->resp_buffer, towrite);
-    ntodo -= towrite;
-    ndone += towrite;
-  }
-
-  /* Start writing the response */
-  TSDebug(SDBG_TAG, "Writing response: |%s| (%" PRId64 ") bytes)", response, 
len);
-  txn->write_vio = TSVConnWrite(txn->vconn, contp, txn->resp_reader, len);
-
-  /* Now that response is in IOBuffer, free up response */
-  TSfree(response);
-
-  return TS_EVENT_IMMEDIATE;
-}
-
-static int
-synserver_txn_write_response_handler(TSCont contp, TSEvent event, void * /* 
data ATS_UNUSED */)
-{
-  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  switch (event) {
-  case TS_EVENT_VCONN_WRITE_READY:
-    TSDebug(SDBG_TAG, "WRITE_READY");
-    TSVIOReenable(txn->write_vio);
-    break;
-
-  case TS_EVENT_VCONN_WRITE_COMPLETE:
-    TSDebug(SDBG_TAG, "WRITE_COMPLETE");
-    TSVConnShutdown(txn->vconn, 0, 1);
-    return synserver_txn_close(contp);
-    break;
-
-  case TS_EVENT_VCONN_EOS:
-    TSDebug(SDBG_TAG, "WRITE_EOS");
-    return synserver_txn_close(contp);
-    break;
-
-  case TS_EVENT_ERROR:
-    TSDebug(SDBG_TAG, "WRITE_ERROR");
-    return synserver_txn_close(contp);
-    break;
-
-  default:
-    TSAssert(!"Invalid event");
-    break;
-  }
-  return TS_EVENT_IMMEDIATE;
-}
-
-static int
-synserver_txn_read_request(TSCont contp)
-{
-  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  int end;
-  TSIOBufferBlock block = TSIOBufferReaderStart(txn->req_reader);
-
-  while (block != nullptr) {
-    int64_t blocklen;
-    const char *blockptr = TSIOBufferBlockReadStart(block, txn->req_reader, 
&blocklen);
-
-    if (txn->request_len + blocklen <= REQUEST_MAX_SIZE) {
-      memcpy((char *)(txn->request + txn->request_len), blockptr, blocklen);
-      txn->request_len += blocklen;
-    } else {
-      TSError("Error: Request length %" PRId64 " > request buffer size %d", 
txn->request_len + blocklen, REQUEST_MAX_SIZE);
-    }
-
-    block = TSIOBufferBlockNext(block);
-  }
-
-  txn->request[txn->request_len] = '\0';
-  TSDebug(SDBG_TAG, "Request = |%s|, req len = %d", txn->request, 
txn->request_len);
-
-  end = (strstr(txn->request, HTTP_REQUEST_END) != nullptr);
-  TSDebug(SDBG_TAG, "End of request = %d", end);
-
-  return end;
-}
-
-static int
-synserver_txn_read_request_handler(TSCont contp, TSEvent event, void * /* data 
ATS_UNUSED */)
-{
-  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  int64_t avail;
-  int end_of_request;
-
-  switch (event) {
-  case TS_EVENT_VCONN_READ_READY:
-  case TS_EVENT_VCONN_READ_COMPLETE:
-    TSDebug(SDBG_TAG, (event == TS_EVENT_VCONN_READ_READY) ? "READ_READY" : 
"READ_COMPLETE");
-    avail = TSIOBufferReaderAvail(txn->req_reader);
-    TSDebug(SDBG_TAG, "%" PRId64 " bytes available in buffer", avail);
-
-    if (avail > 0) {
-      end_of_request = synserver_txn_read_request(contp);
-      TSIOBufferReaderConsume(txn->req_reader, avail);
-
-      if (end_of_request) {
-        TSVConnShutdown(txn->vconn, 1, 0);
-        return synserver_txn_write_response(contp);
-      }
-    }
-
-    TSVIOReenable(txn->read_vio);
-    break;
-
-  case TS_EVENT_VCONN_EOS:
-    TSDebug(SDBG_TAG, "READ_EOS");
-    return synserver_txn_close(contp);
-    break;
-
-  case TS_EVENT_ERROR:
-    TSDebug(SDBG_TAG, "READ_ERROR");
-    return synserver_txn_close(contp);
-    break;
-
-  default:
-    TSAssert(!"Invalid event");
-    break;
-  }
-  return TS_EVENT_IMMEDIATE;
-}
-
-static int
-synserver_txn_main_handler(TSCont contp, TSEvent event, void *data)
-{
-  ServerTxn *txn = (ServerTxn *)TSContDataGet(contp);
-  TSAssert(txn->magic == MAGIC_ALIVE);
-
-  TxnHandler handler = txn->current_handler;
-  return (*handler)(contp, event, data);
-}
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index 34019ce..c9cffeb 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -18,36 +18,70 @@
 
 include $(top_srcdir)/build/tidy.mk
 
-# Note that hdrs is targeted from ../Makefile.am
-SUBDIRS = http http2 logging config
-noinst_LIBRARIES =
-bin_PROGRAMS = \
-       traffic_server
+SUBDIRS = hdrs shared http http2 logging config
+
+noinst_LIBRARIES = libproxy.a
 
 AM_CPPFLAGS += \
        $(iocore_include_dirs) \
+       -I$(abs_top_srcdir)/lib \
        -I$(abs_top_srcdir)/lib/records \
        -I$(abs_srcdir)/http \
-       -I$(abs_srcdir)/http2 \
        -I$(abs_srcdir)/logging \
        -I$(abs_srcdir)/http/remap \
        -I$(abs_srcdir)/hdrs \
-       -I$(abs_srcdir)/shared \
        -I$(abs_top_srcdir)/mgmt \
        -I$(abs_top_srcdir)/mgmt/utils \
-       -I$(abs_top_srcdir)/lib \
-       $(TS_INCLUDES) \
-       @OPENSSL_INCLUDES@
+       $(TS_INCLUDES)
 
 # NOTE: it is safe to use AM_LDFLAGS here because we are only building 
executables. If we start
 # building libtool archives, change these to only apply to the executables.
 AM_LDFLAGS += \
-       $(LUAJIT_LDFLAGS) \
-       @OPENSSL_LDFLAGS@
+       $(LUAJIT_LDFLAGS)
 
 noinst_HEADERS = \
        Show.h
 
+libproxy_a_SOURCES = \
+       CacheControl.cc \
+       CacheControl.h \
+       ControlBase.cc \
+       ControlBase.h \
+       ControlMatcher.cc \
+       ControlMatcher.h \
+       IPAllow.cc \
+       IPAllow.h \
+       ParentConsistentHash.cc \
+       ParentConsistentHash.h \
+       ParentRoundRobin.cc \
+       ParentRoundRobin.h \
+       ParentSelectionStrategy.cc \
+       ParentSelection.cc \
+       ParentSelection.h \
+       Plugin.cc \
+       Plugin.h \
+       PluginVC.cc \
+       PluginVC.h \
+       ProtocolProbeSessionAccept.cc \
+       ProtocolProbeSessionAccept.h \
+       ProxyClientSession.cc \
+       ProxyClientSession.h \
+       ProxyClientTransaction.cc \
+       ProxyClientTransaction \
+       ReverseProxy.cc \
+       ReverseProxy.h \
+       StatPages.cc \
+       StatPages.h \
+       Transform.cc \
+       Transform.h
+
+if BUILD_TESTS
+libproxy_a_SOURCES += \
+       RegressionSM.h \
+       RegressionSM.cc
+endif
+
+
 # These are currently built separate, as part of building the lib/ tree, using
 # the normal LuaJIT build system. We are using the .o's directly, instead of 
the
 # luajit.a to avoid the linker from optimizing symbols away. We could maybe
@@ -117,114 +151,7 @@ LUAJIT = \
        lj_vmevent.o \
        lj_vmmath.o
 
-EXTRA_DIST = InkAPITestTool.cc example_alarm_bin.sh example_prep.sh
-
-traffic_server_SOURCES = \
-       CacheControl.cc \
-       CacheControl.h \
-       ControlBase.cc \
-       ControlBase.h \
-       ControlMatcher.cc \
-       ControlMatcher.h \
-       CoreUtils.cc \
-       CoreUtils.h \
-       Crash.cc \
-       EventName.cc \
-       FetchSM.cc \
-       HostStatus.cc \
-       HostStatus.h \
-       IPAllow.cc \
-       IPAllow.h \
-       InkAPI.cc \
-       InkAPIInternal.h \
-       InkIOCoreAPI.cc \
-       Main.cc \
-       Main.h \
-       Milestones.h \
-       ParentConsistentHash.cc \
-       ParentConsistentHash.h \
-       ParentRoundRobin.cc \
-       ParentRoundRobin.h \
-       ParentSelectionStrategy.cc \
-       ParentSelection.cc \
-       ParentSelection.h \
-       Plugin.cc \
-       Plugin.h \
-       PluginVC.cc \
-       PluginVC.h \
-       ProtocolProbeSessionAccept.cc \
-       ProtocolProbeSessionAccept.h \
-       ProxyClientSession.cc \
-       ProxyClientSession.h \
-       ProxyClientTransaction.cc \
-       ProxyClientTransaction.h \
-       ReverseProxy.cc \
-       ReverseProxy.h \
-       SocksProxy.cc \
-       StatPages.cc \
-       StatPages.h \
-       Transform.cc \
-       Transform.h \
-       TransformInternal.h
-
-if BUILD_TESTS
-traffic_server_SOURCES += \
-       InkAPITest.cc \
-       RegressionSM.h \
-       RegressionSM.cc
-endif
-
-traffic_server_LDADD = \
-       http/libhttp.a \
-       http2/libhttp2.a \
-       http/remap/libhttp_remap.a \
-       logging/liblogging.a \
-       logging/liblogcollation.a \
-       hdrs/libhdrs.a \
-       shared/libdiagsconfig.a \
-       $(top_builddir)/mgmt/libmgmt_p.la \
-       $(top_builddir)/iocore/utils/libinkutils.a \
-       $(top_builddir)/iocore/dns/libinkdns.a \
-       $(top_builddir)/iocore/hostdb/libinkhostdb.a \
-       $(top_builddir)/iocore/dns/libinkdns.a \
-       $(top_builddir)/iocore/cache/libinkcache.a \
-       $(top_builddir)/iocore/aio/libinkaio.a \
-       $(top_builddir)/lib/ts/libtsutil.la \
-       $(top_builddir)/lib/bindings/libbindings.la
-
-if BUILD_LUAJIT
-traffic_server_LDADD += \
-       $(top_builddir)/lib/luajit/src/libluajit.a
-endif
-
-traffic_server_LDADD += \
-       $(top_builddir)/iocore/net/libinknet.a \
-       $(top_builddir)/iocore/eventsystem/libinkevent.a \
-       $(top_builddir)/lib/records/librecords_p.a \
-       $(top_builddir)/iocore/eventsystem/libinkevent.a \
-       $(top_builddir)/lib/tsconfig/libtsconfig.la \
-       @HWLOC_LIBS@ \
-       @LIBPCRE@ \
-       @LIBTCL@ \
-       @LIBRESOLV@ \
-       @LIBZ@ \
-       @LIBLZMA@ \
-       @LIBPROFILER@ \
-       @OPENSSL_LIBS@ \
-       -lm
-
-if BUILD_LUAJIT
-traffic_server_LDADD += $(LUAJIT:%=$(top_builddir)/lib/luajit/src/%)
-endif
-
-if SYSTEM_LUAJIT
-traffic_server_LDADD += @LIBLUAJIT@
-endif
-
-versiondir = $(pkgsysconfdir)
-
-clang-tidy-local: $(noinst_HEADERS) $(traffic_server_SOURCES)
-       $(CXX_Clang_Tidy)
+EXTRA_DIST = example_alarm_bin.sh example_prep.sh
 
 install-data-local:
        if [ `id -un` != "root" ]; then \
diff --git a/proxy/UnixCompletionUtil.h b/proxy/UnixCompletionUtil.h
deleted file mode 100644
index 53f5038..0000000
--- a/proxy/UnixCompletionUtil.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/** @file
-
-  A brief file description
-
-  @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.
- */
-
-#pragma once
-
-// platform specific wrappers for dealing with I/O completion events
-// passed into and back from the I/O core.
-#include "UDPIOEvent.h"
-
-inline Event *
-completionUtil::create()
-{
-  UDPIOEvent *u = UDPIOEventAllocator.alloc();
-  return u;
-};
-inline void
-completionUtil::destroy(Event *e)
-{
-  ink_assert(e != NULL);
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  UDPIOEvent::free(u);
-};
-inline void
-completionUtil::setThread(Event *e, EThread *t)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  u->ethread    = t;
-}
-inline void
-completionUtil::setContinuation(Event *e, Continuation *c)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  *(Action *)u  = c;
-}
-inline void *
-completionUtil::getHandle(Event *e)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  return u->getHandle();
-}
-inline void
-completionUtil::setHandle(Event *e, void *handle)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  u->setHandle(handle);
-}
-inline void
-completionUtil::setInfo(Event *e, int fd, IOBufferBlock *buf, int actual, int 
errno_)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  u->setInfo(fd, buf, actual, errno_);
-}
-inline void
-completionUtil::setInfo(Event *e, int fd, struct msghdr *msg, int actual, int 
errno_)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  u->setInfo(fd, msg, actual, errno_);
-}
-inline int
-completionUtil::getBytesTransferred(Event *e)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  return u->getBytesTransferred();
-}
-inline IOBufferBlock *
-completionUtil::getIOBufferBlock(Event *e)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  return u->getIOBufferBlock();
-}
-inline Continuation *
-completionUtil::getContinuation(Event *e)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  return u->getContinuation();
-}
-inline int
-completionUtil::getError(Event *e)
-{
-  UDPIOEvent *u = (UDPIOEvent *)e;
-  return u->getError();
-}

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to