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:10:11 UTC

[35/51] trafficserver git commit: Documentation reorganization

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/admin-guide/plugins/tcpinfo.en.rst
----------------------------------------------------------------------
diff --git a/doc/admin-guide/plugins/tcpinfo.en.rst b/doc/admin-guide/plugins/tcpinfo.en.rst
new file mode 100644
index 0000000..19db046
--- /dev/null
+++ b/doc/admin-guide/plugins/tcpinfo.en.rst
@@ -0,0 +1,123 @@
+.. _tcpinfo-plugin:
+
+TCPInfo 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.
+
+This global plugin logs TCP metrics at various points in the HTTP
+processing pipeline. The TCP information is retrieved by the
+:manpage:`getsockopt(2)` function using the ``TCP_INFO`` option.
+This is only supported on systems that support the ``TCP_INFO``
+option, currently Linux and BSD.
+
+Plugin Options
+--------------
+
+The following options may be specified in :file:`plugin.config`:
+
+.. NOTE: if the option name is not long enough, docutils will not
+   add the colspan attribute and the options table formatting will
+   be all messed up. Just a trap for young players.
+
+--hooks=NAMELIST
+  This option specifies when TCP information should be logged. The
+  argument is a comma-separated list of the event names listed
+  below. TCP information will be sampled and logged each time the
+  specified set of events occurs.
+
+  ==============  ===============================================
+   Event Name     Triggered when
+  ==============  ===============================================
+  send_resp_hdr   The server begins sending an HTTP response.
+  ssn_close       The TCP connection closes.
+  ssn_start       A new TCP connection is accepted.
+  txn_close       A HTTP transaction is completed.
+  txn_start       A HTTP transaction is initiated.
+  ==============  ===============================================
+
+--log-file=NAME
+  This specifies the base name of the file where TCP information
+  should be logged. If this option is not specified, the name
+  ``tcpinfo`` is used. Traffic Server will automatically append
+  the ``.log`` suffix.
+
+--log-level=LEVEL
+  The log level can be either ``1`` to log only the round trip
+  time estimate, or ``2`` to log the complete set of TCP information.
+
+  The following fields are logged when the log level is ``1``:
+
+  ==========    ==================================================
+  Field Name    Description
+  ==========    ==================================================
+  timestamp     Event timestamp
+  event         Event name (one of the names listed above)
+  client        Client IP address
+  server        Server IP address
+  rtt           Estimated round trip time
+  ==========    ==================================================
+
+  The following fields are logged when the log level is ``2``:
+
+  ==============    ==================================================
+  Field Name        Description
+  ==============    ==================================================
+  timestamp         Event timestamp
+  event             Event name (one of the names listed above)
+  client            Client IP address
+  server            Server IP address
+  rtt               Estimated round trip time
+  rttvar
+  last_sent
+  last_recv
+  snd_cwnd
+  snd_ssthresh
+  rcv_ssthresh
+  unacked
+  sacked
+  lost
+  retrans
+  fackets
+  ==============    ==================================================
+
+--sample-rate=COUNT
+  This is the number of times per 1000 requests that the data will
+  be logged.  A pseudo-random number generator is used to determine if a
+  request will be logged.  The default value is 1000 and this option is
+  not required to be in the configuration file.  To achieve a log rate
+  of 1% you would set this value to 10.
+
+Examples:
+---------
+
+This example logs the simple TCP information to ``tcp-metrics.log``
+at the start of a TCP connection and once for each HTTP
+transaction thereafter::
+
+  tcpinfo.so --log-file=tcp-metrics --log-level=1 --hooks=ssn_start,txn_start
+
+The file ``tcp-metrics.log`` will contain the following log format::
+
+  timestamp event client server rtt
+  20140414.17h40m14s ssn_start 127.0.0.1 127.0.0.1 4000
+  20140414.17h40m14s txn_start 127.0.0.1 127.0.0.1 4000
+  20140414.17h40m16s ssn_start 127.0.0.1 127.0.0.1 4000
+  20140414.17h40m16s txn_start 127.0.0.1 127.0.0.1 4000
+  20140414.17h40m16s ssn_start 127.0.0.1 127.0.0.1 4000
+  20140414.17h40m16s txn_start 127.0.0.1 127.0.0.1 4000

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/admin-guide/plugins/ts_lua.en.rst
----------------------------------------------------------------------
diff --git a/doc/admin-guide/plugins/ts_lua.en.rst b/doc/admin-guide/plugins/ts_lua.en.rst
new file mode 100644
index 0000000..343dd1e
--- /dev/null
+++ b/doc/admin-guide/plugins/ts_lua.en.rst
@@ -0,0 +1,2916 @@
+.. 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
+
+.. _admin-plugins-ts-lua:
+
+ts-lua Plugin
+*************
+
+This module embeds Lua, via the standard Lua 5.1 interpreter, into |ATS|. With
+this module, we can implement ATS plugin by writing Lua script instead of C
+code. Lua code executed using this module can be 100% non-blocking because the
+powerful Lua coroutines have been integrated into the ATS event model.
+
+Synopsis
+========
+
+**test_hdr.lua**
+
+::
+
+    function send_response()
+        ts.client_response.header['Rhost'] = ts.ctx['rhost']
+        return 0
+    end
+
+    function do_remap()
+        local req_host = ts.client_request.header.Host
+        ts.ctx['rhost'] = string.reverse(req_host)
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+        return 0
+    end
+
+**sethost.lua**
+
+::
+
+    local HOSTNAME = ''
+    function __init__(argtb)
+        if (#argtb) < 1 then
+            print(argtb[0], 'hostname parameter required!!')
+            return -1
+        end
+        HOSTNAME = argtb[1]
+    end
+
+    function do_remap()
+        ts.client_request.header['Host'] = HOSTNAME
+        return 0
+    end
+
+
+Installation
+============
+
+This plugin is only built if the configure option
+
+::
+
+    --enable-experimental-plugins
+
+is given at build time.
+
+Configuration
+=============
+
+This module acts as remap plugin of Traffic Server, so we should realize 'do_remap' function in each lua script. We can
+write this in remap.config:
+
+::
+
+    map http://a.tbcdn.cn/ http://inner.tbcdn.cn/ @plugin=/XXX/tslua.so @pparam=/XXX/test_hdr.lua
+
+Sometimes we want to receive parameters and process them in the script, we should realize '__init__' function in the lua
+script, and we can write this in remap.config:
+
+::
+
+    map http://a.x.cn/ http://b.x.cn/ @plugin=/X/tslua.so @pparam=/X/sethost.lua @pparam=a.st.cn
+
+This module can also act as a global plugin of Traffic Server. In this case we should provide one of these functions in
+each lua script:
+
+- **'do_global_txn_start'**
+- **'do_global_txn_close'**
+- **'do_global_os_dns'**
+- **'do_global_pre_remap'**
+- **'do_global_post_remap'**
+- **'do_global_read_request'**
+- **'do_global_send_request'**
+- **'do_global_read_response'**
+- **'do_global_send_response'**
+- **'do_global_cache_lookup_complete'**
+- **'do_global_read_cache'**
+- **'do_global_select_alt'**
+
+We can write this in plugin.config:
+
+::
+
+    tslua.so /etc/trafficserver/script/test_global_hdr.lua
+
+
+TS API for Lua
+==============
+
+Introduction
+------------
+The API is exposed to Lua in the form of one standard packages ``ts``. This package is in the default global scope and
+is always available within lua script. This package can be introduced into Lua like this:
+
+::
+
+    ts.say('Hello World')
+    ts.sleep(10)
+
+`TOP <#ts-lua-plugin>`_
+
+ts.now
+------
+**syntax:** *val = ts.now()*
+
+**context:** global
+
+**description:** This function returns the time since the Epoch (00:00:00 UTC, January 1, 1970), measured in seconds.
+
+Here is an example:
+
+::
+
+    local nt = ts.now()  -- 1395221053
+
+`TOP <#ts-lua-plugin>`_
+
+ts.debug
+--------
+**syntax:** *ts.debug(MESSAGE)*
+
+**context:** global
+
+**description**: Log the MESSAGE to traffic.out if debug is enabled.
+
+Here is an example:
+
+::
+
+       ts.debug('I am in do_remap now.')
+
+The debug tag is **ts_lua** and we should write this in records.config:
+
+``CONFIG proxy.config.diags.debug.tags STRING ts_lua``
+
+`TOP <#ts-lua-plugin>`_
+
+Remap status constants
+----------------------
+**context:** do_remap
+
+::
+
+    TS_LUA_REMAP_NO_REMAP (0)
+    TS_LUA_REMAP_DID_REMAP (1)
+    TS_LUA_REMAP_NO_REMAP_STOP (2)
+    TS_LUA_REMAP_DID_REMAP_STOP (3)
+    TS_LUA_REMAP_ERROR (-1)
+
+These constants are usually used as return value of do_remap function.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_to_url_host
+------------------------
+**syntax:** *ts.remap.get_to_url_host()*
+
+**context:** do_remap
+
+**description**: retrieve the "to" host of the remap rule
+
+Here is an example:
+
+::
+
+    function do_remap()
+        local to_host = ts.remap.get_to_url_host()
+        ts.debug(to_host)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_to_url_port
+------------------------
+**syntax:** *ts.remap.get_to_url_port()*
+
+**context:** do_remap
+
+**description**: retrieve the "to" port of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_to_url_scheme
+--------------------------
+**syntax:** *ts.remap.get_to_url_scheme()*
+
+**context:** do_remap
+
+**description**: retrieve the "to" scheme of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_to_uri
+-------------------
+**syntax:** *ts.remap.get_to_uri()*
+
+**context:** do_remap
+
+**description**: retrieve the "to" path of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_to_url
+-------------------
+**syntax:** *ts.remap.get_to_url()*
+
+**context:** do_remap
+
+**description**: retrieve the "to" url of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_from_url_host
+--------------------------
+**syntax:** *ts.remap.get_from_url_host()*
+
+**context:** do_remap
+
+**description**: retrieve the "from" host of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_from_url_port
+--------------------------
+**syntax:** *ts.remap.get_from_url_port()*
+
+**context:** do_remap
+
+**description**: retrieve the "from" port of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_from_url_scheme
+----------------------------
+**syntax:** *ts.remap.get_from_url_scheme()*
+
+**context:** do_remap
+
+**description**: retrieve the "from" scheme of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_from_uri
+---------------------
+**syntax:** *ts.remap.get_from_uri()*
+
+**context:** do_remap
+
+**description**: retrieve the "from" path of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.remap.get_from_url
+---------------------
+**syntax:** *ts.remap.get_from_url()*
+
+**context:** do_remap
+
+**description**: retrieve the "from" url of the remap rule
+
+`TOP <#ts-lua-plugin>`_
+
+ts.hook
+-------
+**syntax:** *ts.hook(HOOK_POINT, FUNCTION)*
+
+**context:** global or do_remap or do_global_* or later
+
+**description**: Hooks are points in http transaction processing where we can step in and do some work. FUNCTION will be
+called when the http transaction steps in to HOOK_POINT.
+
+Here is an example
+
+::
+
+    function send_response()
+        s.client_response.header['SHE'] = 'belief'
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+    end
+
+Then the client will get the response like this:
+
+::
+
+    HTTP/1.1 200 OK
+    Content-Type: text/html
+    Server: ATS/3.2.0
+    SHE: belief
+    Connection: Keep-Alive
+    ...
+
+You can create global hook as well
+
+::
+
+    function do_some_work()
+       ts.debug('do_some_work')
+       return 0
+    end
+
+    ts.hook(TS_LUA_HOOK_READ_REQUEST_HDR, do_some_work)
+
+    Or you can do it this way
+
+::
+
+    ts.hook(TS_LUA_HOOK_READ_REQUEST_HDR,
+        function()
+            ts.debug('do_some_work')
+            return 0
+        end
+    )
+
+Also the return value of the function will control how the transaction will be re-enabled. Return value of 0 will cause
+the transaction to be re-enabled normally (TS_EVENT_HTTP_CONTINUE). Return value of 1 will be using TS_EVENT_HTTP_ERROR
+instead.
+
+`TOP <#ts-lua-plugin>`_
+
+Hook point constants
+--------------------
+**context:** do_remap or later
+
+::
+
+    TS_LUA_HOOK_OS_DNS
+    TS_LUA_HOOK_PRE_REMAP
+    TS_LUA_HOOK_READ_CACHE_HDR
+    TS_LUA_HOOK_SELECT_ALT
+    TS_LUA_HOOK_TXN_CLOSE
+    TS_LUA_HOOK_POST_REMAP
+    TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE
+    TS_LUA_HOOK_READ_REQUEST_HDR
+    TS_LUA_HOOK_SEND_REQUEST_HDR
+    TS_LUA_HOOK_READ_RESPONSE_HDR
+    TS_LUA_HOOK_SEND_RESPONSE_HDR
+    TS_LUA_REQUEST_TRANSFORM
+    TS_LUA_RESPONSE_TRANSFORM
+
+These constants are usually used in ts.hook method call.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.ctx
+------
+**syntax:** *ts.ctx[KEY] = VALUE*
+
+**syntax:** *VALUE = ts.ctx[KEY]*
+
+**context:** do_remap or do_global_* or later
+
+**description:** This table can be used to store per-request Lua context data and has a life time identical to the
+current request.
+
+Here is an example:
+
+::
+
+    function send_response()
+        ts.client_response.header['F-Header'] = ts.ctx['hdr']
+        return 0
+    end
+
+    function do_remap()
+        ts.ctx['hdr'] = 'foo'
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+        return 0
+    end
+
+Then the client will get the response like this:
+
+::
+
+    HTTP/1.1 200 OK
+    Content-Type: text/html
+    Server: ATS/3.2.0
+    F-Header: foo
+    Connection: Keep-Alive
+    ...
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.get_method
+----------------------------
+**syntax:** *ts.client_request.get_method()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** This function can be used to retrieve the current client request's method name. String like "GET" or
+"POST" is returned.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.set_method
+----------------------------
+**syntax:** *ts.client_request.set_method()*
+
+**context:** do_remap or do_global_*
+
+**description:** This function can be used to override the current client request's method with METHOD_NAME.
+
+ts.client_request.get_version
+-----------------------------
+**syntax:** *ver = ts.client_request.get_version()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** Return the http version string of the client request.
+
+Current possible values are 1.0, 1.1, and 0.9.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.set_version
+-----------------------------
+**syntax:** *ts.client_request.set_version(VERSION_STR)*
+
+**context:** do_remap or do_global_* or later
+
+**description:** Set the http version of the client request with the VERSION_STR
+
+::
+
+    ts.client_request.set_version('1.0')
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.get_uri
+-------------------------
+**syntax:** *ts.client_request.get_uri()*
+
+**context:** do_remap or later
+
+**description:** This function can be used to retrieve the client request's path.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        local uri = ts.client_request.get_uri()
+        print(uri)
+    end
+
+Then ``GET /st?a=1`` will yield the output:
+
+``/st``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.set_uri
+-------------------------
+**syntax:** *ts.client_request.set_uri(PATH)*
+
+**context:** do_remap or do_global_* 
+
+**description:** This function can be used to override the client request's path.
+
+The PATH argument must be a Lua string and starts with ``/``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.get_uri_args
+------------------------------
+**syntax:** *ts.client_request.get_uri_args()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** This function can be used to retrieve the client request's query string.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        local query = ts.client_request.get_uri_args()
+        print(query)
+    end
+
+Then ``GET /st?a=1&b=2`` will yield the output:
+
+``a=1&b=2``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.set_uri_args
+------------------------------
+**syntax:** *ts.client_request.set_uri_args(QUERY_STRING)*
+
+**context:** do_remap or do_global_* 
+
+**description:** This function can be used to override the client request's query string.
+
+::
+
+    ts.client_request.set_uri_args('n=6&p=7')
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.get_url
+-------------------------
+**syntax:** *ts.client_request.get_url()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** This function can be used to retrieve the whole client request's url.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        local url = ts.client_request.get_url()
+        print(url)
+    end
+
+Then ``GET /st?a=1&b=2 HTTP/1.1\r\nHost: a.tbcdn.cn\r\n...`` will yield the output:
+
+``http://a.tbcdn.cn/st?a=1&b=2``
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.header.HEADER
+-------------------------------
+**syntax:** *ts.client_request.header.HEADER = VALUE*
+
+**syntax:** *ts.client_request.header[HEADER] = VALUE*
+
+**syntax:** *VALUE = ts.client_request.header.HEADER*
+
+**context:** do_remap or do_global_* or later
+
+**description:** Set, add to, clear or get the current client request's HEADER.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        local ua = ts.client_request.header['User-Agent']
+        print(ua)
+        ts.client_request.header['Host'] = 'a.tbcdn.cn'
+    end
+
+Then ``GET /st HTTP/1.1\r\nHost: b.tb.cn\r\nUser-Agent: Mozilla/5.0\r\n...`` will yield the output:
+
+``Mozilla/5.0``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.get_headers
+-----------------------------
+**syntax:** *ts.client_request.get_headers()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** Returns a Lua table holding all the headers for the current client request.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        hdrs = ts.client_request.get_headers()
+        for k, v in pairs(hdrs) do
+            print(k..': '..v)
+        end
+    end
+
+Then ``GET /st HTTP/1.1\r\nHost: b.tb.cn\r\nUser-Aget: Mozilla/5.0\r\nAccept: */*`` will yield the output ::
+
+    Host: b.tb.cn
+    User-Agent: Mozilla/5.0
+    Accept: */*
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.client_addr.get_addr
+--------------------------------------
+**syntax:** *ts.client_request.client_addr.get_addr()*
+
+**context:** do_remap or do_global_* or later
+
+**description**: This function can be used to get socket address of the client.
+
+The ts.client_request.client_addr.get_addr function returns three values, ip is a string, port and family is number. 
+
+Here is an example:
+
+::
+
+    function do_remap()
+        ip, port, family = ts.client_request.client_addr.get_addr()
+        print(ip)               -- 192.168.231.17
+        print(port)             -- 17786
+        print(family)           -- 2(AF_INET)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.client_addr.get_incoming_port
+-----------------------------------------------
+**syntax:** *ts.client_request.client_addr.get_incoming_port()*
+
+**context:** do_remap or do_global_* or later
+
+**description**: This function can be used to get incoming port of the request.
+
+The ts.client_request.client_addr.get_incoming_port function returns incoming port as number.
+
+Here is an example:
+
+::
+
+    function do_global_read_request()
+        port = ts.client_request.client_addr.get_incoming_port()
+        print(port)             -- 80
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.get_url_host
+------------------------------
+**syntax:** *host = ts.client_request.get_url_host()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** Return the ``host`` field of the request url.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        local url_host = ts.client_request.get_url_host()
+        print(url_host)
+    end
+
+Then ``GET /liuyurou.txt HTTP/1.1\r\nHost: 192.168.231.129:8080\r\n...`` will yield the output:
+
+``192.168.231.129``
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.set_url_host
+------------------------------
+**syntax:** *ts.client_request.set_url_host(str)*
+
+**context:** do_remap or do_global_* 
+
+**description:** Set ``host`` field of the request url with ``str``. This function is used to change the address of the
+origin server, and we should return TS_LUA_REMAP_DID_REMAP(_STOP) in do_remap.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        ts.client_request.set_url_host('192.168.231.130')
+        ts.client_request.set_url_port(80)
+        ts.client_request.set_url_scheme('http')
+        return TS_LUA_REMAP_DID_REMAP
+    end
+
+remap.config like this:
+
+::
+
+    map http://192.168.231.129:8080/ http://192.168.231.129:9999/
+
+Then server request will connect to ``192.168.231.130:80``
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.get_url_port
+------------------------------
+**syntax:** *port = ts.client_request.get_url_port()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** Returns the ``port`` field of the request url as a Lua number.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        local url_port = ts.client_request.get_url_port()
+        print(url_port)
+    end
+
+Then Then ``GET /liuyurou.txt HTTP/1.1\r\nHost: 192.168.231.129:8080\r\n...`` will yield the output:
+
+``8080``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.set_url_port
+------------------------------
+**syntax:** *ts.client_request.set_url_port(NUMBER)*
+
+**context:** do_remap or do_global_*
+
+**description:** Set ``port`` field of the request url with ``NUMBER``. This function is used to change the address of
+the origin server, and we should return TS_LUA_REMAP_DID_REMAP(_STOP) in do_remap.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.get_url_scheme
+--------------------------------
+**syntax:** *scheme = ts.client_request.get_url_scheme()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** Return the ``scheme`` field of the request url.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        local url_scheme = ts.client_request.get_url_scheme()
+        print(url_scheme)
+    end
+
+Then ``GET /liuyurou.txt HTTP/1.1\r\nHost: 192.168.231.129:8080\r\n...`` will yield the output:
+
+``http``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_request.set_url_scheme
+--------------------------------
+**syntax:** *ts.client_request.set_url_scheme(str)*
+
+**context:** do_remap or do_global_* 
+
+**description:** Set ``scheme`` field of the request url with ``str``. This function is used to change the scheme of the
+server request, and we should return TS_LUA_REMAP_DID_REMAP(_STOP) in do_remap.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.set_cache_url
+---------------------
+**syntax:** *ts.http.set_cache_url(KEY_URL)*
+
+**context:** do_remap or do_global_* 
+
+**description:** This function can be used to modify the cache key for the client request.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        ts.http.set_cache_url('http://a.tbcdn.cn/foo')
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.get_cache_lookup_url
+----------------------------
+**syntax:** *ts.http.get_cache_lookup_url()*
+
+**context:** do_global_cache_lookup_complete
+
+**description:** This function can be used to get the cache lookup url for the client request.
+
+Here is an example
+
+::
+
+    function cache_lookup()
+        ts.http.set_cache_lookup_url('http://bad.com/bad.html')
+        local cache = ts.http.get_cache_lookup_url()
+        ts.debug(cache)
+    end 
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.set_cache_lookup_url
+----------------------------
+**syntax:** *ts.http.set_cache_lookup_url()*
+
+**context:** do_global_cache_lookup_complete
+
+**description:** This function can be used to set the cache lookup url for the client request.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.set_server_resp_no_store
+--------------------------------
+**syntax:** *ts.http.set_server_resp_no_store(status)*
+
+**context:** do_global_read_response
+
+**description:** This function can be used to signal ATS to not store the response in cache
+
+Here is an example:
+
+::
+
+    function do_global_read_response()
+        ts.http.set_server_resp_no_store(1)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.set_resp
+----------------
+**syntax:** *ts.http.set_resp(CODE, BODY)*
+
+**context:** do_remap or do_global_*
+
+**description:** This function can be used to set response for the client with the CODE status and BODY string.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        ts.http.set_resp(403, "Document access failed :)\n")
+        return 0
+    end
+
+We will get the response like this:
+
+::
+
+    HTTP/1.1 403 Forbidden
+    Date: Thu, 20 Mar 2014 06:12:43 GMT
+    Connection: close
+    Server: ATS/5.0.0
+    Cache-Control: no-store
+    Content-Type: text/html
+    Content-Language: en
+    Content-Length: 27
+
+    Document access failed :)
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.get_cache_lookup_status
+-------------------------------
+**syntax:** *ts.http.get_cache_lookup_status()*
+
+**context:** function @ TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE hook point
+
+**description:** This function can be used to get cache lookup status.
+
+Here is an example:
+
+::
+
+    function cache_lookup()
+        local cache_status = ts.http.get_cache_lookup_status()
+        if cache_status == TS_LUA_CACHE_LOOKUP_HIT_FRESH then
+            print('hit')
+        else
+            print('not hit')
+        end
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.set_cache_lookup_status
+-------------------------------
+**syntax:** *ts.http.set_cache_lookup_status()*
+
+**context:** function after TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE hook point
+
+**description:** This function can be used to set cache lookup status.
+
+Here is an example:
+
+::
+
+    function cache_lookup()
+        local cache_status = ts.http.get_cache_lookup_status()
+        if cache_status == TS_LUA_CACHE_LOOKUP_HIT_FRESH then
+            print('hit')
+        else
+            print('not hit')
+        end
+        ts.http.set_cache_lookup_status(TS_LUA_CACHE_LOOKUP_MISS)
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+Http cache lookup status constants
+----------------------------------
+**context:** global
+
+::
+
+    TS_LUA_CACHE_LOOKUP_MISS (0)
+    TS_LUA_CACHE_LOOKUP_HIT_STALE (1)
+    TS_LUA_CACHE_LOOKUP_HIT_FRESH (2)
+    TS_LUA_CACHE_LOOKUP_SKIPPED (3)
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.cached_response.get_status
+-----------------------------
+**syntax:** *status = ts.cached_response.get_status()*
+
+**context:** function @ TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE hook point or later
+
+**description:** This function can be used to retrieve the status code of the cached response. A Lua number will be
+returned.
+
+Here is an example:
+
+::
+
+    function cache_lookup()
+        local cache_status = ts.http.get_cache_lookup_status()
+        if cache_status == TS_LUA_CACHE_LOOKUP_HIT_FRESH then
+            code = ts.cached_response.get_status()
+            print(code)         -- 200
+        end
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.cached_response.get_version
+------------------------------
+**syntax:** *ver = ts.cached_response.get_version()*
+
+**context:** function @ TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE hook point or later
+
+**description:** Return the http version string of the cached response.
+
+Current possible values are 1.0, 1.1, and 0.9.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.cached_response.header.HEADER
+--------------------------------
+**syntax:** *VALUE = ts.cached_response.header.HEADER*
+
+**syntax:** *VALUE = ts.cached_response.header[HEADER]*
+
+**context:** function @ TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE hook point or later
+
+**description:** get the current cached response's HEADER.
+
+Here is an example:
+
+::
+
+    function cache_lookup()
+        local status = ts.http.get_cache_lookup_status()
+        if status == TS_LUA_CACHE_LOOKUP_HIT_FRESH then
+            local ct = ts.cached_response.header['Content-Type']
+            print(ct)         -- text/plain
+        end
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.cached_response.get_headers
+------------------------------
+**syntax:** *ts.cached_response.get_headers()*
+
+**context:** function @ TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE hook point or later
+
+**description:** Returns a Lua table holding all the headers for the current cached response.
+
+Here is an example:
+
+::
+
+    function cache_lookup()
+        local status = ts.http.get_cache_lookup_status()
+        if status == TS_LUA_CACHE_LOOKUP_HIT_FRESH then
+            hdrs = ts.cached_response.get_headers()
+            for k, v in pairs(hdrs) do
+                print(k..': '..v)
+            end
+        end
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+        return 0
+    end
+
+We will get the output:
+
+::
+
+    Connection: keep-alive
+    Content-Type: text/plain
+    Date: Thu, 20 Mar 2014 06:12:20 GMT
+    Cache-Control: max-age=864000
+    Last-Modified: Sun, 19 May 2013 13:22:01 GMT
+    Accept-Ranges: bytes
+    Content-Length: 15
+    Server: ATS/5.0.0
+
+
+`TOP <#ts-lua-plugin>`_
+
+
+ts.server_request.get_uri
+-------------------------
+**syntax:** *ts.server_request.get_uri()*
+
+**context:** function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
+
+**description:** This function can be used to retrieve the server request's path.
+
+Here is an example:
+
+::
+
+    function send_request()
+        local uri = ts.server_request.get_uri()
+        print(uri)
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
+        return 0
+    end
+
+Then ``GET /am.txt?a=1`` will yield the output:
+
+``/am.txt``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.set_uri
+-------------------------
+**syntax:** *ts.server_request.set_uri(PATH)*
+
+**context:** function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point
+
+**description:** This function can be used to override the server request's path.
+
+The PATH argument must be a Lua string and starts with ``/``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.get_uri_args
+------------------------------
+**syntax:** *ts.server_request.get_uri_args()*
+
+**context:** function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
+
+**description:** This function can be used to retrieve the server request's query string.
+
+Here is an example:
+
+::
+
+    function send_request()
+        local query = ts.server_request.get_uri_args()
+        print(query)
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
+        return 0
+    end
+
+Then ``GET /st?a=1&b=2`` will yield the output:
+
+``a=1&b=2``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.set_uri_args
+------------------------------
+**syntax:** *ts.server_request.set_uri_args(QUERY_STRING)*
+
+**context:** function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point
+
+**description:** This function can be used to override the server request's query string.
+
+::
+
+    ts.server_request.set_uri_args('n=6&p=7')
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.header.HEADER
+-------------------------------
+**syntax:** *ts.server_request.header.HEADER = VALUE*
+
+**syntax:** *ts.server_request.header[HEADER] = VALUE*
+
+**syntax:** *VALUE = ts.server_request.header.HEADER*
+
+**context:** function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
+
+**description:** Set, add to, clear or get the current server request's HEADER.
+
+Here is an example:
+
+::
+
+    function send_request()
+        local ua = ts.server_request.header['User-Agent']
+        print(ua)
+        ts.server_request.header['Accept-Encoding'] = 'gzip'
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
+        return 0
+    end
+
+Then ``GET /st HTTP/1.1\r\nHost: b.tb.cn\r\nUser-Agent: Mozilla/5.0\r\n...`` will yield the output:
+
+``Mozilla/5.0``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.get_headers
+-----------------------------
+**syntax:** *ts.server_request.get_headers()*
+
+**context:** function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
+
+**description:** Returns a Lua table holding all the headers for the current server request.
+
+Here is an example:
+
+::
+
+    function send_request()
+        hdrs = ts.cached_response.get_headers()
+        for k, v in pairs(hdrs) do
+            print(k..': '..v)
+        end
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
+        return 0
+    end
+
+We will get the output:
+
+::
+
+    Host: b.tb.cn
+    User-Agent: curl/7.19.7
+    Accept: */*
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.server_addr.get_addr
+--------------------------------------
+**syntax:** *ts.server_request.server_addr.get_addr()*
+
+**context:** do_remap or do_global_* or later
+
+**description**: This function can be used to get socket address of the origin server.
+
+The ts.server_request.server_addr.get_addr function returns three values, ip is a string, port and family is number.
+
+Here is an example:
+
+::
+
+    function do_global_send_request()
+        ip, port, family = ts.server_request.server_addr.get_addr()
+        print(ip)               -- 192.168.231.17
+        print(port)             -- 80
+        print(family)           -- 2(AF_INET)
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.server_addr.get_ip
+------------------------------------
+**syntax:** *ts.server_request.server_addr.get_ip()*
+
+**context:** do_remap or do_global_* or later
+
+**description**: This function can be used to get ip address of the origin server.
+
+The ts.server_request.server_addr.get_ip function returns ip as a string.
+
+Here is an example:
+
+::
+
+    function do_global_send_request()
+        ip = ts.server_request.server_addr.get_ip()
+        print(ip)               -- 192.168.231.17
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.server_addr.get_port
+--------------------------------------
+**syntax:** *ts.server_request.server_addr.get_port()*
+
+**context:** do_remap or do_global_* or later
+
+**description**: This function can be used to get port of the origin server.
+
+The ts.server_request.server_addr.get_port function returns port as number.
+
+Here is an example:
+
+::
+
+    function do_global_send_request()
+        port = ts.server_request.server_addr.get_port()
+        print(port)             -- 80
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_request.server_addr.get_outgoing_port
+-----------------------------------------------
+**syntax:** *ts.server_request.server_addr.get_outgoing_port()*
+
+**context:** do_remap or do_global_* or later
+
+**description**: This function can be used to get outgoing port to the origin server.
+
+The ts.server_request.server_addr.get_outgoing_port function returns outgoing port as number.
+
+Here is an example:
+
+::
+
+    function do_global_send_request()
+        port = ts.server_request.server_addr.get_outgoing_port()
+        print(port)             -- 50880
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_response.get_status
+-----------------------------
+**syntax:** *status = ts.server_response.get_status()*
+
+**context:** function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point or later
+
+**description:** This function can be used to retrieve the status code of the origin server's response. A Lua number
+will be returned.
+
+Here is an example:
+
+::
+
+    function read_response()
+        local code = ts.server_response.get_status()
+        print(code)         -- 200
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_READ_RESPONSE_HDR, read_response)
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_'
+
+ts.server_response.set_status
+-----------------------------
+**syntax:** *ts.server_response.set_status(NUMBER)*
+
+**context:** function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point
+
+**description:** This function can be used to set the status code of the origin server's response.
+
+Here is an example:
+
+::
+
+    function read_response()
+        ts.server_response.set_status(404)
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_READ_RESPONSE_HDR, read_response)
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_'
+
+ts.server_response.get_version
+------------------------------
+**syntax:** *ver = ts.server_response.get_version()*
+
+**context:** function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point or later.
+
+**description:** Return the http version string of the server response.
+
+Current possible values are 1.0, 1.1, and 0.9.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_response.set_version
+------------------------------
+**syntax:** *ts.server_response.set_version(VERSION_STR)*
+
+**context:** function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point
+
+**description:** Set the http version of the server response with the VERSION_STR
+
+::
+
+    ts.server_response.set_version('1.0')
+
+`TOP <#ts-lua-plugin>`_
+
+ts.server_response.header.HEADER
+--------------------------------
+**syntax:** *ts.server_response.header.HEADER = VALUE*
+
+**syntax:** *ts.server_response.header[HEADER] = VALUE*
+
+**syntax:** *VALUE = ts.server_response.header.HEADER*
+
+**context:** function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point or later.
+
+**description:** Set, add to, clear or get the current server response's HEADER.
+
+Here is an example:
+
+::
+
+    function read_response()
+        local ct = ts.server_response.header['Content-Type']
+        print(ct)
+        ts.server_response.header['Cache-Control'] = 'max-age=14400'
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_READ_RESPONSE_HDR, read_response)
+        return 0
+    end
+
+We will get the output:
+
+``text/html``
+
+
+`TOP <#ts-lua-plugin>`_'
+
+ts.server_response.get_headers
+------------------------------
+**syntax:** *ts.server_response.get_headers()*
+
+**context:** function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point or later
+
+**description:** Returns a Lua table holding all the headers for the current server response.
+
+Here is an example:
+
+::
+
+    function read_response()
+        hdrs = ts.server_response.get_headers()
+        for k, v in pairs(hdrs) do
+            print(k..': '..v)
+        end
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_READ_RESPONSE_HDR, read_response)
+        return 0
+    end
+
+We will get the output:
+
+::
+
+    Server: nginx/1.5.9
+    Date: Tue, 18 Mar 2014 10:12:25 GMT
+    Content-Type: text/html
+    Content-Length: 555
+    Last-Modified: Mon, 19 Aug 2013 14:25:55 GMT
+    Connection: keep-alive
+    ETag: "52122af3-22b"
+    Cache-Control: max-age=14400
+    Accept-Ranges: bytes
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_response.get_status
+-----------------------------
+**syntax:** *status = ts.client_response.get_status()*
+
+**context:** function @ TS_LUA_HOOK_SEND_RESPONSE_HDR hook point
+
+**description:** This function can be used to retrieve the status code of the response to the client. A Lua number will
+be returned.
+
+Here is an example:
+
+::
+
+    function send_response()
+        local code = ts.client_response.get_status()
+        print(code)         -- 200
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_response.set_status
+-----------------------------
+**syntax:** *ts.client_response.set_status(NUMBER)*
+
+**context:** function @ TS_LUA_HOOK_SEND_RESPONSE_HDR hook point
+
+**description:** This function can be used to set the status code of the response to the client.
+
+Here is an example:
+
+::
+
+    function send_response()
+        ts.client_response.set_status(404)
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_response.get_version
+------------------------------
+**syntax:** *ver = ts.client_response.get_version()*
+
+**context:** function @ TS_LUA_HOOK_SEND_RESPONSE_HDR hook point.
+
+**description:** Return the http version string of the response to the client.
+
+Current possible values are 1.0, 1.1, and 0.9.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_response.set_version
+------------------------------
+**syntax:** *ts.client_response.set_version(VERSION_STR)*
+
+**context:** function @ TS_LUA_HOOK_SEND_RESPONSE_HDR hook point
+
+**description:** Set the http version of the response to the client with the VERSION_STR
+
+::
+
+    ts.client_response.set_version('1.0')
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_response.header.HEADER
+--------------------------------
+**syntax:** *ts.client_response.header.HEADER = VALUE*
+
+**syntax:** *ts.client_response.header[HEADER] = VALUE*
+
+**syntax:** *VALUE = ts.client_response.header.HEADER*
+
+**context:** function @ TS_LUA_HOOK_SEND_RESPONSE_HDR hook point.
+
+**description:** Set, add to, clear or get the current client response's HEADER.
+
+Here is an example:
+
+::
+
+    function send_response()
+        local ct = ts.client_response.header['Content-Type']
+        print(ct)
+        ts.client_response.header['Cache-Control'] = 'max-age=3600'
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+        return 0
+    end
+
+We will get the output:
+
+``text/html``
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_response.get_headers
+------------------------------
+**syntax:** *ts.client_response.get_headers()*
+
+**context:** function @ TS_LUA_HOOK_SEND_RESPONSE_HDR hook point.
+
+**description:** Returns a Lua table holding all the headers for the current client response.
+
+Here is an example:
+
+::
+
+    function send_response()
+        hdrs = ts.client_response.get_headers()
+        for k, v in pairs(hdrs) do
+            print(k..': '..v)
+        end
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+        return 0
+    end
+
+We will get the output:
+
+::
+
+    Server: ATS/5.0.0
+    Date: Tue, 18 Mar 2014 10:12:25 GMT
+    Content-Type: text/html
+    Transfer-Encoding: chunked
+    Last-Modified: Mon, 19 Aug 2013 14:25:55 GMT
+    Connection: keep-alive
+    Cache-Control: max-age=14400
+    Age: 2641
+    Accept-Ranges: bytes
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.client_response.set_error_resp
+---------------------------------
+**syntax:** *ts.client_response.set_error_resp(CODE, BODY)*
+
+**context:** function @ TS_LUA_HOOK_SEND_RESPONSE_HDR hook point.
+
+**description:** This function can be used to set the error response to the client.
+
+With this function we can jump to send error response to the client if exception exists, meanwhile we should return `-1`
+from the function where exception raises.
+
+Here is an example:
+
+::
+
+    function send_response()
+        ts.client_response.set_error_resp(404, 'bad luck :(\n')
+    end
+
+    function cache_lookup()
+        return -1
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+        return 0
+    end
+
+We will get the response like this:
+
+::
+
+    HTTP/1.1 404 Not Found
+    Date: Tue, 18 Mar 2014 11:16:00 GMT
+    Connection: keep-alive
+    Server: ATS/5.0.0
+    Content-Length: 12
+
+    bad luck :(
+
+
+`TOP <#ts-lua-plugin>`_
+
+Number constants
+----------------------
+**context:** global
+
+::
+
+    TS_LUA_INT64_MAX (9223372036854775808)
+    TS_LUA_INT64_MIN (-9223372036854775808L)
+
+These constants are usually used in transform handler.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.resp_cache_transformed
+------------------------------
+**syntax:** *ts.http.resp_cache_transformed(BOOL)*
+
+**context:** do_remap or do_global_* or later
+
+**description**: This function can be used to tell trafficserver whether to cache the transformed data.
+
+Here is an example:
+
+::
+
+    function upper_transform(data, eos)
+        return string.upper(data), eos
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)
+        ts.http.resp_cache_transformed(0)
+        return 0
+    end
+
+This function is usually called after we hook TS_LUA_RESPONSE_TRANSFORM.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.resp_cache_untransformed
+--------------------------------
+**syntax:** *ts.http.resp_cache_untransformed(BOOL)*
+
+**context:** do_remap or do_global_* or later
+
+**description**: This function can be used to tell trafficserver whether to cache the untransformed data.
+
+Here is an example:
+
+::
+
+    function upper_transform(data, eos)
+        return string.upper(data), eos
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)
+        ts.http.resp_cache_untransformed(1)
+        return 0
+    end
+
+This function is usually called after we hook TS_LUA_RESPONSE_TRANSFORM.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.resp_transform.get_upstream_bytes
+-----------------------------------------
+**syntax:** *ts.http.resp_transform.get_upstream_bytes()*
+
+**context:** transform handler
+
+**description**: This function can be used to retrive the total bytes to be received from the upstream. If we got
+chunked response body from origin server, TS_LUA_INT64_MAX will be returned.
+
+Here is an example:
+
+::
+
+    local APPEND_DATA = 'TAIL\n'
+
+    function append_transform(data, eos)
+        if ts.ctx['len_set'] == nil then
+            local sz = ts.http.resp_transform.get_upstream_bytes()
+            if sz ~= TS_LUA_INT64_MAX then
+                ts.http.resp_transform.set_downstream_bytes(sz + string.len(APPEND_DATA))
+            end
+
+            ts.ctx['len_set'] = true
+        end
+
+        if eos == 1 then
+            return data .. APPEND_DATA, eos
+        else
+            return data, eos
+        end
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_RESPONSE_TRANSFORM, append_transform)
+        ts.http.resp_cache_transformed(0)
+        ts.http.resp_cache_untransformed(1)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.resp_transform.set_downstream_bytes
+-------------------------------------------
+**syntax:** *ts.http.resp_transform.set_downstream_bytes(NUMBER)*
+
+**context:** transform handler
+
+**description**: This function can be used to set the total bytes to be sent to the downstream.
+
+Sometimes we want to set Content-Length header in client_response, and this function should be called before any real
+data is returned from the transform handler.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.skip_remapping_set
+--------------------------
+**syntax:** *ts.http.skip_remapping_set(BOOL)*
+
+**context:** do_global_read_request
+
+**description**: This function can be used to tell trafficserver to skip doing remapping
+
+Here is an example:
+
+::
+
+    function do_global_read_request()
+        ts.http.skip_remapping_set(1);
+        ts.client_request.header['Host'] = 'www.yahoo.com'
+        return 0
+    end
+
+This function is usually called in do_global_read_request function
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.is_internal_request
+---------------------------
+**syntax:** *ts.http.is_internal_request()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** This function can be used to tell is a request is internal or not
+
+Here is an example:
+
+::
+
+    function do_global_read_request()
+        local internal = ts.http.is_internal_request()
+        ts.debug(internal)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.transaction_count
+-------------------------
+**syntax:** *ts.http.transaction_count()*
+
+**context:** do_remap or do_global_* or later
+
+**description:** This function returns the number of transaction in this connection
+
+Here is an example
+
+::
+
+    function do_remap()
+        local count = ts.http.transaction_count()
+        ts.debug(tostring(count))
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.add_package_path
+-------------------
+**syntax:** *ts.add_package_path(lua-style-path-str)*
+
+**context:** init stage of the lua script
+
+**description:** Adds the Lua module search path used by scripts.
+
+The path string is in standard Lua path form.
+
+Here is an example:
+
+::
+
+    ts.add_package_path('/home/a/test/lua/pac/?.lua')
+    local nt = require("nt")
+    function do_remap()
+        print(nt.t9(7979))
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.add_package_cpath
+--------------------
+**syntax:** *ts.add_package_cpath(lua-style-cpath-str)*
+
+**context:** init stage of the lua script
+
+**description:** Adds the Lua C-module search path used by scripts.
+
+The cpath string is in standard Lua cpath form.
+
+Here is an example:
+
+::
+
+    ts.add_package_cpath('/home/a/test/c/module/?.so')
+    local ma = require("ma")
+    function do_remap()
+        print(ma.ft())
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+
+ts.md5
+------
+**syntax:** *digest = ts.md5(str)*
+
+**context:** global
+
+**description:** Returns the hexadecimal representation of the MD5 digest of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        uri = ts.client_request.get_uri()
+        print(uri)              -- /foo
+        print(ts.md5(uri))      -- 1effb2475fcfba4f9e8b8a1dbc8f3caf
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.md5_bin
+----------
+**syntax:** *digest = ts.md5_bin(str)*
+
+**context:** global
+
+**description:** Returns the binary form of the MD5 digest of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        uri = ts.client_request.get_uri()
+        bin = ts.md5_bin(uri)
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.sha1
+-------
+**syntax:** *digest = ts.sha1(str)*
+
+**context:** global
+
+**description:** Returns the hexadecimal representation of the SHA-1 digest of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        uri = ts.client_request.get_uri()
+        print(uri)              -- /foo
+        print(ts.sha1(uri))     -- 6dbd548cc03e44b8b44b6e68e56255ce4273ae49
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.sha1_bin
+-----------
+**syntax:** *digest = ts.sha1_bin(str)*
+
+**context:** global
+
+**description:** Returns the binary form of the SHA-1 digest of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        uri = ts.client_request.get_uri()
+        bin = ts.sha1_bin(uri)
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.base64_encode
+----------------
+**syntax:** *value = ts.base64_encode(str)*
+
+**context:** global
+
+**description:** Returns the base64 encoding of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        uri = ts.client_request.get_uri()
+        value = ts.base64_encode(uri)
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.base64_decode
+----------------
+**syntax:** *value = ts.base64_decode(str)*
+
+**context:** global
+
+**description:** Returns the base64 decoding of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        uri = ts.client_request.get_uri()
+        encoded_value = ts.base64_encode(uri)
+        decoded_value = ts.base64_decode(encoded_value)
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.escape_uri
+-------------
+**syntax:** *value = ts.escape_uri(str)*
+
+**context:** global
+
+**description:** Returns the uri-escaped value of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        test = '/some value/'
+        value = ts.escape_uri(test)
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.unescape_uri
+---------------
+**syntax:** *value = ts.unescape_uri(str)*
+
+**context:** global
+
+**description:** Returns the uri-unescaped value of the ``str`` argument.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        test = '/some value/'
+        escaped_value = ts.escape_uri(test)
+        unescaped_value = ts.unescape_uri(escaped_value)
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.fetch
+-----------
+**syntax:** *res = ts.fetch(url, table?)*
+
+**context:** after do_remap
+
+**description:** Issues a synchronous but still non-block http request with the ``url`` and the optional ``table``.
+
+Returns a Lua table with serveral slots (res.status, res.header, res.body, and res.truncated).
+
+``res.status`` holds the response status code.
+
+``res.header`` holds the response header table.
+
+``res.body`` holds the response body which may be truncated, you need to check res.truncated to see if the data is
+truncated. 
+
+Here is a basic example:
+
+::
+
+    function post_remap()
+        local url = string.format('http://%s/foo.txt', ts.ctx['host'])
+        local res = ts.fetch(url)
+        if res.status == 200 then
+            print(res.body)
+        end
+    end
+
+    function do_remap()
+        local inner = ts.http.is_internal_request()
+        if inner ~= 0 then
+            return 0
+        end
+        local host = ts.client_request.header['Host']
+        ts.ctx['host'] = host
+        ts.hook(TS_LUA_HOOK_POST_REMAP, post_remap)
+    end
+
+We can set the optional table with serveral members:
+
+``header`` holds the request header table.
+
+``method`` holds the request method. The default method is 'GET'.
+
+``cliaddr`` holds the request client address in ip:port form. The default cliaddr is '127.0.0.1:33333'
+
+Issuing a post request:
+
+::
+
+    res = ts.fetch('http://xx.com/foo', {method = 'POST', body = 'hello world'})
+
+`TOP <#ts-lua-plugin>`_
+
+ts.fetch_multi
+--------------
+**syntax:** *vec = ts.fetch_multi({{url, table?}, {url, table?}, ...})*
+
+**context:** after do_remap
+
+Just like `ts.fetch`, but supports multiple http requests running in parallel.
+
+This function will fetch all the urls specified by the input table and return a table which contain all the results in
+the same order.
+
+Here is an example:
+
+::
+
+    local vec = ts.fetch_multi({
+                    {'http://xx.com/slayer'},
+                    {'http://xx.com/am', {cliaddr = '192.168.1.19:35423'}},
+                    {'http://xx.com/naga', {method = 'POST', body = 'hello world'}},
+                })
+
+    for i = 1, #(vec) do
+        print(vec[i].status)
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+
+ts.http.intercept
+-----------------
+**syntax:** *ts.http.intercept(FUNCTION, param1?, param2?, ...)*
+
+**context:** do_remap or do_global_*
+
+**description:** Intercepts the client request and processes it in FUNCTION with optional params.
+
+We should construct the response for the client request, and the request will not be processed by other modules, like
+hostdb, cache, origin server...
+
+Intercept FUNCTION will be executed in a new lua_thread, so we can delivery optional params from old lua_thread to new
+lua_thread if needed.
+
+Here is an example:
+
+::
+
+    require 'os'
+
+    function send_data(dstr)
+        local nt = os.time()..' Zheng.\n'
+        local resp =  'HTTP/1.0 200 OK\r\n' ..
+                      'Server: ATS/3.2.0\r\n' ..
+                      'Content-Type: text/plain\r\n' ..
+                      'Content-Length: ' .. string.format('%d', string.len(nt)) .. '\r\n' ..
+                      'Last-Modified: ' .. os.date("%a, %d %b %Y %H:%M:%S GMT", os.time()) .. '\r\n' ..
+                      'Connection: keep-alive\r\n' ..
+                      'Cache-Control: max-age=7200\r\n' ..
+                      'Accept-Ranges: bytes\r\n\r\n' ..
+                      nt
+        print(dstr)
+        ts.say(resp)
+    end
+
+    function do_remap()
+        ts.http.intercept(send_data, 'hello world')
+        return 0
+    end
+
+Then we will get the response like this:
+
+::
+
+    HTTP/1.1 200 OK
+    Server: ATS/5.0.0
+    Content-Type: text/plain
+    Content-Length: 18
+    Last-Modified: Tue, 18 Mar 2014 08:23:12 GMT
+    Cache-Control: max-age=7200
+    Accept-Ranges: bytes
+    Date: Tue, 18 Mar 2014 12:23:12 GMT
+    Age: 0
+    Connection: keep-alive
+
+    1395145392 Zheng.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.server_intercept
+------------------------
+**syntax:** *ts.http.server_intercept(FUNCTION, param1?, param2?, ...)*
+
+**context:** do_remap or do_global_*
+
+**description:** Intercepts the server request and acts as the origin server.
+
+Just like ts.http.intercept, but this function will intercept the server request, and we can acts as the origin server
+in `FUNCTION`.
+
+Here is an example:
+
+::
+
+    require 'os'
+
+    function process_combo(host)
+        local url1 = string.format('http://%s/css/1.css', host)
+        local url2 = string.format('http://%s/css/2.css', host)
+        local url3 = string.format('http://%s/css/3.css', host)
+
+        local hdr = {
+            ['Host'] = host,
+            ['User-Agent'] = 'blur blur',
+        }
+
+        local ct = {
+            header = hdr,
+            method = 'GET'
+        }
+
+        local arr = ts.fetch_multi(
+                {
+                    {url1, ct},
+                    {url2, ct},
+                    {url3, ct},
+                })
+
+        local ctype = arr[1].header['Content-Type']
+        local body = arr[1].body .. arr[2].body .. arr[3].body
+
+        local resp =  'HTTP/1.1 200 OK\r\n' ..
+                      'Server: ATS/5.2.0\r\n' ..
+                      'Last-Modified: ' .. os.date("%a, %d %b %Y %H:%M:%S GMT", os.time()) .. '\r\n' ..
+                      'Cache-Control: max-age=7200\r\n' ..
+                      'Accept-Ranges: bytes\r\n' ..
+                      'Content-Type: ' .. ctype .. '\r\n' ..
+                      'Content-Length: ' .. string.format('%d', string.len(body)) .. '\r\n\r\n' ..
+                      body
+
+        ts.say(resp)
+    end
+
+    function do_remap()
+        local inner =  ts.http.is_internal_request()
+        if inner ~= 0 then
+            return 0
+        end
+
+        local h = ts.client_request.header['Host']
+        ts.http.server_intercept(process_combo, h)
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.say
+------
+**syntax:** *ts.say(data)*
+
+**context:** *intercept or server_intercept*
+
+**description:** Write response to ATS within intercept or server_intercept.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.flush
+--------
+**syntax:** *ts.flush()*
+
+**context:** *intercept or server_intercept*
+
+**description:** Flushes the output to ATS within intercept or server_intercept.
+
+In synchronous mode, the function will not return until all output data has been written into the system send buffer.
+Note that using the Lua coroutine mechanism means that this function does not block the ATS event loop even in the
+synchronous mode.
+
+Here is an example:
+
+::
+
+    require 'os'
+
+    function send_data()
+        ss = 'wo ai yu ye hua\n'
+        local resp =  'HTTP/1.0 200 OK\r\n' ..
+                      'Server: ATS/3.2.0\r\n' ..
+                      'Content-Type: text/plain\r\n' ..
+                      'Content-Length: ' .. string.format('%d', 5*string.len(ss)) .. '\r\n' ..
+                      'Last-Modified: ' .. os.date("%a, %d %b %Y %H:%M:%S GMT", os.time()) .. '\r\n' ..
+                      'Connection: keep-alive\r\n' ..
+                      'Cache-Control: max-age=7200\r\n' ..
+                      'Accept-Ranges: bytes\r\n\r\n'
+        ts.say(resp)
+        for i=1, 5 do
+            ts.say(ss)
+            ts.flush()
+        end
+    end
+
+    function do_remap()
+        ts.http.intercept(send_data)
+        return 0
+    end
+
+We will get the response like this:
+
+::
+
+    HTTP/1.1 200 OK
+    Server: ATS/5.0.0
+    Content-Type: text/plain
+    Content-Length: 80
+    Last-Modified: Tue, 18 Mar 2014 08:38:29 GMT
+    Cache-Control: max-age=7200
+    Accept-Ranges: bytes
+    Date: Tue, 18 Mar 2014 12:38:29 GMT
+    Age: 0
+    Connection: keep-alive
+
+    wo ai yu ye hua
+    wo ai yu ye hua
+    wo ai yu ye hua
+    wo ai yu ye hua
+    wo ai yu ye hua
+
+`TOP <#ts-lua-plugin>`_
+
+ts.sleep
+--------
+**syntax:** *ts.sleep(sec)*
+
+**context:** *after do_remap*
+
+**description:** Sleeps for the specified seconds without blocking.
+
+Behind the scene, this method makes use of the ATS event model.
+
+Here is an example:
+
+::
+
+    function send_response()
+        ts.sleep(3)
+    end
+
+    function read_response()
+        ts.sleep(3)
+    end
+
+    function do_remap()
+        ts.hook(TS_LUA_HOOK_READ_RESPONSE_HDR, read_response)
+        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.config_int_get
+----------------------
+**syntax:** *val = ts.http.config_int_get(CONFIG)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** Configuration option which has a int value can be retrieved with this function.
+
+::
+
+    val = ts.http.config_int_get(TS_LUA_CONFIG_HTTP_CACHE_HTTP)
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.config_int_set
+----------------------
+**syntax:** *ts.http.config_int_set(CONFIG, NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to overwrite the configuration options.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        ts.http.config_int_set(TS_LUA_CONFIG_HTTP_CACHE_HTTP, 0)    -- bypass the cache processor
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.config_float_get
+------------------------
+**syntax:** *val = ts.http.config_float_get(CONFIG)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** Configuration option which has a float value can be retrieved with this function.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.config_float_set
+------------------------
+**syntax:** *ts.http.config_float_set(CONFIG, NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to overwrite the configuration options.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.config_string_get
+-------------------------
+**syntax:** *val = ts.http.config_string_get(CONFIG)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** Configuration option which has a string value can be retrieved with this function.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.config_string_set
+-------------------------
+**syntax:** *ts.http.config_string_set(CONFIG, NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to overwrite the configuration options.
+
+
+`TOP <#ts-lua-plugin>`_
+
+Http config constants
+---------------------
+**context:** do_remap or do_global_* or later
+
+::
+
+    TS_LUA_CONFIG_URL_REMAP_PRISTINE_HOST_HDR
+    TS_LUA_CONFIG_HTTP_CHUNKING_ENABLED
+    TS_LUA_CONFIG_HTTP_NEGATIVE_CACHING_ENABLED
+    TS_LUA_CONFIG_HTTP_NEGATIVE_CACHING_LIFETIME
+    TS_LUA_CONFIG_HTTP_CACHE_WHEN_TO_REVALIDATE
+    TS_LUA_CONFIG_HTTP_KEEP_ALIVE_ENABLED_IN
+    TS_LUA_CONFIG_HTTP_KEEP_ALIVE_ENABLED_OUT
+    TS_LUA_CONFIG_HTTP_KEEP_ALIVE_POST_OUT
+    TS_LUA_CONFIG_HTTP_SERVER_SESSION_SHARING_MATCH
+    TS_LUA_CONFIG_NET_SOCK_RECV_BUFFER_SIZE_OUT
+    TS_LUA_CONFIG_NET_SOCK_SEND_BUFFER_SIZE_OUT
+    TS_LUA_CONFIG_NET_SOCK_OPTION_FLAG_OUT
+    TS_LUA_CONFIG_HTTP_FORWARD_PROXY_AUTH_TO_PARENT
+    TS_LUA_CONFIG_HTTP_ANONYMIZE_REMOVE_FROM
+    TS_LUA_CONFIG_HTTP_ANONYMIZE_REMOVE_REFERER
+    TS_LUA_CONFIG_HTTP_ANONYMIZE_REMOVE_USER_AGENT
+    TS_LUA_CONFIG_HTTP_ANONYMIZE_REMOVE_COOKIE
+    TS_LUA_CONFIG_HTTP_ANONYMIZE_REMOVE_CLIENT_IP
+    TS_LUA_CONFIG_HTTP_ANONYMIZE_INSERT_CLIENT_IP
+    TS_LUA_CONFIG_HTTP_RESPONSE_SERVER_ENABLED
+    TS_LUA_CONFIG_HTTP_INSERT_SQUID_X_FORWARDED_FOR
+    TS_LUA_CONFIG_HTTP_SERVER_TCP_INIT_CWND
+    TS_LUA_CONFIG_HTTP_SEND_HTTP11_REQUESTS
+    TS_LUA_CONFIG_HTTP_CACHE_HTTP
+    TS_LUA_CONFIG_HTTP_CACHE_CLUSTER_CACHE_LOCAL
+    TS_LUA_CONFIG_HTTP_CACHE_IGNORE_CLIENT_NO_CACHE
+    TS_LUA_CONFIG_HTTP_CACHE_IGNORE_CLIENT_CC_MAX_AGE
+    TS_LUA_CONFIG_HTTP_CACHE_IMS_ON_CLIENT_NO_CACHE
+    TS_LUA_CONFIG_HTTP_CACHE_IGNORE_SERVER_NO_CACHE
+    TS_LUA_CONFIG_HTTP_CACHE_CACHE_RESPONSES_TO_COOKIES
+    TS_LUA_CONFIG_HTTP_CACHE_IGNORE_AUTHENTICATION
+    TS_LUA_CONFIG_HTTP_CACHE_CACHE_URLS_THAT_LOOK_DYNAMIC
+    TS_LUA_CONFIG_HTTP_CACHE_REQUIRED_HEADERS
+    TS_LUA_CONFIG_HTTP_INSERT_REQUEST_VIA_STR
+    TS_LUA_CONFIG_HTTP_INSERT_RESPONSE_VIA_STR
+    TS_LUA_CONFIG_HTTP_CACHE_HEURISTIC_MIN_LIFETIME
+    TS_LUA_CONFIG_HTTP_CACHE_HEURISTIC_MAX_LIFETIME
+    TS_LUA_CONFIG_HTTP_CACHE_GUARANTEED_MIN_LIFETIME
+    TS_LUA_CONFIG_HTTP_CACHE_GUARANTEED_MAX_LIFETIME
+    TS_LUA_CONFIG_HTTP_CACHE_MAX_STALE_AGE
+    TS_LUA_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_IN
+    TS_LUA_CONFIG_HTTP_KEEP_ALIVE_NO_ACTIVITY_TIMEOUT_OUT
+    TS_LUA_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_IN
+    TS_LUA_CONFIG_HTTP_TRANSACTION_NO_ACTIVITY_TIMEOUT_OUT
+    TS_LUA_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_OUT
+    TS_LUA_CONFIG_HTTP_ORIGIN_MAX_CONNECTIONS
+    TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES
+    TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES_DEAD_SERVER
+    TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_RR_RETRIES
+    TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_TIMEOUT
+    TS_LUA_CONFIG_HTTP_POST_CONNECT_ATTEMPTS_TIMEOUT
+    TS_LUA_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME
+    TS_LUA_CONFIG_HTTP_DOWN_SERVER_ABORT_THRESHOLD
+    TS_LUA_CONFIG_HTTP_CACHE_FUZZ_TIME
+    TS_LUA_CONFIG_HTTP_CACHE_FUZZ_MIN_TIME
+    TS_LUA_CONFIG_HTTP_DOC_IN_CACHE_SKIP_DNS
+    TS_LUA_CONFIG_HTTP_BACKGROUND_FILL_ACTIVE_TIMEOUT
+    TS_LUA_CONFIG_HTTP_RESPONSE_SERVER_STR
+    TS_LUA_CONFIG_HTTP_CACHE_HEURISTIC_LM_FACTOR
+    TS_LUA_CONFIG_HTTP_CACHE_FUZZ_PROBABILITY
+    TS_LUA_CONFIG_HTTP_BACKGROUND_FILL_COMPLETED_THRESHOLD
+    TS_LUA_CONFIG_NET_SOCK_PACKET_MARK_OUT
+    TS_LUA_CONFIG_NET_SOCK_PACKET_TOS_OUT
+    TS_LUA_CONFIG_HTTP_INSERT_AGE_IN_RESPONSE
+    TS_LUA_CONFIG_HTTP_CHUNKING_SIZE
+    TS_LUA_CONFIG_HTTP_FLOW_CONTROL_ENABLED
+    TS_LUA_CONFIG_HTTP_FLOW_CONTROL_LOW_WATER_MARK
+    TS_LUA_CONFIG_HTTP_FLOW_CONTROL_HIGH_WATER_MARK
+    TS_LUA_CONFIG_HTTP_CACHE_RANGE_LOOKUP
+    TS_LUA_CONFIG_HTTP_NORMALIZE_AE_GZIP
+    TS_LUA_CONFIG_HTTP_DEFAULT_BUFFER_SIZE
+    TS_LUA_CONFIG_HTTP_DEFAULT_BUFFER_WATER_MARK
+    TS_LUA_CONFIG_HTTP_REQUEST_HEADER_MAX_SIZE
+    TS_LUA_CONFIG_HTTP_RESPONSE_HEADER_MAX_SIZE
+    TS_LUA_CONFIG_HTTP_NEGATIVE_REVALIDATING_ENABLED
+    TS_LUA_CONFIG_HTTP_NEGATIVE_REVALIDATING_LIFETIME
+    TS_LUA_CONFIG_HTTP_ACCEPT_ENCODING_FILTER_ENABLED
+    TS_LUA_CONFIG_SSL_HSTS_MAX_AGE
+    TS_LUA_CONFIG_SSL_HSTS_INCLUDE_SUBDOMAINS
+    TS_LUA_CONFIG_HTTP_CACHE_OPEN_READ_RETRY_TIME
+    TS_LUA_CONFIG_HTTP_CACHE_MAX_OPEN_READ_RETRIES
+    TS_LUA_CONFIG_HTTP_CACHE_RANGE_WRITE
+    TS_LUA_CONFIG_HTTP_POST_CHECK_CONTENT_LENGTH_ENABLED
+    TS_LUA_CONFIG_HTTP_GLOBAL_USER_AGENT_HEADER
+    TS_LUA_CONFIG_HTTP_AUTH_SERVER_SESSION_PRIVATE
+    TS_LUA_CONFIG_HTTP_SLOW_LOG_THRESHOLD
+    TS_LUA_CONFIG_HTTP_CACHE_GENERATION
+    TS_LUA_CONFIG_BODY_FACTORY_TEMPLATE_BASE
+    TS_LUA_CONFIG_HTTP_CACHE_OPEN_WRITE_FAIL_ACTION
+    TS_LUA_CONFIG_HTTP_ENABLE_REDIRECTION
+    TS_LUA_CONFIG_HTTP_NUMBER_OF_REDIRECTIONS
+    TS_LUA_CONFIG_HTTP_CACHE_MAX_OPEN_WRITE_RETRIES
+    TS_LUA_CONFIG_LAST_ENTRY
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.timeout_set
+-------------------
+**syntax:** *ts.http.timeout_set(CONFIG, NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to overwrite the timeout settings.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        ts.http.timeout_set(TS_LUA_TIMEOUT_DNS, 30)    -- 30 seconds
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+Timeout constants
+-----------------
+**context:** do_remap or do_global_* or later
+
+::
+
+    TS_LUA_TIMEOUT_ACTIVE
+    TS_LUA_TIMEOUT_DNS
+    TS_LUA_TIMEOUT_CONNECT
+    TS_LUA_TIMEOUT_NO_ACTIVITY
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.client_packet_mark_set
+------------------------------
+**syntax:** *ts.http.client_packet_mark_set(NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to set packet mark for client connection.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        ts.http.client_packet_mark_set(0)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.server_packet_mark_set
+------------------------------
+**syntax:** *ts.http.server_packet_mark_set(NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to set packet mark for server connection.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.client_packet_tos_set
+-----------------------------
+**syntax:** *ts.http.client_packet_tos_set(NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to set packet tos for client connection.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.server_packet_tos_set
+-----------------------------
+**syntax:** *ts.http.server_packet_tos_set(NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to set packet tos for server connection.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.client_packet_dscp_set
+------------------------------
+**syntax:** *ts.http.client_packet_dscp_set(NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to set packet dscp for client connection.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.server_packet_dscp_set
+------------------------------
+**syntax:** *ts.http.server_packet_dscp_set(NUMBER)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to set packet dscp for server connection.
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.cntl_get
+----------------
+**syntax:** *val = ts.http.cntl_get(CNTL_TYPE)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to retireve the value of control channel.
+
+::
+
+    val = ts.http.cntl_get(TS_LUA_HTTP_CNTL_GET_LOGGING_MODE)
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.cntl_set
+----------------
+**syntax:** *ts.http.cntl_set(CNTL_TYPE, BOOL)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to set the value of control channel.
+
+Here is an example:
+
+::
+
+    function do_remap()
+        ts.http.cntl_set(TS_LUA_HTTP_CNTL_SET_LOGGING_MODE, 0)      -- do not log the request
+        return 0
+    end
+
+
+`TOP <#ts-lua-plugin>`_
+
+Http control channel constants
+------------------------------
+**context:** do_remap or do_global_* or later
+
+::
+
+    TS_LUA_HTTP_CNTL_GET_LOGGING_MODE
+    TS_LUA_HTTP_CNTL_SET_LOGGING_MODE
+    TS_LUA_HTTP_CNTL_GET_INTERCEPT_RETRY_MODE
+    TS_LUA_HTTP_CNTL_SET_INTERCEPT_RETRY_MODE
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.http.milestone_get
+---------------------
+**syntax:** *val = ts.http.milestone_get(MILESTONE_TYPE)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to retireve the various milestone times. They are how long the 
+transaction took to traverse portions of the HTTP state machine. Each milestone value is a fractional number 
+of seconds since the beginning of the transaction.
+
+::
+
+    val = ts.http.milestone_get(TS_LUA_MILESTONE_SM_START)
+
+`TOP <#ts-lua-plugin>`_
+
+Milestone constants
+------------------------------
+**context:** do_remap or do_global_* or later
+
+::
+
+    TS_LUA_MILESTONE_UA_BEGIN
+    TS_LUA_MILESTONE_UA_FIRST_READ
+    TS_LUA_MILESTONE_UA_READ_HEADER_DONE
+    TS_LUA_MILESTONE_UA_BEGIN_WRITE
+    TS_LUA_MILESTONE_UA_CLOSE
+    TS_LUA_MILESTONE_SERVER_FIRST_CONNECT
+    TS_LUA_MILESTONE_SERVER_CONNECT
+    TS_LUA_MILESTONE_SERVER_CONNECT_END
+    TS_LUA_MILESTONE_SERVER_BEGIN_WRITE
+    TS_LUA_MILESTONE_SERVER_FIRST_READ
+    TS_LUA_MILESTONE_SERVER_READ_HEADER_DONE
+    TS_LUA_MILESTONE_SERVER_CLOSE
+    TS_LUA_MILESTONE_CACHE_OPEN_READ_BEGIN
+    TS_LUA_MILESTONE_CACHE_OPEN_READ_END
+    TS_LUA_MILESTONE_CACHE_OPEN_WRITE_BEGIN
+    TS_LUA_MILESTONE_CACHE_OPEN_WRITE_END
+    TS_LUA_MILESTONE_DNS_LOOKUP_BEGIN
+    TS_LUA_MILESTONE_DNS_LOOKUP_END
+    TS_LUA_MILESTONE_SM_START
+    TS_LUA_MILESTONE_SM_FINISH
+    TS_LUA_MILESTONE_PLUGIN_ACTIVE
+    TS_LUA_MILESTONE_PLUGIN_TOTAL
+
+
+`TOP <#ts-lua-plugin>`_
+
+ts.mgmt.get_counter
+-------------------
+**syntax:** *val = ts.mgmt.get_counter(RECORD_NAME)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to retrieve the record value which has a counter type.
+
+::
+
+    n = ts.mgmt.get_counter('proxy.process.http.incoming_requests')
+
+`TOP <#ts-lua-plugin>`_
+
+ts.mgmt.get_int
+---------------
+**syntax:** *val = ts.mgmt.get_int(RECORD_NAME)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to retrieve the record value which has a int type.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.mgmt.get_float
+-----------------
+**syntax:** *val = ts.mgmt.get_float(RECORD_NAME)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to retrieve the record value which has a float type.
+
+`TOP <#ts-lua-plugin>`_
+
+ts.mgmt.get_string
+------------------
+**syntax:** *val = ts.mgmt.get_string(RECORD_NAME)*
+
+**context:** do_remap or do_global_* or later.
+
+**description:** This function can be used to retrieve the record value which has a string type.
+
+::
+
+    name = ts.mgmt.get_string('proxy.config.product_name')
+
+`TOP <#ts-lua-plugin>`_
+
+ts.stat_create
+--------------
+**syntax:** *val = ts.stat_create(STAT_NAME, RECORDDATA_TYPE, PERSISTENT, SYNC)*
+
+**context:** global
+
+**description:** This function can be used to create a statistics record given the name, data type, persistent 
+requirement, and sync requirement. A statistics record table will be created with 4 functions to increment, 
+decrement, get and set the value.
+
+:: 
+
+    stat:increment(value)
+    stat:decrement(value)
+    v = stat:get_value()
+    stat:set_value(value)
+
+Here is an example.
+
+::
+
+    local test_stat;
+
+    function __init__(args)
+        test_stat = ts.stat_create("test_stat", 
+          TS_LUA_RECORDDATATYPE_INT, 
+          TS_LUA_STAT_PERSISTENT, 
+          TS_LUA_STAT_SYNC_COUNT)
+    end
+
+    function do_global_read_request()
+        local value = test_stat:get_value()
+        ts.debug(value)
+        test_stat:increment(1)
+        return 0
+    end
+
+`TOP <#ts-lua-plugin>`_
+
+ts.stat_find
+------------
+**syntax:** *val = ts.stat_create(STAT_NAME)*
+
+**context:** global
+
+**description:** This function can be used to find a statistics record given the name. A statistics record table will 
+be returned with 4 functions to increment, decrement, get and set the value. That is similar to ts.stat_create()
+
+`TOP <#ts-lua-plugin>`_
+
+Todo
+====
+* ts.cache_xxx
+* protocol
+
+Currently when we use ts_lua as a global plugin, each global hook is using a separate lua state for the same
+transaction. This can be wasteful. Also the state cannot be reused for the same transaction across the global hooks. The
+alternative will be to use a TXN_START hook to create a lua state first and then add each global hook in the lua script
+as transaction hook instead. But this will have problem down the road when we need to have multiple plugins to work
+together in some proper orderings. In the future, we should consider different approach, such as creating and
+maintaining the lua state in the ATS core. 
+
+`TOP <#ts-lua-plugin>`_
+
+Notes on Unit Testing Lua scripts for ATS Lua Plugin
+====================================================
+Follow the steps below to use busted framework to run some unit tests on sample scripts and modules
+
+* Build and install lua 5.1.5 using the source code from here - http://www.lua.org/ftp/lua-5.1.tar.gz
+
+* Build and install luarocks 2.2.2 from here - https://github.com/keplerproject/luarocks/wiki/Download
+
+* Run "sudo luarocks install busted"
+
+* Run "sudo luarocks install luacov"
+
+* "cd trafficserver/plugins/experimental/ts_lua/ci"
+
+* Run "busted -c module_test.lua; luacov". It will produce "luacov.report.out" containing the code coverage for
+* "module.lua"
+
+* Run "busted -c script_test.lua; luacov". It will produce "luacov.report.out" containing the code coverage for
+* "script.lua"
+
+Reference for further information
+
+* Busted - http://olivinelabs.com/busted/
+
+* Specifications for asserts/mocks/stubs/etc inside busted framework - 
+https://github.com/Olivine-Labs/luassert/tree/master/spec 
+
+* luacov - https://luarocks.org/modules/hisham/luacov
+
+`TOP <#ts-lua-plugin>`_
+
+More docs
+=========
+
+* https://github.com/portl4t/ts-lua
+
+`TOP <#ts-lua-plugin>`_
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/admin-guide/plugins/xdebug.en.rst
----------------------------------------------------------------------
diff --git a/doc/admin-guide/plugins/xdebug.en.rst b/doc/admin-guide/plugins/xdebug.en.rst
new file mode 100644
index 0000000..6d43369
--- /dev/null
+++ b/doc/admin-guide/plugins/xdebug.en.rst
@@ -0,0 +1,83 @@
+.. _xdebug-plugin:
+
+XDebug 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 `XDebug` plugin allows HTTP clients to debug the operation of
+the Traffic Server cache using the default ``X-Debug`` header. The plugin
+is triggered by the presence of the ``X-Debug`` or the configured header in
+the client request. The contents of this header should be the names of the
+debug headers that are desired in the response. The `XDebug` plugin
+will remove the ``X-Debug`` header from the client request and
+inject the desired headers into the client response.
+
+`XDebug` is a global plugin. It is installed by adding it to the
+:file:`plugin.config` file. It currently takes a single, optional
+configuration option, ``--header``. E.g.
+
+    --header=ATS-My-Debug
+
+This overrides the default ``X-Debug`` header name.
+
+
+Debugging Headers
+=================
+
+The `XDebug` plugin is able to generate the following debugging headers:
+
+Via
+    If the ``Via`` header is requested, the `XDebug` plugin sets the
+    :ts:cv:`proxy.config.http.insert_response_via_str` configuration variable
+    to ``3`` for the request.
+
+Diags
+    If the ``Diags`` header is requested, the `XDebug` plugin enables the
+    transaction specific diagnostics for the transaction. This also requires
+    that :ts:cv:`proxy.config.diags.debug.enabled` is set to ``1``.
+
+X-Cache-Key
+    The ``X-Cache-Key`` header contains the URL that identifies the HTTP object in the
+    Traffic Server cache. This header is particularly useful if a custom cache
+    key is being used.
+
+X-Cache
+    The ``X-Cache`` header contains the results of any cache lookup.
+
+    ==========  ===========
+    Value       Description
+    ==========  ===========
+    none        No cache lookup was attempted.
+    miss        The object was not found in the cache.
+    hit-stale   The object was found in the cache, but it was stale.
+    hit-fresh   The object was fresh in the cache.
+    skipped     The cache lookup was skipped.
+    ==========  ===========
+
+X-Cache-Generation
+  The cache generation ID for this transaction, as specified by the
+  :ts:cv:`proxy.config.http.cache.generation` configuration variable.
+
+X-Milestones
+    The ``X-Milestones`` header contains detailed information about
+    how long the transaction took to traverse portions of the HTTP
+    state machine. The timing information is obtained from the
+    :c:func:`TSHttpTxnMilestoneGet` API. Each milestone value is a
+    fractional number of seconds since the beginning of the
+    transaction.