Lua Plugin
This module embeds Lua, via the LuaJIT engine (>2.0.4), into Apache Traffic Server™. 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.
Installation
This plugin is only built if LuaJIT (>2.0.4) is installed. The configure option
--with-luajit=<path to luajit prefix>
can be used to specify a LuaJIT install. Otherwise, configure will use pkg-config to find a viable installation.
Example Scripts
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
ts.debug(argtb[0] .. ' hostname parameter required!!')
return -1
end
HOSTNAME = argtb[1]
end
function do_remap()
ts.client_request.header['Host'] = HOSTNAME
return 0
end
test_global_hdr.lua
function send_response()
ts.client_response.header['Rhost'] = ts.ctx['rhost']
return 0
end
function do_global_read_request()
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)
end
Usage with Example Scripts
This module acts as remap plugin of Traffic Server, so we should realize ‘do_remap’ or ‘do_os_response’ function in each lua script. The path referencing a file with the lua script can be relative to the configuration directory or an absolute path. 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_vconn_start’
‘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’
We can write this in plugin.config:
tslua.so /etc/trafficserver/script/test_global_hdr.lua
Configuration for number of Lua states
We can also define the number of Lua states to be used for the plugin. If it is used as global plugin, we can write the following in plugin.config
tslua.so --states=64 /etc/trafficserver/script/test_global_hdr.lua
If it is used as remap plugin, we can write the following in remap.config to define the number of Lua states
map http://a.tbcdn.cn/ http://inner.tbcdn.cn/ @plugin=/XXX/tslua.so @pparam=--states=64 @pparam=/XXX/test_hdr.lua
The maximum number of allowed states is set to 256 which is also the default states value. The default value can be globally changed by adding a configuration option to records.config.
CONFIG proxy.config.plugin.lua.max_states INT 64
Any per plugin –states value overrides this default value but must be less than or equal to this value. This setting is not reloadable since it must be applied when all the lua states are first initialized.
For remap instances, the LuaJIT garbage collector can be set to be called automatically whenever a remap instance is created or deleted. This happens when the remap.config file has been modified, and the configuration has been reloaded. This does not apply to global plugin instances since these exist for the life-time of the ATS process, i.e., they are not reloadable or reconfigurable by modifying plugin.config while ATS is running.
By default, the LuaJIT garbage collector will run on its own according to its own internal criteria. However, in some cases, the garbage collector should be run in a guaranteed fashion.
For example, in Linux, total Lua memory may be limited to 2GB depending on the LuaJIT version. It may be required to release memory on demand in order to prevent out of memory errors when running close to the memory limit. Note that the memory usage is doubled during configuration reloads since the ATS must hold both the current and new configurations during the transition. If garbage collection occurs does not occur immediately, memory usage may exceed this double usage.
On demand garbage collection can be enabled by adding the following to each remap line. A value of ‘1’ means enabled. The default value of ‘0’ means disabled.
map http://a.tbcdn.cn/ http://inner.tbcdn.cn/ @plugin=/XXX/tslua.so @pparam=--ljgc=1
Configuration for JIT mode
We can also turn off JIT mode for LuaJIT when it is acting as global plugin for Traffic Server. The default is on (1). We can write this in plugin.config to turn off JIT
tslua.so --jit=0 /etc/trafficserver/script/test_global_hdr.lua
Profiling
The lua module collects runtime statistics about the lua states, for remap and global instances. Per state stats are constantly maintained and are made available through a lifecycle hook. These may be accessed through:
traffic_ctl plugin msg ts_lua stats_print
Sample output:
[Feb 5 19:00:15.072] ts_lua (remap) id: 0 gc_kb: 2508 gc_kb_max: 3491 threads: 417 threads_max: 438
[Feb 5 19:00:15.072] ts_lua (remap) id: 1 gc_kb: 1896 gc_kb_max: 3646 threads: 417 threads_max: 446
[Feb 5 19:00:15.072] ts_lua (remap) id: 2 gc_kb: 3376 gc_kb_max: 3740 threads: 417 threads_max: 442
Max values may be reset at any time by running:
traffic_ctl plugin msg ts_lua stats_reset
Summary statistics are aggregated every 5s and are available as metrics.
traffic_ctl metric match lua
Sample output:
plugin.lua.global.states 8
plugin.lua.remap.gc_bytes_min 4804608
plugin.lua.remap.gc_bytes_mean 5552537
plugin.lua.remap.gc_bytes_max 5779456
plugin.lua.remap.threads_min 31
plugin.lua.remap.threads_mean 44
plugin.lua.remap.threads_max 146
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)
ts.process.uuid
syntax: val = ts.process.uuid()
context: global
description: This function returns the global process id.
Here is an example:
local pid = ts.process.uuid() -- a436bae6-082c-4805-86af-78a5916c4a91
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. It includes milliseconds as the decimal part.
Here is an example:
local nt = ts.now() -- 1395221053.123
ts.debug
syntax: ts.debug(TAG?, MESSAGE)
context: global
description: Log the MESSAGE to traffic.out if debug TAG is enabled(the default TAG is ts_lua).
Here is an example:
ts.debug('I am in do_remap now.')
ts.debug("scw", "hello world")
We should write this TAG in records.config(If TAG is missing, default TAG will be set):
CONFIG proxy.config.diags.debug.tags STRING TAG
ts.is_debug_tag_set
syntax: ts.is_debug_tag_set(TAG?)
context: global
description: Returns ‘1’ if debug TAG is enabled(the default TAG is ts_lua).
Here is an example:
if ts.is_debug_tag_set() then
ts.debug("hello world")
end
ts.error
syntax: ts.error(MESSAGE)
context: global
description: Log the MESSAGE to error.log
Here is an example:
ts.error('This is an error message')
ts.fatal
syntax: ts.fatal(MESSAGE)
context: global
description: Log the MESSAGE to error.log and shutdown Traffic Server
Here is an example:
ts.fatal('This is an fatal message')
ts.emergency
syntax: ts.emergency(MESSAGE)
context: global
description: Log the MESSAGE to error.log and shutdown Traffic Server
Here is an example:
ts.emergency('This is an emergency message')
ts.status
syntax: ts.status(MESSAGE)
context: global
description: Log the MESSAGE to error.log as status
ts.note
syntax: ts.note(MESSAGE)
context: global
description: Log the MESSAGE to error.log as note
ts.warning
syntax: ts.warning(MESSAGE)
context: global
description: Log the MESSAGE to error.log as warning
ts.alert
syntax: ts.alert(MESSAGE)
context: global
description: Log the MESSAGE to error.log as alert
TS Basic Internal Information
syntax: ts.get_install_dir() syntax: ts.get_runtime_dir() syntax: ts.get_config_dir() syntax: ts.get_plugin_dir() syntax: ts.get_traffic_server_version()
context: global
description: get basic internal information for the TS instance, such as install directory, runtime directory, config directory, plugin directory and version of ATS
Here is an example:
local config_dir = ts.get_config_dir()
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.
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
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
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
ts.remap.get_to_uri
syntax: ts.remap.get_to_uri()
context: do_remap
description: retrieve the “to” path of the remap rule
ts.remap.get_to_url
syntax: ts.remap.get_to_url()
context: do_remap
description: retrieve the “to” url of the remap rule
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
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
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
ts.remap.get_from_uri
syntax: ts.remap.get_from_uri()
context: do_remap
description: retrieve the “from” path of the remap rule
ts.remap.get_from_url
syntax: ts.remap.get_from_url()
context: do_remap
description: retrieve the “from” url of the remap rule
ts.hook
syntax: ts.hook(HOOK_POINT, FUNCTION)
context: global or do_remap/do_os_response 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.
Hook point constants
TS_LUA_HOOK_VCONN_START
TS_LUA_HOOK_OS_DNS
TS_LUA_HOOK_PRE_REMAP
TS_LUA_HOOK_READ_CACHE_HDR
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.
Additional Information:
Hook Point |
Lua Hook Point constant |
Hook function be registered within do_remap() via ts.hook()? |
Hook function be registered within do_os_response() via ts.hook()? |
Hook function be registered within global context via ts.hook()? |
---|---|---|---|---|
TS_VCONN_START_HOOK |
TS_LUA_HOOK_VCONN_START |
NO |
NO |
YES |
TS_HTTP_TXN _START_HOOK |
TS_LUA_HOOK _TXN_START |
NO |
NO |
YES |
TS_HTTP_READ _REQUEST_HDR_HOOK |
TS_LUA_HOOK _READ_REQUEST_HDR |
NO |
NO |
YES |
TS_HTTP_PRE _REMAP_HOOK |
TS_LUA_HOOK _PRE_REMAP |
NO |
NO |
YES |
TS_HTTP_POST _REMAP_HOOK |
TS_LUA_HOOK _POST_REMAP |
YES |
NO |
YES |
TS_HTTP_READ _CACHE_HDR_HOOK |
TS_LUA_HOOK _READ_CACHE_HDR |
YES |
NO |
YES |
TS_HTTP_OS _DNS_HOOK |
TS_LUA_HOOK _OS_DNS |
YES |
NO |
YES |
TS_HTTP_CACHE _LOOKUP_COMPLETE_HOOK |
TS_LUA_HOOK _CACHE_LOOKUP_COMPLETE |
YES |
NO |
YES |
TS_HTTP_SEND _REQUEST_HDR_HOOK |
TS_LUA_HOOK _SEND_REQUEST_HDR |
YES |
NO |
YES |
TS_HTTP_READ _RESPONSE_HDR_HOOK |
TS_LUA_HOOK _READ_RESPONSE_HDR |
YES |
YES |
YES |
TS_HTTP_SEND _RESPONSE_HDR_HOOK |
TS_LUA_HOOK _SEND_RESPONSE_HDR |
YES |
YES |
YES |
TS_HTTP_REQUEST _TRANSFORM_HOOK |
TS_LUA_REQUEST_TRANSFORM |
YES |
NO |
YES |
TS_HTTP_RESPONSE _TRANSFORM_HOOK |
TS_LUA_RESPONSE_TRANSFORM |
YES |
YES |
YES |
TS_HTTP_TXN _CLOSE_HOOK |
TS_LUA_HOOK_TXN_CLOSE |
YES |
YES |
YES |
ts.ctx
syntax: ts.ctx[KEY] = VALUE
syntax: VALUE = ts.ctx[KEY]
context: do_remap/do_os_response 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
...
ts.client_request.get_method
syntax: ts.client_request.get_method()
context: do_remap/do_os_response 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.
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/do_os_response 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.
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')
ts.client_request.get_uri
syntax: ts.client_request.get_uri()
context: do_remap/do_os_response 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()
ts.debug(uri)
end
Then GET /st?a=1
will yield the output:
/st
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 /
ts.client_request.get_uri_args
syntax: ts.client_request.get_uri_args()
context: do_remap/do_os_response 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()
ts.debug(query)
end
Then GET /st?a=1&b=2
will yield the output:
a=1&b=2
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')
ts.client_request.get_uri_params
syntax: ts.client_request.get_uri_params()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to retrieve the client request’s parameter string.
Here is an example:
function do_remap()
local query = ts.client_request.get_uri_params()
ts.debug(query)
end
Then GET /st;a=1
will yield the output:
a=1
ts.client_request.set_uri_params
syntax: ts.client_request.set_uri_params(PARAMETER_STRING)
context: do_remap or do_global_*
description: This function can be used to override the client request’s parameter string.
ts.client_request.set_uri_params('n=6')
ts.client_request.get_url
syntax: ts.client_request.get_url()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to retrieve the client request url (TSHttpTxnEffectiveUrlStringGet()
).
Here is an example:
function do_remap()
local url = ts.client_request.get_url()
ts.debug(url)
end
ts.client_request.get_pristine_url
syntax: ts.client_request.get_pristine_url()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to retrieve the client request pristine url.
Here is an example:
function do_remap()
local url = ts.client_request.get_pristine_url()
ts.debug(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
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/do_os_response 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']
ts.debug(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
ts.client_request.header_table
syntax: VALUE = ts.client_request.header_table[HEADER]
context: do_remap/do_os_response or do_global_* or later
description: get the current client request’s HEADER as a table.
ts.client_request.get_headers
syntax: ts.client_request.get_headers()
context: do_remap/do_os_response 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
ts.debug(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: */*
ts.client_request.client_addr.get_addr
syntax: ts.client_request.client_addr.get_addr()
context: do_remap/do_os_response 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()
ts.debug(ip) -- 192.168.231.17
ts.debug(port) -- 17786
ts.debug(family) -- 2(AF_INET)
return 0
end
ts.client_request.client_addr.get_incoming_port
syntax: ts.client_request.client_addr.get_incoming_port()
context: do_remap/do_os_response 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()
ts.debug(port) -- 80
end
ts.client_request.get_url_host
syntax: host = ts.client_request.get_url_host()
context: do_remap/do_os_response 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()
ts.debug(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
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
ts.client_request.get_url_port
syntax: port = ts.client_request.get_url_port()
context: do_remap/do_os_response 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()
ts.debug(url_port)
end
Then GET /liuyurou.txt HTTP/1.1\r\nHost: 192.168.231.129:8080\r\n...
will yield the output:
8080
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.
ts.client_request.get_url_scheme
syntax: scheme = ts.client_request.get_url_scheme()
context: do_remap/do_os_response 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()
ts.debug(url_scheme)
end
Then GET /liuyurou.txt HTTP/1.1\r\nHost: 192.168.231.129:8080\r\n...
will yield the output:
http
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.
ts.client_request.get_ssl_reused
syntax: ts.client_request.get_ssl_reused()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to know if the SSL session has been reused (1) or not (0)
Here is an example:
function do_global_read_request()
ssl_reused = ts.client_request.get_ssl_reused()
ts.debug(ssl_reused) -- 0
end
ts.client_request.get_ssl_protocol
syntax: ts.client_request.get_ssl_protocol()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to get the SSL protocol used to communicate with the client
Here is an example:
function do_global_read_request()
ssl_protocol = ts.client_request.get_ssl_protocol()
ts.debug(ssl_protocol) -- TLSv1.2
end
ts.client_request.get_ssl_cipher
syntax: ts.client_request.get_ssl_cipher()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to get the SSL cipher used to communicate with the client
Here is an example:
function do_global_read_request()
ssl_cipher = ts.client_request.get_ssl_cipher()
ts.debug(ssl_cipher) -- ECDHE-ECDSA-AES256-GCM-SHA384
end
ts.client_request.get_ssl_curve
syntax: ts.client_request.get_ssl_curve()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to get the SSL Elliptic curve used to communicate with the client
Here is an example:
function do_global_read_request()
ssl_curve = ts.client_request.get_ssl_curve()
ts.debug(ssl_curve) -- X25519
end
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
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
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.
ts.http.redo_cache_lookup
syntax: ts.http.redo_cache_lookup()
context: do_global_cache_lookup_complete
description: This function can be used to redo cache lookup with a different url.
ts.http.get_parent_proxy
syntax: ts.http.get_parent_proxy()
context: do_global_cache_lookup_complete
description: This function can be used to get the parent proxy host and port.
Here is an example
function cache_lookup()
ts.http.set_parent_proxy('test1.test.com', 1111)
host, port = ts.http.get_parent_proxy()
ts.debug(host)
ts.debug(port)
end
function do_remap()
ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
return 0
end
ts.http.set_parent_proxy
syntax: ts.http.set_parent_proxy()
context: do_global_cache_lookup_complete
description: This function can be used to set the parent proxy host and name.
ts.http.get_parent_selection_url
syntax: ts.http.get_parent_selection_url()
context: do_global_cache_lookup_complete
description: This function can be used to get the parent selection url for the client request.
Here is an example
function cache_lookup()
ts.http.set_parent_selection_url('http://bad.com/bad.html')
local cache = ts.http.get_parent_selection_url()
ts.debug(cache)
end
function do_remap()
ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
return 0
end
ts.http.set_parent_selection_url
syntax: ts.http.set_parent_selection_url()
context: do_global_cache_lookup_complete
description: This function can be used to set the parent selection url for the client request.
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
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 :)
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
ts.debug('hit')
else
ts.debug('not hit')
end
end
function do_remap()
ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
return 0
end
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
ts.debug('hit')
else
ts.debug('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
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)
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()
ts.debug(code) -- 200
end
end
function do_remap()
ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
return 0
end
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.
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']
ts.debug(ct) -- text/plain
end
end
function do_remap()
ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
return 0
end
ts.cached_response.header_table
syntax: VALUE = ts.cached_response.header_table[HEADER]
context: function @ TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE hook point or later
description: get the current cached response’s HEADER as a table.
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
ts.debug(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
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()
ts.debug(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
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 /
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()
ts.debug(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
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')
ts.server_request.get_uri_params
syntax: ts.server_request.get_uri_params()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
description: This function can be used to retrieve the server request’s parameter string.
Here is an example:
function send_request()
local query = ts.server_request.get_uri_params()
ts.debug(query)
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
return 0
end
Then GET /st;a=1
will yield the output:
a=1
ts.server_request.set_uri_params
syntax: ts.server_request.set_uri_params(PARAMETER_STRING)
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point
description: This function can be used to override the server request’s parameter string.
ts.server_request.set_uri_params('n=6')
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']
ts.debug(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
ts.server_request.header_table
syntax: VALUE = ts.server_request.header_table[HEADER]
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
description: get the current server request’s HEADER as a table.
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
ts.debug(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: */*
ts.server_request.server_addr.set_addr
syntax: ts.server_request.server_addr.set_addr()
context: no later than function @ TS_LUA_HOOK_OS_DNS hook point
description: This function can be used to set socket address of the origin server.
The ts.server_request.server_addr.set_addr function requires three inputs, ip is a string, port and family is number.
Here is an example:
function do_global_read_request()
ts.server_request.server_addr.set_addr("192.168.231.17", 80, TS_LUA_AF_INET)
end
Socket address family
context: global
TS_LUA_AF_INET (2)
TS_LUA_AF_INET6 (10)
ts.server_request.server_addr.get_addr
syntax: ts.server_request.server_addr.get_addr()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point 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()
ts.debug(ip) -- 192.168.231.17
ts.debug(port) -- 80
ts.debug(family) -- 2(AF_INET)
end
ts.server_request.server_addr.get_nexthop_addr
syntax: ts.server_request.server_addr.get_nexthop_addr()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
description: This function can be used to get socket address of the next hop to the origin server.
The ts.server_request.server_addr.get_nexthop_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_nexthop_addr()
ts.debug(ip) -- 192.168.231.17
ts.debug(port) -- 80
ts.debug(family) -- 2(AF_INET)
end
ts.server_request.server_addr.get_nexthop_name
syntax: ts.server_request.server_addr.get_nexthop_name()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
description: This function can be used to get the host name of the next hop to the origin server.
The ts.server_request.server_addr.get_nexthop_name function returns the name as a string.
Here is an example:
function do_global_send_request()
name = ts.server_request.server_addr.get_nexthop_name()
print(name) -- test
end
ts.server_request.server_addr.get_nexthop_port
syntax: ts.server_request.server_addr.get_nexthop_port()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
description: This function can be used to get the port name of the next hop to the origin server.
The ts.server_request.server_addr.get_nexthop_port function returns the port as an integer .
Here is an example:
function do_global_send_request()
port = ts.server_request.server_addr.get_nexthop_port()
print(name) -- test
end
ts.sha256
syntax: digest = ts.sha256(str)
context: global
description: Returns the hexadecimal representation of the SHA-256 digest of the str
argument.
Here is an example:
function do_remap()
uri = ts.client_request.get_uri()
print(uri)
print(ts.sha256(uri))
end
ts.sha256_bin
syntax: digest = ts.sha256_bin(str)
context: global
description: Returns the binary form of the SHA-256 digest of the str
argument.
Here is an example:
function do_remap()
uri = ts.client_request.get_uri()
bin = ts.sha256_bin(uri)
end
ts.hmac_md5
syntax: digest = ts.hmac_md5(key, str)
context: global
description: Returns the hexadecimal representation of the HMAC of the str
argument.
The message digest function used is MD5.
The key value used is contained in the key
argument. This should be a hexadecimal representation of the key value.
Here is an example:
function do_remap()
key = "012345"
uri = ts.client_request.get_uri()
print(uri)
print(ts.hmac_md5(key, uri))
end
ts.hmac_sha1
syntax: digest = ts.hmac_sha1(key, str)
context: global
description: Returns the hexadecimal representation of the HMAC of the str
argument.
The message digest function used is SHA-1.
The key value used is contained in the key
argument. This should be a hexadecimal representation of the key value.
Here is an example:
function do_remap()
key = "012345"
uri = ts.client_request.get_uri()
print(uri)
print(ts.hmac_sha1(key, uri))
end
ts.hmac_sha256
syntax: digest = ts.hmac_sha256(key, str)
context: global
description: Returns the hexadecimal representation of the HMAC of the str
argument.
The message digest function used is SHA-256.
The key value used is contained in the key
argument. This should be a hexadecimal representation of the key value.
Here is an example:
function do_remap()
key = "012345"
uri = ts.client_request.get_uri()
print(uri)
print(ts.hmac_sha256(key, uri))
end
ts.server_request.server_addr.get_ip
syntax: ts.server_request.server_addr.get_ip()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point 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()
ts.debug(ip) -- 192.168.231.17
end
ts.server_request.server_addr.get_port
syntax: ts.server_request.server_addr.get_port()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point 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()
ts.debug(port) -- 80
end
ts.server_request.server_addr.get_outgoing_port
syntax: ts.server_request.server_addr.get_outgoing_port()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point 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()
ts.debug(port) -- 50880
end
ts.server_request.server_addr.set_outgoing_addr
syntax: ts.server_request.server_addr.set_outgoing_addr()
context: earlier than or inside function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point
description: This function can be used to set outgoing socket address for the request to origin.
The ts.server_request.server_addr.set_outgoing_addr function requires three inputs, ip is a string, port and family is number.
Here is an example:
function do_global_send_request()
ts.server_request.server_addr.set_outgoing_addr("192.168.231.17", 80, TS_LUA_AF_INET)
end
ts.server_request.get_url_host
syntax: host = ts.server_request.get_url_host()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point
description: Return the host
field of the request url.
Here is an example:
function send_request()
local url_host = ts.server_request.get_url_host()
ts.debug(url_host)
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
return 0
end
Then GET http://abc.com/p2/a.txt HTTP/1.1
will yield the output:
abc.com
ts.server_request.set_url_host
syntax: ts.server_request.set_url_host(str)
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point
description: Set host
field of the request url with str
. This function is used to change the host name in the GET request to next tier
Here is an example:
function send_request()
ts.server_request.set_url_host("")
ts.server_request.set_url_scheme("")
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
return 0
end
The GET request like this:
+++++++++ Proxy's Request +++++++++
– State Machine Id: 5593
GET http://origin.com/dir1/a.txt HTTP/1.1
User-Agent: curl/7.29.0
Host: abc.com
Accept: /
Client-ip: 135.xx.xx.xx
X-Forwarded-For: 135.xx.xx.xx
Will be changed to:
+++++++++ Proxy's Request +++++++++
– State Machine Id: 5593
GET /dir1/a.txt HTTP/1.1
User-Agent: curl/7.29.0
Host: abc.com
Accept: /
Client-ip: 135.xx.xx.xx
X-Forwarded-For: 135.xx.xx.xx
ts.server_request.get_url_scheme
syntax: scheme = ts.server_request.get_url_scheme()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point
description: Return the scheme
field of the request url.
Here is an example:
function send_request()
local url_scheme = ts.server_request.get_url_scheme()
ts.debug(url_host)
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
return 0
end
Then GET /liuyurou.txt HTTP/1.1\r\nHost: 192.168.231.129:8080\r\n...
will yield the output:
http
ts.server_request.set_url_scheme
syntax: ts.server_request.set_url_scheme(str)
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point
description: Set scheme
field of the request url with str
. This function is used to change the scheme of the server request.
ts.server_request.get_method
syntax: ts.server_request.get_method()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
description: This function can be used to retrieve the current server request’s method name. String like “GET” or “POST” is returned.
Here is an example:
function send_request()
local method = ts.server_request.get_method()
ts.debug(method)
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
return 0
end
Then HEAD /
will yield the output:
HEAD
ts.server_request.set_method
syntax: ts.server_request.set_method()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later
description: This function can be used to override the current server request’s method with METHOD_NAME.
- ::
ts.server_request.set_method(‘HEAD’)
ts.server_request_get_version
syntax: ver = ts.server_request.get_version()
context: function @ TS_LUA_HOOK_SEND_REQUEST_HDR hook point or later.
description: Return the http version string of the server request.
Current possible values are 1.0, 1.1, and 0.9.
function send_request()
local version = ts.server_request.get_version()
ts.debug(version)
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_REQUEST_HDR, send_request)
return 0
end
ts.server_request.set_version
syntax: ts.server_request.set_version(VERSION_STR)
context: function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point
description: Set the http version of the server request with the VERSION_STR
ts.server_request.set_version('1.0')
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()
ts.debug(code) -- 200
end
function do_remap()
ts.hook(TS_LUA_HOOK_READ_RESPONSE_HDR, read_response)
return 0
end
TOP’
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.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.
ts.server_response.is_cacheable
syntax: can_cache = ts.server_response.is_cacheable()
context: function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point or later.
description: Return 1 if the server response can be cached, 0 otherwise.
ts.server_response.get_maxage
syntax: maxage = ts.server_response.get_maxage()
context: function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point or later.
description: Return the maximum age of the server response in seconds if specified by Cache-Control, -1 otherwise.
For example:
function debug_long_maxage()
maxage = ts.server_response.get_maxage()
if ts.server_response.is_cacheable() and maxage > 86400 then
ts.debug('Cacheable response with maxage=' .. maxage)
end
end
function do_remap()
ts.hook(TS_LUA_HOOK_READ_RESPONSE_HDR, debug_long_maxage)
return 0
end
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')
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']
ts.debug(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.server_response.header_table
syntax: VALUE = ts.server_response.header_table[HEADER]
context: function @ TS_LUA_HOOK_READ_RESPONSE_HDR hook point or later.
description: get the current server response’s HEADER as a table.
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
ts.debug(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
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()
ts.debug(code) -- 200
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
return 0
end
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
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.
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')
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']
ts.debug(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
ts.client_response.header_table
syntax: VALUE = ts.client_response.header_table[HEADER]
context: function @ TS_LUA_HOOK_SEND_RESPONSE_HDR hook point.
description: get the current client response’s HEADER as a table.
Here is an example:
function send_response()
local hdrs = ts.client_response.header_table['Set-Cookie'] or {}
for k, v in pairs(hdrs) do
ts.debug(k..': '..v)
end
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
return 0
end
If there are multiple ‘Set-Cookie’ response header, they will be printed as debug message.
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
ts.debug(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
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 :(
Number constants
context: global
TS_LUA_INT64_MAX (9223372036854775808)
TS_LUA_INT64_MIN (-9223372036854775808L)
These constants are usually used in transform handler.
ts.http.resp_cache_transformed
syntax: ts.http.resp_cache_transformed(BOOL)
context: do_remap/do_os_response 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.
ts.http.resp_cache_untransformed
syntax: ts.http.resp_cache_untransformed(BOOL)
context: do_remap/do_os_response 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.
ts.http.resp_transform.get_upstream_bytes
syntax: ts.http.resp_transform.get_upstream_bytes()
context: transform handler for response
description: This function can be used to retrieve 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
The above example also shows the use of eos passed as a parameter to transform function. It indicates the end of the data stream to the transform function.
ts.http.resp_transform.get_upstream_watermark_bytes
syntax: ts.http.resp_transform.get_upstream_watermark_bytes()
context: transform handler for response
description: This function can be used to retrieve the current watermark bytes for the upstream transform buffer.
ts.http.resp_transform.set_upstream_watermark_bytes
syntax: ts.http.resp_transform.set_upstream_watermark_bytes(NUMBER)
context: transform handler for response
description: This function can be used to set the watermark bytes of the upstream transform buffer.
Setting the watermark bytes above 32kb may improve the performance of the transform handler.
ts.http.resp_transform.set_downstream_bytes
syntax: ts.http.resp_transform.set_downstream_bytes(NUMBER)
context: transform handler for response
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.
ts.http.req_transform.get_downstream_bytes
syntax: ts.http.req_transform.get_downstream_bytes()
context: transform handler for request
description: This function can be used to retrieve the total bytes to be received from downstream.
Here is an example:
function transform_print(data, eos)
ts.ctx['reqbody'] = ts.ctx['reqbody'] .. data
if ts.ctx['len_set'] == nil then
local sz = ts.http.req_transform.get_downstream_bytes()
ts.http.req_transform.set_upstream_bytes(sz)
ts.ctx['len_set'] = true
end
if (eos == 1) then
ts.debug('End of Stream and the reqbody is ... ')
ts.debug(ts.ctx['reqbody'])
end
return data, eos
end
function do_remap()
if (ts.client_request.get_method() == 'POST') then
ts.ctx['reqbody'] = ''
ts.hook(TS_LUA_REQUEST_TRANSFORM, transform_print)
end
return 0
end
The above example also shows the use of eos passed as a parameter to transform function. It indicates the end of the data stream to the transform function.
ts.http.req_transform.get_downstream_watermark_bytes
syntax: ts.http.req_transform.get_downstream_watermark_bytes()
context: transform handler for request
description: This function can be used to retrieve the current watermark bytes for the downstream transform buffer.
ts.http.req_transform.set_downstream_watermark_bytes
syntax: ts.http.req_transform.set_downstream_watermark_bytes(NUMBER)
context: transform handler for request
description: This function can be used to set the watermark bytes of the downstream transform buffer.
Setting the watermark bytes above 32kb may improve the performance of the transform handler.
ts.http.req_transform.set_upstream_bytes
syntax: ts.http.req_transform.set_upstream_bytes(NUMBER)
context: transform handler for request
description: This function can be used to set the total bytes to be sent to the upstream.
This function should be called before any real data is returned from the transform handler.
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
ts.http.get_client_protocol_stack
syntax: ts.http.get_client_protocol_stack()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to get client protocol stack information
Here is an example:
function do_global_read_request()
local stack = {ts.http.get_client_protocol_stack()}
for k,v in pairs(stack) do
ts.debug(v)
end
return 0
end
ts.http.get_server_protocol_stack
syntax: ts.http.get_server_protocol_stack()
context: do_global_read_response or later
description: This function can be used to get server protocol stack information
Here is an example:
function do_global_read_response()
local stack = {ts.http.get_server_protocol_stack()}
for k,v in pairs(stack) do
ts.debug(v)
end
return 0
end
ts.http.server_push
syntax: ts.http.server_push()
context: do_remap/do_os_response or do_global_* or later
description: This function can do http/2 server push for the input url
Here is an example:
function do_global_read_request()
ts.http.server_push("https://test.com/test.js")
return 0
end
ts.http.is_websocket
syntax: ts.http.is_websocket()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to tell if the transaction is websocket
Here is an example:
function do_global_read_request()
local flag = ts.http.is_websocket()
ts.debug(flag)
return 0
end
ts.http.get_plugin_tag
syntax: ts.http.get_plugin_tag()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to get plugin tag of a transaction
Here is an example:
function do_global_read_request()
local tag = ts.http.get_plugin_tag() or ''
ts.debug(tag)
return 0
end
ts.http.id
syntax: ts.http.id()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to tell id of a transaction
Here is an example:
function do_global_read_request()
local id = ts.http.id()
ts.debug(id)
return 0
end
ts.http.ssn_id
syntax: ts.http.ssn_id()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to tell id of a client session
Here is an example:
function do_global_read_request()
local id = ts.http.ssn_id()
ts.debug(id)
return 0
end
ts.http.is_internal_request
syntax: ts.http.is_internal_request()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to tell if 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
ts.http.is_aborted
syntax: ts.http.is_aborted()
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to tell if a request is aborted or not
Here is an example:
function do_global_read_request()
local aborted = ts.http.is_aborted()
ts.debug(aborted)
return 0
end
ts.http.transaction_count
syntax: ts.http.transaction_count()
context: do_remap/do_os_response or do_global_* or later
description: This function returns the number of transaction in this client connection
Here is an example
function do_remap()
local count = ts.http.transaction_count()
ts.debug(tostring(count))
return 0
end
ts.http.server_transaction_count
syntax: ts.http.server_transaction_count()
context: do_remap/do_os_response or do_global_* or later
description: This function returns the number of transaction in this server connection
ts.http.redirect_url_set
syntax: ts.http.redirect_url_set()
context: do_remap/do_os_response or do_global_* or later
description: This function sets the redirect url and instructs the transaction to follow the redirection as response
Here is an example
function do_global_read_response()
ts.http.redirect_url_set('http://foo.com')
return 0
end
ts.http.get_server_state
syntax: ts.http.get_server_state()
context: do_remap/do_os_response or do_global_* or later
description: This function returns the current server state
Here is an example
function do_os_response()
local result = ts.http.get_server_state()
if result == TS_LUA_SRVSTATE_CONNECTION_ALIVE then
ts.debug('Alive')
end
end
Server state constants
context: global
TS_LUA_SRVSTATE_STATE_UNDEFINED (0)
TS_LUA_SRVSTATE_ACTIVE_TIMEOUT (1)
TS_LUA_SRVSTATE_BAD_INCOMING_RESPONSE (2)
TS_LUA_SRVSTATE_CONNECTION_ALIVE (3)
TS_LUA_SRVSTATE_CONNECTION_CLOSED (4)
TS_LUA_SRVSTATE_CONNECTION_ERROR (5)
TS_LUA_SRVSTATE_INACTIVE_TIMEOUT(6)
TS_LUA_SRVSTATE_OPEN_RAW_ERROR (7)
TS_LUA_SRVSTATE_PARSE_ERROR (8)
TS_LUA_SRVSTATE_TRANSACTION_COMPLETE (9)
TS_LUA_SRVSTATE_PARENT_RETRY (10)
ts.http.get_remap_from_url
syntax: ts.http.get_remap_from_url()
context: do_global_post_remap
description: This function can be used to get the from URL in the matching line in remap.config
.
Here is an example
function do_global_post_remap()
local from_url = ts.http.get_remap_from_url()
ts.debug(from_url)
end
ts.http.get_remap_to_url
syntax: ts.http.get_remap_to_url()
context: do_global_post_remap
description: This function can be used to get the to URL in the matching line in remap.config
.
Here is an example
function do_global_post_remap()
local to_url = ts.http.get_remap_to_url()
ts.debug(to_url)
end
ts.http.get_client_fd
syntax: ts.http.get_client_fd()
context: after do_global_read_request
description: This function can be used to get the client FD for the transaction.
Here is an example
function do_global_read_request()
local fd = ts.http.get_client_fd()
ts.debug(fd)
end
ts.http.get_server_fd
syntax: ts.http.get_server_fd()
context: after do_global_send_request
description: This function can be used to get the server (origin) FD for the transaction.
Here is an example
function do_global_send_request()
local fd = ts.http.get_server_fd()
ts.debug(fd)
end
ts.http.get_ssn_remote_addr
syntax: ts.http.get_ssn_remote_addr()
context: after do_global_read_reqest
description: This function can be used to get the remote address (IP, port, family) of the session.
ts.http.get_client_received_error
syntax: ts.http.get_client_received_error()
context: after do_global_txn_close
description: This function can be used to get the client received error from transaction.
Here is an example
function do_global_txn_close()
local class, code = ts.http.get_client_received_error()
ts.debug('txn_close: '..class)
ts.debug('txn_close: '..code)
end
ts.http.get_client_sent_error
syntax: ts.http.get_client_sent_error()
context: after do_global_txn_close
description: This function can be used to get the client sent error from transaction.
ts.http.get_server_received_error
syntax: ts.http.get_server_received_error()
context: after do_global_txn_close
description: This function can be used to get the server received error from transaction.
ts.http.get_server_sent_error
syntax: ts.http.get_server_sent_error()
context: after do_global_txn_close
description: This function can be used to get the server sent error from transaction.
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()
ts.debug(nt.t9(7979))
return 0
end
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()
ts.debug(ma.ft())
return 0
end
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()
ts.debug(uri) -- /foo
ts.debug(ts.md5(uri)) -- 1effb2475fcfba4f9e8b8a1dbc8f3caf
end
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
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()
ts.debug(uri) -- /foo
ts.debug(ts.sha1(uri)) -- 6dbd548cc03e44b8b44b6e68e56255ce4273ae49
end
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
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
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
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
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
ts.fetch
syntax: res = ts.fetch(url, table?)
context: hook point functions added 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 several 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
ts.debug(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 several 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'})
ts.fetch_multi
syntax: vec = ts.fetch_multi({{url, table?}, {url, table?}, …})
context: hook point functions added 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
ts.debug(vec[i].status)
end
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
ts.debug(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.
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
ts.say
syntax: ts.say(data)
context: intercept or server_intercept
description: Write response to ATS within intercept or server_intercept.
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
ts.sleep
syntax: ts.sleep(sec)
context: hook point functions added 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
ts.host_lookup
syntax: ts.host_lookup(hostname)
context: hook point functions added after do_remap
description: Look for ip address of the host name without blocking. Nil if address cannot be found.
Behind the scene, this method makes use of the ATS event model.
Here is an example:
function send_response()
local result = ts.host_lookup("www.xyz.com") -- ip address of www.xyz.com
end
function do_remap()
ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
end
ts.schedule
syntax: ts.schedule(THREAD_TYPE, sec, FUNCTION, param1?, param2?, …)
context: hook point functions added after do_remap
description: Schedule function to be run after specified seconds without blocking.
Behind the scene, this method makes use of the ATS event model.
Here is an example:
function schedule()
ts.debug('test schedule starts')
end
function cache_lookup()
ts.debug('cache-lookup')
ts.schedule(TS_LUA_THREAD_POOL_NET, 0, schedule)
return 0
end
function do_remap()
ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
end
ts.http.config_int_get
syntax: val = ts.http.config_int_get(CONFIG)
context: do_remap/do_os_response 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)
ts.http.config_int_set
syntax: ts.http.config_int_set(CONFIG, NUMBER)
context: do_remap/do_os_response 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
ts.http.config_float_get
syntax: val = ts.http.config_float_get(CONFIG)
context: do_remap/do_os_response or do_global_* or later
description: Configuration option which has a float value can be retrieved with this function.
ts.http.config_float_set
syntax: ts.http.config_float_set(CONFIG, NUMBER)
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to overwrite the configuration options.
ts.http.config_string_get
syntax: val = ts.http.config_string_get(CONFIG)
context: do_remap/do_os_response or do_global_* or later
description: Configuration option which has a string value can be retrieved with this function.
ts.http.config_string_set
syntax: ts.http.config_string_set(CONFIG, NUMBER)
context: do_remap/do_os_response or do_global_* or later
description: This function can be used to overwrite the configuration options.
Http config constants
context: do_remap/do_os_response 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_INSERT_FORWARDED
TS_LUA_CONFIG_HTTP_PROXY_PROTOCOL_OUT
TS_LUA_CONFIG_HTTP_SEND_HTTP11_REQUESTS
TS_LUA_CONFIG_HTTP_CACHE_HTTP
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_SERVER_MIN_KEEP_ALIVE_CONNS
TS_LUA_CONFIG_HTTP_PER_SERVER_CONNECTION_MAX
TS_LUA_CONFIG_HTTP_PER_SERVER_CONNECTION_MATCH
TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES
TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_MAX_RETRIES_DEAD_SERVER
TS_LUA_CONFIG_HTTP_CONNECT_DEAD_POLICY
TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_RR_RETRIES
TS_LUA_CONFIG_HTTP_CONNECT_ATTEMPTS_TIMEOUT
TS_LUA_CONFIG_HTTP_DOWN_SERVER_CACHE_TIME
TS_LUA_CONFIG_HTTP_DOWN_SERVER_ABORT_THRESHOLD
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_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_DROP_CHUNKED_TRAILERS
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
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_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_NUMBER_OF_REDIRECTIONS
TS_LUA_CONFIG_HTTP_CACHE_MAX_OPEN_WRITE_RETRIES
TS_LUA_CONFIG_HTTP_REDIRECT_USE_ORIG_CACHE_KEY
TS_LUA_CONFIG_HTTP_ATTACH_SERVER_SESSION_TO_CLIENT
TS_LUA_CONFIG_HTTP_MAX_PROXY_CYCLES
TS_LUA_CONFIG_WEBSOCKET_NO_ACTIVITY_TIMEOUT
TS_LUA_CONFIG_WEBSOCKET_ACTIVE_TIMEOUT
TS_LUA_CONFIG_HTTP_UNCACHEABLE_REQUESTS_BYPASS_PARENT
TS_LUA_CONFIG_HTTP_PARENT_PROXY_TOTAL_CONNECT_ATTEMPTS
TS_LUA_CONFIG_HTTP_TRANSACTION_ACTIVE_TIMEOUT_IN
TS_LUA_CONFIG_SRV_ENABLED
TS_LUA_CONFIG_HTTP_FORWARD_CONNECT_METHOD
TS_LUA_CONFIG_SSL_CERT_FILENAME
TS_LUA_CONFIG_SSL_CERT_FILEPATH
TS_LUA_CONFIG_PARENT_FAILURES_UPDATE_HOSTDB
TS_LUA_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_MISMATCH
TS_LUA_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_LANGUAGE_MISMATCH
TS_LUA_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_ENCODING_MISMATCH
TS_LUA_CONFIG_HTTP_CACHE_IGNORE_ACCEPT_CHARSET_MISMATCH
TS_LUA_CONFIG_HTTP_PARENT_PROXY_FAIL_THRESHOLD
TS_LUA_CONFIG_HTTP_PARENT_PROXY_RETRY_TIME
TS_LUA_CONFIG_HTTP_PER_PARENT_CONNECT_ATTEMPTS
TS_LUA_CONFIG_HTTP_ALLOW_MULTI_RANGE
TS_LUA_CONFIG_HTTP_REQUEST_BUFFER_ENABLED
TS_LUA_CONFIG_HTTP_ALLOW_HALF_OPEN
TS_LUA_CONFIG_SSL_CLIENT_VERIFY_SERVER_POLICY
TS_LUA_CONFIG_SSL_CLIENT_VERIFY_SERVER_PROPERTIES
TS_LUA_CONFIG_SSL_CLIENT_SNI_POLICY
TS_LUA_CONFIG_SSL_CLIENT_PRIVATE_KEY_FILENAME
TS_LUA_CONFIG_SSL_CLIENT_CA_CERT_FILENAME
TS_LUA_CONFIG_HTTP_HOST_RESOLUTION_PREFERENCE
TS_LUA_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX
TS_LUA_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK
TS_LUA_CONFIG_NET_SOCK_NOTSENT_LOWAT
TS_LUA_CONFIG_BODY_FACTORY_RESPONSE_SUPPRESSION_MODE
TS_LUA_CONFIG_LAST_ENTRY
ts.http.timeout_set
syntax: ts.http.timeout_set(CONFIG, NUMBER)
context: do_remap/do_os_response 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 ms
return 0
end
Timeout constants
context: do_remap/do_os_response or do_global_* or later
TS_LUA_TIMEOUT_ACTIVE
TS_LUA_TIMEOUT_DNS
TS_LUA_TIMEOUT_CONNECT
TS_LUA_TIMEOUT_NO_ACTIVITY
ts.http.client_packet_mark_set
syntax: ts.http.client_packet_mark_set(NUMBER)
context: do_remap/do_os_response 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
ts.http.server_packet_mark_set
syntax: ts.http.server_packet_mark_set(NUMBER)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to set packet mark for server connection.
ts.http.client_packet_tos_set
syntax: ts.http.client_packet_tos_set(NUMBER)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to set packet tos for client connection.
ts.http.server_packet_tos_set
syntax: ts.http.server_packet_tos_set(NUMBER)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to set packet tos for server connection.
ts.http.client_packet_dscp_set
syntax: ts.http.client_packet_dscp_set(NUMBER)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to set packet dscp for client connection.
ts.http.server_packet_dscp_set
syntax: ts.http.server_packet_dscp_set(NUMBER)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to set packet dscp for server connection.
ts.http.enable_redirect
syntax: ts.http.enable_redirect(NUMBER)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to make transaction follow redirect
Here is an example:
function do_remap()
ts.http.enable_redirect(1)
return 0
end
ts.http.set_debug
syntax: ts.http.set_debug(NUMBER)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to enable debug log for the transaction
Here is an example:
function do_remap()
ts.http.set_debug(1)
return 0
end
ts.http.cntl_get
syntax: val = ts.http.cntl_get(CNTL_TYPE)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to retrieve the value of various control mechanisms in HTTP transaction.
val = ts.http.cntl_get(TS_LUA_HTTP_CNTL_LOGGING_MODE)
ts.http.cntl_set
syntax: ts.http.cntl_set(CNTL_TYPE, BOOL)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to set the value of various control mechanisms in HTTP transaction.
Here is an example:
function do_remap()
ts.http.cntl_set(TS_LUA_HTTP_CNTL_LOGGING_MODE, 0) -- do not log the request
return 0
end
Http control mechanism constants
context: do_remap/do_os_response or do_global_* or later
TS_LUA_HTTP_CNTL_LOGGING_MODE
TS_LUA_HTTP_CNTL_INTERCEPT_RETRY_MODE
TS_LUA_HTTP_CNTL_RESPONSE_CACHEABLE
TS_LUA_HTTP_CNTL_REQUEST_CACHEABLE
TS_LUA_HTTP_CNTL_SERVER_NO_STORE
TS_LUA_HTTP_CNTL_TXN_DEBUG
TS_LUA_HTTP_CNTL_SKIP_REMAPPING
ts.http.milestone_get
syntax: val = ts.http.milestone_get(MILESTONE_TYPE)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to retrieve 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)
Milestone constants
context: do_remap/do_os_response 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
TS_LUA_MILESTONE_TLS_HANDSHAKE_START
TS_LUA_MILESTONE_TLS_HANDSHAKE_END
ts.http.txn_info_get
syntax: val = ts.http.txn_info_get(TXN_INFO_TYPE)
context: do_global_cache_lookup_complete
description: This function can be used to retrieve the various cache related info about a transaction.
val = ts.http.txn_info_get(TS_LUA_TXN_INFO_CACHE_HIT_RAM)
Txn Info constants
context: do_global_cache_lookup_complete
TS_LUA_TXN_INFO_CACHE_HIT_RAM
TS_LUA_TXN_INFO_CACHE_COMPRESSED_IN_RAM
TS_LUA_TXN_INFO_CACHE_HIT_RWW
TS_LUA_TXN_INFO_CACHE_OPEN_READ_TRIES
TS_LUA_TXN_INFO_CACHE_OPEN_WRITE_TRIES
TS_LUA_TXN_INFo_CACHE_VOLUME
ts.mgmt.get_counter
syntax: val = ts.mgmt.get_counter(RECORD_NAME)
context: do_remap/do_os_response 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')
ts.mgmt.get_int
syntax: val = ts.mgmt.get_int(RECORD_NAME)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to retrieve the record value which has a int type.
ts.mgmt.get_float
syntax: val = ts.mgmt.get_float(RECORD_NAME)
context: do_remap/do_os_response or do_global_* or later.
description: This function can be used to retrieve the record value which has a float type.
ts.mgmt.get_string
syntax: val = ts.mgmt.get_string(RECORD_NAME)
context: do_remap/do_os_response 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')
ts.mgmt.add_config_file
syntax: ts.mgmt.add_config_file(parent, filename)
context: do_remap/do_os_response or do_global_* or later.
description: This function invokes TSMgmtConfigFileAdd
API.
remap = ts.mgmt.get_string('proxy.config.url_remap.filename')
ts.mgmt.add_config_file(remap, '/etc/my.config')
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
ts.stat_find
syntax: val = ts.stat_find(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()
ts.vconn.get_fd
syntax: ts.vconn.get_fd()
context: do_global_vconn_start
description: This function can be used to get the file descriptor of the virtual connection.
ts.vconn.disable_h2
syntax: ts.vconn.disable_h2()
context: do_global_vconn_start
description: This function can be used to disable http/2 for the virtual connection.
ts.vconn.get_remote_addr
syntax: ts.vconn.get_remote_addr()
context: do_global_vconn_start
description: This function can be used to get the remote address (IP, port, family) of the virtual connection.
Todo
ts.cache_xxx
protocol
Currently when we use this 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.
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/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