You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2015/11/03 07:09:55 UTC
[19/51] trafficserver git commit: Documentation reorganization
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/host-resolution-proposal.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/host-resolution-proposal.en.rst b/doc/developer-guide/host-resolution-proposal.en.rst
new file mode 100644
index 0000000..af34e6f
--- /dev/null
+++ b/doc/developer-guide/host-resolution-proposal.en.rst
@@ -0,0 +1,170 @@
+.. 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
+
+Host Resolution Proposal
+************************
+
+Introduction
+------------
+
+The current mechanism for resolving host names to IP addresses for Traffic Server is contained the HostDB and DNS
+libraries. These take hostnames and provide IP addresses for them.
+
+The current implementation is generally considered inadequate, both from a functionality point of view and difficulty in
+working with it in other parts of Traffic Server. As Traffic Server is used in more complex situtations this inadequacy
+presents increasing problems.
+
+Goals
+-----
+
+Updating the host name resolution (currently referred to as "HostDB") has several functions goals
+
+* Enable additional processing layers to be easily added.
+* Enable plugins to directly access the name resolution logic
+* Enable plugins to provide name resolution
+* Asynchronous (immediate resolve or callback on block)
+* Minimize allocations -- in particular no allocations for cached resolutions
+* Simplify interactions with the resolution, particularly with regard to nameservers, origin server failover, and
+ address family handling.
+
+It is also necessary to support a number of specific features that are either currently available or strongly desired.
+
+* SplitDNS or its equivalent
+* Use of a hosts file (e.g. ``/etc/hosts``)
+* Simultaneous IPv4 and IPv6 queries
+* IP family control
+* Negative caching
+ * Server connection failures
+ * Query failures
+ * Nameserver failures.
+* Address validity time out control
+* Address round robin support
+* SRV record support (weighted records)
+* Nameserver round robin
+* Plugin access to nameserver data (add, remove, enumerate)
+* Plugin provision of resolvers.
+* Hooks for plugin detection / recovery from resolution events.
+
+One issue is persistence of the cached resolutions. This creates problems for the current implementation (because of
+size limits it imposes on the cached data) but also allows for quicker restarts in a busy environment.
+
+Basics
+------
+
+The basic design is to separate the functionality into chainable layers so that a resolver with the desired attributes
+can be assembled from those layers. The core interface is that of a lazy iterator. This object returns one of four
+results when asked for an address
+
+* An IP address
+* Done(no more addresses are available)
+* Wait(an address may be available in the future)
+* Fail (no address is available and none will be so in the future)
+
+Each layer (except the bottom) uses this API and also provides it. This enables higher level logic such as the state
+machine to simply use the resolver as a list without having to backtrack states in the case of failures, or have special
+cases for different resolution sources.
+
+To perform a resolution, a client creates a query object (potentially on the stack), initializes it with the required
+data (at least the hostname) and then starts the resolution. Methods on the query object allow its state and IP address
+data to be accessed.
+
+Required Resolvers
+------------------
+
+Nameserver
+ A bottom level resolver that directly queries a nameserver for DNS data. This contains much of the functionality
+ currently in the ``iocore/dns`` directory.
+
+SplitDNS
+ A resolver that directs requests to one of several resolvers. To emulate current behavior these would be Nameserver
+ instances.
+
+NameserverGroup
+ A grouping mechanism for Nameserver instances that provides failover, round robin, and ordering capabilities. It may be
+ reasonable to merge this with the SplitDNS resolver.
+
+HostFile
+ A resolver that uses a local file to resolve names.
+
+AddressCache
+ A resolver that also has a cache for resolution results. It requires another resolver instance to perform the actual
+ resolution.
+
+Preloaded
+ A resolver that can contain one or more explicitly set IP addresses which are returned. When those are exhausted it
+ falls back to another resolver.
+
+Configuration
+-------------
+
+To configuration the resolution, each resolver would be assigned a tag. It is not, however, sufficient to simply provide
+the list of resolver tags because some resolvers require additional configuration. Unfortunately this will likely
+require a separate configuration file outside of :file:`records.config`, although we would be able to remove
+:file:`splitdns.config`. In this case we would need chain start / end markers around a list of resolver tags. Each tag
+would the be able to take additional resolver configuration data. For instance, for a SplitDNS resolver the nameservers.
+
+Examples
+--------
+
+Transparent operations would benefit from the *Preloaded* resolver. This would be loaded with the origin host address
+provided by the client connection. This could be done early in processing and then no more logic would be required to
+skip DNS processing as it would happen without additional action by the state machine. It would handle the problem of de
+facto denial of service if an origin server becomes unavailable in that configuration, as *Preloaded* would switch to
+alternate addresses automatically.
+
+Adding host file access would be easier as well, as it could be done in a much more modular fashion and then added to
+the stack at configuration time. Whether such addresses were cached would be controlled by chain arrangement rather yet
+more configuration knobs.
+
+The default configuration would be *Preloaded* : *AddressCache* : *Nameserver*.
+
+In all cases the state machine makes requests against the request object to get IP addresses as needed.
+
+Issues
+------
+
+Request object allocation
+=========================
+
+The biggest hurdle is being able to unwind a resolver chain when a block is encountered. There are some ways to deal with this.
+
+1) Set a maximum resolver chain length and declare the request instance so that there is storage for state for that many
+resolvers. If needed and additional value of maximum storage per chain could be set as well. The expected number of
+elements in a chain is expected to be limited, 10 would likely be a reaosnable limit. If settable at source
+configuration time this should be sufficient.
+
+2) Embed class allocators in resolver chains and mark the top / outermost / first resolver. The maximum state size for a
+resolution can be calculated when the chain is created and then the top level resolver can use an allocation pool to
+efficiently allocate request objects. This has an advantage that with a wrapper class the request object can be passed
+along cheaply. Whether that's an advantage in practice is unclear.
+
+Plugin resolvers
+================
+
+If plugins can provide resolvers, how can these can integrated in to existing resolver chains for use by the HTTP SM for
+instance?
+
+Feedback
+========
+
+It should be possible for a client to provide feedback about addresses (e.g., the origin server at this address is not
+available). Not all resolvers will handle feedback but some will and that must be possible.
+
+Related to this is that caching resolvers (such as *AddressCache*) must be able to iterator over all resolved addresses
+even if their client does not ask for them. In effect they must background fill the address data.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/index.en.rst b/doc/developer-guide/index.en.rst
new file mode 100644
index 0000000..5abe670
--- /dev/null
+++ b/doc/developer-guide/index.en.rst
@@ -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.
+
+.. include:: ../common.defs
+
+.. _developer-guide:
+
+Developer's Guide
+*****************
+
+This documentation is a work in progress. It was originally written for
+a previous, commercially-available version of Traffic Server that
+supported different operating systems and more functions than the
+current version. As a result, some of the sections may refer to
+functionality that no longer exists.
+
+If you find any such issues, you may want to submit a `bug or a
+patch <https://issues.apache.org/jira/secure/CreateIssue!default.jspa?pid=12310963>`__.
+We also have a Wiki page explaining how to `create useful bug reports
+<https://cwiki.apache.org/confluence/display/TS/Filing+useful+bug+reports>`__.
+We encourage everyone to file tickets, early and often. Looking for existing,
+duplicate bugs is encouraged, but not required.
+
+.. toctree::
+ :maxdepth: 2
+
+ introduction/index.en
+ release-process/index.en
+ contributing/index.en
+ testing-with-vagrant/index.en
+ debugging/index.en
+ architecture/index.en
+ plugins/index.en
+ config-vars.en
+ api/index.en
+ continuous-integration/index.en
+ documentation/index.en
+ host-resolution-proposal.en
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/introduction/audience.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/introduction/audience.en.rst b/doc/developer-guide/introduction/audience.en.rst
new file mode 100644
index 0000000..540d08e
--- /dev/null
+++ b/doc/developer-guide/introduction/audience.en.rst
@@ -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.
+
+.. include:: ../../common.defs
+
+.. _developer-preface:
+
+Preface
+********
+
+.. toctree::
+ :maxdepth: 2
+
+ preface/how-to-use-this-book.en
+ preface/typographical-conventions.en
+
+The |TS| Software Developer's Kit is a reference for creating plugins.
+*Plugins* are programs that add services (such as filtering or content
+transformation) or entire features (such as new protocol support) to |TS|. If
+you are new to writing |TS| plugins, then read the first two chapters,
+:ref:`developer-plugins-getting-started` and
+:ref:`developer-plugins-introduction`, and use the remaining chapters as
+needed. :ref:`developer-plugins-header-based-examples` provides details about
+plugins that work on HTTP headers, while
+:ref:`developer-plugins-http-transformations` explains how to write a plugin
+that transforms or scans the body of an HTTP response. If you want to support
+your own protocol on Traffic Server, then reference
+:ref:`developer-plugins-new-protocol-plugins`.
+
+.. _developer-audience:
+
+Audience
+--------
+
+This manual is intended for programmers who want to write plugin
+programs that add services or features to Traffic Server. It assumes a
+cursory knowledge of the C programming language, Hyper-Text Transfer
+Protocol (HTTP), and Multipurpose Internet Mail Extensions (MIME).
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/introduction/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/introduction/index.en.rst b/doc/developer-guide/introduction/index.en.rst
new file mode 100644
index 0000000..d5f2415
--- /dev/null
+++ b/doc/developer-guide/introduction/index.en.rst
@@ -0,0 +1,117 @@
+.. 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
+
+.. _developer-introduction:
+
+Introduction
+************
+
+This book has the following basic components:
+
+- Introduction and overview
+
+- Tutorials about writing specific kinds of plugins: HTTP header-based
+ plugins, content transformation plugins, and protocol plugins
+
+- Guides about specific interfaces
+
+- Reference material
+
+If you're new to writing |TS| plugins, :ref:`developer-plugins-getting-started`
+should be your starting point. :ref:`developer-plugins-header-based-examples`
+provides details about plugins that work on HTTP headers, while
+:ref:`developer-plugins-http-transformations` explains how to write a plugin
+that transforms or scans the body of an HTTP response.
+:ref:`developer-plugins-new-protocol-plugins` provides essential information if
+you want to support your own protocol on |TS|.
+
+For a reference to the C API functions and types that your plugin will use,
+refer to the :ref:`developer-api-reference`.
+
+Below is a section-by-section breakdown of this guide:
+
+:ref:`developer-plugins-getting-started`
+ How to compile and load plugins. Walks through a simple "hello world"
+ example; explains how to initialize and register plugins. Basic structures
+ that all plugins use: events, continuations, and how to hook on to |TS|
+ processes. Detailed explication of a sample blacklisting plugin.
+
+:ref:`developer-plugins-examples-query-remap`
+ This chapter demonstrates on a practical example how you can
+ exploit the Traffic Server remap API for your plugins.
+
+:ref:`developer-plugins-header-based-examples`
+ Detailed explanation about writing plugins that work on HTTP
+ headers; discusses sample blacklisting and basic authorization
+ plugins.
+
+:ref:`developer-plugins-http-transformations`
+ Detailed explanation of the null-transform example; also discusses
+ ``VConnections``, ``VIOs``, and IO buffers.
+
+:ref:`developer-plugins-new-protocol-plugins`
+ Detailed explanation of a sample protocol plugin that supports a
+ synthetic protocol. Discusses ``VConnections`` and mutexes, as well
+ as the new ``NetConnection``, DNS lookup, logging, and cache APIs.
+
+The remaining sections comprise the API function reference and are organized by
+function type:
+
+:ref:`developer-plugins-interfaces`
+ Details error-writing and tracing functions, thread functions, and |TS| API
+ versions of the ``malloc`` and ``fopen`` families. The |TS| API versions
+ overcome various C library limitations.
+
+:ref:`developer-plugins-hooks-and-transactions`
+ Functions in this chapter hook your plugin to Traffic Server HTTP processes.
+
+:ref:`developer-plugins-http-headers`
+ Contains instructions for implementing performance enhancements for
+ all plugins that manipulate HTTP headers. These functions examine and
+ modify HTTP headers, MIME headers, URLs, and the marshal buffers that
+ contain header information. If you are working with headers, then be
+ sure to read this chapter.
+
+:ref:`developer-plugins-mutexes`
+
+:ref:`developer-plugins-continuations`
+ Continuations provide the basic callback mechanism and data
+ abstractions used in Traffic Server.
+
+:ref:`developer-plugins-configuration`
+
+:ref:`developer-plugins-actions`
+ Describes how to use ``TSActions`` and the ``TSDNSLookup`` API.
+
+:ref:`developer-plugins-io`
+ Describes how to use the Traffic Server IO interfaces:
+ ``TSVConnection``, ``TSVIO``, ``TSIOBuffer``, ``TSNetVConnection``,
+ the Cache API.
+
+:ref:`developer-plugins-management`
+ These functions enable you to set up a configuration interface for
+ plugins, access installed plugin files, and set up plugin licensing.
+
+:ref:`developer-plugins-add-statistics`
+ These functions add statistics to your plugin.
+
+:ref:`developer-api-ref-functions`
+ Traffic Server API Function Documentation.
+
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/actions/hosts-lookup-api.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/actions/hosts-lookup-api.en.rst b/doc/developer-guide/plugins/actions/hosts-lookup-api.en.rst
new file mode 100644
index 0000000..5b2fe4e
--- /dev/null
+++ b/doc/developer-guide/plugins/actions/hosts-lookup-api.en.rst
@@ -0,0 +1,32 @@
+.. 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
+
+.. _developer-plugins-actions-hosts-lookup:
+
+Hosts Lookup API
+****************
+
+The hosts lookup enables plugins to ask Traffic Server to do a host
+lookup of a host name, much like a DNS lookup.
+
+The hosts lookup functions are as follows:
+
+- :c:func:`TSHostLookup`
+- :c:func:`TSHostLookupResultAddrGet`
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/actions/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/actions/index.en.rst b/doc/developer-guide/plugins/actions/index.en.rst
new file mode 100644
index 0000000..12eeb24
--- /dev/null
+++ b/doc/developer-guide/plugins/actions/index.en.rst
@@ -0,0 +1,178 @@
+.. 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
+
+.. _developer-plugins-actions:
+
+Actions
+*******
+
+.. toctree::
+ :maxdepth: 2
+
+ hosts-lookup-api.en
+
+An **action** is a handle to an operation initiated by a plugin that has
+not yet completed. For example: when a plugin connects to a remote
+server, it uses the call ``TSNetConnect`` - which takes ``TSCont`` as an
+argument to call back when the connection is established.
+``TSNetConnect`` might not call the continuation back immediately and
+will return an ``TSAction`` structure that the caller can use to cancel
+the operation. Cancelling the operation does not necessarily mean that
+the operation will not occur; it simply means that the continuation
+passed into the operation will not be called back. In such an example,
+the connection might still occur if the action is cancelled; however,
+the continuation that initiated the connection would not be called back.
+
+In the preceding example, it is also possible that the connection will
+complete and call back the continuation before ``TSNetConnect`` returns.
+If that occurs, then ``TSNetConnect`` returns a special action that
+causes ``TSActionDone`` to return ``1``. This specifies that the
+operation has already completed, so it's pointless to try to cancel the
+operation. Also note that an action will never change from non-completed
+to completed. When the operation actually succeeds and the continuation
+is called back, the continuation must zero out its action pointer to
+indicate to itself that the operation succeeded.
+
+The asynchronous nature of all operations in Traffic Server necessitates
+actions. You should notice from the above discussion that once a call to
+a function like ``TSNetConnect`` is made by a continuation and that
+function returns a valid action (``TSActionDone`` returns ``0``), it is
+not safe for the continuation to do anything else except return from its
+handler function. It is not safe to modify or examine the continuation's
+data because the continuation may have already been destroyed.
+
+Below is an example of typical usage for an action:
+
+.. code-block:: c
+
+ #include <ts/ts.h>
+ static int
+ handler (TSCont contp, TSEvent event, void *edata)
+ {
+ if (event == TS_EVENT_IMMEDIATE) {
+ TSAction actionp = TSNetConnect (contp, 127.0.0.1, 9999);
+ if (!TSActionDone (actionp)) {
+ TSContDataSet (contp, actionp);
+ } else {
+ /* We've already been called back... */
+ return 0;
+ }
+ } else if (event == TS_EVENT_NET_CONNECT) {
+ /* Net connection succeeded */
+ TSContDataSet (contp, NULL);
+ return 0;
+ } else if (event == TS_EVENT_NET_CONNECT_FAILED) {
+ /* Net connection failed */
+ TSContDataSet (contp, NULL);
+ return 0;
+ }
+ return 0;
+ }
+
+ void
+ TSPluginInit (int argc, const char *argv[])
+ {
+ TSCont contp;
+
+ contp = TSContCreate (handler, TSMutexCreate ());
+
+ /* We don't want to call things out of TSPluginInit
+ directly since it's called before the rest of the
+ system is initialized. We'll simply schedule an event
+ on the continuation to occur as soon as the rest of
+ the system is started up. */
+ TSContSchedule (contp, 0);
+ }
+
+The example above shows a simple plugin that creates a continuation and
+then schedules it to be called immediately. When the plugin's handler
+function is called the first time, the event is ``TS_EVENT_IMMEDIATE``.
+The plugin then tries to open a net connection to port 9999 on
+``localhost`` (127.0.0.1). The IP description was left in cider notation
+to further clarify what is going on; also note that the above won't
+actually compile until the IP address is modified. The action returned
+from ``TSNetConnect`` is examined by the plugin. If the operation has
+not completed, then the plugin stores the action in its continuation.
+Otherwise, the plugin knows it has already been called back and there is
+no reason to store the action pointer.
+
+A final question might be, "why would a plugin want to cancel an
+action?" In the above example, a valid reason could be to place a limit
+on the length of time it takes to open a connection. The plugin could
+schedule itself to get called back in 30 seconds and then initiate the
+net connection. If the timeout expires first, then the plugin would
+cancel the action. The following sample code implements this:
+
+.. code-block:: c
+
+ #include <ts/ts.h>
+ static int
+ handler (TSCont contp, TSEvent event, void *edata)
+ {
+ switch (event) {
+ case (TS_EVENT_IMMEDIATE):
+ TSContSchedule (contp, 30000);
+ TSAction actionp = TSNetConnect(contp, 127.0.0.1, 9999);
+ if (!TSActionDone (actionp)) {
+ TSContDataSet (contp, actionp);
+ } else {
+ /* We've already been called back ... */
+ }
+ break;
+
+ case (TS_EVENT_TIMEOUT):
+ TSAction actionp = TSContDataGet (contp);
+ if (!TSActionDone(actionp)) {
+ TSActionCancel (actionp);
+ }
+ break;
+
+ case (TS_EVENT_NET_CONNECT):
+ /* Net connection succeeded */
+ TSContDataSet (contp, NULL);
+ break;
+
+ case (TS_EVENT_NET_CONNECT_FAILED):
+ /* Net connection failed */
+ TSContDataSet (contp, NULL);
+ break;
+
+ }
+ return 0;
+ }
+
+ void
+ TSPluginInit (int argc, const char *argv[])
+ {
+ TSCont contp;
+
+ contp = TSContCreate (handler, TSMutexCreate ());
+ /* We don't want to call things out of TSPluginInit
+ directly since it's called before the rest of the
+ system is initialized. We'll simply schedule an event
+ on the continuation to occur as soon as the rest of
+ the system is started up. */
+ TSContSchedule (contp, 0);
+ }
+
+The action functions are:
+
+- :c:func:`TSActionCancel`
+- :c:func:`TSActionDone`
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/adding-statistics.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/adding-statistics.en.rst b/doc/developer-guide/plugins/adding-statistics.en.rst
new file mode 100644
index 0000000..b0c5480
--- /dev/null
+++ b/doc/developer-guide/plugins/adding-statistics.en.rst
@@ -0,0 +1,190 @@
+.. 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
+
+.. _developer-plugins-add-statistics:
+
+Adding Statistics
+*****************
+
+This chapter describes how to add statistics to your plugins. Statistics
+can be coupled or uncoupled. *Coupled* statistics are quantities that
+are related and must therefore be updated together. The Traffic Server
+API statistics functions add your plugin's statistics to the Traffic
+Server statistics system. You can view your plugin statistics as you
+would any other Traffic Server statistic, using Traffic Line (Traffic
+Server's command line interface). This chapter contains the following
+topics:
+
+.. toctree::
+ :maxdepth: 2
+
+ adding-statistics/coupled-statistics.en
+ adding-statistics/viewing-statistics-using-traffic-line.en
+
+
+Uncoupled Statistics
+====================
+
+A statistic is an object of type ``TSStat``. The value of the statistic
+is of type ``TSStatType``. The possible ``TSStatTypes`` are:
+
+- ``TSSTAT_TYPE_INT64``
+
+- ``TSSTAT_TYPE_FLOAT``
+
+There is *no* ``TSSTAT_TYPE_INT32``.
+
+To add uncoupled statistics, follow the steps below:
+
+1. Declare your statistic as a global variable in your plugin. For
+ example:
+
+ .. code-block:: c
+
+ static TSStat my_statistic;
+
+2. In ``TSPluginInit``, create new statistics using ``TSStatCreate``.
+ When you create a new statistic, you need to give it an "external"
+ name that the Traffic Server command line interface (Traffic Line)
+ uses to access the statistic. For example:
+
+ .. code-block:: c
+
+ my_statistic = TSStatCreate ("my.statistic", TSSTAT_TYPE_INT64);
+
+3. Modify (increment, decrement, or other modification) your statistic
+ in plugin functions.
+
+Coupled Statistics
+==================
+
+Use coupled statistics for quantities that are related and therefore
+must be updated jointly.
+
+As a very simple example, suppose you have three statistics: ``sum``,
+``part_1``, and ``part_2``. They must always preserve the relationship
+that ``sum = part_1 + part_2``. If you update ``part_1`` without
+updating ``sum`` at the same time, then the equation becomes untrue.
+Therefore, the statistics are said to be *coupled*.
+
+The mechanism for updating coupled statistics jointly is to create local
+copies of global coupled statistics in the routines that modifiy them.
+When each local copy is updated appropriately, do a global update using
+``TSStatsCoupledUpdate``. To specify which statistics are related to one
+another, establish a coupled statistic category and make sure that each
+coupled statistic belongs to the appropriate category. When it is time
+to do the global update, specify the category to be updated.
+
+.. note::
+
+ The local statistic copy must have a duplicate set of statistics as that
+ of the master copy. Local statistics must also be added to the local
+ statistic category in the same order as their master copy counterparts
+ were originally added.
+
+Below are the steps you need to follow, along with a code example taken
+from the ``redirect-1.c`` sample plugin.
+
+To add coupled statistics
+-------------------------
+
+1. Declare the global category for your coupled statistics as a global
+ ``TSCoupledStat`` variable in your plugin.
+
+2. Declare your coupled statistics as global ``TSStat`` variables in
+ your plugin.
+
+3. In ``TSPluginInit``, create a new global coupled category using
+ ``TSStatCoupledGlobalCategoryCreate``.
+
+4. In ``TSPluginInit``, create new global coupled statistics using
+ ``TSStatCoupledGlobalAdd``. When you create a new statistic, you need
+ to give it an "external" name that the Traffic Server command line
+ interface (Traffic Line) uses to access the statistic.
+
+5. In any routine wherein you want to modify (increment, decrement, or
+ other modification) your coupled statistics, declare local copies of
+ the coupled category and coupled statistics.
+
+6. Create local copies using ``TSStatCoupledLocalCopyCreate`` and
+ ``TSStatCoupledLocalAdd``.
+
+7. Modify the local copies of your statistics. Then call
+ ``TSStatsCoupledUpdate`` to update the global copies jointly.
+
+8. When you are finished, you must destroy all of the local copies in
+ the category via ``TSStatCoupledLocalCopyDestroy``.
+
+Example Using the redirect-1.c Sample Plugin
+--------------------------------------------
+
+.. code-block:: c
+
+ static TSCoupledStat request_outcomes;
+
+ static TSStat requests_all;
+ static TSStat requests_redirects;
+ static TSStat requests_unchanged;
+
+ request_outcomes = TSStatCoupledGlobalCategoryCreate ("request_outcomes");
+
+ requests_all = TSStatCoupledGlobalAdd (request_outcomes, "requests.all", TSSTAT_TYPE_FLOAT);
+ requests_redirects = TSStatCoupledGlobalAdd (request_outcomes, "requests.redirects",
+ TSSTAT_TYPE_INT64);
+ requests_unchanged = TSStatCoupledGlobalAdd (request_outcomes, "requests.unchanged",
+ TSSTAT_TYPE_INT64);
+
+ TSCoupledStat local_request_outcomes;
+ TSStat local_requests_all;
+ TSStat local_requests_redirects;
+ TSStat local_requests_unchanged;
+
+ local_request_outcomes = TSStatCoupledLocalCopyCreate("local_request_outcomes",
+ request_outcomes);
+ local_requests_all = TSStatCoupledLocalAdd(local_request_outcomes, "requests.all.local",
+ TSSTAT_TYPE_FLOAT);
+ local_requests_redirects = TSStatCoupledLocalAdd(local_request_outcomes,
+ "requests.redirects.local", TSSTAT_TYPE_INT64);
+ local_requests_unchanged = TSStatCoupledLocalAdd(local_request_outcomes,
+ "requests.unchanged.local", TSSTAT_TYPE_INT64);
+
+ TSStatFloatAddTo( local_requests_all, 1.0 ) ;
+ ...
+ TSStatIncrement (local_requests_unchanged);
+ TSStatsCoupledUpdate(local_request_outcomes);
+
+ TSStatCoupledLocalCopyDestroy(local_request_outcomes);
+
+Viewing Statistics Using Traffic Line
+=====================================
+
+.. XXX: This documentation seems to be duplicated from the admin docs.
+
+To view statistics for your plugin, follow the steps below:
+
+1. Make sure you know the name of your statistic (i.e., the name used in
+ the ``TSStatCoupledGlobalAdd``, ``TSStatCreate``, or
+ ``TSStatCoupledGlobalCategoryCreate`` call).
+
+2. In your ``<Traffic Server>/bin`` directory, enter the following:
+
+ ::
+
+ ./traffic\_line -r the\_name
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/building-plugins.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/building-plugins.en.rst b/doc/developer-guide/plugins/building-plugins.en.rst
new file mode 100644
index 0000000..5494e40
--- /dev/null
+++ b/doc/developer-guide/plugins/building-plugins.en.rst
@@ -0,0 +1,24 @@
+.. 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
+
+.. _developer-plugins-building:
+
+Building Plugins
+****************
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/configuration.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/configuration.en.rst b/doc/developer-guide/plugins/configuration.en.rst
new file mode 100644
index 0000000..409df3e
--- /dev/null
+++ b/doc/developer-guide/plugins/configuration.en.rst
@@ -0,0 +1,105 @@
+.. 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
+
+.. _developer-plugins-configuration:
+
+Plugin Configuration
+********************
+
+The functions discussed in this section do not examine or modify |TS|
+configuration variables. To examine |TS| configuration and statistics
+variables, see :ref:`developer-plugins-management-settings-and-statistics`.
+
+The collection of ``TSConfig*`` functions are designed to provide a fast and
+efficient mechanism for accessing and changing global configuration information
+within a plugin. Such a mechanism is simple enough to provide in a
+single-threaded program, but the translation to a multi-threaded program such
+as |TS| is difficult. A common technique is to have a single mutex protect the
+global configuration information; however, the problem with this solution is
+that a single mutex becomes a performance bottleneck very quickly.
+
+These functions define an interface to storing and retrieving an opaque data
+pointer. Internally, |TS| maintains reference count information about the data
+pointer so that a call to :c:func:`TSConfigSet` will not disturb another thread
+using the current data pointer. The philosophy is that once a user has a hold
+of the configuration pointer, it is okay for it to be used even if the
+configuration changes. All that a user typically wants is a non-changing
+snapshot of the configuration. You should use :c:func:`TSConfigSet` for all
+global data updates.
+
+Here's how the interface works:
+
+.. code-block:: c
+
+ /* Assume that you have previously defined a plugin configuration
+ * data structure named ConfigData, along with its constructor
+ * plugin_config_allocator () and its destructor
+ * plugin_config_destructor (ConfigData *data)
+ */
+ ConfigData *plugin_config;
+
+ /* You will need to assign plugin_config a unique identifier of type
+ * unsigned int. It is important to initialize this identifier to zero
+ * (see the documentation of the function).
+ */
+ static unsigned int my_id = 0;
+
+ /* You will need an TSConfig pointer to access a snapshot of the
+ * current plugin_config.
+ */
+ TSConfig config_ptr;
+
+ /* Initialize plugin_config. */
+ plugin_config = plugin_config_allocator();
+
+ /* Assign plugin_config an identifier using TSConfigSet. */
+ my_id = TSConfigSet (my_id, plugin_config, plugin_config_destructor);
+
+ /* Get a snapshot of the current configuration using TSConfigGet. */
+ config_ptr = TSConfigGet (my_id);
+
+ /* With an TSConfig pointer to the current configuration, you can
+ * retrieve the configuration's current data using TSConfigDataGet.
+ */
+ plugin_config = (ConfigData*) TSConfigDataGet (config_ptr);
+
+ /* Do something with plugin_config here. */
+
+ /* When you are done with retrieving or modifying the plugin data, you
+ * release the pointers to the data with a call to TSConfigRelease.
+ */
+ TSConfigRelease (my_id, config_ptr);
+
+ /* Any time you want to modify plugin_config, you must repeat these
+ * steps, starting with
+ * my_id = TSConfigSet (my_id,plugin_config, plugin_config_destructor);
+ * and continuing up to TSConfigRelease.
+ */
+
+The configuration functions are:
+
+- :c:func:`TSConfigDataGet`
+
+- :c:func:`TSConfigGet`
+
+- :c:func:`TSConfigRelease`
+
+- :c:func:`TSConfigSet`
+
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/continuations/activating-continuations.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/continuations/activating-continuations.en.rst b/doc/developer-guide/plugins/continuations/activating-continuations.en.rst
new file mode 100644
index 0000000..6b4135f
--- /dev/null
+++ b/doc/developer-guide/plugins/continuations/activating-continuations.en.rst
@@ -0,0 +1,40 @@
+.. 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
+
+.. _developer-plugins-continuations-activate:
+
+Activating Continuations
+************************
+
+Continuations are activated when they receive an event or by
+``TSContSchedule`` (which schedules a continuation to receive an event).
+Continuations might receive an event because:
+
+- Your plugin calls ``TSContCall``
+
+- The Traffic Server HTTP state machine sends an event corresponding to
+ a particular HTTP hook
+
+- A Traffic Server IO processor (such as a cache processor or net
+ processor) is letting a continuation know there is data (cache or
+ network) available to read or write. These callbacks are a result of
+ using functions such ``TSVConnRead``/``Write`` or
+ ``TSCacheRead``/``Write``
+
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/continuations/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/continuations/index.en.rst b/doc/developer-guide/plugins/continuations/index.en.rst
new file mode 100644
index 0000000..94bd132
--- /dev/null
+++ b/doc/developer-guide/plugins/continuations/index.en.rst
@@ -0,0 +1,135 @@
+.. 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
+
+.. _developer-plugins-continuations:
+
+Continuations
+*************
+
+.. toctree::
+ :maxdepth: 2
+
+ activating-continuations.en
+ writing-handler-functions.en
+
+The continuation interface is Traffic Server's basic callback mechanism.
+**Continuations** are instances of the opaque data type ``TSCont``. In
+its basic form, a continuation represents a handler function and a
+mutex.
+
+This chapter covers the following topics:
+
+- `Mutexes and Data`_
+
+- :ref:`developer-plugins-continuations-activate`
+
+- :ref:`developer-plugins-continuations-handler-functions`
+
+Mutexes and Data
+================
+
+A continuation must be created with a mutex if your continuation does
+one of the following:
+
+- is registered globally (``TSHttpHookAdd`` or ``TSHttpSsnHookAdd``) to
+ an HTTP hook and uses ``TSContDataSet/Get``
+
+- is registered locally (``TSHttpTxnHookAdd``), but for multiple
+ transactions uses ``TSContDataSet/Get``
+
+- uses ``TSCacheXXX``, ``TSNetXXX``, ``TSHostLookup``, or
+ ``TSContSchedule`` APIs
+
+Before being activated, a caller must grab the continuation's mutex.
+This requirement makes it possible for a continuation's handler function
+to safely access its data and to prevent multiple callers from running
+it at the same time (see the :ref:`about-the-sample-protocol` for usage). The
+data protected by the mutex is any global or continuation data
+associated to the continuation by ``TSContDataSet``. This does not
+include the local data created by the continuation handler function. A
+typical example of continuations created with associated data structures
+and mutexes is the transaction state machine created in the sample
+Protocol plugin (see :ref:`one-way-to-implement-a-transaction-state-machine`).
+
+A reentrant call occurs when the continuation passed as an argument to
+the API can be called in the same stack trace as the function calling
+the API. For example, if you call ``TSCacheRead`` (``contp, mykey``), it
+is possible that ``contp``'s handler will be called directly and then
+``TSCacheRead`` returns.
+
+Caveats that could cause issues include the following:
+
+- a continuation has data associated with it (``TSContDataGet``).
+
+- the reentrant call passes itself as a continuation to the reentrant
+ API. In this case, the continuation should not try to access its data
+ after calling the reentrant API. The reason for this is that data may be
+ modified by the section of code in the continuation's handler that
+ handles the event sent by the API. It is recommended that you always
+ return after a reentrant call to avoid accessing something that has been
+ deallocated.
+
+Below is an example, followed by an explanation.
+
+.. code-block:: c
+
+ continuation_handler (TSCont contp, TSEvent event, void *edata) {
+ switch (event) {
+ case event1:
+ TSReentrantCall (contp);
+ /* Return right away after this call */
+ break;
+ case event2:
+ TSContDestroy (contp);
+ break;
+ }
+ }
+
+The above example first assumes that the continuation is called back
+with ``event1``; it then does the first reentrant call that schedules
+the continuation to receive ``event2``. Because the call is reentrant,
+the processor calls back the continuation right away with ``event2`` and
+the continuation is destroyed. If you try to access the continuation or
+one of its members after the reentrant call, then you might access
+something that has been deallocated. To avoid accessing something that
+has been deallocated, never access the continuation or any of its
+members after a reentrant call - just exit the handler.
+
+**Note:** Most HTTP transaction plugin continuations do not need
+non-null mutexes because they're called within the processing of an HTTP
+transaction, and therefore have the transaction's mutex.
+
+It is also possible to specify a continuation's mutex as ``NULL``. This
+should be done only when registering a continuation to a global hook, by
+a call to ``TSHttpHookAdd``. In this case, the continuation can be
+called simultaneously by different instances of HTTP SM running on
+different threads. Having a mutex here would slow and/or hinder Traffic
+Server performance, since all the threads will try to lock the same
+mutex. The drawback of not having a mutex is that such a continuation
+cannot have data associated with it (i.e., ``TSContDataGet/Set`` cannot
+be used).
+
+When using a ``NULL`` mutex it is dangerous to access the continuation's
+data, but usually continuations with ``NULL`` mutexes have no data
+associated with them anyway. An example of such a continuation is one
+that gets called back every time an HTTP request is read, and then
+determines from the request alone if the request should go through or be
+rejected. An HTTP transaction gives its continuation data to the
+``contp``.
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/continuations/writing-handler-functions.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/continuations/writing-handler-functions.en.rst b/doc/developer-guide/plugins/continuations/writing-handler-functions.en.rst
new file mode 100644
index 0000000..c8cf516
--- /dev/null
+++ b/doc/developer-guide/plugins/continuations/writing-handler-functions.en.rst
@@ -0,0 +1,129 @@
+.. 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
+
+.. _developer-plugins-continuations-handler-functions:
+
+Writing Handler Functions
+*************************
+
+.. default-domain:: c
+
+The handler function is the key component of a continuation. It is
+supposed to examine the event and event data, and then do something
+appropriate. The probable action might be to schedule another event for
+the continuation to received, to open up a connection to a server, or
+simply to destroy itself.
+
+The continuation's handler function is a function of type
+:type:`TSEventFunc`. Its arguments are a continuation, an event, and a
+pointer to some data (this data is passed to the continuation by the
+caller - do not confuse this data with the continuation's own data,
+associated by :func:`TSContDataSet`). When the continuation is called back,
+the continuation and an event are passed to the handler function. The
+continuation is a handle to the same continuation that is invoked. The
+handler function typically has a switch statement to handle the events
+it receives:
+
+.. code-block:: c
+
+ static int some_handler (TScont contp, TSEvent event, void *edata)
+ {
+ // .....
+ switch(event) {
+ case TS_EVENT_SOME_EVENT_1:
+ do_some_thing_1;
+ return;
+ case TS_EVENT_SOME_EVENT_2:
+ do_some_thing_2;
+ return;
+ case TS_EVENT_SOME_EVENT_3:
+ do_some_thing_3;
+ return;
+ default: break;
+ }
+ return 0;
+ }
+
+.. caution::
+
+ You might notice that a continuation cannot determine if more events are
+ "in flight" toward it. Do not use :func:`TSContDestroy` to delete a
+ continuation before you make sure that all incoming events, such as
+ those sent because of :func:`TSHttpTxnHookAdd`, have been handled.
+
+The following table lists events and the corresponding type of
+`void* data` passed to handler functions:
+
+============================================ =========================================== ==========================
+Event Event Sender Data Type
+============================================ =========================================== ==========================
+:data:`TS_EVENT_HTTP_READ_REQUEST_HDR` :data:`TS_HTTP_READ_REQUEST_HDR_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_OS_DNS` :data:`TS_HTTP_OS_DNS_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_SEND_REQUEST_HDR` :data:`TS_HTTP_SEND_REQUEST_HDR_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_READ_CACHE_HDR` :data:`TS_HTTP_READ_CACHE_HDR_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_READ_RESPONSE_HDR` :data:`TS_HTTP_READ_RESPONSE_HDR_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_SEND_RESPONSE_HDR` :data:`TS_HTTP_SEND_RESPONSE_HDR_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_SELECT_ALT` :data:`TS_HTTP_SELECT_ALT_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_TXN_START` :data:`TS_HTTP_TXN_START_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_TXN_CLOSE` :data:`TS_HTTP_TXN_CLOSE_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_HTTP_SSN_START` :data:`TS_HTTP_SSN_START_HOOK` :type:`TSHttpSsn`
+:data:`TS_EVENT_HTTP_SSN_CLOSE` :data:`TS_HTTP_SSN_CLOSE_HOOK` :type:`TSHttpSsn`
+:data:`TS_EVENT_NONE`
+:data:`TS_EVENT_CACHE_LOOKUP_COMPLETE` :data:`TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK` :type:`TSHttpTxn`
+:data:`TS_EVENT_IMMEDIATE` :func:`TSVConnClose`
+ :func:`TSVIOReenable`
+ :func:`TSContSchedule`
+:data:`TS_EVENT_IMMEDIATE` :data:`TS_HTTP_REQUEST_TRANSFORM_HOOK`
+:data:`TS_EVENT_IMMEDIATE` :data:`TS_HTTP_RESPONSE_TRANSFORM_HOOK`
+:data:`TS_EVENT_CACHE_OPEN_READ` :func:`TSCacheRead` Cache VC
+:data:`TS_EVENT_CACHE_OPEN_READ_FAILED` :func:`TSCacheRead` TS_CACHE_ERROR code
+:data:`TS_EVENT_CACHE_OPEN_WRITE` :func:`TSCacheWrite` Cache VC
+:data:`TS_EVENT_CACHE_OPEN_WRITE_FAILED` :func:`TSCacheWrite` TS_CACHE_ERROR code
+:data:`TS_EVENT_CACHE_REMOVE` :func:`TSCacheRemove`
+:data:`TS_EVENT_CACHE_REMOVE_FAILED` :func:`TSCacheRemove` TS_CACHE_ERROR code
+:data:`TS_EVENT_NET_ACCEPT` :func:`TSNetAccept` :type:`TSNetVConnection`
+ :func:`TSHttpTxnServerIntercept`
+ :func:`TSHttpTxnIntercept`
+:data:`TS_EVENT_NET_ACCEPT_FAILED` :func:`TSNetAccept`
+ :func:`TSHttpTxnServerIntercept`
+ :func:`TSHttpTxnIntercept`
+:data:`TS_EVENT_HOST_LOOKUP` :func:`TSHostLookup` :type:`TSHostLookupResult`
+:data:`TS_EVENT_TIMEOUT` :func:`TSContSchedule`
+:data:`TS_EVENT_ERROR`
+:data:`TS_EVENT_VCONN_READ_READY` :func:`TSVConnRead` :type:`TSVIO`
+:data:`TS_EVENT_VCONN_WRITE_READY` :func:`TSVConnWrite` :type:`TSVIO`
+:data:`TS_EVENT_VCONN_READ_COMPLETE` :func:`TSVConnRead` :type:`TSVIO`
+:data:`TS_EVENT_VCONN_WRITE_COMPLETE` :func:`TSVConnWrite` :type:`TSVIO`
+:data:`TS_EVENT_VCONN_EOS` :func:`TSVConnRead` :type:`TSVIO`
+:data:`TS_EVENT_NET_CONNECT` :func:`TSNetConnect` :type:`TSVConn`
+:data:`TS_EVENT_NET_CONNECT_FAILED` :func:`TSNetConnect` :type:`TSVConn`
+:data:`TS_EVENT_HTTP_CONTINUE`
+:data:`TS_EVENT_HTTP_ERROR`
+:data:`TS_EVENT_MGMT_UPDATE` :func:`TSMgmtUpdateRegister`
+============================================ =========================================== ==========================
+
+The continuation functions are listed below:
+
+- :func:`TSContCall`
+- :func:`TSContCreate`
+- :func:`TSContDataGet`
+- :func:`TSContDataSet`
+- :func:`TSContDestroy`
+- :func:`TSContMutexGet`
+- :func:`TSContSchedule`
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/basic-authorization/implementing-the-handler-and-getting-a-handle-to-the-transaction.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/basic-authorization/implementing-the-handler-and-getting-a-handle-to-the-transaction.en.rst b/doc/developer-guide/plugins/example-plugins/basic-authorization/implementing-the-handler-and-getting-a-handle-to-the-transaction.en.rst
new file mode 100644
index 0000000..6258557
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/basic-authorization/implementing-the-handler-and-getting-a-handle-to-the-transaction.en.rst
@@ -0,0 +1,46 @@
+.. 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
+
+Implementing the Handler and Getting a Handle to the Transaction
+****************************************************************
+
+The handler function for the plugin's parent continuation is implemented
+as follows:
+
+.. code-block:: c
+
+ static int
+ auth_plugin (TSCont contp, TSEvent event, void *edata)
+ {
+
+ TSHttpTxn txnp = (TSHttpTxn) edata;
+ switch (event) {
+ case TS_EVENT_HTTP_OS_DNS:
+ handle_dns (txnp, contp);
+ return 0;
+ case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
+ handle_response (txnp);
+ return 0;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/basic-authorization/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/basic-authorization/index.en.rst b/doc/developer-guide/plugins/example-plugins/basic-authorization/index.en.rst
new file mode 100644
index 0000000..553aeb1
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/basic-authorization/index.en.rst
@@ -0,0 +1,48 @@
+.. 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
+
+.. _developer-plugins-examples-basic-auth:
+
+Basic Authorization Plugin
+**************************
+
+The sample basic authorization plugin, ``basic-auth.c``, checks for
+basic HTTP proxy authorization. In HTTP basic proxy authorization,
+client user names and passwords are contained in the
+``Proxy-Authorization`` header. The password is encoded using base64
+encoding. The plugin checks all incoming requests for the authorization
+header, user name, and password. If the plugin does not find all of the
+these, then it reenables with an error (effectively stopping the
+transaction) and adds a transaction hook to the send response header
+event.
+
+Creating the Plugin's Parent Continuation and Global Hook
+=========================================================
+
+The parent continuation and global hook are created as follows:
+
+``TSHttpHookAdd (TS_HTTP_OS_DNS_HOOK, TSContCreate (auth_plugin, NULL));``
+
+.. toctree::
+ :maxdepth: 2
+
+ implementing-the-handler-and-getting-a-handle-to-the-transaction.en
+ working-with-http-headers.en
+ setting-a-transaction-hook.en
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/basic-authorization/setting-a-transaction-hook.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/basic-authorization/setting-a-transaction-hook.en.rst b/doc/developer-guide/plugins/example-plugins/basic-authorization/setting-a-transaction-hook.en.rst
new file mode 100644
index 0000000..793260a
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/basic-authorization/setting-a-transaction-hook.en.rst
@@ -0,0 +1,58 @@
+.. 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
+
+Setting a Transaction Hook
+**************************
+
+If the request does not have the ``Proxy-Authorization`` field set to
+Basic authorization or a valid username/password, then the plugin sends
+the 407 Proxy authorization ``required`` status code back to the client.
+The client will then prompt the user for a username and password, and
+then resend the request.
+
+In the ``handle_dns`` routine, the following lines handle the
+authorization error case:
+
+.. code-block:: c
+
+ done:
+ TSHttpTxnHookAdd (txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
+ TSHttpTxnReenable (txnp, TS_EVENT_HTTP_ERROR);
+
+If ``handle_dns`` does not find the ``Proxy-Authorization`` field set to
+Basic authorization or a valid username/password, then it adds a
+``SEND_RESPONSE_HDR_HOOK`` to the transaction being processed. This
+means that Traffic Server will call the plugin back when sending the
+client response. ``handle_dns`` reenables the transaction with
+``TS_EVENT_HTTP_ERROR``, which means that the plugin wants Traffic
+Server to terminate the transaction.
+
+When Traffic Server terminates the transaction, it sends the client an
+error message. Because of the ``SEND_RESPONSE_HDR_HOOK``, Traffic Server
+calls the plugin back. The ``auth-plugin`` routine calls
+``handle_response`` to send the client a ``407`` status code. When the
+client resends the request with the ``Proxy-Authorization`` field, a new
+transaction begins.
+
+``handle_dns`` calls ``base64_decode`` to decode the username and
+password; ``handle_dns`` also calls ``authorized`` to validate the
+username and password. In this plugin, sample NT code is provided for
+password validation. UNIX programmers can supply their own validation
+mechanism.
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/basic-authorization/working-with-http-headers.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/basic-authorization/working-with-http-headers.en.rst b/doc/developer-guide/plugins/example-plugins/basic-authorization/working-with-http-headers.en.rst
new file mode 100644
index 0000000..bae0b9e
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/basic-authorization/working-with-http-headers.en.rst
@@ -0,0 +1,98 @@
+.. 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
+
+Working With HTTP Headers
+*************************
+
+The plugin checks all client request headers for the Proxy-Authorization
+MIME field, which should contain the user name and password. The
+plugin's continuation handler, ``auth-plugin``, calls ``handle_dns`` to
+check the ``Proxy-Authorization`` field. The ``handle_dns`` routine uses
+``TSHttpTxnClientReqGet`` and ``TSMimeHdrFieldFind`` to obtain the
+``Proxy-Authorization`` field:
+
+.. code-block:: c
+
+ {
+ TSMBuffer bufp;
+ TSMLoc hdr_loc;
+ TSMLoc field_loc;
+ const char *val;
+ char *user, *password;
+
+ if (!TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc)) {
+ TSError ("[basic_authorization] Couldn't retrieve client request header");
+ goto done;
+ }
+
+ field_loc = TSMimeHdrFieldFind (bufp, hdr_loc,
+ TS_MIME_FIELD_PROXY_AUTHORIZATION);
+
+If the ``Proxy-Authorization`` field is present, then the plugin checks
+that the authentication type is "Basic", and the user name and password
+are present and valid:
+
+.. code-block:: c
+
+ val = TSMimeHdrFieldValueStringGet (bufp, hdr_loc, field_loc, -1, &authval_length);
+ if (!val) {
+ TSError ("[basic_authorization] No value in Proxy-Authorization field");
+ TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+ TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+ goto done;
+ }
+
+ if (strncmp (val, "Basic", 5) != 0) {
+ TSError ("[basic_authorization] No Basic auth type in Proxy-Authorization");
+ TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+ TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+ goto done;
+ }
+
+ val += 5;
+ while ((*val == ' ') || (*val == '\t')) {
+ val += 1;
+ }
+
+ user = base64_decode (val);
+ password = strchr (user, ':');
+ if (!password) {
+ TSError ("[basic_authorization] No password in authorization information");
+ TSfree (user);
+ TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+ TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+ goto done;
+ }
+ *password = '\0';
+ password += 1;
+
+ if (!authorized (user, password)) {
+ TSError ("[basic_authorization] %s:%s not authorized", user, password);
+ TSfree (user);
+ TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+ TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+ goto done;
+ }
+
+ TSfree (user);
+ TSHandleMLocRelease (bufp, hdr_loc, field_loc);
+ TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+ TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
+ return;
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/blacklist/accessing-the-transaction-being-processed.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/accessing-the-transaction-being-processed.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/accessing-the-transaction-being-processed.en.rst
new file mode 100644
index 0000000..46d2a54
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/accessing-the-transaction-being-processed.en.rst
@@ -0,0 +1,64 @@
+.. 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
+
+.. _developer-plugins-blacklist-access-process-txn:
+
+Accessing the Transaction Being Processed
+*****************************************
+
+A continuation's handler function is of type ``TSEventFunc``; the
+prototype is as follows:
+
+``static int function_name (TSCont contp, TSEvent event, void *edata)``
+
+In general, the return value of the handler function is not used. The
+continuation argument is the continuation being called back, the event
+is the event being sent to the continuation, and the data pointed to by
+``void *edata`` depends on the type of event. The data types for each
+event type are listed in :doc:`Writing Handler
+Functions <../../continuations/writing-handler-functions.en>`
+
+The key here is that if the event is an HTTP transaction event, then the
+data passed to the continuation's handler is of type ``TSHttpTxn`` (a
+data type that represents HTTP transactions). Your plugin can then do
+things with the transaction. Here's how it looks in the code for the
+Blacklist plugin's handler:
+
+.. code-block:: c
+
+ static int
+ blacklist_plugin (TSCont contp, TSEvent event, void *edata)
+ {
+ TSHttpTxn txnp = (TSHttpTxn) edata;
+ switch (event) {
+ case TS_EVENT_HTTP_OS_DNS:
+ handle_dns (txnp, contp);
+ return 0;
+ case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
+ handle_response (txnp);
+ return 0;
+ default:
+ break;
+ }
+ return 0;
+ }
+
+For example: when the origin server DNS lookup event is sent,
+``blacklist_plugin`` can call ``handle_dns``\ and pass ``txnp`` as an
+argument.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/blacklist/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/index.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/index.en.rst
new file mode 100644
index 0000000..624c22c
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/index.en.rst
@@ -0,0 +1,111 @@
+.. 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
+
+.. _developer-plugins-examples-blacklist:
+
+Blacklist Plugin
+****************
+
+The sample blacklisting plugin included in the Traffic Server SDK is
+``blacklist-1.c``. This plugin checks every incoming HTTP client request
+against a list of blacklisted web sites. If the client requests a
+blacklisted site, then the plugin returns an ``Access forbidden``
+message to the client.
+
+The flow of HTTP processing with the blacklist plugin is illustrated in
+the figure titled :ref:`BlackListPlugin`.
+This example also contains a simple configuration management interface.
+It can read a list of blacklisted sites from a file (``blacklist.txt``)
+that can be updated by a Traffic Server administrator. When the
+configuration file is updated, Traffic Server sends an event to the
+plugin that wakes it up to do some work.
+
+Creating the Parent Continuation
+================================
+
+You create the static parent continuation in the mandatory
+``TSPluginInit`` function. This parent continuation effectively **is**
+the plugin: the plugin executes only when this continuation receives an
+event from Traffic Server. Traffic Server passes the event as an
+argument to the continuation's handler function. When you create
+continuations, you must create and specify their handler functions.
+
+You can specify an optional mutex lock when you create continuations.
+The mutex lock protects data shared by asynchronous processes. Because
+Traffic Server has a multi-threaded design, race conditions can occur if
+several threads try to access the same continuation's data.
+
+Here is how the static parent continuation is created in
+``blacklist-1.c``:
+
+.. code-block:: c
+
+ void
+ TSPluginInit (int argc, const char *argv[])
+ {
+ // ...
+ TSCont contp;
+
+ contp = TSContCreate (blacklist_plugin, NULL);
+ // ...
+ }
+
+The handler function for the plugin is ``blacklist_plugin``, and the
+mutex is null. The continuation handler function's job is to handle the
+events that are sent to it; accordingly, the ``blacklist_plugin``
+routine consists of a switch statement that covers each of the events
+that might be sent to it:
+
+.. code-block:: c
+
+ static int
+ blacklist_plugin (TSCont contp, TSEvent event, void *edata)
+ {
+ TSHttpTxn txnp = (TSHttpTxn) edata;
+ switch (event) {
+ case TS_EVENT_HTTP_OS_DNS:
+ handle_dns (txnp, contp);
+ return 0;
+ case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
+ handle_response (txnp);
+ return 0;
+ default:
+ TSDebug ("blacklist_plugin", "This event was unexpected: %d\n", );
+ break;
+ }
+ return 0;
+ }
+
+When you write handler functions, you have to anticipate any events that
+might be sent to the handler by hooks or by other functions. In the
+Blacklist plugin, ``TS_EVENT_OS_DNS`` is sent because of the global hook
+established in ``TSPluginInit``, ``TS_EVENT_HTTP_SEND_RESPONSE_HDR`` is
+sent because the plugin contains a transaction hook
+(see :ref:`developer-plugins-examples-blacklist-txn-hook`).
+It is good practice to have a default case in your switch statements.
+
+.. toctree::
+ :maxdepth: 2
+
+ setting-a-global-hook.en
+ accessing-the-transaction-being-processed.en
+ setting-up-a-transaction-hook.en
+ working-with-http-header-functions.en
+ source-code.en
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/blacklist/setting-a-global-hook.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/setting-a-global-hook.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/setting-a-global-hook.en.rst
new file mode 100644
index 0000000..65bc059
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/setting-a-global-hook.en.rst
@@ -0,0 +1,38 @@
+.. 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
+
+Setting a Global Hook
+*********************
+
+Global hooks are always added in ``TSPluginInit`` using
+``TSHttpHookAdd``. The two arguments of ``TSHttpHookAdd`` are the hook
+ID and the continuation to call when processing the event corresponding
+to the hook. In ``blacklist-1.c``, the global hook is added as follows:
+
+.. code-block:: c
+
+ TSHttpHookAdd (TS_HTTP_OS_DNS_HOOK, contp);
+
+Above, ``TS_HTTP_OS_DNS_HOOK`` is the ID for the origin server DNS
+lookup hook and ``contp`` is the parent continuation created earlier.
+
+This means that the Blacklist plugin is called at every origin server
+DNS lookup. When it is called, the handler functio ``blacklist_plugin``
+receives ``TS_EVENT_HTTP_OS_DNS`` and calls ``handle_dns`` to see if the
+request is forbidden.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/example-plugins/blacklist/setting-up-a-transaction-hook.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/example-plugins/blacklist/setting-up-a-transaction-hook.en.rst b/doc/developer-guide/plugins/example-plugins/blacklist/setting-up-a-transaction-hook.en.rst
new file mode 100644
index 0000000..7f89d31
--- /dev/null
+++ b/doc/developer-guide/plugins/example-plugins/blacklist/setting-up-a-transaction-hook.en.rst
@@ -0,0 +1,84 @@
+.. 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
+
+.. _developer-plugins-examples-blacklist-txn-hook:
+
+Setting Up a Transaction Hook
+*****************************
+
+The Blacklist plugin sends "access forbidden" messages to clients if
+their requests are directed to blacklisted hosts. Therefore, the plugin
+needs a transaction hook so it will be called back when Traffic Server's
+HTTP state machine reaches the "send response header" event. In the
+Blacklist plugin's ``handle_dns`` routine, the transaction hook is added
+as follows:
+
+.. code-block:: c
+
+ TSMutexLock (sites_mutex);
+ for (i = 0; i < nsites; i++) {
+ if (strncmp (host, sites[i], host_length) == 0) {
+ printf ("blacklisting site: %s\n", sites[i]);
+ TSHttpTxnHookAdd (txnp,
+ TS_HTTP_SEND_RESPONSE_HDR_HOOK,
+ contp);
+ TSHandleMLocRelease (bufp, hdr_loc, url_loc);
+ TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+ TSHttpTxnReenable (txnp, TS_EVENT_HTTP_ERROR);
+ TSMutexUnlock (sites_mutex);
+ return;
+ }
+ }
+ TSMutexUnlock (sites_mutex);
+ done:
+ TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
+
+This code fragment shows some interesting features. The plugin is
+comparing the requested site to the list of blacklisted sites. While the
+plugin is using the blacklist, it must acquire the mutex lock for the
+blacklist to prevent configuration changes in the middle of a
+blacklisting operation. If the requested site is blacklisted, then the
+following things happen:
+
+#. A transaction hook is added with ``TSHttpTxnHookAdd``; the plugin is
+ called back at the "send response header" event (i.e., the plugin
+ sends an Access forbidden message to the client). You can see that in
+ order to add a transaction hook, you need a handle to the transaction
+ being processed.
+
+#. The transaction is reenabled using ``TSHttpTxnReenable`` with
+ ``TS_EVENT_HTTP_ERROR`` as its event argument. Reenabling with an
+ error event tells the HTTP state machine to stop the transaction and
+ jump to the "send response header" state. Notice that if the
+ requested site is not blacklisted, then the transaction is reenabled
+ with the ``TS_EVENT_HTTP_CONTINUE`` event.
+
+#. The string and ``TSMLoc`` data stored in the marshal buffer ``bufp`` is
+ released by ``TSHandleMLocRelease`` (see
+ :ref:`developer-plugins-http-headers-marshal-buffers`). Release these
+ handles before re-enabling the transaction.
+
+In general, whenever the plugin is doing something to a transaction, it
+must reenable the transaction when it is finished. In other words: every
+time your handler function handles a transaction event, it must call
+``TSHttpTxnReenable`` when it is finished. Similarly, after your plugin
+handles session events (``TS_EVENT_HTTP_SSN_START`` and
+``TS_EVENT_HTTP_SSN_CLOSE``), it must reenable the session with
+``TSHttpSsnReenable``. Reenabling the transaction twice in the same
+plugin routine is a bad error.