From acf2a1cce1b88fbaaeede78c3b984821af09aa1e Mon Sep 17 00:00:00 2001 From: bneradt Date: Thu, 7 May 2026 13:10:04 -0500 Subject: [PATCH] Fix combo paths with embedded colons Combo handler query parameters use a colon to select the bucket prefix, but asset paths can also contain colons. Requests with an embedded path colon were split at the last colon, producing the wrong internal fetch URL and failing instead of fetching the requested object. This keeps the first colon as the combo delimiter and leaves later colons in the asset path. This also adds an AuTest case with a neutral asset name so the parser regression is covered. --- plugins/esi/combo_handler.cc | 2 +- .../pluginTest/combo_handler/combo_handler.test.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/plugins/esi/combo_handler.cc b/plugins/esi/combo_handler.cc index 276d1bcd132..9ff34ccecf2 100644 --- a/plugins/esi/combo_handler.cc +++ b/plugins/esi/combo_handler.cc @@ -712,7 +712,7 @@ parseQueryParameters(const char *query, int query_len, ClientRequest &creq) } } param_start_pos = i + 1; - } else if (query[i] == ':') { + } else if ((query[i] == ':') && (colon_pos < param_start_pos)) { colon_pos = i; } } diff --git a/tests/gold_tests/pluginTest/combo_handler/combo_handler.test.py b/tests/gold_tests/pluginTest/combo_handler/combo_handler.test.py index 6cdcc5be7f9..711566a9b70 100644 --- a/tests/gold_tests/pluginTest/combo_handler/combo_handler.test.py +++ b/tests/gold_tests/pluginTest/combo_handler/combo_handler.test.py @@ -83,6 +83,7 @@ def add_server_obj(content_type, path): add_server_obj("text/javascript", "/sub/obj2") add_server_obj("text/argh", "/obj3") add_server_obj("application/javascript", "/obj4") +add_server_obj("application/javascript", "/s/assets/module:variant_v1.js") ts = Test.MakeATSProcess("ts") @@ -96,6 +97,7 @@ def add_server_obj(content_type, path): ts.Disk.remap_config.AddLine('map http://xyz/ http://127.0.0.1/ @plugin=combo_handler.so') ts.Disk.remap_config.AddLine(f'map http://localhost/127.0.0.1/ http://127.0.0.1:{server.Variables.Port}/') ts.Disk.remap_config.AddLine(f'map http://localhost/sub/ http://127.0.0.1:{server.Variables.Port}/sub/') +ts.Disk.remap_config.AddLine(f'map http://localhost/s/ http://127.0.0.1:{server.Variables.Port}/s/') # Configure the combo_handler's configuration file. ts.Setup.Copy("ctwl.txt", ts.Variables.CONFIGDIR) @@ -122,4 +124,14 @@ def add_server_obj(content_type, path): f = tr.Disk.File("_output/2-tr-Default/stream.all.txt") f.Content = "combo_handler_files/tr2.gold" +tr = Test.AddTestRun() +tr.Processes.Default.Command = tcp_client( + "127.0.0.1", ts.Variables.port, + "GET /admin/v1/combo?s:assets/module:variant_v1.js HTTP/1.1\n" + "Host: xyz\n" + "Connection: close\n" + "\n") +tr.Processes.Default.ReturnCode = 0 +f = tr.Disk.File("_output/3-tr-Default/stream.all.txt") +f.Content = Testers.ContainsExpression("HTTP/1.1 200 OK", "Should successfully combine an object with a colon in its path") +f.Content += Testers.ContainsExpression( + "Content for /s/assets/module:variant_v1.js", "Should fetch the object path after the first colon") + ts.Disk.diags_log.Content = Testers.ContainsExpression("ERROR", "Some tests are failure tests")