ts-lua Plugin¶
Embed the Power of Lua into TrafficServer.
Status¶
This module is being tested under our production environment.
Version¶
ts-lua has not been released yet.
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
if req_host == nil then
return 0
end
ts.ctx['rhost'] = string.reverse(req_host)
ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
return 0
end
test_transform.lua
function upper_transform(data, eos)
if eos == 1 then
return string.upper(data)..'S.H.E.\n', eos
else
return string.upper(data), eos
end
end
function send_response()
ts.client_response.header['SHE'] = ts.ctx['tb']['she']
return 0
end
function do_remap()
local req_host = ts.client_request.header.Host
if req_host == nil then
return 0
end
ts.ctx['tb'] = {}
ts.ctx['tb']['she'] = 'wo ai yu ye hua'
ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)
ts.http.resp_cache_transformed(0)
ts.http.resp_cache_untransformed(1)
return 0
end
test_cache_lookup.lua
function send_response()
ts.client_response.header['Rhost'] = ts.ctx['rhost']
ts.client_response.header['CStatus'] = ts.ctx['cstatus']
end
function cache_lookup()
local cache_status = ts.http.get_cache_lookup_status()
ts.ctx['cstatus'] = cache_status
end
function do_remap()
local req_host = ts.client_request.header.Host
if req_host == nil then
return 0
end
ts.ctx['rhost'] = string.reverse(req_host)
ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
ts.hook(TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE, cache_lookup)
return 0
end
test_ret_403.lua
function send_response()
ts.client_response.header['Now'] = ts.now()
return 0
end
function do_remap()
local uri = ts.client_request.get_uri()
pos, len = string.find(uri, '/css/')
if pos ~= nil then
ts.http.set_resp(403, "Document access failed :)\n")
return 0
end
ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, send_response)
return 0
end
sethost.lua
HOSTNAME = ''
function __init__(argtb)
if (#argtb) < 1 then
print(argtb[0], 'hostname parameter required!!')
return -1
end
HOSTNAME = argtb[1]
end
function do_remap()
local req_host = ts.client_request.header.Host
if req_host == nil then
return 0
end
ts.client_request.header['Host'] = HOSTNAME
return 0
end
test_intercept.lua
require 'os'
function send_data()
local nt = os.time()..' Zheng.\n'
local resp = 'HTTP/1.1 200 OK\r\n' ..
'Server: ATS/3.2.0\r\n' ..
'Content-Type: text/plain\r\n' ..
'Content-Length: ' .. 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.sleep(1)
return resp
end
function do_remap()
ts.http.intercept(send_data)
return 0
end
test_server_intercept.lua
require 'os'
function send_data()
local nt = os.time()..'\n'
local resp = 'HTTP/1.1 200 OK\r\n' ..
'Server: ATS/3.2.0\r\n' ..
'Content-Type: text/plain\r\n' ..
'Content-Length: ' .. 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=30\r\n' ..
'Accept-Ranges: bytes\r\n\r\n' ..
nt
return resp
end
function do_remap()
ts.http.server_intercept(send_data)
return 0
end
Description¶
This module embeds Lua, via the standard Lua 5.1 interpreter, into Apache Traffic Server. 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=/usr/lib64/trafficserver/plugins/libtslua.so @pparam=/etc/trafficserver/script/test_hdr.lua
Sometimes we want to receive parameters and process them in the script, we should realize ‘__init__’ function in the lua script(sethost.lua is a reference), and we can write this in remap.config::
map http://a.tbcdn.cn/ http://inner.tbcdn.cn/ @plugin=/usr/lib64/trafficserver/plugins/libtslua.so @pparam=/etc/trafficserver/script/sethost.lua @pparam=img03.tbcdn.cn
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.
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::
function send_response()
ts.client_response.header['Now'] = ts.now()
return 0
end
ts.debug¶
syntax: ts.debug(MESSAGE)
context: global
description: Log the MESSAGE to traffic.out if debug is enabled.
Here is an example::
function do_remap()
ts.debug('I am in do_remap now.')
return 0
end
The debug tag is ts_lua and we should write this in records.config::
CONFIG proxy.config.diags.debug.tags STRING ts_lua
ts.hook¶
syntax: ts.hook(HOOK_POINT, FUNCTION)
context: do_remap 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
Hook point constants¶
context: do_remap or later
TS_LUA_HOOK_CACHE_LOOKUP_COMPLETE 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.
ts.ctx¶
syntax: ts.ctx[KEY]
context: do_remap 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['RR'] = 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
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 send_response()
ts.client_response.header['CStatus'] = ts.ctx['cstatus']
end
function cache_lookup()
local cache_status = ts.http.get_cache_lookup_status()
if cache_status == TS_LUA_CACHE_LOOKUP_HIT_FRESH:
ts.ctx['cstatus'] = 'hit'
else
ts.ctx['cstatus'] = 'not hit'
end
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
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.http.set_cache_url¶
syntax: ts.http.set_cache_url(KEY_URL)
context: do_remap
description: This function can be used to modify the cache key for the request.
Here is an example::
function do_remap()
ts.http.set_cache_url('http://127.0.0.1:8080/abc/')
return 0
end
ts.http.resp_cache_transformed¶
syntax: ts.http.resp_cache_transformed(BOOL)
context: do_remap 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)
if eos == 1 then
return string.upper(data)..'S.H.E.\n', eos
else
return string.upper(data), eos
end
end
function do_remap()
ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)
ts.http.resp_cache_transformed(0)
ts.http.resp_cache_untransformed(1)
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 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)
if eos == 1 then
return string.upper(data)..'S.H.E.\n', eos
else
return string.upper(data), eos
end
end
function do_remap()
ts.hook(TS_LUA_RESPONSE_TRANSFORM, upper_transform)
ts.http.resp_cache_transformed(0)
ts.http.resp_cache_untransformed(1)
return 0
end
This function is usually called after we hook TS_LUA_RESPONSE_TRANSFORM.
ts.client_request.client_addr.get_addr¶
syntax: ts.client_request.client_addr.get_addr()
context: do_remap or later
description: This function can be used to get socket address of the client.
Here is an example::
function do_remap
ip, port, family = ts.client_request.client_addr.get_addr()
return 0
end
The ts.client_request.client_addr.get_addr function returns three values, ip is a string, port and family is number.
ts.client_request.get_method¶
syntax: ts.client_request.get_method()
context: do_remap or later
description: This function can be used to retrieve the current request’s request method name. String like “GET” or “POST” is returned.
ts.client_request.set_method¶
syntax: ts.client_request.set_method(METHOD_NAME)
context: do_remap
description: This function can be used to override the current request’s request method with METHOD_NAME.
ts.client_request.get_url¶
syntax: ts.client_request.get_url()
context: do_remap or later
description: This function can be used to retrieve the whole request’s url.
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 request’s path.
ts.client_request.set_uri¶
syntax: ts.client_request.set_uri(PATH)
context: do_remap
description: This function can be used to override the request’s path.
ts.client_request.get_uri_args¶
syntax: ts.client_request.get_uri_args()
context: do_remap or later
description: This function can be used to retrieve the request’s query string.
ts.client_request.set_uri_args¶
syntax: ts.client_request.set_uri_args(QUERY_STRING)
context: do_remap
description: This function can be used to override the request’s query string.
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 later
description: Set, add to, clear or get the current request’s HEADER.
Here is an example::
function do_remap()
local req_host = ts.client_request.header.Host
ts.client_request.header['Host'] = 'a.tbcdn.cn'
end