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 2013/05/31 04:46:54 UTC

[27/38] add sdk docs.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/preface/how-to-use-this-book.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/preface/how-to-use-this-book.en.rst b/doc/source/sdk/preface/how-to-use-this-book.en.rst
new file mode 100644
index 0000000..7d78d63
--- /dev/null
+++ b/doc/source/sdk/preface/how-to-use-this-book.en.rst
@@ -0,0 +1,132 @@
+How to Use This Book
+********************
+
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+ 
+   http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+This 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 Traffic Server plugins, then read `Getting
+Started <../getting-started>`__ and `Creating Traffic Server
+Plugins <../how-to-create-trafficserver-plugins>`__, and use the
+remaining chapters as needed. `Header-Based Plugin
+Examples <../header-based-plugin-examples>`__ provides details about
+plugins that work on HTTP headers, while `HTTP Transformation
+Plugins <../http-transformation-plugin>`__ explains how to write a
+plugin that transforms or scans the body of an HTTP response. `New
+Protocol Plugins <../new-protocol-plugins>`__ provides essential
+information if you want to support your own protocol on Traffic Server.
+
+You can look up information in the following reference sections:
+
+-  `Index <concept-index>`__: lists information by subject
+-  `Function
+   Index <http://ci.apache.org/projects/trafficserver/trunk/doxygen/>`__:
+   Doxygen reference
+-  `Type
+   Index <http://ci.apache.org/projects/trafficserver/trunk/doxygen/classes.html>`__
+-  `Sample Source Code <../sample-source-code>`__
+-  `Deprecated
+   Functions <http://ci.apache.org/projects/trafficserver/trunk/doxygen/deprecated.html>`__
+
+Below is a section-by-section breakdown of this guide:
+
+-  | `Getting Started <../getting-started>`__
+   | How to compile and load plugins. Walks through a simple "hello
+   world" example; explains how to initialize and register plugins.
+
+-  | `How to Create Traffic Server
+   Plugins <../how-to-create-trafficserver-plugins>`__
+   | Basic structures that all plugins use: events, continuations, and
+   how to hook on to Traffic Server processes. Detailed explication of a
+   sample blacklisting plugin.
+
+-  | `Remap Plugin <../remap-plugin>`__
+   | This chapter demonstrates on a practical example how you can
+   exploit the Traffic Server remap API for your plugins.
+
+-  | `Header-Based Plugin Examples <../header-based-plugin-examples>`__
+   | Detailed explanation about writing plugins that work on HTTP
+   headers; discusses sample blacklisting and basic authorization
+   plugins.
+
+-  | `HTTP Transformation Plugins <../http-transformation-plugin>`__
+   | Detailed explanation of the null-transform example; also discusses
+   ``VConnections``, ``VIOs``, and IO buffers.
+
+-  | `New Protocol 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:
+
+-  | `Miscellaneous Interface Guide <../misc-interface-guide>`__
+   | Details error-writing and tracing functions, thread functions, and
+   Traffic Server API versions of the ``malloc`` and ``fopen`` families.
+   The Traffic Server API versions overcome various C library
+   limitations.
+
+-  | `HTTP Hooks and Transactions <../http-hoooks-and-transactions>`__
+   | Functions in this chapter hook your plugin to Traffic Server HTTP
+   processes.
+
+-  | `HTTP Headers <../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.
+
+-  `Mutex Guide <../mutex-guide>`__
+
+-  | `Continuations <../continuations>`__
+   | Continuations provide the basic callback mechanism and data
+   abstractions used in Traffic Server.
+
+-  `Plugin Configurations <../plugin-configurations>`__
+
+-  | `Actions Guide <../actions-guide>`__
+   | Describes how to use ``TSActions`` and the ``TSDNSLookup`` API.
+
+-  | `IO Guide <../io-guide>`__
+   | Describes how to use the Traffic Server IO interfaces:
+   ``TSVConnection``, ``TSVIO``, ``TSIOBuffer``, ``TSNetVConnection``,
+   the Cache API.
+
+-  | `Plugin Management <../plugin-management>`__
+   | These functions enable you to set up a configuration interface for
+   plugins, access installed plugin files, and set up plugin licensing.
+
+-  | `Adding Statistics <../adding-statistics>`__
+   | These functions add statistics to your plugin.
+
+-  `Function
+   Index <http://ci.apache.org/projects/trafficserver/trunk/doxygen/>`__
+   Doxygen generated Traffic Server API Documentation
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/preface/typographical-conventions.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/preface/typographical-conventions.en.rst b/doc/source/sdk/preface/typographical-conventions.en.rst
new file mode 100644
index 0000000..3b75c04
--- /dev/null
+++ b/doc/source/sdk/preface/typographical-conventions.en.rst
@@ -0,0 +1,36 @@
+Typographical Conventions
+*************************
+
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+ 
+   http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+This document uses the following typographic conventions:
+
+\_italics \_ or *\* bold*\ \*
+    Used to introduce terms.
+
+``monospaced face``
+    Represents C language statements, commands, file content, and
+    computer output.
+
+*``monospaced italic``*
+    Represents variables for which you should substitute a value.
+
+``...`` (ellipsis)
+    Indicates the omission of irrelevant or unimportant information.
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/remap-plugin.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/remap-plugin.en.rst b/doc/source/sdk/remap-plugin.en.rst
new file mode 100644
index 0000000..6506653
--- /dev/null
+++ b/doc/source/sdk/remap-plugin.en.rst
@@ -0,0 +1,75 @@
+Remap Plugin
+************
+
+.. 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.
+
+.. toctree::
+   :maxdepth: 2
+
+   remap-plugin/example-query-remap.en
+
+
+The Remap plugin provides a more flexible, dynamic way of specifying
+remap rules. It is not built on top of the Traffic Server APIs and
+exists solely for the purpose of URL remapping. The remap plugin is not
+global --it is configured on a per-remap rule basis, which enables you
+to customize how URLs are redirected based on individual rules in the
+``remap.config`` file.
+
+The Traffic Server Remap API enables a plugin to dynamically map a
+client request to a target URL. Each plugin is associated with one or
+more remap rules in ``remap.config`` (an "instance"). If a request URL
+matches a remap rule's "fromURL", then Traffic Server calls the
+plugin-defined remap function for that request.
+
+((Editor's note: additional text TBD; text in this chapter is still
+under development))
+
+Getting Started
+---------------
+
+Remap Header File
+~~~~~~~~~~~~~~~~~
+
+The ``remap.h`` header file contains the Traffic Server remap API. By
+default, the header file location is: ``/usr/local/include/ts/remap.h``
+
+Required Functions
+~~~~~~~~~~~~~~~~~~
+
+A remap plugin is required to implement the following functions:
+
+-  ```TSRemapInit`` <http://people.apache.org/~amc/ats/doc/html/remap_8h.html#af7e9b1eee1c38c6f8dcc67a65ba02c24>`__:
+   the remap initialization function, called once when the plugin is
+   loaded
+
+-  ```TSRemapNewInstance`` <http://people.apache.org/~amc/ats/doc/html/remap_8h.html#a963de3eeed2ed7a2da483acf77dc42ca>`__:
+   a new instance is created for each rule associated with the plugin.
+   Called each time the plugin used in a remap rule (this function is
+   what processes the pparam values)
+
+-  ```TSRemapDoRemap`` <http://people.apache.org/~amc/ats/doc/html/remap_8h.html#acf73f0355c591e145398211b3c0596fe>`__:
+   the entry point used by Traffic Server to find the new URL to which
+   it remaps; called every time a request comes in
+
+Configuration
+~~~~~~~~~~~~~
+
+To associate a remap plugin with a remap rule, use the ``@plugin``
+parameter. See the Admin Guide section (?TBD?) for details on
+configuring remap plugins

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/remap-plugin/example-query-remap.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/remap-plugin/example-query-remap.en.rst b/doc/source/sdk/remap-plugin/example-query-remap.en.rst
new file mode 100644
index 0000000..757b76e
--- /dev/null
+++ b/doc/source/sdk/remap-plugin/example-query-remap.en.rst
@@ -0,0 +1,152 @@
+Example: Query Remap Plugin
+***************************
+
+.. 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.
+
+The sample remap plugin, ``query_remap.c``, maps client requests to a
+number of servers based on a hash of the request's URL query parameter.
+This can be useful for spreading load for a given type of request among
+backend servers, while still maintaining "stickiness" to a single server
+for similar requests. For example, a search engine may want to send
+repeated queries for the same keywords to a server that has likely
+cached the result from a prior query.
+
+Configuration of query\_remap
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The query remap plugin will allow the query parameter name to be
+specified, along with the hostnames of the servers to hash across.
+Sample ``remap.config`` rules using ``query_remap`` will look like:
+
+::
+
+    map http://www.example.com/search http://srch1.example.com/search @plugin=query_remap.so @pparam=q @pparam=srch1.example.com @pparam=srch2.example.com @pparam=srch3.example.com
+    map http://www.example.com/profiles http://prof1.example.com/profiles @plugin=query_remap.so @pparam=user_id @pparam=prof1.example.com @pparam=prof2.example.com
+
+The first ``@pparam`` specifies the query param key for which the value
+will be hashed. The remaining parameters list the hostnames of the
+servers. A request for ``http://www.example.com/search?q=apache`` will
+match the first rule. The plugin will look for the *``q``* parameter and
+hash the value '``apache``\ ' to pick from among
+``srch_[1-3]_.example.com`` to send the request.
+
+If the request does not include a *``q``* query parameter and the plugin
+decides not to modify the request, the default toURL
+'``http://srch1.example.com/search``\ ' will be used by TS.
+
+The parameters are passed to the plugin's ``tsremap_new_instance``
+function. In ``query_remap``, ``tsremap_new_instance`` creates a
+plugin-defined ``query_remap_info`` struct to store its configuration
+parameters. The ihandle, an opaque pointer that can be used to pass
+per-instance data, is set to this struct pointer and will be passed to
+the ``tsremap_remap`` function when it is triggered for a request.
+
+::
+
+    :::c
+    typedef struct _query_remap_info {
+      char *param_name;
+      size_t param_len;
+      char **hosts;
+      int num_hosts;
+    } query_remap_info;
+        
+        
+    int tsremap_new_instance(int argc,char *argv[],ihandle *ih,char *errbuf,int errbuf_size)
+    {
+      int i;
+        
+      if (argc param_name = strdup(argv[2]);
+      qri->param_len = strlen(qri->param_name);
+      qri->num_hosts = argc - 3;
+      qri->hosts = (char**) TSmalloc(qri->num_hosts*sizeof(char*));
+        
+      for (i=0; i num_hosts; ++i) {
+        qri->hosts[i] = strdup(argv[i+3]);
+      }
+        
+      *ih = (ihandle)qri;
+      return 0;
+    }
+
+Another way remap plugins may want handle more complex configuration is
+to specify a configuration filename as a ``pparam`` and parse the
+specified file during instance initialization.
+
+Performing the Remap
+~~~~~~~~~~~~~~~~~~~~
+
+The plugin implements the ``tsremap_remap`` function, which is called
+when TS has read the client HTTP request headers and matched the request
+to a remap rule configured for the plugin. The ``TSRemapRequestInfo``
+struct contains input and output members for the remap operation.
+
+``tsremap_remap`` uses the configuration information passed via the
+``ihandle`` and checks the ``request_query`` for the configured query
+parameter. If the parameter is found, the plugin sets a ``new_host`` to
+modify the request host:
+
+::
+
+    :::c
+    int tsremap_remap(ihandle ih, rhandle rh, TSRemapRequestInfo *rri)
+    {
+      int hostidx = -1;
+      query_remap_info *qri = (query_remap_info*)ih;
+        
+      if (!qri) {
+        TSError("NULL ihandle");
+        return 0;
+      }
+          
+      if (rri && rri->request_query && rri->request_query_size > 0) {
+        char *q, *s, *key;
+            
+        //make a copy of the query, as it is read only
+        q = (char*) TSmalloc(rri->request_query_size+1);
+        strncpy(q, rri->request_query, rri->request_query_size);
+        q[rri->request_query_size] = '\0';
+            
+        s = q;
+        //parse query parameters
+        for (key = strsep(&s, "&"); key != NULL; key = strsep(&s, "&")) {
+          char *val = strchr(key, '=');
+          if (val && (size_t)(val-key) == qri->param_len &&
+              !strncmp(key, qri->param_name, qri->param_len)) {
+            ++val;
+            //the param key matched the configured param_name
+            //hash the param value to pick a host
+            hostidx = hash_fnv32(val, strlen(val)) % (u_int32_t)qri->num_hosts;
+            break;
+          }
+        }
+            
+        TSfree(q);
+            
+        if (hostidx >= 0) {
+          rri->new_host_size = strlen(qri->hosts[hostidx]);
+          if (rri->new_host_size new_host, qri->hosts[hostidx], rri->new_host_size);
+            return 1; //host has been modified
+          }
+        }
+      }
+        
+      //the request was not modified, TS will use the toURL from the remap rule
+      return 0;
+    }
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/sample-source-code.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/sample-source-code.en.rst b/doc/source/sdk/sample-source-code.en.rst
new file mode 100644
index 0000000..42be2a9
--- /dev/null
+++ b/doc/source/sdk/sample-source-code.en.rst
@@ -0,0 +1,309 @@
+Sample Source Code
+******************
+
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+ 
+   http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+This appendix provides several source code examples. In the online
+formats of this book, function calls are linked to their references in
+the previous chapters. The following sample plugins are provided:
+
+-  `blacklist-1.c <App_SampleSourceCode.html#Sample_blacklist-1.c>`__
+
+blacklist-1.c
+-------------
+
+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.
+
+This plugin illustrates:
+
+-  An HTTP transaction extension
+
+-  How to examine HTTP request headers
+
+-  How to use the logging interface
+
+-  How to use the plugin configuration management interface
+
+.. raw:: html
+
+   <pre>
+       /* blacklist-1.c:  An example program that denies client access
+        *                 to blacklisted sites. This plugin illustrates
+        *                 how to use configuration information from the
+        *                 blacklist.txt configuration file.
+        *
+        * Usage:
+        * (Solaris) : blacklist-1.so
+        *
+        *
+        */
+
+       #include <stdio.h>
+       #include <string.h>
+       #include <ts/ts.h>
+
+       #define MAX_NSITES 500
+
+       static char* sites[MAX_NSITES];
+       static int nsites;
+       static TSMutex sites_mutex;
+       static TSTextLogObject log;
+
+       static void
+       handle_dns (TSHttpTxn txnp, TSCont contp)
+       {
+           TSMBuffer bufp;
+           TSMLoc hdr_loc;
+           TSMLoc url_loc;
+           const char *host;
+           int i;
+           int host_length;
+
+           if (!TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc)) {
+               TSError ("couldn't retrieve client request header\n");
+               goto done;
+           }
+
+           url_loc = TSHttpHdrUrlGet (bufp, hdr_loc);
+           if (!url_loc) {
+               TSError ("couldn't retrieve request url\n");
+               TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+               goto done;
+           }
+
+           host = TSUrlHostGet (bufp, url_loc, &host_length);
+           if (!host) {
+               TSError ("couldn't retrieve request hostname\n");
+               TSHandleMLocRelease (bufp, hdr_loc, url_loc);
+               TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+               goto done;
+           }
+
+           TSMutexLock(sites_mutex);
+
+           for (i = 0; i < nsites; i++) {
+               if (strncmp (host, sites[i], host_length) == 0) {
+                   if (log) {
+                       TSTextLogObjectWrite(log, "blacklisting site: %s", sites[i]);
+                   } else {
+                       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);
+           TSHandleMLocRelease (bufp, hdr_loc, url_loc);
+           TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+
+        done:
+           TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
+       }
+
+       static void
+       handle_response (TSHttpTxn txnp)
+       {
+           TSMBuffer bufp;
+           TSMLoc hdr_loc;
+           TSMLoc url_loc;
+           char *url_str;
+           char *buf;
+           int url_length;
+
+           if (!TSHttpTxnClientRespGet (txnp, &bufp, &hdr_loc)) {
+               TSError ("couldn't retrieve client response header\n");
+               goto done;
+           }
+
+           TSHttpHdrStatusSet (bufp, hdr_loc, TS_HTTP_STATUS_FORBIDDEN);
+           TSHttpHdrReasonSet (bufp, hdr_loc,
+               TSHttpHdrReasonLookup (TS_HTTP_STATUS_FORBIDDEN),
+               strlen (TSHttpHdrReasonLookup (TS_HTTP_STATUS_FORBIDDEN)) );
+
+           if (!TSHttpTxnClientReqGet (txnp, &bufp, &hdr_loc)) {
+               TSError ("couldn't retrieve client request header\n");
+               TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+               goto done;
+           }
+
+           url_loc = TSHttpHdrUrlGet (bufp, hdr_loc);
+           if (!url_loc) {
+               TSError ("couldn't retrieve request url\n");
+               TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+               goto done;
+           }
+
+           buf = (char *)TSmalloc (4096);
+
+           url_str = TSUrlStringGet (bufp, url_loc, &url_length);
+           sprintf (buf, "You are forbidden from accessing \"%s\"\n", url_str);
+           TSfree (url_str);
+           TSHandleMLocRelease (bufp, hdr_loc, url_loc);
+           TSHandleMLocRelease (bufp, TS_NULL_MLOC, hdr_loc);
+
+           TSHttpTxnErrorBodySet (txnp, buf, strlen (buf), NULL);
+
+        done:
+           TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
+       }
+
+       static void
+       read_blacklist (void)
+       {
+           char blacklist_file[1024];
+           TSFile file;
+
+           sprintf (blacklist_file, "%s/blacklist.txt", TSPluginDirGet());
+           file = TSfopen(blacklist_file, "r");
+
+           TSMutexLock (sites_mutex);
+           nsites = 0;
+
+           if (file != NULL) {
+               char buffer[1024];
+
+               while (TSfgets (file, buffer, sizeof(buffer)-1) != NULL && nsites < MAX_NSITES) {
+                   char* eol;
+                   if ((eol = strstr(buffer, "\r\n")) != NULL) {
+                       /* To handle newlines on Windows */
+                       *eol = '\0';
+                   } else if ((eol = strchr(buffer, '\n')) != NULL) {
+                       *eol = '\0';
+                   } else {
+                       /* Not a valid line, skip it */
+                       continue;
+                  }
+                  if (sites[nsites] != NULL) {
+                       TSfree (sites[nsites]);
+                  }
+                  sites[nsites] = TSstrdup (buffer);
+                  nsites++;
+              }
+
+               TSfclose (file);
+           } else {
+              TSError ("unable to open %s\n", blacklist_file);
+              TSError ("all sites will be allowed\n", blacklist_file);
+           }
+
+           TSMutexUnlock (sites_mutex);
+       }
+
+       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;
+           case TS_EVENT_MGMT_UPDATE:
+               read_blacklist ();
+               return 0;
+           default:
+               break;
+           }
+           return 0;
+       }
+
+       int
+       check_ts_version()
+       {
+
+          const char *ts_version = TSTrafficServerVersionGet();
+          int result = 0;
+
+          if (ts_version) {
+              int major_ts_version = 0;
+              int minor_ts_version = 0;
+              int patch_ts_version = 0;
+
+              if (sscanf(ts_version, "%d.%d.%d", &major_ts_version, &minor_ts_version, &patch_ts_version) != 3) {
+                   return 0;
+              }
+
+              /* Need at least TS 2.0 */
+              if (major_ts_version >= 2) {
+                   result = 1;
+              }
+
+          }
+
+          return result;
+       }
+
+       void
+       TSPluginInit (int argc, const char *argv[])
+       {
+           int i;
+           TSCont contp;
+           TSPluginRegistrationInfo info;
+           int error;
+
+           info.plugin_name = "blacklist-1";
+           info.vendor_name = "DsCompany";
+           info.support_email = "ts-api-support@DsCompany.com";
+
+           if (!TSPluginRegister (TS_SDK_VERSION_2_0 , &info)) {
+               TSError ("Plugin registration failed.\n");
+           }
+
+           if (!check_ts_version()) {
+              TSError ("Plugin requires Traffic Server 2.0 or later\n");
+              return;
+           }
+
+           /* create an TSTextLogObject to log blacklisted requests to */
+           log = TSTextLogObjectCreate("blacklist", TS_LOG_MODE_ADD_TIMESTAMP,
+                    NULL, &error);
+           if (!log) {
+               printf("Blacklist plugin: error %d while creating log\n", error);
+           }
+
+           sites_mutex = TSMutexCreate ();
+
+           nsites = 0;
+           for (i = 0; i < MAX_NSITES; i++) {
+               sites[i] = NULL;
+           }
+
+           read_blacklist ();
+
+           contp = TSContCreate (blacklist_plugin, NULL);
+
+           TSHttpHookAdd (TS_HTTP_OS_DNS_HOOK, contp);
+
+           TSMgmtUpdateRegister (contp, "Super Blacklist Plugin", "blacklist.cgi");
+       }
+
+   </pre>
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/troubleshooting-tips.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/troubleshooting-tips.en.rst b/doc/source/sdk/troubleshooting-tips.en.rst
new file mode 100644
index 0000000..3863485
--- /dev/null
+++ b/doc/source/sdk/troubleshooting-tips.en.rst
@@ -0,0 +1,57 @@
+Troubleshooting Tips
+********************
+
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+ 
+   http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+This appendix lists the following troubleshooting tips.
+
+.. toctree::
+   :maxdepth: 2
+
+   troubleshooting-tips/unable-to-load-plugins.en
+   troubleshooting-tips/unable-to-debug-tags.en
+   troubleshooting-tips/using-a-debugger.en
+   troubleshooting-tips/debugging-memory-leaks.en
+
+
+Unable to Compile Plugins
+-------------------------
+
+The process for compiling a shared library varies with the platform
+used, so the Traffic Server API includes the ``tsxs`` script you can use
+to create shared libraries on all supported Traffic Server platforms.
+
+Example
+~~~~~~~
+
+Assuming the sample program is stored in the file ``hello-world.c``, you
+could use the following commands to building a shared library:
+
+::
+
+        :::text
+        tsxs -c hello-world.c -o hello-world.so
+
+To install this plugin in your ``plugindir`` use the equivalent of sudo
+on your platform to execute:
+
+::
+
+        :::text
+        sudo tsxs -o hello-world.so -i
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/troubleshooting-tips/debugging-memory-leaks.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/troubleshooting-tips/debugging-memory-leaks.en.rst b/doc/source/sdk/troubleshooting-tips/debugging-memory-leaks.en.rst
new file mode 100644
index 0000000..4021e07
--- /dev/null
+++ b/doc/source/sdk/troubleshooting-tips/debugging-memory-leaks.en.rst
@@ -0,0 +1,32 @@
+Debugging Memory Leaks
+**********************
+
+.. 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.
+
+Memory leaks in a plugin can be detected using e.g. an MRTG graph
+related to memory - you can use memory dump information. Enable
+``mem dump`` in ``records.config`` as follows:
+
+::
+
+      :::text
+      CONFIG proxy.config.dump_mem_info_frequency INT <value>
+
+This causes Traffic Server to dump memory information to ``traffic.out``
+at ``<value>`` (intervals are in seconds). A zero value means that it is
+disabled.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/troubleshooting-tips/unable-to-debug-tags.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/troubleshooting-tips/unable-to-debug-tags.en.rst b/doc/source/sdk/troubleshooting-tips/unable-to-debug-tags.en.rst
new file mode 100644
index 0000000..8e3a30b
--- /dev/null
+++ b/doc/source/sdk/troubleshooting-tips/unable-to-debug-tags.en.rst
@@ -0,0 +1,113 @@
+Using Debug Tags
+****************
+
+.. 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.
+
+Use the API
+``void TSDebug (const char *tag, const char *format_str, ...)`` to add
+traces in your plugin. In this API:
+
+-  ``tag`` is the Traffic Server parameter that enables Traffic Server
+   to print out *``format_str``*
+
+-  ``...`` are variables for *``format_str``* in the standard ``printf``
+   style.
+
+Run Traffic Server with the ``-Ttag`` option. For example, if the tag is
+``my-plugin``, then the debug output goes to ``traffic.out.``\ See
+below:
+
+::
+
+       :::text
+       traffic_server -T"my-plugin"
+
+Set the following variables in ``records.config`` (in the Traffic Server
+``config`` directory):
+
+::
+
+       :::text
+       proxy.config.diags.debug.enabled INT 1
+       proxy.config.diags.debug.tags STRING debug-tag-name
+
+In this case, debug output goes to ``traffic.out``.
+
+Example:
+
+::
+
+       :::c
+       TSDebug ("my-plugin", "Starting my-plugin at %d\n", the_time);
+
+The statement ``"Starting my-plugin at <time>"`` appears whenever you
+run Traffic Server with the ``my-plugin`` tag:
+
+::
+
+       :::text
+       traffic_server -T"my-plugin"
+
+Other Useful Internal Debug Tags
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Embedded in the base Traffic Server code are many debug tags for
+internal debugging purposes. These can also be used to follow Traffic
+Server behavior for testing and analysis.
+
+The debug tag setting (``-T`` and ``proxy.config.diag.debug.tags``) is a
+anchored regular expression against which the tag for a specific debug
+message is matched. This means the value "http" matches debug emssages
+with the tag "http" but also "http\_seq" and "http\_trans". If you want
+multiple tags then use a pipe symbol to separate the tags. For example
+"http\_tproxy\|dns\|hostdb" will match any of the message tags
+"http\_tproxy", "dns", "hostdb", or "dns\_srv" (but not "http\_trans"
+nor "splitdns").
+
+Some of the useful HTTP debug tags are:
+
+-  ``http_hdrs`` - traces all incoming and outgoing HTTP headers.
+
+-  ``http_trans`` - traces actions in an HTTP transaction.
+
+-  ``http_seq`` - traces the sequence of the HTTP state machine.
+
+-  ``http_tproxy`` - transparency related HTTP events
+
+-  ``dns`` - DNS operations
+
+-  ``hostdb`` - Host name lookup
+
+-  ``iocore_net`` - Socket and low level IO (very voluminous)
+
+-  ``socket`` - socket operations
+
+-  ``ssl`` - SSL related events
+
+-  ``cache`` - Cache operations (many subtags, examine the output to
+   narrow the tag set)
+
+-  ``cache_update`` - Cache updates including writes
+
+-  ``cache_read`` - Cache read events.
+
+-  ``dir_probe`` - Cache searches.
+
+-  ``sdk`` - gives some warning concerning API usage.
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/troubleshooting-tips/unable-to-load-plugins.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/troubleshooting-tips/unable-to-load-plugins.en.rst b/doc/source/sdk/troubleshooting-tips/unable-to-load-plugins.en.rst
new file mode 100644
index 0000000..70d21bd
--- /dev/null
+++ b/doc/source/sdk/troubleshooting-tips/unable-to-load-plugins.en.rst
@@ -0,0 +1,36 @@
+Unable to Load Plugins
+**********************
+
+.. 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.
+
+To load plugins, follow the steps below.
+
+1. Make sure that your plugin source code contains an ``TSPluginInit``
+   initialization function.
+
+2. Compile your plugin source code, creating a shared library.
+
+3. Add an entry to the ``plugin.config`` file for your plugin.
+
+4. Add the path to your plugin shared library to the ``records.config``
+   file.
+
+5. Restart Traffic Server.
+
+For detailed information about each step above, refer to `A Simple
+Plugin <../getting-started/a-simple-plugin>`__.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/80368908/doc/source/sdk/troubleshooting-tips/using-a-debugger.en.rst
----------------------------------------------------------------------
diff --git a/doc/source/sdk/troubleshooting-tips/using-a-debugger.en.rst b/doc/source/sdk/troubleshooting-tips/using-a-debugger.en.rst
new file mode 100644
index 0000000..82a0165
--- /dev/null
+++ b/doc/source/sdk/troubleshooting-tips/using-a-debugger.en.rst
@@ -0,0 +1,40 @@
+Using a Debugger
+****************
+
+.. 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.
+
+A debugger can set breakpoints in a plugin. Use a Traffic Server debug
+build and compile the plugin with the ``-g`` option. A debugger can also
+be used to analyze a core dump. To generate core, set the size limit of
+the core files in the ``records.config`` file to -1 as follows:
+
+::
+
+    :::c
+    CONFIG proxy.config.core_limit INT -1
+
+This is the equivalent of setting ``ulimit -c unlimited``
+
+Debugging Tips:
+~~~~~~~~~~~~~~~
+
+-  Use a Traffic Server debug version.
+
+-  Use assertions in your plugin (``TSAssert``/``TSReleaseAssert``).
+
+