This is an automated email from the ASF dual-hosted git repository. cmcfarlen pushed a commit to branch 10.0.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 2e4d641eb6973cc38052ec9d08aa6c6401ff614c Author: Brian Neradt <[email protected]> AuthorDate: Fri Apr 19 12:56:28 2024 -0500 tslua.so: handle unrecognized status codes (#11272) Update the set_error_resp API to handle setting HTTP response statuses that do not have a recognized reason string. (cherry picked from commit 9e14e07ccde05c758b1f8f60a07251a23211cca4) --- plugins/lua/ts_lua_client_response.cc | 7 +- .../pluginTest/lua/lua_set_error_response.test.py | 98 ++++++++++++++++++++++ .../pluginTest/lua/set_error_response.lua | 29 +++++++ .../pluginTest/lua/set_error_response.replay.yaml | 51 +++++++++++ 4 files changed, 184 insertions(+), 1 deletion(-) diff --git a/plugins/lua/ts_lua_client_response.cc b/plugins/lua/ts_lua_client_response.cc index 8b6bfdc160..82d68c4d50 100644 --- a/plugins/lua/ts_lua_client_response.cc +++ b/plugins/lua/ts_lua_client_response.cc @@ -480,7 +480,12 @@ ts_lua_client_response_set_error_resp(lua_State *L) status = luaL_checkinteger(L, 1); - reason = TSHttpHdrReasonLookup(TSHttpStatus(status)); + reason = TSHttpHdrReasonLookup(TSHttpStatus(status)); + if (reason == nullptr) { + // ATS core could not find a reason string for this status. Simply use an + // empty string for the reason. + reason = ""; + } reason_len = strlen(reason); TSHttpHdrStatusSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, TSHttpStatus(status)); diff --git a/tests/gold_tests/pluginTest/lua/lua_set_error_response.test.py b/tests/gold_tests/pluginTest/lua/lua_set_error_response.test.py new file mode 100644 index 0000000000..7408566ded --- /dev/null +++ b/tests/gold_tests/pluginTest/lua/lua_set_error_response.test.py @@ -0,0 +1,98 @@ +'''Verify ts.client_response.set_error_resp functionality.''' +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +Test.Summary = ''' +Test lua functionality +''' + +Test.SkipUnless(Condition.PluginExists('tslua.so'),) + + +class TestLuaSetErrorResponse: + '''Verify ts.client_response.set_error_resp functionality.''' + + replay_file: str = 'set_error_response.replay.yaml' + lua_script: str = 'set_error_response.lua' + + def __init__(self): + tr = Test.AddTestRun("Lua ts.client_response.set_error_resp") + self._configure_dns(tr) + self._configure_server(tr) + self._configure_ts(tr) + self._configure_client(tr) + + def _configure_dns(self, tr: 'TestRun') -> 'Process': + '''Configure the DNS server. + + :param tr: The test run to configure the DNS server in. + :return: The newly created DNS process. + ''' + dns = tr.MakeDNServer("dns", default='127.0.0.1') + self._dns = dns + return dns + + def _configure_server(self, tr: 'TestRun') -> 'Process': + '''Configure the origin server. + + :param tr: The test run to configure the server in. + :return: The newly created server process. + ''' + server = tr.AddVerifierServerProcess("server", self.replay_file) + self._server = server + return server + + def _configure_ts(self, tr: 'TestRun') -> 'Process': + '''Configure the ATS process. + + :param tr: The test run to configure the ATS process in. + :return: The newly created ATS process. + ''' + ts = tr.MakeATSProcess("ts", enable_cache=False) + self._ts = ts + ts.Setup.Copy(self.lua_script, ts.Variables.CONFIGDIR) + port = self._server.Variables.http_port + ts.Disk.remap_config.AddLine(f'map / http://backend.example.com:{port}/ @plugin=tslua.so @pparam={self.lua_script}') + ts.Disk.records_config.update( + { + 'proxy.config.diags.debug.enabled': 1, + 'proxy.config.diags.debug.tags': 'ts_lua|http', + 'proxy.config.dns.nameservers': f"127.0.0.1:{self._dns.Variables.Port}", + 'proxy.config.dns.resolv_conf': 'NULL' + }) + return ts + + def _configure_client(self, tr: 'TestRun') -> 'Process': + '''Configure the client process. + + :param tr: The test run to configure the client process in. + :return: The newly created client process. + ''' + port = self._ts.Variables.port + client = tr.AddVerifierClientProcess('client', self.replay_file, http_ports=[port]) + self._client = client + client.StartBefore(self._server) + client.StartBefore(self._dns) + client.StartBefore(self._ts) + client.Streams.All += Testers.ContainsExpression( + 'HTTP/1.1 418', 'The modified HTTP 418 response should be received by the client.') + client.Streams.All += Testers.ContainsExpression('bad luck', 'The modified HTTP response body should contain "bad luck".') + return client + + +TestLuaSetErrorResponse() diff --git a/tests/gold_tests/pluginTest/lua/set_error_response.lua b/tests/gold_tests/pluginTest/lua/set_error_response.lua new file mode 100644 index 0000000000..4bc84ac161 --- /dev/null +++ b/tests/gold_tests/pluginTest/lua/set_error_response.lua @@ -0,0 +1,29 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +function send_response() + ts.client_response.set_error_resp(418, 'bad luck :(') +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 diff --git a/tests/gold_tests/pluginTest/lua/set_error_response.replay.yaml b/tests/gold_tests/pluginTest/lua/set_error_response.replay.yaml new file mode 100644 index 0000000000..eb52c4e8c7 --- /dev/null +++ b/tests/gold_tests/pluginTest/lua/set_error_response.replay.yaml @@ -0,0 +1,51 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +meta: + version: '1.0' + +sessions: + +- transactions: + - client-request: + method: GET + url: /some/path/flower.jpeg + version: '1.1' + headers: + fields: + - [ Host, www.example.com ] + - [ Content-Type, image/jpeg ] + - [ Content-Length, '0' ] + - [ uuid, first-request ] + + server-response: + status: 200 + reason: OK + headers: + fields: + - [ Date, "Sat, 16 Mar 2019 03:11:36 GMT" ] + - [ Content-Type, image/jpeg ] + - [ Transfer-Encoding, chunked ] + - [ Connection, keep-alive ] + content: + size: 3432 + + # The lua script modifies the response to be a 418. + proxy-response: + status: 418 + content: + verify: {value: 'bad luck :(', as: equal} +
