You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2019/09/03 18:13:21 UTC

[trafficserver] branch master updated: Doc: Guide to remap plugin API.

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

amc 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 5cb4b31  Doc: Guide to remap plugin API.
5cb4b31 is described below

commit 5cb4b316ad93fd4c78f44effc4c1dfbe4949543c
Author: Alan M. Carroll <am...@apache.org>
AuthorDate: Fri Aug 16 18:55:48 2019 -0500

    Doc: Guide to remap plugin API.
---
 doc/developer-guide/api/functions/TSRemap.en.rst |  16 +--
 doc/developer-guide/api/functions/TSTypes.en.rst |  40 ++++++
 doc/developer-guide/plugins/index.en.rst         |   1 +
 doc/developer-guide/plugins/remap-plugins.en.rst | 148 +++++++++++++++++++++++
 4 files changed, 198 insertions(+), 7 deletions(-)

diff --git a/doc/developer-guide/api/functions/TSRemap.en.rst b/doc/developer-guide/api/functions/TSRemap.en.rst
index 38d06d8..ddd9917 100644
--- a/doc/developer-guide/api/functions/TSRemap.en.rst
+++ b/doc/developer-guide/api/functions/TSRemap.en.rst
@@ -29,11 +29,11 @@ Synopsis
 `#include <ts/ts.h>`
 `#include <ts/remap.h>`
 
-.. function:: TSReturnCode TSRemapInit(TSRemapInterface * api_info, char * errbuf, int errbuf_size)
+.. function:: TSReturnCode TSRemapInit(TSRemapInterface * api_info, char * errbuff, int errbuff_size)
 .. function:: void TSRemapConfigReload(void)
 .. function:: void TSRemapDone(void)
 .. function:: TSRemapStatus TSRemapDoRemap(void * ih, TSHttpTxn rh, TSRemapRequestInfo * rri)
-.. function:: TSReturnCode TSRemapNewInstance(int argc, char * argv[], void ** ih, char * errbuf, int errbuf_size)
+.. function:: TSReturnCode TSRemapNewInstance(int argc, char * argv[], void ** ih, char * errbuff, int errbuff_size)
 .. function:: void TSRemapDeleteInstance(void * )
 .. function:: void TSRemapOSResponse(void * ih, TSHttpTxn rh, int os_response_type)
 
@@ -50,8 +50,8 @@ route the transaction through your plugin. Multiple remap plugins can be
 specified for a single remap rule, resulting in a remap plugin chain
 where each plugin is given an opportunity to examine the HTTP transaction.
 
-:func:`TSRemapInit` is a required entry point. This function will be called
-once when Traffic Server loads the plugin. If the optional :func:`TSRemapDone`
+:func:`TSRemapInit` is a required entry point. This function will be called once when Traffic Server
+loads the plugin. If the optional :func:`TSRemapDone`
 entry point is available, Traffic Server will call then when unloading
 the remap plugin.
 
@@ -65,15 +65,17 @@ any data or continuations associated with that instance.
 entry point. In this function, the remap plugin may examine and modify
 the HTTP transaction.
 
-:func:`TSRemapConfigReload` is called once for every remap plugin just before the
-remap configuration file (:file:`remap.config`) is reloaded. This is an optional
-entry point, which takes no arguments and has no return value.
+:func:`TSRemapConfigReload` is called once for every remap plugin immediately after a new
+configuration is successfully loaded and immediately before the new remap configuration becomes
+active. This is an optional entry point, which takes no arguments and has no return value.
 
 Generally speaking, calls to these functions are mutually exclusive. The exception
 is for functions which take an HTTP transaction as a parameter. Calls to these
 transaction-specific functions for different transactions are not necessarily mutually exclusive
 of each other.
 
+For further information, see :ref:`developer-plugins-remap`.
+
 Types
 =====
 
diff --git a/doc/developer-guide/api/functions/TSTypes.en.rst b/doc/developer-guide/api/functions/TSTypes.en.rst
index 9ffc318..20bed44 100644
--- a/doc/developer-guide/api/functions/TSTypes.en.rst
+++ b/doc/developer-guide/api/functions/TSTypes.en.rst
@@ -143,8 +143,48 @@ more widely. Those are described on this page.
 
 .. type:: TSRemapInterface
 
+   Data passed to a remap plugin via :func:`TSRemapInit`.
+
+   .. member:: unsigned long size
+
+      The size of the structure in bytes, including this member.
+
+   .. member:: unsigned long tsremap_version
+
+      The API version of the C API. The lower 16 bits are the minor version, and the upper bits
+      the major version.
+
 .. type:: TSRemapRequestInfo
 
+   Data passed to a remap plugin during the invocation of a remap rule.
+
+   .. member:: TSMBuffer requestBufp
+
+      The client request. All of the other :type:`TSMLoc` values use this as the base buffer.
+
+   .. member:: TSMLoc requestHdrp
+
+      The client request.
+
+   .. member:: TSMLoc mapFromUrl
+
+      The match URL in the remap rule.
+
+   .. member:: TSMLoc mapToUrl
+
+      The target URL in the remap rule.
+
+   .. member:: TSMLoc requestUrl
+
+      The current request URL. The remap rule and plugins listed earlier in the remap rule can modify this
+      from the client request URL. Remap plugins are expected to modify this value to perform the
+      remapping of the request. Note this is the same :code:`TSMLoc` as would be obtained by
+      calling :func:`TSHttpTxnClientReqGet`.
+
+   .. member:: int redirect
+
+      Flag for using the remapped URL as an explicit redirection. This can be set by the remap plugin.
+
 .. type:: TSSslX509
 
     This type represents the :code:`X509` object created from an SSL certificate.
diff --git a/doc/developer-guide/plugins/index.en.rst b/doc/developer-guide/plugins/index.en.rst
index 35ba0ff..4f52843 100644
--- a/doc/developer-guide/plugins/index.en.rst
+++ b/doc/developer-guide/plugins/index.en.rst
@@ -37,6 +37,7 @@ Plugin Development
    io/index.en
    http-headers/index.en
    http-transformations/index.en
+   remap-plugins.en
    new-protocol-plugins.en
    plugin-interfaces.en
    adding-statistics.en
diff --git a/doc/developer-guide/plugins/remap-plugins.en.rst b/doc/developer-guide/plugins/remap-plugins.en.rst
new file mode 100644
index 0000000..7b691c6
--- /dev/null
+++ b/doc/developer-guide/plugins/remap-plugins.en.rst
@@ -0,0 +1,148 @@
+.. 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:: ../../common.defs
+.. default-domain:: c
+.. _developer-plugins-remap:
+
+Remap Plugins
+*************
+
+Remap plugins are called during remap (URL rewriting). The particular plugins and the order is
+determined by the remap rule. The :file:`remap.config` file can contain explicit references to
+remap plugins in a rule and the presence of such a reference in a rule causes the plugin to be
+invoked when the rule is matched. For example, a rule such as
+
+.. code-block:: text
+
+   map http://example.one/ http://example.two/ @plugin=example.so @pparam=first_arg @pparm=second_arg
+
+will, if matched, cause the plugin "example.so" to be called with parameters "first_arg" and "second_arg".
+
+A key difference between global and remap plugins is reconfiguration and reloading. If
+:file:`remap.config` is reloaded, then all remap plugins are reconfigured based on the new version
+of the file. Global plugins need to handle their own configuration reloading, if any.
+
+In addition, as of |TS| 9.0, remap plugins can be reloaded during runtime. During a
+:file:`remap.config` reload, if the plugin image file has changed, a new one is loaded and used.
+
+All of the externally invoked functions must be declared as :code:`extern "C"` in order to be
+correctly located by the Traffic Server core. This is already done if :ts:git:`include/ts/remap.h`
+is included, otherwise it must be done explicitly.
+
+Initialization
+==============
+
+If any rule uses a plugin, the remap configuration loading will load the dynamic library and then
+call :func:`TSRemapInit`. The plugin must return :macro:`TS_SUCCESS` or the configuration loading
+will fail. If there is an error during the invocation of this function a C string style message
+should be placed in :arg:`errbuff`, taking note of the maximum size of the buffer passed in
+:arg:`errbuff_size`. The message is checked if the function returns a value other than
+:macro:`TS_SUCCESS`.
+
+This function should perform any plugin global initialization, such as setting up static data
+tables. It only be called immediately after the dynamic library is loaded from disk.
+
+Configuration
+=============
+
+For each plugin invocation in a remap rule, :func:`TSRemapNewInstance` is called.
+
+The parameters :arg:`argc`, :arg:`argv` specify an array of arguments to the invocation instance in
+the standard way. :arg:`argc` is the number of arguments present and :arg:`argv` is an array of
+pointers, each of which points to a plugin parameter. The number of valid elements is :arg:`argc`.
+Note these pointers are valid only for the duration of the function call. If any part of them need
+persistent storage, that must be provided by the plugin.
+
+:arg:`ih` is for invocation instance storage data. This initially points at a :code:`nullptr`. If
+that pointer is updated the new value will be preserved and passed back to the plugin in later
+callbacks. This enables it to serve to identify which particular rule was matched and provide
+context data. The standard use is to allocate a class instance, store rule relevant context data in
+that instance, and update :arg:`ih` to point at the instance. The most common data is that derived
+from the invocation arguments passed in :arg:`argc`, :arg:`argv`.
+
+:arg:`errbuff` and :arg:`errbuff_size` specify a writeable buffer used to report errors. Error
+messages must be C strings and must fit in the buffer, including the terminating null.
+
+In essence, :func:`TSRemapNewInstance` is called to create an invocation instance for the plugin to
+store rule local data. If the plugin is invoked multiples time on a rule, this will be called
+multiple times for the rule, once for each invocation. Only the value store in :arg:`ih` will be
+available when the rule is actually matched. In particular the plugin arguments will not be
+available.
+
+Calls to :func:`TSRemapNewInstance` are serialized.
+
+If there is an error then the callback should return :macro:`TS_ERROR` and fill in the
+:arg:`errbuff` with a C-string describing the error. Otherwise the function must return
+:macro:`TS_SUCCESS`.
+
+Runtime
+=======
+
+At runtime, if a remap rule is matched, the plugin is invoked by calling :func:`TSRemapDoRemap`.
+This function is responsible for performing the plugin operation for the transaction.
+
+:arg:`ih` is the same value set in :func:`TSRemapNewInstance` for the invocation instance. This is
+not examined or checked by the core. :arg:`rh` is the transaction for which the rule matched.
+:arg:`rri` is information about the rule and the transaction.
+
+The callback is required to return a :type:`TSRemapStatus` indicating whether it performed a remap.
+This is used for verifying a request was remapped if remapping is required. This can also be used
+to prevent further remapping, although this should be used with caution.
+
+Calls to :func:`TSRemapDoRemap` are not serialized, they can be concurrent, even for the same
+invocation instance. However, the callbacks for a single rule for a single transaction are
+serialized in the order the plugins are invoked in the rule.
+
+All calls to :func:`TSRemapNewInstance` for a given configuration will be called and completed
+before any calls to :func:`TSRemapDoRemap`.
+
+Cleanup
+=======
+
+When a new :file:`remap.config` is loaded successfully, the prior configuration is cleaned up. For
+each call to :func:`TSRemapNewInstance` a corresponding call to :func:`TSRemapDeleteInstance` is
+called. The only argument is the invocation instance handle, originally provided by the plugin to
+:func:`TSRemapNewInstance`. This is expected to suffice for the plugin to clean up any rule specific
+data.
+
+As part of the old configuration cleanup :func:`TSRemapConfigReload` is called on the plugins in the
+old configuration before any calls to :func:`TSRemapDeleteInstance`. This is an optional entry
+point.
+
+.. note::
+
+   This is called per *plugin*, not per invocation of the plugin in :file:`remap.config`, and only
+   called if the plugin was called at least once with :func:`TSRemapNewInstance` for that
+   configuration.
+
+.. note::
+
+   There is no explicit indication or connection between the call to :func:`TSRemapConfigReload` and
+   the "old" (existing) configuration. It is guaranteeed that :func:`TSRemapConfigReload` will be
+   called on all the plugins before any :func:`TSRemapDeleteInstance` and these calls will be
+   serial. Similarly, :func:`TSRemapConfigReload` will be called serially after all calls to
+   :func:`TSRemapNewInstance` for a given configuration.
+
+.. note::
+
+   The old configuration, if any, is still active during the call to :func:`TSRemapConfigReload` and
+   therefore calls to :func:`TSRemapDoRemap` may occur concurrently with that function.
+
+The intention of :func:`TSRemapConfigReload` is to provide for temporary data structures used only
+during configuration loading. These can be created as needed when an invocation instance is loaded
+and used in subsequent invocation instance loading, then cleaned up in :func:`TSRemapConfigReload`.
+
+If no rule uses a plugin, it may be unloaded. In that case :func:`TSRemapDone` is called. This is
+an optional entry point, a plugin is not required to provide it. It is called once per plugin, not
+per plugin invocation.