From 816e4ee49be6b7880087234dd1954b79321fd5ca Mon Sep 17 00:00:00 2001 From: Kit Chan Date: Tue, 25 Jan 2022 16:50:22 -0800 Subject: [PATCH 1/2] Additional helper functions for request transform --- doc/admin-guide/plugins/lua.en.rst | 88 +++++++++++++++++++++++++++-- example/plugins/lua-api/reqbody.lua | 10 ++++ plugins/lua/ts_lua_http.c | 54 ++++++++++++++++++ 3 files changed, 148 insertions(+), 4 deletions(-) diff --git a/doc/admin-guide/plugins/lua.en.rst b/doc/admin-guide/plugins/lua.en.rst index 81a305a1243..02b6421c25f 100644 --- a/doc/admin-guide/plugins/lua.en.rst +++ b/doc/admin-guide/plugins/lua.en.rst @@ -2804,7 +2804,7 @@ ts.http.resp_transform.get_upstream_bytes ----------------------------------------- **syntax:** *ts.http.resp_transform.get_upstream_bytes()* -**context:** transform handler +**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. @@ -2848,7 +2848,7 @@ ts.http.resp_transform.get_upstream_watermark_bytes --------------------------------------------------- **syntax:** *ts.http.resp_transform.get_upstream_watermark_bytes()* -**context:** transform handler +**context:** transform handler for response **description**: This function can be used to retrieve the current watermark bytes for the upstream transform buffer. @@ -2859,7 +2859,7 @@ ts.http.resp_transform.set_upstream_watermark_bytes --------------------------------------------------- **syntax:** *ts.http.resp_transform.set_upstream_watermark_bytes(NUMBER)* -**context:** transform handler +**context:** transform handler for response **description**: This function can be used to set the watermark bytes of the upstream transform buffer. @@ -2872,7 +2872,7 @@ ts.http.resp_transform.set_downstream_bytes ------------------------------------------- **syntax:** *ts.http.resp_transform.set_downstream_bytes(NUMBER)* -**context:** transform handler +**context:** transform handler for response **description**: This function can be used to set the total bytes to be sent to the downstream. @@ -2880,6 +2880,86 @@ Sometimes we want to set Content-Length header in client_response, and this func data is returned from the transform handler. +:ref:`TOP ` + +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. + +:ref:`TOP ` + +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. + + +:ref:`TOP ` + +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. + + +:ref:`TOP ` + +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. + + :ref:`TOP ` ts.http.skip_remapping_set diff --git a/example/plugins/lua-api/reqbody.lua b/example/plugins/lua-api/reqbody.lua index 13f87ad59f8..48bb511f4b6 100644 --- a/example/plugins/lua-api/reqbody.lua +++ b/example/plugins/lua-api/reqbody.lua @@ -17,6 +17,16 @@ function encrypt(data, eos) ts.ctx['reqbody'] = ts.ctx['reqbody'] .. data + if ts.ctx['len_set'] == nil then + ts.debug("len not set") + local sz = ts.http.req_transform.get_downstream_bytes() + ts.debug("len "..sz) + ts.http.req_transform.set_upstream_bytes(sz) + ts.ctx['len_set'] = true + end + + ts.debug("req transform got " .. string.len(data) .. "bytes, eos=" .. eos) + if (eos == 1) then ts.debug('End of Stream and the reqbody is ... ') ts.debug(ts.ctx['reqbody']) diff --git a/plugins/lua/ts_lua_http.c b/plugins/lua/ts_lua_http.c index 80ec27563a3..e0249bd1256 100644 --- a/plugins/lua/ts_lua_http.c +++ b/plugins/lua/ts_lua_http.c @@ -113,6 +113,12 @@ static int ts_lua_http_resp_transform_get_upstream_watermark_bytes(lua_State *L) static int ts_lua_http_resp_transform_set_upstream_watermark_bytes(lua_State *L); static int ts_lua_http_resp_transform_set_downstream_bytes(lua_State *L); +static void ts_lua_inject_http_req_transform_api(lua_State *L); +static int ts_lua_http_req_transform_get_downstream_bytes(lua_State *L); +static int ts_lua_http_req_transform_get_downstream_watermark_bytes(lua_State *L); +static int ts_lua_http_req_transform_set_downstream_watermark_bytes(lua_State *L); +static int ts_lua_http_req_transform_set_upstream_bytes(lua_State *L); + void ts_lua_inject_http_api(lua_State *L) { @@ -196,6 +202,11 @@ ts_lua_inject_http_transform_api(lua_State *L) lua_newtable(L); ts_lua_inject_http_resp_transform_api(L); lua_setfield(L, -2, "resp_transform"); + + /* ts.http.req_transform api */ + lua_newtable(L); + ts_lua_inject_http_req_transform_api(L); + lua_setfield(L, -2, "req_transform"); } static void @@ -214,6 +225,22 @@ ts_lua_inject_http_resp_transform_api(lua_State *L) lua_setfield(L, -2, "set_downstream_bytes"); } +static void +ts_lua_inject_http_req_transform_api(lua_State *L) +{ + lua_pushcfunction(L, ts_lua_http_req_transform_get_downstream_bytes); + lua_setfield(L, -2, "get_downstream_bytes"); + + lua_pushcfunction(L, ts_lua_http_req_transform_get_downstream_watermark_bytes); + lua_setfield(L, -2, "get_downstream_watermark_bytes"); + + lua_pushcfunction(L, ts_lua_http_req_transform_set_downstream_watermark_bytes); + lua_setfield(L, -2, "set_downstream_watermark_bytes"); + + lua_pushcfunction(L, ts_lua_http_req_transform_set_upstream_bytes); + lua_setfield(L, -2, "set_upstream_bytes"); +} + static void ts_lua_inject_http_misc_api(lua_State *L) { @@ -1010,3 +1037,30 @@ ts_lua_http_resp_transform_set_downstream_bytes(lua_State *L) return 0; } + +// Request transform are similar to response transform. It works against the transform context available. +// We can get the downstream bytes and set the upstream bytes. +// We can also get and set the downstream watermark as well. +static int +ts_lua_http_req_transform_get_downstream_bytes(lua_State *L) +{ + return ts_lua_http_resp_transform_get_upstream_bytes(L); +} + +static int +ts_lua_http_req_transform_get_downstream_watermark_bytes(lua_State *L) +{ + return ts_lua_http_resp_transform_get_upstream_watermark_bytes(L); +} + +static int +ts_lua_http_req_transform_set_downstream_watermark_bytes(lua_State *L) +{ + return ts_lua_http_resp_transform_set_upstream_watermark_bytes(L); +} + +static int +ts_lua_http_req_transform_set_upstream_bytes(lua_State *L) +{ + return ts_lua_http_resp_transform_set_downstream_bytes(L); +} From 65e04ba2c3f52b6f092ad9dd71424e131b23f534 Mon Sep 17 00:00:00 2001 From: Kit Chan Date: Fri, 4 Feb 2022 14:42:01 -0800 Subject: [PATCH 2/2] Update example --- example/plugins/lua-api/reqbody.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/example/plugins/lua-api/reqbody.lua b/example/plugins/lua-api/reqbody.lua index 48bb511f4b6..005032dedba 100644 --- a/example/plugins/lua-api/reqbody.lua +++ b/example/plugins/lua-api/reqbody.lua @@ -14,7 +14,10 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -function encrypt(data, eos) +-- This example illustrates how to do request body transform. +-- It stores the request body and prints it at the end of the transform. + +function request_transform(data, eos) ts.ctx['reqbody'] = ts.ctx['reqbody'] .. data if ts.ctx['len_set'] == nil then @@ -39,7 +42,7 @@ function do_remap() ts.debug('do_remap') if (ts.client_request.get_method() == 'POST') then ts.ctx['reqbody'] = '' - ts.hook(TS_LUA_REQUEST_TRANSFORM, encrypt) + ts.hook(TS_LUA_REQUEST_TRANSFORM, request_transform) end return 0