This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 8.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/8.0.x by this push:
new ada64b9 Moves traffic_server to cmd/traffic_server
ada64b9 is described below
commit ada64b9f1cd91e361ce5202effd3c18f5286ab50
Author: Leif Hedstrom <[email protected]>
AuthorDate: Tue Jun 5 13:51:20 2018 +0200
Moves traffic_server to cmd/traffic_server
(cherry picked from commit 7d6248ea44da16d1e263f0f332c74b1e5f753fc8)
---
.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 db2ccce..e0c41da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -38,7 +38,7 @@ m4_define([TS_VERSION_N],[8000000])
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].