You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ki...@apache.org on 2019/06/22 02:11:18 UTC

[trafficserver] branch master updated: update example directory structure and add examples for lua plugin

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

kichan 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 0c947f1  update example directory structure and add examples for lua plugin
0c947f1 is described below

commit 0c947f1258517fc80198f66a5bc770ee7e3ec7c5
Author: Kit Chan <ki...@apache.org>
AuthorDate: Sat Jun 15 18:43:52 2019 -0700

    update example directory structure and add examples for lua plugin
---
 configure.ac                                       |   3 +
 .../api/functions/TSClientProtocolStack.en.rst     |   4 +-
 .../api/functions/TSHttpArgs.en.rst                |   2 +-
 .../api/functions/TSSslClientContext.en.rst        |   4 +-
 .../api/functions/TSVConnFdCreate.en.rst           |   4 +-
 .../plugins/adding-statistics.en.rst               |   2 +-
 .../example-plugins/blacklist/source-code.en.rst   |   2 +-
 .../query_remap/example-query-remap.en.rst         |   6 +-
 ...plugin-registration-and-version-checking.en.rst |   2 +-
 .../plugins/http-transformations/index.en.rst      |   2 +-
 .../api/functions/TSVConnFdCreate.en.po            |   2 +-
 .../plugins/http-transformations/index.en.po       |   2 +-
 example/Makefile.am                                | 179 +------------------
 .../{thread_pool/include => plugins}/Makefile.am   |  10 +-
 example/plugins/c-api/Makefile.am                  | 114 +++++++++++++
 .../{ => plugins/c-api}/add_header/add_header.c    |   0
 example/{ => plugins/c-api}/add_header/readme.txt  |   0
 .../c-api}/append_transform/append_transform.c     |   0
 .../c-api}/append_transform/readme.txt             |   0
 .../{ => plugins/c-api}/basic_auth/basic_auth.c    |   0
 example/{ => plugins/c-api}/basic_auth/readme.txt  |   0
 .../{ => plugins/c-api}/blacklist_0/blacklist_0.c  |   0
 .../{ => plugins/c-api}/blacklist_1/blacklist.txt  |   0
 .../{ => plugins/c-api}/blacklist_1/blacklist_1.c  |   0
 example/{ => plugins/c-api}/blacklist_1/readme.txt |   0
 .../c-api}/bnull_transform/bnull_transform.c       |   0
 .../{ => plugins/c-api}/cache_scan/cache_scan.cc   |   0
 example/plugins/c-api/cert_update/cert_update.cc   |  86 ++++++++++
 .../client_context_dump/client_context_dump.cc     | 190 +++++++++++++++++++++
 .../c-api}/disable_http2/disable_http2.cc          |   0
 .../{ => plugins/c-api}/disable_http2/readme.txt   |   0
 example/{ => plugins/c-api}/file_1/file_1.c        |   0
 example/{ => plugins/c-api}/file_1/readme.txt      |   0
 example/{ => plugins/c-api}/hello/hello.c          |   0
 example/{ => plugins/c-api}/intercept/intercept.cc |   0
 .../c-api}/lifecycle_plugin/lifecycle_plugin.c     |   0
 .../c-api}/lifecycle_plugin/readme.txt             |   0
 .../c-api}/null_transform/null_transform.c         |   0
 .../{ => plugins/c-api}/null_transform/readme.txt  |   0
 .../c-api}/output_header/output_header.c           |   0
 example/{ => plugins/c-api}/output_header/readme   |   0
 example/{ => plugins/c-api}/passthru/passthru.cc   |   0
 example/{ => plugins/c-api}/protocol/Protocol.c    |   0
 example/{ => plugins/c-api}/protocol/Protocol.h    |   0
 example/{ => plugins/c-api}/protocol/README.txt    |   0
 example/{ => plugins/c-api}/protocol/TxnSM.c       |   0
 example/{ => plugins/c-api}/protocol/TxnSM.h       |   0
 .../c-api}/protocol/test/ProtocolClientTest.java   |   0
 .../c-api}/protocol/test/ProtocolServerTest.java   |   0
 .../{ => plugins/c-api}/protocol/test/file_gen.sh  |   0
 .../c-api}/protocol_stack/protocol_stack.cc        |   0
 .../{ => plugins/c-api}/query_remap/query_remap.c  |   0
 example/{ => plugins/c-api}/redirect_1/readme.txt  |   0
 .../{ => plugins/c-api}/redirect_1/redirect_1.c    |   0
 example/{ => plugins/c-api}/remap/build.txt        |   0
 example/{ => plugins/c-api}/remap/remap.cc         |   0
 .../{ => plugins/c-api}/remap_header_add/build.txt |   0
 .../c-api}/remap_header_add/remap_header_add.cc    |   0
 .../c-api}/replace_header/replace_header.c         |   0
 .../c-api}/request_buffer/request_buffer.c         |   0
 .../c-api}/response_header_1/response_header_1.c   |   0
 example/{ => plugins/c-api}/secure_link/readme.txt |   0
 .../{ => plugins/c-api}/secure_link/secure_link.c  |   0
 .../{ => plugins/c-api}/server_push/server_push.c  |   0
 .../c-api}/server_transform/server_transform.c     |   0
 .../c-api}/session_hooks/session_hooks.c           |   0
 .../c-api}/ssl_preaccept/ssl_preaccept.cc          |   0
 example/{ => plugins/c-api}/ssl_sni/ssl_sni.cc     |   0
 .../c-api}/ssl_sni_whitelist/ssl_sni_whitelist.cc  |   0
 example/{ => plugins/c-api}/statistic/statistic.cc |   0
 example/{ => plugins/c-api}/thread_1/readme.txt    |   0
 example/{ => plugins/c-api}/thread_1/thread_1.c    |   0
 example/{ => plugins/c-api}/thread_pool/README.txt |   0
 .../{ => plugins/c-api}/thread_pool/TESTPLAN.txt   |   0
 .../c-api}/thread_pool/include/Makefile.am         |   0
 .../{ => plugins/c-api}/thread_pool/include/gen.c  |   0
 .../c-api}/thread_pool/include/gen_inc.sh          |   0
 example/{ => plugins/c-api}/thread_pool/psi.c      |   0
 .../thread_pool/test/SDKTest/SDKtest_server.config |   0
 .../c-api}/thread_pool/test/SDKTest/psi_server.c   |   0
 .../thread_pool/test/SynTest/Tests/Psi/1.cfg       |   0
 .../thread_pool/test/SynTest/Tests/Psi/10.cfg      |   0
 .../thread_pool/test/SynTest/Tests/Psi/11.cfg      |   0
 .../thread_pool/test/SynTest/Tests/Psi/12.cfg      |   0
 .../thread_pool/test/SynTest/Tests/Psi/13.cfg      |   0
 .../thread_pool/test/SynTest/Tests/Psi/2.cfg       |   0
 .../thread_pool/test/SynTest/Tests/Psi/3.cfg       |   0
 .../thread_pool/test/SynTest/Tests/Psi/4.cfg       |   0
 .../thread_pool/test/SynTest/Tests/Psi/5.cfg       |   0
 .../thread_pool/test/SynTest/Tests/Psi/6.cfg       |   0
 .../thread_pool/test/SynTest/Tests/Psi/7.cfg       |   0
 .../thread_pool/test/SynTest/Tests/Psi/8.cfg       |   0
 .../thread_pool/test/SynTest/Tests/Psi/9.cfg       |   0
 .../test/SynTest/Tests/Psi/psi_files/tc10_file.txt |   0
 .../test/SynTest/Tests/Psi/psi_files/tc11_file.txt |   0
 .../test/SynTest/Tests/Psi/psi_files/tc12_file.txt |   0
 .../test/SynTest/Tests/Psi/psi_files/tc13_file.txt |   0
 .../test/SynTest/Tests/Psi/psi_files/tc1_file.txt  |   0
 .../test/SynTest/Tests/Psi/psi_files/tc2_file.txt  |   0
 .../test/SynTest/Tests/Psi/psi_files/tc3_file.txt  |   0
 .../test/SynTest/Tests/Psi/psi_files/tc4_file.txt  |   0
 .../test/SynTest/Tests/Psi/psi_files/tc5_file.txt  |   0
 .../test/SynTest/Tests/Psi/psi_files/tc6_file.txt  |   0
 .../test/SynTest/Tests/Psi/psi_files/tc7_file.txt  |   0
 .../test/SynTest/Tests/Psi/psi_files/tc8_file.txt  |   0
 .../test/SynTest/Tests/Psi/psi_files/tc9_file.txt  |   0
 .../c-api}/thread_pool/test/SynTest/system.cfg     |   0
 .../c-api}/thread_pool/test/SynTest/tests_psi.cfg  |   0
 example/{ => plugins/c-api}/thread_pool/thread.c   |   0
 example/{ => plugins/c-api}/thread_pool/thread.h   |   0
 .../c-api}/txn_data_sink/txn_data_sink.c           |   0
 .../{ => plugins/c-api}/vconn_args/vconn_args.cc   |   0
 .../{ => plugins/c-api}/verify_cert/verify_cert.cc |   0
 example/{ => plugins/c-api}/version/version.c      |   0
 example/plugins/cpp-api/Makefile.am                | 109 ++++++++++++
 .../cpp-api}/async_http_fetch/AsyncHttpFetch.cc    |   0
 .../AsyncHttpFetchStreaming.cc                     |   0
 .../cpp-api}/async_timer/AsyncTimer.cc             |   0
 .../{cppapi => plugins/cpp-api}/boom/README.txt    |   0
 example/{cppapi => plugins/cpp-api}/boom/boom.cc   |   0
 .../cpp-api}/clientredirect/ClientRedirect.cc      |   0
 .../cpp-api}/clientrequest/ClientRequest.cc        |   0
 .../CustomErrorRemapPlugin.cc                      |   0
 .../cpp-api}/customresponse/CustomResponse.cc      |   0
 .../DelayTransformationPlugin.cc                   |   0
 .../cpp-api}/globalhook/GlobalHookPlugin.cc        |   0
 .../GzipTransformationPlugin.cc                    |   0
 .../cpp-api}/helloworld/HelloWorldPlugin.cc        |   0
 .../cpp-api}/intercept/intercept.cc                |   0
 .../InternalTransactionHandling.cc                 |   0
 .../cpp-api}/logger_example/LoggerExample.cc       |   0
 .../MultipleTransactionHookPlugins.cc              |   0
 .../NullTransformationPlugin.cc                    |   0
 .../cpp-api}/post_buffer/PostBuffer.cc             |   0
 .../cpp-api}/remap_plugin/RemapPlugin.cc           |   0
 .../cpp-api}/serverresponse/ServerResponse.cc      |   0
 .../cpp-api}/stat_example/StatExample.cc           |   0
 .../timeout_example/TimeoutExamplePlugin.cc        |   0
 .../transactionhook/TransactionHookPlugin.cc       |   0
 .../cpp-api}/websocket/README.txt                  |   0
 .../cpp-api}/websocket/WSBuffer.cc                 |   0
 .../cpp-api}/websocket/WSBuffer.h                  |   0
 .../cpp-api}/websocket/WebSocket.cc                |   0
 .../cpp-api}/websocket/WebSocket.h                 |   0
 example/plugins/lua-api/connect_geoip.lua          |  36 ++++
 example/plugins/lua-api/connect_redis.lua          |  49 ++++++
 example/plugins/lua-api/sorted_query_params.lua    |  53 ++++++
 example/plugins/lua-api/uncompress.lua             |  52 ++++++
 148 files changed, 714 insertions(+), 199 deletions(-)

diff --git a/configure.ac b/configure.ac
index 1267cec..5a4f5d9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2027,6 +2027,9 @@ AC_CONFIG_FILES([
   doc/ext/local-config.py
   doc/uml/Makefile
   example/Makefile
+  example/plugins/Makefile
+  example/plugins/c-api/Makefile
+  example/plugins/cpp-api/Makefile
   include/Makefile
   include/ts/Makefile
   include/tscpp/api/Makefile
diff --git a/doc/developer-guide/api/functions/TSClientProtocolStack.en.rst b/doc/developer-guide/api/functions/TSClientProtocolStack.en.rst
index d5953f1..246b47d 100644
--- a/doc/developer-guide/api/functions/TSClientProtocolStack.en.rst
+++ b/doc/developer-guide/api/functions/TSClientProtocolStack.en.rst
@@ -102,10 +102,10 @@ QUIC        quic
 Examples
 --------
 
-The example below is excerpted from `example/protocol_stack/protocol_stack.cc`
+The example below is excerpted from `example/plugins/c-api/protocol_stack/protocol_stack.cc`
 in the Traffic Server source distribution. It demonstrates how to
 use :func:`TSHttpTxnClientProtocolStackGet` and :func:`TSHttpTxnClientProtocolStackContains`
 
-.. literalinclude:: ../../../../example/protocol_stack/protocol_stack.cc
+.. literalinclude:: ../../../../example/plugins/c-api/protocol_stack/protocol_stack.cc
   :language: c
   :lines: 31-46
diff --git a/doc/developer-guide/api/functions/TSHttpArgs.en.rst b/doc/developer-guide/api/functions/TSHttpArgs.en.rst
index b007b62..d152680 100644
--- a/doc/developer-guide/api/functions/TSHttpArgs.en.rst
+++ b/doc/developer-guide/api/functions/TSHttpArgs.en.rst
@@ -64,7 +64,7 @@ base plugin argument is reserved by calling :func:`TSHttpSsnArgIndexReserve`. Bo
 The functions return :code:`TS_SUCCESS` if an index was reserved,
 :code:`TS_ERROR` if not (most likely because all of the indices have already been reserved).
 Generally this will be a file or library scope global which is set at plugin initialization. This
-function is used in the example remap plugin :ts:git:`example/remap/remap.cc`. The index is stored
+function is used in the example remap plugin :ts:git:`example/plugins/c-api/remap/remap.cc`. The index is stored
 in the plugin global :code:`arg_index`. Transaction and session plugin argument indices are reserved
 independently.
 
diff --git a/doc/developer-guide/api/functions/TSSslClientContext.en.rst b/doc/developer-guide/api/functions/TSSslClientContext.en.rst
index 62e6379..a024827 100644
--- a/doc/developer-guide/api/functions/TSSslClientContext.en.rst
+++ b/doc/developer-guide/api/functions/TSSslClientContext.en.rst
@@ -51,10 +51,10 @@ function with :func:`TSSslContextDestroy`.
 Examples
 ========
 
-The example below is excerpted from `example/client_context_dump/client_context_dump.cc` in the Traffic 
+The example below is excerpted from `example/plugins/c-api/client_context_dump/client_context_dump.cc` in the Traffic 
 Server source distribution. It demonstrates how to use :func:`TSSslClientContextsNamesGet` and 
 :func:`TSSslClientContextFindByName` to retreive all contextxs.
 
-.. literalinclude:: ../../../../example/client_context_dump/client_context_dump.cc
+.. literalinclude:: ../../../../example/plugins/c-api/client_context_dump/client_context_dump.cc
   :language: c
   :lines: 137-145
diff --git a/doc/developer-guide/api/functions/TSVConnFdCreate.en.rst b/doc/developer-guide/api/functions/TSVConnFdCreate.en.rst
index 4b6b472..48e9aec 100644
--- a/doc/developer-guide/api/functions/TSVConnFdCreate.en.rst
+++ b/doc/developer-guide/api/functions/TSVConnFdCreate.en.rst
@@ -47,12 +47,12 @@ is returned, the socket is unchanged and the caller must close it.
 Examples
 ========
 
-The example below is excerpted from `example/intercept/intercept.cc`
+The example below is excerpted from `example/plugins/c-api/intercept/intercept.cc`
 in the Traffic Server source distribution. It demonstrates how to
 use :func:`TSVConnFdCreate` to construct a :type:`TSVConn` from a
 connected socket.
 
-.. literalinclude:: ../../../../example/intercept/intercept.cc
+.. literalinclude:: ../../../../example/plugins/c-api/intercept/intercept.cc
   :language: c
   :lines: 288-336
 
diff --git a/doc/developer-guide/plugins/adding-statistics.en.rst b/doc/developer-guide/plugins/adding-statistics.en.rst
index aae3283..3dd740d 100644
--- a/doc/developer-guide/plugins/adding-statistics.en.rst
+++ b/doc/developer-guide/plugins/adding-statistics.en.rst
@@ -36,7 +36,7 @@ increment a statistic from multiple plugins. Once you have a handle to the stati
 with :c:func:`TSStatIntSet`, and increment it with :c:func:`TSStatIntIncrement` or
 :c:func:`TSStatIntDecrement`.
 
-.. literalinclude:: ../../../example/statistic/statistic.cc
+.. literalinclude:: ../../../example/plugins/c-api/statistic/statistic.cc
    :language: cpp
    :lines: 32-
 
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/source-code.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/source-code.en.rst
index 6e634a3..0be1804 100644
--- a/doc/developer-guide/plugins/example-plugins/blacklist/source-code.en.rst
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/source-code.en.rst
@@ -43,5 +43,5 @@ This plugin illustrates:
 
 -  How to use the plugin configuration management interface
 
-.. literalinclude:: ../../../../../example/blacklist_1/blacklist_1.c
+.. literalinclude:: ../../../../../example/plugins/c-api/blacklist_1/blacklist_1.c
    :language: c
diff --git a/doc/developer-guide/plugins/example-plugins/query_remap/example-query-remap.en.rst b/doc/developer-guide/plugins/example-plugins/query_remap/example-query-remap.en.rst
index 33a4c77..edb796e 100644
--- a/doc/developer-guide/plugins/example-plugins/query_remap/example-query-remap.en.rst
+++ b/doc/developer-guide/plugins/example-plugins/query_remap/example-query-remap.en.rst
@@ -54,7 +54,7 @@ function. In ``query_remap``, ``tsremap_new_instance`` creates a
 plugin-defined ``query_remap_info`` struct to store its configuration
 parameters.
 
-.. literalinclude:: ../../../../../example/query_remap/query_remap.c
+.. literalinclude:: ../../../../../example/plugins/c-api/query_remap/query_remap.c
   :language: c
   :lines: 37-42
 
@@ -62,7 +62,7 @@ The :code:`ihandle`, an opaque pointer that can be used to pass
 per-instance data, is set to this struct pointer and will be passed to
 the :code:`TSRemapDoRemap` function when it is triggered for a request.
 
-.. literalinclude:: ../../../../../example/query_remap/query_remap.c
+.. literalinclude:: ../../../../../example/plugins/c-api/query_remap/query_remap.c
   :language: c
   :lines: 53-88
 
@@ -83,6 +83,6 @@ struct contains input and output members for the remap operation.
 parameter. If the parameter is found, the plugin sets a ``new_host`` to
 modify the request host:
 
-.. literalinclude:: ../../../../../example/query_remap/query_remap.c
+.. literalinclude:: ../../../../../example/plugins/c-api/query_remap/query_remap.c
   :language: c
   :lines: 112-166
diff --git a/doc/developer-guide/plugins/getting-started/plugin-registration-and-version-checking.en.rst b/doc/developer-guide/plugins/getting-started/plugin-registration-and-version-checking.en.rst
index 6cbe5c8..8e44433 100644
--- a/doc/developer-guide/plugins/getting-started/plugin-registration-and-version-checking.en.rst
+++ b/doc/developer-guide/plugins/getting-started/plugin-registration-and-version-checking.en.rst
@@ -34,7 +34,7 @@ Use the following interfaces:
 The plugin registers the plugin and ensures it's running with a
 compatible version of Traffic Server.
 
-.. literalinclude:: ../../../../example/version/version.c
+.. literalinclude:: ../../../../example/plugins/c-api/version/version.c
   :language: c
   :lines: 23-
 
diff --git a/doc/developer-guide/plugins/http-transformations/index.en.rst b/doc/developer-guide/plugins/http-transformations/index.en.rst
index 92f48ad..e70c74d 100644
--- a/doc/developer-guide/plugins/http-transformations/index.en.rst
+++ b/doc/developer-guide/plugins/http-transformations/index.en.rst
@@ -181,5 +181,5 @@ and will keep the transaction and the origin server connection up. This is usefu
 run to completion even if the user agent disconnects. Examples would be a standard transform that is expensive to initiate, or expensive
 origin server connections that should be :ts:cv:`shared <proxy.config.http.server_session_sharing.match>`.
 
-There is an `example plugin <https://github.com/apache/trafficserver/blob/master/example/txn_data_sink/txn_data_sink.c>`_ that demonstrates
+There is an `example plugin <https://github.com/apache/trafficserver/blob/master/example/plugins/c-api/txn_data_sink/txn_data_sink.c>`_ that demonstrates
 this used as a pure data sink to keep the transaction up regardless of whether the user agent disconnects.
diff --git a/doc/locale/ja/LC_MESSAGES/developer-guide/api/functions/TSVConnFdCreate.en.po b/doc/locale/ja/LC_MESSAGES/developer-guide/api/functions/TSVConnFdCreate.en.po
index 29acfa1..3bbf36a 100644
--- a/doc/locale/ja/LC_MESSAGES/developer-guide/api/functions/TSVConnFdCreate.en.po
+++ b/doc/locale/ja/LC_MESSAGES/developer-guide/api/functions/TSVConnFdCreate.en.po
@@ -77,7 +77,7 @@ msgstr "参照"
 
 #: ../../developer-guide/api/functions/TSVConnFdCreate.en.rst:50
 msgid ""
-"The example below is excerpted from `example/intercept/intercept.cc` in the "
+"The example below is excerpted from `example/plugins/c-api/intercept/intercept.cc` in the "
 "Traffic Server source distribution. It demonstrates how to use :func:"
 "`TSVConnFdCreate` to construct a :type:`TSVConn` from a connected socket."
 msgstr ""
diff --git a/doc/locale/ja/LC_MESSAGES/developer-guide/plugins/http-transformations/index.en.po b/doc/locale/ja/LC_MESSAGES/developer-guide/plugins/http-transformations/index.en.po
index c8bc94f..7951165 100644
--- a/doc/locale/ja/LC_MESSAGES/developer-guide/plugins/http-transformations/index.en.po
+++ b/doc/locale/ja/LC_MESSAGES/developer-guide/plugins/http-transformations/index.en.po
@@ -235,7 +235,7 @@ msgstr ""
 #: ../../developer-guide/plugins/http-transformations/index.en.rst:184
 msgid ""
 "There is an `example plugin <https://github.com/apache/trafficserver/blob/"
-"master/example/txn-data-sink/txn-data-sink.c>`_ that demonstrates this used "
+"master/example/plugins/c-api/txn-data-sink/txn-data-sink.c>`_ that demonstrates this used "
 "as a pure data sink to keep the transaction up regardless of whether the "
 "user agent disconnects."
 msgstr ""
diff --git a/example/Makefile.am b/example/Makefile.am
index f81b9ef..2975563 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -1,3 +1,5 @@
+# example Makefile.am
+#
 #  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
@@ -14,179 +16,4 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-include $(top_srcdir)/build/plugins.mk
-include $(top_srcdir)/build/tidy.mk
-
-AM_CXXFLAGS += -Wno-unused-variable
-AM_LDFLAGS = $(TS_PLUGIN_LD_FLAGS)
-
-libtscppapi = $(top_builddir)/src/tscpp/api/libtscppapi.la
-
-if BUILD_EXAMPLE_PLUGINS
-
-example_Plugins = \
-	add_header.la \
-	append_transform.la \
-	basic_auth.la \
-	blacklist_0.la \
-	blacklist_1.la \
-	bnull_transform.la \
-	cert_update.la \
-	request_buffer.la \
-	cache_scan.la \
-	client_context_dump.la \
-	file_1.la \
-	hello.la \
-	intercept.la \
-	lifecycle_plugin.la \
-	null_transform.la \
-	output_header.la \
-	passthru.la \
-	protocol_stack.la \
-	protocol.la \
-	psi.la \
-	query_remap.la \
-	redirect_1.la \
-	remap.la \
-	remap_header_add.la \
-	replace_header.la \
-	response_header_1.la \
-	secure_link.la \
-	server_push.la \
-	server_transform.la \
-	session_hooks.la \
-	ssl_preaccept.la \
-	ssl_sni_whitelist.la \
-	ssl_sni.la \
-	statistic.la \
-	thread_1.la \
-	txn_data_sink.la \
-	version.la \
-	disable_http2.la \
-	verify_cert.la \
-	vconn_args.la
-
-example_Plugins += \
-	cppapi/AsyncHttpFetch.la \
-	cppapi/AsyncHttpFetchStreaming.la \
-	cppapi/AsyncTimer.la \
-	cppapi/ClientRedirect.la \
-	cppapi/ClientRequest.la \
-	cppapi/CustomErrorRemapPlugin.la \
-	cppapi/CustomResponse.la \
-	cppapi/DelayTransformationPlugin.la \
-	cppapi/GlobalHookPlugin.la \
-	cppapi/GzipTransformationPlugin.la \
-	cppapi/HelloWorldPlugin.la \
-	cppapi/InternalTransactionHandling.la \
-	cppapi/LoggerExample.la \
-	cppapi/MultipleTransactionHookPlugins.la \
-	cppapi/NullTransformationPlugin.la \
-	cppapi/PostBuffer.la \
-	cppapi/RemapPlugin.la \
-	cppapi/ServerResponse.la \
-	cppapi/StatExample.la \
-	cppapi/TimeoutExamplePlugin.la \
-	cppapi/TransactionHookPlugin.la \
-	cppapi/WebSocket.la \
-	cppapi/boom.la \
-	cppapi/intercept.la
-
-pkglib_LTLIBRARIES = $(example_Plugins)
-
-endif
-
-add_header_la_SOURCES = add_header/add_header.c
-append_transform_la_SOURCES = append_transform/append_transform.c
-basic_auth_la_SOURCES = basic_auth/basic_auth.c
-blacklist_0_la_SOURCES = blacklist_0/blacklist_0.c
-blacklist_1_la_SOURCES = blacklist_1/blacklist_1.c
-bnull_transform_la_SOURCES = bnull_transform/bnull_transform.c
-cert_update_la_SOURCES = cert_update/cert_update.cc
-request_buffer_la_SOURCES = request_buffer/request_buffer.c
-cache_scan_la_SOURCES = cache_scan/cache_scan.cc
-client_context_dump_la_SOURCES = client_context_dump/client_context_dump.cc
-file_1_la_SOURCES = file_1/file_1.c
-hello_la_SOURCES = hello/hello.c
-intercept_la_SOURCES = intercept/intercept.cc
-lifecycle_plugin_la_SOURCES = lifecycle_plugin/lifecycle_plugin.c
-null_transform_la_SOURCES = null_transform/null_transform.c
-output_header_la_SOURCES = output_header/output_header.c
-passthru_la_SOURCES = passthru/passthru.cc
-protocol_la_SOURCES = protocol/Protocol.c protocol/TxnSM.c
-protocol_stack_la_SOURCES = protocol_stack/protocol_stack.cc
-psi_la_SOURCES = thread_pool/psi.c thread_pool/thread.c
-query_remap_la_SOURCES = query_remap/query_remap.c
-remap_header_add_la_SOURCES = remap_header_add/remap_header_add.cc
-remap_la_SOURCES = remap/remap.cc
-replace_header_la_SOURCES = replace_header/replace_header.c
-response_header_1_la_SOURCES = response_header_1/response_header_1.c
-secure_link_la_SOURCES = secure_link/secure_link.c
-server_push_la_SOURCES = server_push/server_push.c
-server_transform_la_SOURCES = server_transform/server_transform.c
-ssl_preaccept_la_SOURCES = ssl_preaccept/ssl_preaccept.cc
-ssl_sni_la_SOURCES = ssl_sni/ssl_sni.cc
-ssl_sni_whitelist_la_SOURCES = ssl_sni_whitelist/ssl_sni_whitelist.cc
-disable_http2_la_SOURCES = disable_http2/disable_http2.cc
-verify_cert_la_SOURCES = verify_cert/verify_cert.cc
-statistic_la_SOURCES = statistic/statistic.cc
-thread_1_la_SOURCES = thread_1/thread_1.c
-txn_data_sink_la_SOURCES = txn_data_sink/txn_data_sink.c
-version_la_SOURCES = version/version.c
-redirect_1_la_SOURCES = redirect_1/redirect_1.c
-session_hooks_la_SOURCES = session_hooks/session_hooks.c
-vconn_args_la_SOURCES = vconn_args/vconn_args.cc
-
-cppapi_AsyncHttpFetchStreaming_la_SOURCES = cppapi/async_http_fetch_streaming/AsyncHttpFetchStreaming.cc
-cppapi_AsyncHttpFetch_la_SOURCES = cppapi/async_http_fetch/AsyncHttpFetch.cc
-cppapi_AsyncTimer_la_SOURCES = cppapi/async_timer/AsyncTimer.cc
-cppapi_ClientRedirect_la_SOURCES = cppapi/clientredirect/ClientRedirect.cc
-cppapi_ClientRequest_la_SOURCES = cppapi/clientrequest/ClientRequest.cc
-cppapi_CustomErrorRemapPlugin_la_SOURCES = cppapi/custom_error_remap_plugin/CustomErrorRemapPlugin.cc
-cppapi_CustomResponse_la_SOURCES = cppapi/customresponse/CustomResponse.cc
-cppapi_DelayTransformationPlugin_la_SOURCES = cppapi/delay_transformation_plugin/DelayTransformationPlugin.cc
-cppapi_GlobalHookPlugin_la_SOURCES = cppapi/globalhook/GlobalHookPlugin.cc
-cppapi_GzipTransformationPlugin_la_SOURCES = cppapi/gzip_transformation/GzipTransformationPlugin.cc
-cppapi_HelloWorldPlugin_la_SOURCES = cppapi/helloworld/HelloWorldPlugin.cc
-cppapi_InternalTransactionHandling_la_SOURCES = cppapi/internal_transaction_handling/InternalTransactionHandling.cc
-cppapi_LoggerExample_la_SOURCES = cppapi/logger_example/LoggerExample.cc
-cppapi_MultipleTransactionHookPlugins_la_SOURCES = cppapi/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc
-cppapi_NullTransformationPlugin_la_SOURCES = cppapi/null_transformation_plugin/NullTransformationPlugin.cc
-cppapi_PostBuffer_la_SOURCES = cppapi/post_buffer/PostBuffer.cc
-cppapi_RemapPlugin_la_SOURCES = cppapi/remap_plugin/RemapPlugin.cc
-cppapi_ServerResponse_la_SOURCES = cppapi/serverresponse/ServerResponse.cc
-cppapi_StatExample_la_SOURCES = cppapi/stat_example/StatExample.cc
-cppapi_TimeoutExamplePlugin_la_SOURCES = cppapi/timeout_example/TimeoutExamplePlugin.cc
-cppapi_TransactionHookPlugin_la_SOURCES = cppapi/transactionhook/TransactionHookPlugin.cc
-cppapi_WebSocket_la_SOURCES = cppapi/websocket/WebSocket.cc cppapi/websocket/WSBuffer.cc
-cppapi_boom_la_SOURCES = cppapi/boom/boom.cc
-cppapi_intercept_la_SOURCES = cppapi/intercept/intercept.cc
-
-cppapi_AsyncHttpFetchStreaming_la_LIBADD = $(libtscppapi)
-cppapi_AsyncHttpFetch_la_LIBADD = $(libtscppapi)
-cppapi_AsyncTimer_la_LIBADD = $(libtscppapi)
-cppapi_ClientRedirect_la_LIBADD = $(libtscppapi)
-cppapi_ClientRequest_la_LIBADD = $(libtscppapi)
-cppapi_CustomErrorRemapPlugin_la_LIBADD = $(libtscppapi)
-cppapi_CustomResponse_la_LIBADD = $(libtscppapi)
-cppapi_DelayTransformationPlugin_la_LIBADD = $(libtscppapi)
-cppapi_GlobalHookPlugin_la_LIBADD = $(libtscppapi)
-cppapi_GzipTransformationPlugin_la_LIBADD = $(libtscppapi)
-cppapi_HelloWorldPlugin_la_LIBADD = $(libtscppapi)
-cppapi_InternalTransactionHandling_la_LIBADD = $(libtscppapi)
-cppapi_LoggerExample_la_LIBADD = $(libtscppapi)
-cppapi_MultipleTransactionHookPlugins_la_LIBADD = $(libtscppapi)
-cppapi_NullTransformationPlugin_la_LIBADD = $(libtscppapi)
-cppapi_PostBuffer_la_LIBADD = $(libtscppapi)
-cppapi_RemapPlugin_la_LIBADD = $(libtscppapi)
-cppapi_ServerResponse_la_LIBADD = $(libtscppapi)
-cppapi_StatExample_la_LIBADD = $(libtscppapi)
-cppapi_TimeoutExamplePlugin_la_LIBADD = $(libtscppapi)
-cppapi_TransactionHookPlugin_la_LIBADD = $(libtscppapi)
-cppapi_WebSocket_la_LIBADD = $(libtscppapi)
-cppapi_boom_la_LIBADD = $(libtscppapi)
-cppapi_intercept_la_LIBADD = $(libtscppapi)
-
-clang-tidy-local: $(DIST_SOURCES)
-	$(CXX_Clang_Tidy)
-	$(CC_Clang_Tidy)
+SUBDIRS = plugins
diff --git a/example/thread_pool/include/Makefile.am b/example/plugins/Makefile.am
similarity index 91%
copy from example/thread_pool/include/Makefile.am
copy to example/plugins/Makefile.am
index b6f4351..c4d72d3 100644
--- a/example/thread_pool/include/Makefile.am
+++ b/example/plugins/Makefile.am
@@ -1,3 +1,5 @@
+# example/plugins Makefile.am
+#
 #  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
@@ -14,10 +16,4 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-all: gen
-
-gen: gen.c
-	$(CC) -o gen gen.c
-
-clean-local:
-	rm -f gen gen.o
+SUBDIRS = c-api cpp-api
diff --git a/example/plugins/c-api/Makefile.am b/example/plugins/c-api/Makefile.am
new file mode 100644
index 0000000..b63f81e
--- /dev/null
+++ b/example/plugins/c-api/Makefile.am
@@ -0,0 +1,114 @@
+#  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 $(top_srcdir)/build/plugins.mk
+include $(top_srcdir)/build/tidy.mk
+
+AM_CXXFLAGS += -Wno-unused-variable
+AM_LDFLAGS = $(TS_PLUGIN_LD_FLAGS)
+
+if BUILD_EXAMPLE_PLUGINS
+
+example_Plugins = \
+	add_header.la \
+	append_transform.la \
+	basic_auth.la \
+	blacklist_0.la \
+	blacklist_1.la \
+	bnull_transform.la \
+	cert_update.la \
+	request_buffer.la \
+	cache_scan.la \
+	client_context_dump.la \
+	file_1.la \
+	hello.la \
+	intercept.la \
+	lifecycle_plugin.la \
+	null_transform.la \
+	output_header.la \
+	passthru.la \
+	protocol_stack.la \
+	protocol.la \
+	psi.la \
+	query_remap.la \
+	redirect_1.la \
+	remap.la \
+	remap_header_add.la \
+	replace_header.la \
+	response_header_1.la \
+	secure_link.la \
+	server_push.la \
+	server_transform.la \
+	session_hooks.la \
+	ssl_preaccept.la \
+	ssl_sni_whitelist.la \
+	ssl_sni.la \
+	statistic.la \
+	thread_1.la \
+	txn_data_sink.la \
+	version.la \
+	disable_http2.la \
+	verify_cert.la \
+	vconn_args.la
+
+pkglib_LTLIBRARIES = $(example_Plugins)
+
+endif
+
+add_header_la_SOURCES = add_header/add_header.c
+append_transform_la_SOURCES = append_transform/append_transform.c
+basic_auth_la_SOURCES = basic_auth/basic_auth.c
+blacklist_0_la_SOURCES = blacklist_0/blacklist_0.c
+blacklist_1_la_SOURCES = blacklist_1/blacklist_1.c
+bnull_transform_la_SOURCES = bnull_transform/bnull_transform.c
+cert_update_la_SOURCES = cert_update/cert_update.cc
+request_buffer_la_SOURCES = request_buffer/request_buffer.c
+cache_scan_la_SOURCES = cache_scan/cache_scan.cc
+client_context_dump_la_SOURCES = client_context_dump/client_context_dump.cc
+file_1_la_SOURCES = file_1/file_1.c
+hello_la_SOURCES = hello/hello.c
+intercept_la_SOURCES = intercept/intercept.cc
+lifecycle_plugin_la_SOURCES = lifecycle_plugin/lifecycle_plugin.c
+null_transform_la_SOURCES = null_transform/null_transform.c
+output_header_la_SOURCES = output_header/output_header.c
+passthru_la_SOURCES = passthru/passthru.cc
+protocol_la_SOURCES = protocol/Protocol.c protocol/TxnSM.c
+protocol_stack_la_SOURCES = protocol_stack/protocol_stack.cc
+psi_la_SOURCES = thread_pool/psi.c thread_pool/thread.c
+query_remap_la_SOURCES = query_remap/query_remap.c
+remap_header_add_la_SOURCES = remap_header_add/remap_header_add.cc
+remap_la_SOURCES = remap/remap.cc
+replace_header_la_SOURCES = replace_header/replace_header.c
+response_header_1_la_SOURCES = response_header_1/response_header_1.c
+secure_link_la_SOURCES = secure_link/secure_link.c
+server_push_la_SOURCES = server_push/server_push.c
+server_transform_la_SOURCES = server_transform/server_transform.c
+ssl_preaccept_la_SOURCES = ssl_preaccept/ssl_preaccept.cc
+ssl_sni_la_SOURCES = ssl_sni/ssl_sni.cc
+ssl_sni_whitelist_la_SOURCES = ssl_sni_whitelist/ssl_sni_whitelist.cc
+disable_http2_la_SOURCES = disable_http2/disable_http2.cc
+verify_cert_la_SOURCES = verify_cert/verify_cert.cc
+statistic_la_SOURCES = statistic/statistic.cc
+thread_1_la_SOURCES = thread_1/thread_1.c
+txn_data_sink_la_SOURCES = txn_data_sink/txn_data_sink.c
+version_la_SOURCES = version/version.c
+redirect_1_la_SOURCES = redirect_1/redirect_1.c
+session_hooks_la_SOURCES = session_hooks/session_hooks.c
+vconn_args_la_SOURCES = vconn_args/vconn_args.cc
+
+clang-tidy-local: $(DIST_SOURCES)
+	$(CXX_Clang_Tidy)
+	$(CC_Clang_Tidy)
diff --git a/example/add_header/add_header.c b/example/plugins/c-api/add_header/add_header.c
similarity index 100%
rename from example/add_header/add_header.c
rename to example/plugins/c-api/add_header/add_header.c
diff --git a/example/add_header/readme.txt b/example/plugins/c-api/add_header/readme.txt
similarity index 100%
rename from example/add_header/readme.txt
rename to example/plugins/c-api/add_header/readme.txt
diff --git a/example/append_transform/append_transform.c b/example/plugins/c-api/append_transform/append_transform.c
similarity index 100%
rename from example/append_transform/append_transform.c
rename to example/plugins/c-api/append_transform/append_transform.c
diff --git a/example/append_transform/readme.txt b/example/plugins/c-api/append_transform/readme.txt
similarity index 100%
rename from example/append_transform/readme.txt
rename to example/plugins/c-api/append_transform/readme.txt
diff --git a/example/basic_auth/basic_auth.c b/example/plugins/c-api/basic_auth/basic_auth.c
similarity index 100%
rename from example/basic_auth/basic_auth.c
rename to example/plugins/c-api/basic_auth/basic_auth.c
diff --git a/example/basic_auth/readme.txt b/example/plugins/c-api/basic_auth/readme.txt
similarity index 100%
rename from example/basic_auth/readme.txt
rename to example/plugins/c-api/basic_auth/readme.txt
diff --git a/example/blacklist_0/blacklist_0.c b/example/plugins/c-api/blacklist_0/blacklist_0.c
similarity index 100%
rename from example/blacklist_0/blacklist_0.c
rename to example/plugins/c-api/blacklist_0/blacklist_0.c
diff --git a/example/blacklist_1/blacklist.txt b/example/plugins/c-api/blacklist_1/blacklist.txt
similarity index 100%
rename from example/blacklist_1/blacklist.txt
rename to example/plugins/c-api/blacklist_1/blacklist.txt
diff --git a/example/blacklist_1/blacklist_1.c b/example/plugins/c-api/blacklist_1/blacklist_1.c
similarity index 100%
rename from example/blacklist_1/blacklist_1.c
rename to example/plugins/c-api/blacklist_1/blacklist_1.c
diff --git a/example/blacklist_1/readme.txt b/example/plugins/c-api/blacklist_1/readme.txt
similarity index 100%
rename from example/blacklist_1/readme.txt
rename to example/plugins/c-api/blacklist_1/readme.txt
diff --git a/example/bnull_transform/bnull_transform.c b/example/plugins/c-api/bnull_transform/bnull_transform.c
similarity index 100%
rename from example/bnull_transform/bnull_transform.c
rename to example/plugins/c-api/bnull_transform/bnull_transform.c
diff --git a/example/cache_scan/cache_scan.cc b/example/plugins/c-api/cache_scan/cache_scan.cc
similarity index 100%
rename from example/cache_scan/cache_scan.cc
rename to example/plugins/c-api/cache_scan/cache_scan.cc
diff --git a/example/plugins/c-api/cert_update/cert_update.cc b/example/plugins/c-api/cert_update/cert_update.cc
new file mode 100644
index 0000000..4c8d860
--- /dev/null
+++ b/example/plugins/c-api/cert_update/cert_update.cc
@@ -0,0 +1,86 @@
+/** @file
+
+  an example cert update plugin
+
+  @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 <stdio.h>
+#include <cstring>
+#include <string>
+#include <string_view>
+
+#include "ts/ts.h"
+#include "tscpp/util/TextView.h"
+
+#define PLUGIN_NAME "cert_update"
+
+// Plugin Message Continuation
+int
+CB_cert_update(TSCont, TSEvent, void *edata)
+{
+  TSPluginMsg *msg = static_cast<TSPluginMsg *>(edata);
+  static constexpr std::string_view PLUGIN_PREFIX("cert_update."_sv);
+
+  std::string_view tag(msg->tag, strlen(msg->tag));
+  const char *server_cert_path = nullptr;
+  const char *client_cert_path = nullptr;
+  if (tag.substr(0, PLUGIN_PREFIX.size()) == PLUGIN_PREFIX) {
+    tag.remove_prefix(PLUGIN_PREFIX.size());
+    if (tag == "server") {
+      server_cert_path = static_cast<const char *>(msg->data);
+      TSDebug(PLUGIN_NAME, "Received Msg to update server cert with %s", server_cert_path);
+    } else if (tag == "client") {
+      client_cert_path = static_cast<const char *>(msg->data);
+      TSDebug(PLUGIN_NAME, "Received Msg to update client cert with %s", client_cert_path);
+    }
+  }
+
+  if (server_cert_path) {
+    if (TS_SUCCESS == TSSslServerCertUpdate(server_cert_path, nullptr)) {
+      TSDebug(PLUGIN_NAME, "Successfully updated server cert with %s", server_cert_path);
+    } else {
+      TSDebug(PLUGIN_NAME, "Failed to update server cert with %s", server_cert_path);
+    }
+  }
+  if (client_cert_path) {
+    if (TS_SUCCESS == TSSslClientCertUpdate(client_cert_path, nullptr)) {
+      TSDebug(PLUGIN_NAME, "Successfully updated client cert with %s", client_cert_path);
+    } else {
+      TSDebug(PLUGIN_NAME, "Failed to update client cert with %s", client_cert_path);
+    }
+  }
+  return TS_SUCCESS;
+}
+
+void
+TSPluginInit(int argc, const char *argv[])
+{
+  TSPluginRegistrationInfo info;
+
+  info.plugin_name   = PLUGIN_NAME;
+  info.vendor_name   = "Apache Software Foundation";
+  info.support_email = "dev@trafficserver.apache.org";
+
+  if (TSPluginRegister(&info) != TS_SUCCESS) {
+    TSError("[%s] Plugin registration failed", PLUGIN_NAME);
+  }
+  TSDebug(PLUGIN_NAME, "Initialized.");
+  TSLifecycleHookAdd(TS_LIFECYCLE_MSG_HOOK, TSContCreate(CB_cert_update, nullptr));
+}
diff --git a/example/plugins/c-api/client_context_dump/client_context_dump.cc b/example/plugins/c-api/client_context_dump/client_context_dump.cc
new file mode 100644
index 0000000..919fa4f
--- /dev/null
+++ b/example/plugins/c-api/client_context_dump/client_context_dump.cc
@@ -0,0 +1,190 @@
+/** @file
+   an example client context dump plugin
+   @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 <stdio.h>
+#include <cstring>
+#include <string>
+#include <string_view>
+
+#ifdef OPENSSL_NO_SSL_INTERN
+#undef OPENSSL_NO_SSL_INTERN
+#endif
+
+#include <openssl/opensslv.h>
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "ts/ts.h"
+#include "tscpp/util/TextView.h"
+
+#define PLUGIN_NAME "client_context_dump"
+TSTextLogObject context_dump_log;
+
+char *
+asn1_string_extract(ASN1_STRING *s)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x010100000
+  return reinterpret_cast<char *>(const_cast<unsigned char *>(ASN1_STRING_get0_data(s)));
+#else
+  return reinterpret_cast<char *>(ASN1_STRING_data(s));
+#endif
+}
+
+// For 1.0.2, needs access to internal structure
+// For 1.1.0 and 1.1.1, use API
+void
+dump_context(const char *ca_path, const char *ck_path)
+{
+  TSSslContext ctx = TSSslClientContextFindByName(ca_path, ck_path);
+  if (ctx) {
+    SSL *s = SSL_new(reinterpret_cast<SSL_CTX *>(ctx));
+    if (s) {
+      char *data  = nullptr;
+      long length = 0;
+      std::string subject_s, san_s, serial_s, time_s;
+      X509 *cert = SSL_get_certificate(s);
+      if (cert) {
+        // Retrieve state info and write to log object
+        // expiration date, serial number, common name, and subject alternative names
+        const ASN1_TIME *not_after = X509_get_notAfter(cert);
+        const ASN1_INTEGER *serial = X509_get_serialNumber(cert);
+        X509_NAME *subject_name    = X509_get_subject_name(cert);
+
+        // Subject name
+        BIO *subject_bio = BIO_new(BIO_s_mem());
+        X509_NAME_print_ex(subject_bio, subject_name, 0, XN_FLAG_RFC2253);
+        length = BIO_get_mem_data(subject_bio, &data);
+        if (length > 0 && data) {
+          subject_s = std::string(data, length);
+        }
+        length = 0;
+        data   = nullptr;
+        BIO_free(subject_bio);
+
+        // Subject Alternative Name
+        GENERAL_NAMES *names = static_cast<GENERAL_NAMES *>(X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr));
+        if (names) {
+          unsigned count = sk_GENERAL_NAME_num(names);
+          for (unsigned i = 0; i < count; ++i) {
+            GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
+            data               = nullptr;
+            length             = 0;
+            switch (name->type) {
+            case (GEN_EMAIL): {
+              data   = asn1_string_extract(name->d.rfc822Name);
+              length = ASN1_STRING_length(name->d.rfc822Name);
+              break;
+            }
+            case (GEN_DNS): {
+              data   = asn1_string_extract(name->d.dNSName);
+              length = ASN1_STRING_length(name->d.dNSName);
+              break;
+            }
+            case (GEN_URI): {
+              data   = asn1_string_extract(name->d.uniformResourceIdentifier);
+              length = ASN1_STRING_length(name->d.uniformResourceIdentifier);
+              break;
+            }
+            default:
+              break;
+            }
+            if (data) {
+              san_s.append(data, length);
+              san_s.push_back(',');
+            }
+          }
+          if (san_s.back() == ',') {
+            san_s.pop_back();
+          }
+        }
+
+        // Serial number
+        int64_t sn = 0;
+#if OPENSSL_VERSION_NUMBER >= 0x010100000
+        ASN1_INTEGER_get_int64(&sn, serial);
+#else
+        sn = ASN1_INTEGER_get(serial);
+#endif
+        if (sn != 0 && sn != -1) {
+          serial_s = std::to_string(sn);
+        }
+
+        // Expiration
+        BIO *time_bio = BIO_new(BIO_s_mem());
+        ASN1_TIME_print(time_bio, not_after);
+        length = BIO_get_mem_data(time_bio, &data);
+        time_s = std::string(data, length);
+        BIO_free(time_bio);
+        TSDebug(PLUGIN_NAME, "LookupName: %s:%s, Subject: %s. SAN: %s. Serial: %s. NotAfter: %s.", ca_path, ck_path,
+                subject_s.c_str(), san_s.c_str(), serial_s.c_str(), time_s.c_str());
+        TSTextLogObjectWrite(context_dump_log, "LookupName: %s:%s, Subject: %s. SAN: %s. Serial: %s. NotAfter: %s.", ca_path,
+                             ck_path, subject_s.c_str(), san_s.c_str(), serial_s.c_str(), time_s.c_str());
+      }
+    }
+    SSL_free(s);
+    TSSslContextDestroy(ctx);
+  }
+}
+
+// Plugin Message Continuation
+int
+CB_context_dump(TSCont, TSEvent, void *edata)
+{
+  TSPluginMsg *msg = static_cast<TSPluginMsg *>(edata);
+  static constexpr std::string_view PLUGIN_PREFIX("client_context_dump."_sv);
+
+  std::string_view tag(msg->tag, strlen(msg->tag));
+
+  if (tag.substr(0, PLUGIN_PREFIX.size()) == PLUGIN_PREFIX) {
+    tag.remove_prefix(PLUGIN_PREFIX.size());
+    // Grab all keys by API and dump to log file according to arg passed in
+    int count = 0;
+    TSSslClientContextsNamesGet(0, nullptr, &count);
+    if (count > 0) {
+      char const **results = static_cast<char const **>(malloc(sizeof(const char *) * count));
+      TSSslClientContextsNamesGet(count, results, nullptr);
+      for (int i = 0; i < count; i += 2) {
+        dump_context(results[i], results[i + 1]);
+      }
+    }
+  }
+  TSTextLogObjectFlush(context_dump_log);
+  return TS_SUCCESS;
+}
+
+void
+TSPluginInit(int argc, const char *argv[])
+{
+  TSPluginRegistrationInfo info;
+
+  info.plugin_name   = PLUGIN_NAME;
+  info.vendor_name   = "Apache Software Foundation";
+  info.support_email = "dev@trafficserver.apache.org";
+
+  if (TSPluginRegister(&info) != TS_SUCCESS) {
+    TSError("[%s] Plugin registration failed", PLUGIN_NAME);
+    return;
+  }
+  if (TSTextLogObjectCreate(PLUGIN_NAME, TS_LOG_MODE_ADD_TIMESTAMP, &context_dump_log) != TS_SUCCESS || !context_dump_log) {
+    TSError("[%s] Failed to create log file", PLUGIN_NAME);
+    return;
+  }
+  TSDebug(PLUGIN_NAME, "Initialized.");
+  TSLifecycleHookAdd(TS_LIFECYCLE_MSG_HOOK, TSContCreate(CB_context_dump, nullptr));
+}
diff --git a/example/disable_http2/disable_http2.cc b/example/plugins/c-api/disable_http2/disable_http2.cc
similarity index 100%
rename from example/disable_http2/disable_http2.cc
rename to example/plugins/c-api/disable_http2/disable_http2.cc
diff --git a/example/disable_http2/readme.txt b/example/plugins/c-api/disable_http2/readme.txt
similarity index 100%
rename from example/disable_http2/readme.txt
rename to example/plugins/c-api/disable_http2/readme.txt
diff --git a/example/file_1/file_1.c b/example/plugins/c-api/file_1/file_1.c
similarity index 100%
rename from example/file_1/file_1.c
rename to example/plugins/c-api/file_1/file_1.c
diff --git a/example/file_1/readme.txt b/example/plugins/c-api/file_1/readme.txt
similarity index 100%
rename from example/file_1/readme.txt
rename to example/plugins/c-api/file_1/readme.txt
diff --git a/example/hello/hello.c b/example/plugins/c-api/hello/hello.c
similarity index 100%
rename from example/hello/hello.c
rename to example/plugins/c-api/hello/hello.c
diff --git a/example/intercept/intercept.cc b/example/plugins/c-api/intercept/intercept.cc
similarity index 100%
rename from example/intercept/intercept.cc
rename to example/plugins/c-api/intercept/intercept.cc
diff --git a/example/lifecycle_plugin/lifecycle_plugin.c b/example/plugins/c-api/lifecycle_plugin/lifecycle_plugin.c
similarity index 100%
rename from example/lifecycle_plugin/lifecycle_plugin.c
rename to example/plugins/c-api/lifecycle_plugin/lifecycle_plugin.c
diff --git a/example/lifecycle_plugin/readme.txt b/example/plugins/c-api/lifecycle_plugin/readme.txt
similarity index 100%
rename from example/lifecycle_plugin/readme.txt
rename to example/plugins/c-api/lifecycle_plugin/readme.txt
diff --git a/example/null_transform/null_transform.c b/example/plugins/c-api/null_transform/null_transform.c
similarity index 100%
rename from example/null_transform/null_transform.c
rename to example/plugins/c-api/null_transform/null_transform.c
diff --git a/example/null_transform/readme.txt b/example/plugins/c-api/null_transform/readme.txt
similarity index 100%
rename from example/null_transform/readme.txt
rename to example/plugins/c-api/null_transform/readme.txt
diff --git a/example/output_header/output_header.c b/example/plugins/c-api/output_header/output_header.c
similarity index 100%
rename from example/output_header/output_header.c
rename to example/plugins/c-api/output_header/output_header.c
diff --git a/example/output_header/readme b/example/plugins/c-api/output_header/readme
similarity index 100%
rename from example/output_header/readme
rename to example/plugins/c-api/output_header/readme
diff --git a/example/passthru/passthru.cc b/example/plugins/c-api/passthru/passthru.cc
similarity index 100%
rename from example/passthru/passthru.cc
rename to example/plugins/c-api/passthru/passthru.cc
diff --git a/example/protocol/Protocol.c b/example/plugins/c-api/protocol/Protocol.c
similarity index 100%
rename from example/protocol/Protocol.c
rename to example/plugins/c-api/protocol/Protocol.c
diff --git a/example/protocol/Protocol.h b/example/plugins/c-api/protocol/Protocol.h
similarity index 100%
rename from example/protocol/Protocol.h
rename to example/plugins/c-api/protocol/Protocol.h
diff --git a/example/protocol/README.txt b/example/plugins/c-api/protocol/README.txt
similarity index 100%
rename from example/protocol/README.txt
rename to example/plugins/c-api/protocol/README.txt
diff --git a/example/protocol/TxnSM.c b/example/plugins/c-api/protocol/TxnSM.c
similarity index 100%
rename from example/protocol/TxnSM.c
rename to example/plugins/c-api/protocol/TxnSM.c
diff --git a/example/protocol/TxnSM.h b/example/plugins/c-api/protocol/TxnSM.h
similarity index 100%
rename from example/protocol/TxnSM.h
rename to example/plugins/c-api/protocol/TxnSM.h
diff --git a/example/protocol/test/ProtocolClientTest.java b/example/plugins/c-api/protocol/test/ProtocolClientTest.java
similarity index 100%
rename from example/protocol/test/ProtocolClientTest.java
rename to example/plugins/c-api/protocol/test/ProtocolClientTest.java
diff --git a/example/protocol/test/ProtocolServerTest.java b/example/plugins/c-api/protocol/test/ProtocolServerTest.java
similarity index 100%
rename from example/protocol/test/ProtocolServerTest.java
rename to example/plugins/c-api/protocol/test/ProtocolServerTest.java
diff --git a/example/protocol/test/file_gen.sh b/example/plugins/c-api/protocol/test/file_gen.sh
similarity index 100%
rename from example/protocol/test/file_gen.sh
rename to example/plugins/c-api/protocol/test/file_gen.sh
diff --git a/example/protocol_stack/protocol_stack.cc b/example/plugins/c-api/protocol_stack/protocol_stack.cc
similarity index 100%
rename from example/protocol_stack/protocol_stack.cc
rename to example/plugins/c-api/protocol_stack/protocol_stack.cc
diff --git a/example/query_remap/query_remap.c b/example/plugins/c-api/query_remap/query_remap.c
similarity index 100%
rename from example/query_remap/query_remap.c
rename to example/plugins/c-api/query_remap/query_remap.c
diff --git a/example/redirect_1/readme.txt b/example/plugins/c-api/redirect_1/readme.txt
similarity index 100%
rename from example/redirect_1/readme.txt
rename to example/plugins/c-api/redirect_1/readme.txt
diff --git a/example/redirect_1/redirect_1.c b/example/plugins/c-api/redirect_1/redirect_1.c
similarity index 100%
rename from example/redirect_1/redirect_1.c
rename to example/plugins/c-api/redirect_1/redirect_1.c
diff --git a/example/remap/build.txt b/example/plugins/c-api/remap/build.txt
similarity index 100%
rename from example/remap/build.txt
rename to example/plugins/c-api/remap/build.txt
diff --git a/example/remap/remap.cc b/example/plugins/c-api/remap/remap.cc
similarity index 100%
rename from example/remap/remap.cc
rename to example/plugins/c-api/remap/remap.cc
diff --git a/example/remap_header_add/build.txt b/example/plugins/c-api/remap_header_add/build.txt
similarity index 100%
rename from example/remap_header_add/build.txt
rename to example/plugins/c-api/remap_header_add/build.txt
diff --git a/example/remap_header_add/remap_header_add.cc b/example/plugins/c-api/remap_header_add/remap_header_add.cc
similarity index 100%
rename from example/remap_header_add/remap_header_add.cc
rename to example/plugins/c-api/remap_header_add/remap_header_add.cc
diff --git a/example/replace_header/replace_header.c b/example/plugins/c-api/replace_header/replace_header.c
similarity index 100%
rename from example/replace_header/replace_header.c
rename to example/plugins/c-api/replace_header/replace_header.c
diff --git a/example/request_buffer/request_buffer.c b/example/plugins/c-api/request_buffer/request_buffer.c
similarity index 100%
rename from example/request_buffer/request_buffer.c
rename to example/plugins/c-api/request_buffer/request_buffer.c
diff --git a/example/response_header_1/response_header_1.c b/example/plugins/c-api/response_header_1/response_header_1.c
similarity index 100%
rename from example/response_header_1/response_header_1.c
rename to example/plugins/c-api/response_header_1/response_header_1.c
diff --git a/example/secure_link/readme.txt b/example/plugins/c-api/secure_link/readme.txt
similarity index 100%
rename from example/secure_link/readme.txt
rename to example/plugins/c-api/secure_link/readme.txt
diff --git a/example/secure_link/secure_link.c b/example/plugins/c-api/secure_link/secure_link.c
similarity index 100%
rename from example/secure_link/secure_link.c
rename to example/plugins/c-api/secure_link/secure_link.c
diff --git a/example/server_push/server_push.c b/example/plugins/c-api/server_push/server_push.c
similarity index 100%
rename from example/server_push/server_push.c
rename to example/plugins/c-api/server_push/server_push.c
diff --git a/example/server_transform/server_transform.c b/example/plugins/c-api/server_transform/server_transform.c
similarity index 100%
rename from example/server_transform/server_transform.c
rename to example/plugins/c-api/server_transform/server_transform.c
diff --git a/example/session_hooks/session_hooks.c b/example/plugins/c-api/session_hooks/session_hooks.c
similarity index 100%
rename from example/session_hooks/session_hooks.c
rename to example/plugins/c-api/session_hooks/session_hooks.c
diff --git a/example/ssl_preaccept/ssl_preaccept.cc b/example/plugins/c-api/ssl_preaccept/ssl_preaccept.cc
similarity index 100%
rename from example/ssl_preaccept/ssl_preaccept.cc
rename to example/plugins/c-api/ssl_preaccept/ssl_preaccept.cc
diff --git a/example/ssl_sni/ssl_sni.cc b/example/plugins/c-api/ssl_sni/ssl_sni.cc
similarity index 100%
rename from example/ssl_sni/ssl_sni.cc
rename to example/plugins/c-api/ssl_sni/ssl_sni.cc
diff --git a/example/ssl_sni_whitelist/ssl_sni_whitelist.cc b/example/plugins/c-api/ssl_sni_whitelist/ssl_sni_whitelist.cc
similarity index 100%
rename from example/ssl_sni_whitelist/ssl_sni_whitelist.cc
rename to example/plugins/c-api/ssl_sni_whitelist/ssl_sni_whitelist.cc
diff --git a/example/statistic/statistic.cc b/example/plugins/c-api/statistic/statistic.cc
similarity index 100%
rename from example/statistic/statistic.cc
rename to example/plugins/c-api/statistic/statistic.cc
diff --git a/example/thread_1/readme.txt b/example/plugins/c-api/thread_1/readme.txt
similarity index 100%
rename from example/thread_1/readme.txt
rename to example/plugins/c-api/thread_1/readme.txt
diff --git a/example/thread_1/thread_1.c b/example/plugins/c-api/thread_1/thread_1.c
similarity index 100%
rename from example/thread_1/thread_1.c
rename to example/plugins/c-api/thread_1/thread_1.c
diff --git a/example/thread_pool/README.txt b/example/plugins/c-api/thread_pool/README.txt
similarity index 100%
rename from example/thread_pool/README.txt
rename to example/plugins/c-api/thread_pool/README.txt
diff --git a/example/thread_pool/TESTPLAN.txt b/example/plugins/c-api/thread_pool/TESTPLAN.txt
similarity index 100%
rename from example/thread_pool/TESTPLAN.txt
rename to example/plugins/c-api/thread_pool/TESTPLAN.txt
diff --git a/example/thread_pool/include/Makefile.am b/example/plugins/c-api/thread_pool/include/Makefile.am
similarity index 100%
rename from example/thread_pool/include/Makefile.am
rename to example/plugins/c-api/thread_pool/include/Makefile.am
diff --git a/example/thread_pool/include/gen.c b/example/plugins/c-api/thread_pool/include/gen.c
similarity index 100%
rename from example/thread_pool/include/gen.c
rename to example/plugins/c-api/thread_pool/include/gen.c
diff --git a/example/thread_pool/include/gen_inc.sh b/example/plugins/c-api/thread_pool/include/gen_inc.sh
similarity index 100%
rename from example/thread_pool/include/gen_inc.sh
rename to example/plugins/c-api/thread_pool/include/gen_inc.sh
diff --git a/example/thread_pool/psi.c b/example/plugins/c-api/thread_pool/psi.c
similarity index 100%
rename from example/thread_pool/psi.c
rename to example/plugins/c-api/thread_pool/psi.c
diff --git a/example/thread_pool/test/SDKTest/SDKtest_server.config b/example/plugins/c-api/thread_pool/test/SDKTest/SDKtest_server.config
similarity index 100%
rename from example/thread_pool/test/SDKTest/SDKtest_server.config
rename to example/plugins/c-api/thread_pool/test/SDKTest/SDKtest_server.config
diff --git a/example/thread_pool/test/SDKTest/psi_server.c b/example/plugins/c-api/thread_pool/test/SDKTest/psi_server.c
similarity index 100%
rename from example/thread_pool/test/SDKTest/psi_server.c
rename to example/plugins/c-api/thread_pool/test/SDKTest/psi_server.c
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/1.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/1.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/1.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/1.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/10.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/10.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/10.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/10.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/11.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/11.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/11.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/11.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/12.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/12.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/12.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/12.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/13.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/13.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/13.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/13.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/2.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/2.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/2.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/2.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/3.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/3.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/3.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/3.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/4.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/4.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/4.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/4.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/5.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/5.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/5.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/5.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/6.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/6.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/6.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/6.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/7.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/7.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/7.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/7.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/8.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/8.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/8.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/8.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/9.cfg b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/9.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/9.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/9.cfg
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc10_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc10_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc10_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc10_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc11_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc11_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc11_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc11_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc12_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc12_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc12_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc12_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc13_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc13_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc13_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc13_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc1_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc1_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc1_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc1_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc2_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc2_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc2_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc2_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc3_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc3_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc3_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc3_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc4_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc4_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc4_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc4_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc5_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc5_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc5_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc5_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc6_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc6_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc6_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc6_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc7_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc7_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc7_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc7_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc8_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc8_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc8_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc8_file.txt
diff --git a/example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc9_file.txt b/example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc9_file.txt
similarity index 100%
rename from example/thread_pool/test/SynTest/Tests/Psi/psi_files/tc9_file.txt
rename to example/plugins/c-api/thread_pool/test/SynTest/Tests/Psi/psi_files/tc9_file.txt
diff --git a/example/thread_pool/test/SynTest/system.cfg b/example/plugins/c-api/thread_pool/test/SynTest/system.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/system.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/system.cfg
diff --git a/example/thread_pool/test/SynTest/tests_psi.cfg b/example/plugins/c-api/thread_pool/test/SynTest/tests_psi.cfg
similarity index 100%
rename from example/thread_pool/test/SynTest/tests_psi.cfg
rename to example/plugins/c-api/thread_pool/test/SynTest/tests_psi.cfg
diff --git a/example/thread_pool/thread.c b/example/plugins/c-api/thread_pool/thread.c
similarity index 100%
rename from example/thread_pool/thread.c
rename to example/plugins/c-api/thread_pool/thread.c
diff --git a/example/thread_pool/thread.h b/example/plugins/c-api/thread_pool/thread.h
similarity index 100%
rename from example/thread_pool/thread.h
rename to example/plugins/c-api/thread_pool/thread.h
diff --git a/example/txn_data_sink/txn_data_sink.c b/example/plugins/c-api/txn_data_sink/txn_data_sink.c
similarity index 100%
rename from example/txn_data_sink/txn_data_sink.c
rename to example/plugins/c-api/txn_data_sink/txn_data_sink.c
diff --git a/example/vconn_args/vconn_args.cc b/example/plugins/c-api/vconn_args/vconn_args.cc
similarity index 100%
rename from example/vconn_args/vconn_args.cc
rename to example/plugins/c-api/vconn_args/vconn_args.cc
diff --git a/example/verify_cert/verify_cert.cc b/example/plugins/c-api/verify_cert/verify_cert.cc
similarity index 100%
rename from example/verify_cert/verify_cert.cc
rename to example/plugins/c-api/verify_cert/verify_cert.cc
diff --git a/example/version/version.c b/example/plugins/c-api/version/version.c
similarity index 100%
rename from example/version/version.c
rename to example/plugins/c-api/version/version.c
diff --git a/example/plugins/cpp-api/Makefile.am b/example/plugins/cpp-api/Makefile.am
new file mode 100644
index 0000000..7d94479
--- /dev/null
+++ b/example/plugins/cpp-api/Makefile.am
@@ -0,0 +1,109 @@
+#  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 $(top_srcdir)/build/plugins.mk
+include $(top_srcdir)/build/tidy.mk
+
+AM_CXXFLAGS += -Wno-unused-variable
+AM_LDFLAGS = $(TS_PLUGIN_LD_FLAGS)
+
+libtscppapi = $(top_builddir)/src/tscpp/api/libtscppapi.la
+
+if BUILD_EXAMPLE_PLUGINS
+
+example_Plugins = \
+	AsyncHttpFetch.la \
+	AsyncHttpFetchStreaming.la \
+	AsyncTimer.la \
+	ClientRedirect.la \
+	ClientRequest.la \
+	CustomErrorRemapPlugin.la \
+	CustomResponse.la \
+	DelayTransformationPlugin.la \
+	GlobalHookPlugin.la \
+	GzipTransformationPlugin.la \
+	HelloWorldPlugin.la \
+	InternalTransactionHandling.la \
+	LoggerExample.la \
+	MultipleTransactionHookPlugins.la \
+	NullTransformationPlugin.la \
+	PostBuffer.la \
+	RemapPlugin.la \
+	ServerResponse.la \
+	StatExample.la \
+	TimeoutExamplePlugin.la \
+	TransactionHookPlugin.la \
+	WebSocket.la \
+	boom.la \
+	intercept.la
+
+pkglib_LTLIBRARIES = $(example_Plugins)
+
+endif
+
+AsyncHttpFetchStreaming_la_SOURCES = async_http_fetch_streaming/AsyncHttpFetchStreaming.cc
+AsyncHttpFetch_la_SOURCES = async_http_fetch/AsyncHttpFetch.cc
+AsyncTimer_la_SOURCES = async_timer/AsyncTimer.cc
+ClientRedirect_la_SOURCES = clientredirect/ClientRedirect.cc
+ClientRequest_la_SOURCES = clientrequest/ClientRequest.cc
+CustomErrorRemapPlugin_la_SOURCES = custom_error_remap_plugin/CustomErrorRemapPlugin.cc
+CustomResponse_la_SOURCES = customresponse/CustomResponse.cc
+DelayTransformationPlugin_la_SOURCES = delay_transformation_plugin/DelayTransformationPlugin.cc
+GlobalHookPlugin_la_SOURCES = globalhook/GlobalHookPlugin.cc
+GzipTransformationPlugin_la_SOURCES = gzip_transformation/GzipTransformationPlugin.cc
+HelloWorldPlugin_la_SOURCES = helloworld/HelloWorldPlugin.cc
+InternalTransactionHandling_la_SOURCES = internal_transaction_handling/InternalTransactionHandling.cc
+LoggerExample_la_SOURCES = logger_example/LoggerExample.cc
+MultipleTransactionHookPlugins_la_SOURCES = multiple_transaction_hooks/MultipleTransactionHookPlugins.cc
+NullTransformationPlugin_la_SOURCES = null_transformation_plugin/NullTransformationPlugin.cc
+PostBuffer_la_SOURCES = post_buffer/PostBuffer.cc
+RemapPlugin_la_SOURCES = remap_plugin/RemapPlugin.cc
+ServerResponse_la_SOURCES = serverresponse/ServerResponse.cc
+StatExample_la_SOURCES = stat_example/StatExample.cc
+TimeoutExamplePlugin_la_SOURCES = timeout_example/TimeoutExamplePlugin.cc
+TransactionHookPlugin_la_SOURCES = transactionhook/TransactionHookPlugin.cc
+WebSocket_la_SOURCES = websocket/WebSocket.cc websocket/WSBuffer.cc
+boom_la_SOURCES = boom/boom.cc
+intercept_la_SOURCES = intercept/intercept.cc
+
+AsyncHttpFetchStreaming_la_LIBADD = $(libtscppapi)
+AsyncHttpFetch_la_LIBADD = $(libtscppapi)
+AsyncTimer_la_LIBADD = $(libtscppapi)
+ClientRedirect_la_LIBADD = $(libtscppapi)
+ClientRequest_la_LIBADD = $(libtscppapi)
+CustomErrorRemapPlugin_la_LIBADD = $(libtscppapi)
+CustomResponse_la_LIBADD = $(libtscppapi)
+DelayTransformationPlugin_la_LIBADD = $(libtscppapi)
+GlobalHookPlugin_la_LIBADD = $(libtscppapi)
+GzipTransformationPlugin_la_LIBADD = $(libtscppapi)
+HelloWorldPlugin_la_LIBADD = $(libtscppapi)
+InternalTransactionHandling_la_LIBADD = $(libtscppapi)
+LoggerExample_la_LIBADD = $(libtscppapi)
+MultipleTransactionHookPlugins_la_LIBADD = $(libtscppapi)
+NullTransformationPlugin_la_LIBADD = $(libtscppapi)
+PostBuffer_la_LIBADD = $(libtscppapi)
+RemapPlugin_la_LIBADD = $(libtscppapi)
+ServerResponse_la_LIBADD = $(libtscppapi)
+StatExample_la_LIBADD = $(libtscppapi)
+TimeoutExamplePlugin_la_LIBADD = $(libtscppapi)
+TransactionHookPlugin_la_LIBADD = $(libtscppapi)
+WebSocket_la_LIBADD = $(libtscppapi)
+boom_la_LIBADD = $(libtscppapi)
+intercept_la_LIBADD = $(libtscppapi)
+
+clang-tidy-local: $(DIST_SOURCES)
+	$(CXX_Clang_Tidy)
+	$(CC_Clang_Tidy)
diff --git a/example/cppapi/async_http_fetch/AsyncHttpFetch.cc b/example/plugins/cpp-api/async_http_fetch/AsyncHttpFetch.cc
similarity index 100%
rename from example/cppapi/async_http_fetch/AsyncHttpFetch.cc
rename to example/plugins/cpp-api/async_http_fetch/AsyncHttpFetch.cc
diff --git a/example/cppapi/async_http_fetch_streaming/AsyncHttpFetchStreaming.cc b/example/plugins/cpp-api/async_http_fetch_streaming/AsyncHttpFetchStreaming.cc
similarity index 100%
rename from example/cppapi/async_http_fetch_streaming/AsyncHttpFetchStreaming.cc
rename to example/plugins/cpp-api/async_http_fetch_streaming/AsyncHttpFetchStreaming.cc
diff --git a/example/cppapi/async_timer/AsyncTimer.cc b/example/plugins/cpp-api/async_timer/AsyncTimer.cc
similarity index 100%
rename from example/cppapi/async_timer/AsyncTimer.cc
rename to example/plugins/cpp-api/async_timer/AsyncTimer.cc
diff --git a/example/cppapi/boom/README.txt b/example/plugins/cpp-api/boom/README.txt
similarity index 100%
rename from example/cppapi/boom/README.txt
rename to example/plugins/cpp-api/boom/README.txt
diff --git a/example/cppapi/boom/boom.cc b/example/plugins/cpp-api/boom/boom.cc
similarity index 100%
rename from example/cppapi/boom/boom.cc
rename to example/plugins/cpp-api/boom/boom.cc
diff --git a/example/cppapi/clientredirect/ClientRedirect.cc b/example/plugins/cpp-api/clientredirect/ClientRedirect.cc
similarity index 100%
rename from example/cppapi/clientredirect/ClientRedirect.cc
rename to example/plugins/cpp-api/clientredirect/ClientRedirect.cc
diff --git a/example/cppapi/clientrequest/ClientRequest.cc b/example/plugins/cpp-api/clientrequest/ClientRequest.cc
similarity index 100%
rename from example/cppapi/clientrequest/ClientRequest.cc
rename to example/plugins/cpp-api/clientrequest/ClientRequest.cc
diff --git a/example/cppapi/custom_error_remap_plugin/CustomErrorRemapPlugin.cc b/example/plugins/cpp-api/custom_error_remap_plugin/CustomErrorRemapPlugin.cc
similarity index 100%
rename from example/cppapi/custom_error_remap_plugin/CustomErrorRemapPlugin.cc
rename to example/plugins/cpp-api/custom_error_remap_plugin/CustomErrorRemapPlugin.cc
diff --git a/example/cppapi/customresponse/CustomResponse.cc b/example/plugins/cpp-api/customresponse/CustomResponse.cc
similarity index 100%
rename from example/cppapi/customresponse/CustomResponse.cc
rename to example/plugins/cpp-api/customresponse/CustomResponse.cc
diff --git a/example/cppapi/delay_transformation_plugin/DelayTransformationPlugin.cc b/example/plugins/cpp-api/delay_transformation_plugin/DelayTransformationPlugin.cc
similarity index 100%
rename from example/cppapi/delay_transformation_plugin/DelayTransformationPlugin.cc
rename to example/plugins/cpp-api/delay_transformation_plugin/DelayTransformationPlugin.cc
diff --git a/example/cppapi/globalhook/GlobalHookPlugin.cc b/example/plugins/cpp-api/globalhook/GlobalHookPlugin.cc
similarity index 100%
rename from example/cppapi/globalhook/GlobalHookPlugin.cc
rename to example/plugins/cpp-api/globalhook/GlobalHookPlugin.cc
diff --git a/example/cppapi/gzip_transformation/GzipTransformationPlugin.cc b/example/plugins/cpp-api/gzip_transformation/GzipTransformationPlugin.cc
similarity index 100%
rename from example/cppapi/gzip_transformation/GzipTransformationPlugin.cc
rename to example/plugins/cpp-api/gzip_transformation/GzipTransformationPlugin.cc
diff --git a/example/cppapi/helloworld/HelloWorldPlugin.cc b/example/plugins/cpp-api/helloworld/HelloWorldPlugin.cc
similarity index 100%
rename from example/cppapi/helloworld/HelloWorldPlugin.cc
rename to example/plugins/cpp-api/helloworld/HelloWorldPlugin.cc
diff --git a/example/cppapi/intercept/intercept.cc b/example/plugins/cpp-api/intercept/intercept.cc
similarity index 100%
rename from example/cppapi/intercept/intercept.cc
rename to example/plugins/cpp-api/intercept/intercept.cc
diff --git a/example/cppapi/internal_transaction_handling/InternalTransactionHandling.cc b/example/plugins/cpp-api/internal_transaction_handling/InternalTransactionHandling.cc
similarity index 100%
rename from example/cppapi/internal_transaction_handling/InternalTransactionHandling.cc
rename to example/plugins/cpp-api/internal_transaction_handling/InternalTransactionHandling.cc
diff --git a/example/cppapi/logger_example/LoggerExample.cc b/example/plugins/cpp-api/logger_example/LoggerExample.cc
similarity index 100%
rename from example/cppapi/logger_example/LoggerExample.cc
rename to example/plugins/cpp-api/logger_example/LoggerExample.cc
diff --git a/example/cppapi/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc b/example/plugins/cpp-api/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc
similarity index 100%
rename from example/cppapi/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc
rename to example/plugins/cpp-api/multiple_transaction_hooks/MultipleTransactionHookPlugins.cc
diff --git a/example/cppapi/null_transformation_plugin/NullTransformationPlugin.cc b/example/plugins/cpp-api/null_transformation_plugin/NullTransformationPlugin.cc
similarity index 100%
rename from example/cppapi/null_transformation_plugin/NullTransformationPlugin.cc
rename to example/plugins/cpp-api/null_transformation_plugin/NullTransformationPlugin.cc
diff --git a/example/cppapi/post_buffer/PostBuffer.cc b/example/plugins/cpp-api/post_buffer/PostBuffer.cc
similarity index 100%
rename from example/cppapi/post_buffer/PostBuffer.cc
rename to example/plugins/cpp-api/post_buffer/PostBuffer.cc
diff --git a/example/cppapi/remap_plugin/RemapPlugin.cc b/example/plugins/cpp-api/remap_plugin/RemapPlugin.cc
similarity index 100%
rename from example/cppapi/remap_plugin/RemapPlugin.cc
rename to example/plugins/cpp-api/remap_plugin/RemapPlugin.cc
diff --git a/example/cppapi/serverresponse/ServerResponse.cc b/example/plugins/cpp-api/serverresponse/ServerResponse.cc
similarity index 100%
rename from example/cppapi/serverresponse/ServerResponse.cc
rename to example/plugins/cpp-api/serverresponse/ServerResponse.cc
diff --git a/example/cppapi/stat_example/StatExample.cc b/example/plugins/cpp-api/stat_example/StatExample.cc
similarity index 100%
rename from example/cppapi/stat_example/StatExample.cc
rename to example/plugins/cpp-api/stat_example/StatExample.cc
diff --git a/example/cppapi/timeout_example/TimeoutExamplePlugin.cc b/example/plugins/cpp-api/timeout_example/TimeoutExamplePlugin.cc
similarity index 100%
rename from example/cppapi/timeout_example/TimeoutExamplePlugin.cc
rename to example/plugins/cpp-api/timeout_example/TimeoutExamplePlugin.cc
diff --git a/example/cppapi/transactionhook/TransactionHookPlugin.cc b/example/plugins/cpp-api/transactionhook/TransactionHookPlugin.cc
similarity index 100%
rename from example/cppapi/transactionhook/TransactionHookPlugin.cc
rename to example/plugins/cpp-api/transactionhook/TransactionHookPlugin.cc
diff --git a/example/cppapi/websocket/README.txt b/example/plugins/cpp-api/websocket/README.txt
similarity index 100%
rename from example/cppapi/websocket/README.txt
rename to example/plugins/cpp-api/websocket/README.txt
diff --git a/example/cppapi/websocket/WSBuffer.cc b/example/plugins/cpp-api/websocket/WSBuffer.cc
similarity index 100%
rename from example/cppapi/websocket/WSBuffer.cc
rename to example/plugins/cpp-api/websocket/WSBuffer.cc
diff --git a/example/cppapi/websocket/WSBuffer.h b/example/plugins/cpp-api/websocket/WSBuffer.h
similarity index 100%
rename from example/cppapi/websocket/WSBuffer.h
rename to example/plugins/cpp-api/websocket/WSBuffer.h
diff --git a/example/cppapi/websocket/WebSocket.cc b/example/plugins/cpp-api/websocket/WebSocket.cc
similarity index 100%
rename from example/cppapi/websocket/WebSocket.cc
rename to example/plugins/cpp-api/websocket/WebSocket.cc
diff --git a/example/cppapi/websocket/WebSocket.h b/example/plugins/cpp-api/websocket/WebSocket.h
similarity index 100%
rename from example/cppapi/websocket/WebSocket.h
rename to example/plugins/cpp-api/websocket/WebSocket.h
diff --git a/example/plugins/lua-api/connect_geoip.lua b/example/plugins/lua-api/connect_geoip.lua
new file mode 100644
index 0000000..a1af55b
--- /dev/null
+++ b/example/plugins/lua-api/connect_geoip.lua
@@ -0,0 +1,36 @@
+--  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.
+
+
+-- This example depends on "luajit-geoip".
+-- It illustrates how to connect to GeoIP and use it to look up country of an IP address.
+-- It can be used in plugin.config with the lua plugin.
+
+-- Setup Instructions
+-- 1) install GeoIP - 1.6.12
+-- 2) install GeoIP legacy country database - https://dev.maxmind.com/geoip/legacy/install/country/
+-- 3) install luajit-geoip (https://github.com/leafo/luajit-geoip) 
+--    or just copy geoip/init.lua from the repo to /usr/local/share/lua/5.1/geoip/init.lua  
+-- 4) You may need to make change so luajit-geoip does ffi.load() on /usr/local/lib/libGeoIP.so 
+
+ts.add_package_path('/usr/local/share/lua/5.1/?.lua')
+
+local geoip = require 'geoip'
+
+function do_global_send_response()
+  local res = geoip.lookup_addr("8.8.8.8")
+  ts.client_response.header['X-Country'] = res.country_code
+end
diff --git a/example/plugins/lua-api/connect_redis.lua b/example/plugins/lua-api/connect_redis.lua
new file mode 100644
index 0000000..8d34f15
--- /dev/null
+++ b/example/plugins/lua-api/connect_redis.lua
@@ -0,0 +1,49 @@
+--  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.
+
+
+-- This example depends on "redis-lua" 2.0.4 - https://github.com/nrk/redis-lua
+-- And redis-lua depends on LuaSocket v3.0-rc1 - https://github.com/diegonehab/luasocket
+-- It illustrates how to connect to redis and retrieve a key value. 
+-- It can be used in plugin.config with the lua plugin.
+
+-- unix domain socket has better performance and so we should set up local redis to use that
+-- Note the sock must be readable/writable by nobody since ATS runs as that user
+-- Sample instructions for setting up redis 2.8.4 and putting a key in
+-- 1. edit /etc/redis/redis.conf to set "port 0", "unixsocket /var/run/redis/redis.sock" and "unixsocketperm 755"
+-- 2. sudo chown nobody /var/run/redis
+-- 3. sudo chgrp nogroup /var/run/redis
+-- 4. sudo chown nobody /var/log/redis
+-- 5. sudo chgrp nogroup /var/log/redis
+-- 6. sudo -u nobody redis-server /etc/redis/redis.conf
+-- 7. sudo -u nobody redis-cli -s /var/run/redis/redis.sock set mykey helloworld
+
+ts.add_package_cpath('/usr/local/lib/lua/5.1/socket/?.so;/usr/local/lib/lua/5.1/mime/?.so')
+ts.add_package_path('/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/socket/?.lua')
+
+local redis = require 'redis'
+-- not connecting to redis default port
+-- local client = redis.connect('127.0.0.1', 6379)
+
+-- connecting to unix domain socket
+local client = redis.connect('unix:///var/run/redis/redis.sock')
+
+function do_global_send_response()
+  local response = client:ping()
+  local value = client:get('mykey')
+  ts.client_response.header['X-Redis-Ping'] = tostring(response)
+  ts.client_response.header['X-Redis-MyKey'] = value
+end
diff --git a/example/plugins/lua-api/sorted_query_params.lua b/example/plugins/lua-api/sorted_query_params.lua
new file mode 100644
index 0000000..e4a45e9
--- /dev/null
+++ b/example/plugins/lua-api/sorted_query_params.lua
@@ -0,0 +1,53 @@
+--  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.
+
+
+-- This script is for sorting query parameters on incoming requests before doing cache lookup
+-- so we can get better cache hit ratio
+-- It can be used in remap.config for a remap rule with the lua plugin.
+
+function pairsByKeys (t, f)
+  local a = {}
+  for n in pairs(t) do table.insert(a, n) end
+  table.sort(a, f)
+  local i = 0      -- iterator variable
+  local iter = function ()   -- iterator function
+    i = i + 1
+    if a[i] == nil then return nil
+    else return a[i], t[a[i]]
+    end
+  end
+  return iter
+end
+
+function do_remap()
+  t = {} 
+  s = ts.client_request.get_uri_args() or ''
+  -- Original String
+  i = 1
+  for k, v in string.gmatch(s, "([0-9a-zA-Z-_]+)=([0-9a-zA-Z-_]+)") do
+    t[k] = v
+  end
+
+  output = ''
+  for name, line in pairsByKeys(t) do
+    output = output .. '&' .. name .. '=' .. line
+  end
+  output = string.sub(output, 2)
+  -- Modified String 
+  ts.client_request.set_uri_args(output)
+  return 0
+end 
diff --git a/example/plugins/lua-api/uncompress.lua b/example/plugins/lua-api/uncompress.lua
new file mode 100644
index 0000000..c80ff22
--- /dev/null
+++ b/example/plugins/lua-api/uncompress.lua
@@ -0,0 +1,52 @@
+--  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.
+
+
+-- This example depends on "lua-zlib". 
+-- It uncompresses a gzipped content body and prints it out in debug log.
+-- It can be added in remap.config for a remap rule with the lua plugin.
+
+-- Setup Instructions
+-- 1) install lua-zlib - v1.2
+
+ts.add_package_cpath('/usr/lib/lua/5.1/?.so')
+
+local zlib = require "zlib"
+
+function upper_transform(data, eos)
+    ts.ctx['text'] = ts.ctx['text'] .. data
+
+    if eos ==1 then
+      local stream = zlib.inflate()
+      local inflated, eof, bytes_in, bytes_out = stream(ts.ctx['text'])
+      if (eof == true) then
+         ts.debug("==== eof ====")
+      end
+      ts.debug("==== bytes_in: "..(bytes_in or ''))
+      ts.debug("==== bytes_out:"..(bytes_out or ''))
+      ts.debug("==== uncompressed data begin ===")
+      ts.debug(inflated or 'no data')
+      ts.debug("==== uncompressed data end ===")
+    end
+
+    return string.upper(data), eos
+end
+
+function do_remap()
+    ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)
+    ts.ctx['text'] = ''
+    return 0
+end