From a8455a446409aedf4914f3a939d1ffeb9fda94b0 Mon Sep 17 00:00:00 2001 From: Mo Chen Date: Mon, 12 Sep 2022 14:17:38 -0500 Subject: [PATCH 1/4] s3_auth: accept longer config lines --- plugins/s3_auth/aws_auth_v4.cc | 28 ++----- plugins/s3_auth/aws_auth_v4.h | 18 ++++- plugins/s3_auth/s3_auth.cc | 42 ++++------- .../s3_auth/gold/s3_auth_parsing.gold | 17 +++++ .../s3_auth/gold/s3_auth_parsing_ts.gold | 5 ++ .../s3_auth/rules/v4-parse-test.conf | 29 +++++++ .../pluginTest/s3_auth/s3_auth_config.test.py | 75 +++++++++++++++++++ 7 files changed, 164 insertions(+), 50 deletions(-) create mode 100644 tests/gold_tests/pluginTest/s3_auth/gold/s3_auth_parsing.gold create mode 100644 tests/gold_tests/pluginTest/s3_auth/gold/s3_auth_parsing_ts.gold create mode 100644 tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.conf create mode 100644 tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py diff --git a/plugins/s3_auth/aws_auth_v4.cc b/plugins/s3_auth/aws_auth_v4.cc index 004c0b3935a..1ea4af04508 100644 --- a/plugins/s3_auth/aws_auth_v4.cc +++ b/plugins/s3_auth/aws_auth_v4.cc @@ -22,11 +22,12 @@ * @see aws_auth_v4.h */ -#include /* strlen() */ -#include /* stoi() */ -#include /* strftime(), time(), gmtime_r() */ -#include /* std::setw */ -#include /* std::stringstream */ +#include /* strlen() */ +#include /* stoi() */ +#include /* strftime(), time(), gmtime_r() */ +#include /* std::setw */ +#include /* std::stringstream */ +#include #include /* SHA(), sha256_Update(), SHA256_Final, etc. */ #include /* HMAC() */ @@ -204,23 +205,6 @@ trimWhiteSpacesAndSqueezeInnerSpaces(const char *in, size_t inLen) return out_str; } -/** - * @brief Trim white spaces from beginning and end. - * @returns trimmed string - */ -String -trimWhiteSpaces(const String &s) -{ - /* @todo do this better? */ - static const String whiteSpace = " \t\n\v\f\r"; - size_t start = s.find_first_not_of(whiteSpace); - if (String::npos == start) { - return String(); - } - size_t stop = s.find_last_not_of(whiteSpace); - return s.substr(start, stop - start + 1); -} - /* * Group of static inline helper function for less error prone parameter handling and unit test logging. */ diff --git a/plugins/s3_auth/aws_auth_v4.h b/plugins/s3_auth/aws_auth_v4.h index 865a199385f..1e590cc66af 100644 --- a/plugins/s3_auth/aws_auth_v4.h +++ b/plugins/s3_auth/aws_auth_v4.h @@ -67,7 +67,23 @@ static const String X_AMZ = "x-amz-"; static const String CONTENT_TYPE = "content-type"; static const String HOST = "host"; -String trimWhiteSpaces(const String &s); +/** + * @brief Trim white spaces from beginning and end. + * @returns trimmed string + */ +template +StringLike +trimWhiteSpaces(const StringLike &s) +{ + /* @todo do this better? */ + static const auto whiteSpace = " \t\n\v\f\r"; + size_t start = s.find_first_not_of(whiteSpace); + if (StringLike::npos == start) { + return StringLike(); + } + size_t stop = s.find_last_not_of(whiteSpace); + return s.substr(start, stop - start + 1); +} template void diff --git a/plugins/s3_auth/s3_auth.cc b/plugins/s3_auth/s3_auth.cc index df5c090779c..26e0087a015 100644 --- a/plugins/s3_auth/s3_auth.cc +++ b/plugins/s3_auth/s3_auth.cc @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -523,41 +525,29 @@ S3Config::parse_config(const std::string &config_fname) TSError("[%s] called without a config file, this is broken", PLUGIN_NAME); return false; } else { - char line[512]; // These are long lines ... - FILE *file = fopen(config_fname.c_str(), "r"); + std::ifstream file; + file.open(config_fname, std::ios_base::in); - if (nullptr == file) { + if (!file.is_open()) { TSError("[%s] unable to open %s", PLUGIN_NAME, config_fname.c_str()); return false; } - while (fgets(line, sizeof(line), file) != nullptr) { - char *pos1, *pos2; + for (std::string buf; std::getline(file, buf);) { + std::string_view line{buf}; - // Skip leading white spaces - pos1 = line; - while (*pos1 && isspace(*pos1)) { - ++pos1; - } - if (!*pos1 || ('#' == *pos1)) { - continue; - } + // Skip leading/trailing white spaces + const auto key_val = trimWhiteSpaces(line); - // Skip trailing white spaces - pos2 = pos1; - pos1 = pos2 + strlen(pos2) - 1; - while ((pos1 > pos2) && isspace(*pos1)) { - *(pos1--) = '\0'; - } - if (pos1 == pos2) { + // Skip empty or comment lines + if (key_val.length() == 0 || ('#' == key_val[0])) { continue; } // Identify the keys (and values if appropriate) - std::string key_val(pos2, pos1 - pos2 + 1); - size_t eq_pos = key_val.find_first_of("="); - std::string key_str = trimWhiteSpaces(key_val.substr(0, eq_pos == String::npos ? key_val.size() : eq_pos)); - std::string val_str = eq_pos == String::npos ? "" : trimWhiteSpaces(key_val.substr(eq_pos + 1, key_val.size())); + size_t eq_pos = key_val.find_first_of('='); + std::string key_str{trimWhiteSpaces(key_val.substr(0, eq_pos == std::string_view::npos ? key_val.size() : eq_pos))}; + std::string val_str{eq_pos == std::string_view::npos ? "" : trimWhiteSpaces(key_val.substr(eq_pos + 1, key_val.size()))}; if (key_str == "secret_key") { set_secret(val_str.c_str()); @@ -578,11 +568,9 @@ S3Config::parse_config(const std::string &config_fname) } else if (key_str == "expiration") { set_expiration(val_str.c_str()); } else { - // ToDo: warnings? + TSWarning("[%s] unknown config key: %s", PLUGIN_NAME, key_str.c_str()); } } - - fclose(file); } return true; diff --git a/tests/gold_tests/pluginTest/s3_auth/gold/s3_auth_parsing.gold b/tests/gold_tests/pluginTest/s3_auth/gold/s3_auth_parsing.gold new file mode 100644 index 00000000000..50a707eb2d3 --- /dev/null +++ b/tests/gold_tests/pluginTest/s3_auth/gold/s3_auth_parsing.gold @@ -0,0 +1,17 @@ +* Trying 127.0.0.1:``... +* Connected to 127.0.0.1 (127.0.0.1) port `` (#0) +> GET /s3-bucket HTTP/1.1 +> Host: www.example.com +> User-Agent: curl/`` +> Accept: */* +> +* Mark bundle as not supporting multiuse +< HTTP/1.1 200 OK +< Content-Length: 8 +< Date: `` +< Age: 0 +< Connection: keep-alive +< Server: `` +< +{ [8 bytes data] +* Connection #0 to host 127.0.0.1 left intact diff --git a/tests/gold_tests/pluginTest/s3_auth/gold/s3_auth_parsing_ts.gold b/tests/gold_tests/pluginTest/s3_auth/gold/s3_auth_parsing_ts.gold new file mode 100644 index 00000000000..d266d6a69e6 --- /dev/null +++ b/tests/gold_tests/pluginTest/s3_auth/gold/s3_auth_parsing_ts.gold @@ -0,0 +1,5 @@ +``DIAG: (s3_auth) New rule: access_key=1234567, virtual_host=no, version=4 +``DIAG: (s3_auth) Set the header x-amz-content-sha256: UNSIGNED-PAYLOAD +``DIAG: (s3_auth) Set the header x-amz-date: `` +``DIAG: (s3_auth) Set the header x-amz-security-token: hkMsi6/bfHyBKrSeM/H0hoXeyx8z1yZ/mJ0c+B/TqYx=tTJDjnQWtul38Z9iVJjeH1HB4VT2c=2o3yE3o=I9kmFs/lJDR85qWjB8e5asY/WbjyRpbAzmDipQpboIcYnUYg55bxrQFidV/q8gZa5A9MpR3n=op1C0lWjeBqcEJxpevNZxteSQTQfeGsi98Cdf+On=/SINVlKrNhMnmMsDOLMGx1YYt9d4UsRg1jtVrwxL4Vd/F7aHCZySAXKv+1rkhACR023wpa3dhp+xirGJxSO9LWwvcrTdM4xJo4RS8B40tGENOJ1NKixUJxwN/6og58Oft/u==uleR89Ja=7zszK2H7tX3DqmEYNvNDYQh/7VBRe5otghQtPwJzWpXAGk+Vme4hPPM5K6axH2LxipXzRiIV=oxNs0upKNu1FvuzbCQmkQdKQVmXl0344vngngrgN7wkEfrYtmKwICmpAS0cbW9jdSClgziVo4NaFc/hsIfok=4UA3hVtxIdw74lFNXD0RR7HKXkFPLIn85M7peOZsqMUCfO4gxr7KCfabszQQf0YcP/mt79XK50=WrSJG7oUyn+clUySPhlegqHAfT9a50uSK5WiQmOnGNGLF4wDO10sqKN1xRgQbYHPtwL+Ye0EMisvmYA3==kScorTSGaQWyibSWXAvxq9+IVGBYShVJ6S7DmTT=u/2d/fGEge+Xmbxlftza=cxJ=Md=k1Q71Lp6Boa56d7wtYRpK6tXHJ9I/2r7rN1E4OtwkFqb7SfWV3UXwyUrXyaaNPTIbqnAHnbgUGtuU6pgICpfREiIxVqvKBf6ErbxHRmMmAuYKxk5E9Mn6nnbxR4WTniweKYeDv2w39zge/tss+36Moeuio9d2eoyRFqXhq=rUGtDwX3fzXV0wV+dUojxOYQ57GQDl7+68PwHPcX794OIXuGOxBk83lNIYIcYz3Vc7qnGy6tFTz7f6S9+EZuSGN7TY5VKkT2eWye46DebrDF9Nwzs/FVpTzbPD/KGDIBtFIbazglhKoWe9txqb1QW8vFNNVOEhYa+cViO3g8ZmY1wG960US2zsnX5Eg8Q5a4h3+sxaJSJ4ONiXZWJuAgKRQzcrszu+M5C0ZVoCOv1goEgfNJeSm/yFc/3rx8wmeWLIJFtq65B7zF72HRKq1nthHAguaxXr20nguHpKkDpNBDVa=WwuJsbeGI +``DIAG: (s3_auth) Set the header Authorization: AWS4-HMAC-SHA256 Credential=``/us-east-1/s3/aws4_request,SignedHeaders=accept;client-ip;host;user-agent;x-amz-content-sha256;x-amz-date;x-amz-security-token,Signature=`` diff --git a/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.conf b/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.conf new file mode 100644 index 00000000000..b63c2480f97 --- /dev/null +++ b/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.conf @@ -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. + +# Test empty lines + +# Test space in front + access_key=1234567 + +# Test space behind +secret_key=9999999 + +# long line +session_token=hkMsi6/bfHyBKrSeM/H0hoXeyx8z1yZ/mJ0c+B/TqYx=tTJDjnQWtul38Z9iVJjeH1HB4VT2c=2o3yE3o=I9kmFs/lJDR85qWjB8e5asY/WbjyRpbAzmDipQpboIcYnUYg55bxrQFidV/q8gZa5A9MpR3n=op1C0lWjeBqcEJxpevNZxteSQTQfeGsi98Cdf+On=/SINVlKrNhMnmMsDOLMGx1YYt9d4UsRg1jtVrwxL4Vd/F7aHCZySAXKv+1rkhACR023wpa3dhp+xirGJxSO9LWwvcrTdM4xJo4RS8B40tGENOJ1NKixUJxwN/6og58Oft/u==uleR89Ja=7zszK2H7tX3DqmEYNvNDYQh/7VBRe5otghQtPwJzWpXAGk+Vme4hPPM5K6axH2LxipXzRiIV=oxNs0upKNu1FvuzbCQmkQdKQVmXl0344vngngrgN7wkEfrYtmKwICmpAS0cbW9jdSClgziVo4NaFc/hsIfok=4UA3hVtxIdw74lFNXD0RR7HKXkFPLIn85M7peOZsqMUCfO4gxr7KCfabszQQf0YcP/mt79XK50=WrSJG7oUyn+clUySPhlegqHAfT9a50uSK5WiQmOnGNGLF4wDO10sqKN1xRgQbYHPtwL+Ye0EMisvmYA3==kScorTSGaQWyibSWXAvxq9+IVGBYShVJ6S7DmTT=u/2d/fGEge+Xmbxlftza=cxJ=Md=k1Q71Lp6Boa56d7wtYRpK6tXHJ9I/2r7rN1E4OtwkFqb7SfWV3UXwyUrXyaaNPTIbqnAHnbgUGtuU6pgICpfREiIxVqvKBf6ErbxHRmMmAuYKxk5E9Mn6nnbxR4WTniweKYeDv2w39zge/tss+36Moeuio9d2eoyRFqXhq=rUGtDwX3fzXV0wV+dUojxOYQ57GQDl7+68PwHPcX794OIXuGOxBk83lNIYIcYz3Vc7qnGy6tFTz7f6S9+EZuSGN7TY5VKkT2eWye46DebrDF9Nwzs/FVpTzbPD/KGDIBtFIbazglhKoWe9txqb1QW8vFNNVOEhYa+cViO3g8ZmY1wG960US2zsnX5Eg8Q5a4h3+sxaJSJ4ONiXZWJuAgKRQzcrszu+M5C0ZVoCOv1goEgfNJeSm/yFc/3rx8wmeWLIJFtq65B7zF72HRKq1nthHAguaxXr20nguHpKkDpNBDVa=WwuJsbeGI + +version=4 diff --git a/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py new file mode 100644 index 00000000000..c6716187b37 --- /dev/null +++ b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py @@ -0,0 +1,75 @@ +''' +Test s3_auth config parsing +''' +# 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. + +ts = Test.MakeATSProcess("ts") +server = Test.MakeOriginServer("server") + +Test.testName = "s3_auth: config parsing" + +# define the request header and the desired response header +request_header = { + "headers": "GET /s3-bucket HTTP/1.1\r\nHost: www.example.com\r\n\r\n", + "timestamp": "1469733493.993", + "x-amz-security-token": "hkMsi6/bfHyBKrSeM/H0hoXeyx8z1yZ/mJ0c+B/TqYx=tTJDjnQWtul38Z9iVJjeH1HB4VT2c=2o3yE3o=I9kmFs/lJDR85qWjB8e5asY/WbjyRpbAzmDipQpboIcYnUYg55bxrQFidV/q8gZa5A9MpR3n=op1C0lWjeBqcEJxpevNZxteSQTQfeGsi98Cdf+On=/SINVlKrNhMnmMsDOLMGx1YYt9d4UsRg1jtVrwxL4Vd/F7aHCZySAXKv+1rkhACR023wpa3dhp+xirGJxSO9LWwvcrTdM4xJo4RS8B40tGENOJ1NKixUJxwN/6og58Oft/u==uleR89Ja=7zszK2H7tX3DqmEYNvNDYQh/7VBRe5otghQtPwJzWpXAGk+Vme4hPPM5K6axH2LxipXzRiIV=oxNs0upKNu1FvuzbCQmkQdKQVmXl0344vngngrgN7wkEfrYtmKwICmpAS0cbW9jdSClgziVo4NaFc/hsIfok=4UA3hVtxIdw74lFNXD0RR7HKXkFPLIn85M7peOZsqMUCfO4gxr7KCfabszQQf0YcP/mt79XK50=WrSJG7oUyn+clUySPhlegqHAfT9a50uSK5WiQmOnGNGLF4wDO10sqKN1xRgQbYHPtwL+Ye0EMisvmYA3==kScorTSGaQWyibSWXAvxq9+IVGBYShVJ6S7DmTT=u/2d/fGEge+Xmbxlftza=cxJ=Md=k1Q71Lp6Boa56d7wtYRpK6tXHJ9I/2r7rN1E4OtwkFqb7SfWV3UXwyUrXyaaNPTIbqnAHnbgUGtuU6pgICpfREiIxVqvKBf6ErbxHRmMmAuYKxk5E9Mn6nnbxR4WTniweKYeDv2w39zge/tss+36Moeuio9d2eoyRFqXhq=rUGtDwX3fzXV0wV+dUojxOYQ57GQDl7+68PwHPcX794OIXuGOxBk83lNIYIcYz3Vc7qnGy6tFTz7f6S9+EZuSGN7TY5VKkT2eWye46DebrDF9Nwzs/FVpTzbPD/KGDIBtFIbazglhKoWe9txqb1QW8vFNNVOEhYa+cViO3g8ZmY1wG960US2zsnX5Eg8Q5a4h3+sxaJSJ4ONiXZWJuAgKRQzcrszu+M5C0ZVoCOv1goEgfNJeSm/yFc/3rx8wmeWLIJFtq65B7zF72HRKq1nthHAguaxXr20nguHpKkDpNBDVa=WwuJsbeGI", + "body": "" +} + +# desired response form the origin server +response_header = { + "headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", + "timestamp": "1469733493.993", + "body": "success!" +} + +# add request/response +server.addResponse("sessionlog.log", request_header, response_header) + +ts.Disk.records_config.update({ + 'proxy.config.diags.debug.enabled': 1, + 'proxy.config.diags.debug.tags': 's3_auth', +}) + +ts.Setup.CopyAs('rules/v4-parse-test.conf', Test.RunDirectory) + +ts.Disk.remap_config.AddLine( + 'map http://www.example.com http://127.0.0.1:{0} \ + @plugin=s3_auth.so \ + @pparam=--config @pparam={1}/v4-parse-test.conf' + .format(server.Variables.Port, Test.RunDirectory) +) + +# Commands to get the following response headers +# 1. make a request +# 2. modify the config +# 3. make another request +curlRequest = ( + 'curl -s -v -H "Host: www.example.com" http://127.0.0.1:{0}/s3-bucket;' +) + +# Test Case +tr = Test.AddTestRun() +tr.Processes.Default.Command = curlRequest.format(ts.Variables.port, Test.RunDirectory) +tr.Processes.Default.ReturnCode = 0 +tr.Processes.Default.StartBefore(server) +tr.Processes.Default.StartBefore(ts) +tr.Processes.Default.Streams.stderr = "gold/s3_auth_parsing.gold" +tr.StillRunningAfter = server + +ts.Disk.traffic_out.Content = "gold/s3_auth_parsing_ts.gold" +ts.ReturnCode = 0 From c2a5b5ae7691953c5781a618b8bbe23de8d97350 Mon Sep 17 00:00:00 2001 From: Mo Chen Date: Tue, 13 Sep 2022 11:30:36 -0500 Subject: [PATCH 2/4] Tell CI to ignore intentional trailing spaces Rename v4-parse-test.conf to .test_input --- .../rules/{v4-parse-test.conf => v4-parse-test.test_input} | 0 tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py | 6 ++++-- 2 files changed, 4 insertions(+), 2 deletions(-) rename tests/gold_tests/pluginTest/s3_auth/rules/{v4-parse-test.conf => v4-parse-test.test_input} (100%) diff --git a/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.conf b/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.test_input similarity index 100% rename from tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.conf rename to tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.test_input diff --git a/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py index c6716187b37..0753deaeecf 100644 --- a/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py +++ b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py @@ -17,6 +17,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os + ts = Test.MakeATSProcess("ts") server = Test.MakeOriginServer("server") @@ -45,12 +47,12 @@ 'proxy.config.diags.debug.tags': 's3_auth', }) -ts.Setup.CopyAs('rules/v4-parse-test.conf', Test.RunDirectory) +ts.Setup.CopyAs('rules/v4-parse-test.test_input', Test.RunDirectory) ts.Disk.remap_config.AddLine( 'map http://www.example.com http://127.0.0.1:{0} \ @plugin=s3_auth.so \ - @pparam=--config @pparam={1}/v4-parse-test.conf' + @pparam=--config @pparam={1}/v4-parse-test.test_input' .format(server.Variables.Port, Test.RunDirectory) ) From 062e93709e5981a1241a268e4d82280c2cd8a59f Mon Sep 17 00:00:00 2001 From: Mo Chen Date: Tue, 20 Sep 2022 13:57:24 -0500 Subject: [PATCH 3/4] Address PR review comments --- plugins/s3_auth/aws_auth_v4.cc | 28 +++++++++++++++---- plugins/s3_auth/aws_auth_v4.h | 18 +----------- plugins/s3_auth/s3_auth.cc | 13 ++++----- .../s3_auth/rules/v4-parse-test.test_input | 8 +++--- .../pluginTest/s3_auth/s3_auth_config.test.py | 15 ++-------- 5 files changed, 36 insertions(+), 46 deletions(-) diff --git a/plugins/s3_auth/aws_auth_v4.cc b/plugins/s3_auth/aws_auth_v4.cc index 1ea4af04508..004c0b3935a 100644 --- a/plugins/s3_auth/aws_auth_v4.cc +++ b/plugins/s3_auth/aws_auth_v4.cc @@ -22,12 +22,11 @@ * @see aws_auth_v4.h */ -#include /* strlen() */ -#include /* stoi() */ -#include /* strftime(), time(), gmtime_r() */ -#include /* std::setw */ -#include /* std::stringstream */ -#include +#include /* strlen() */ +#include /* stoi() */ +#include /* strftime(), time(), gmtime_r() */ +#include /* std::setw */ +#include /* std::stringstream */ #include /* SHA(), sha256_Update(), SHA256_Final, etc. */ #include /* HMAC() */ @@ -205,6 +204,23 @@ trimWhiteSpacesAndSqueezeInnerSpaces(const char *in, size_t inLen) return out_str; } +/** + * @brief Trim white spaces from beginning and end. + * @returns trimmed string + */ +String +trimWhiteSpaces(const String &s) +{ + /* @todo do this better? */ + static const String whiteSpace = " \t\n\v\f\r"; + size_t start = s.find_first_not_of(whiteSpace); + if (String::npos == start) { + return String(); + } + size_t stop = s.find_last_not_of(whiteSpace); + return s.substr(start, stop - start + 1); +} + /* * Group of static inline helper function for less error prone parameter handling and unit test logging. */ diff --git a/plugins/s3_auth/aws_auth_v4.h b/plugins/s3_auth/aws_auth_v4.h index 1e590cc66af..865a199385f 100644 --- a/plugins/s3_auth/aws_auth_v4.h +++ b/plugins/s3_auth/aws_auth_v4.h @@ -67,23 +67,7 @@ static const String X_AMZ = "x-amz-"; static const String CONTENT_TYPE = "content-type"; static const String HOST = "host"; -/** - * @brief Trim white spaces from beginning and end. - * @returns trimmed string - */ -template -StringLike -trimWhiteSpaces(const StringLike &s) -{ - /* @todo do this better? */ - static const auto whiteSpace = " \t\n\v\f\r"; - size_t start = s.find_first_not_of(whiteSpace); - if (StringLike::npos == start) { - return StringLike(); - } - size_t stop = s.find_last_not_of(whiteSpace); - return s.substr(start, stop - start + 1); -} +String trimWhiteSpaces(const String &s); template void diff --git a/plugins/s3_auth/s3_auth.cc b/plugins/s3_auth/s3_auth.cc index 26e0087a015..e9ac6c53c90 100644 --- a/plugins/s3_auth/s3_auth.cc +++ b/plugins/s3_auth/s3_auth.cc @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -49,6 +48,7 @@ #include #include #include "tscore/ink_config.h" +#include "tscpp/util/TextView.h" #include "aws_auth_v4.h" @@ -534,20 +534,19 @@ S3Config::parse_config(const std::string &config_fname) } for (std::string buf; std::getline(file, buf);) { - std::string_view line{buf}; + ts::TextView line{buf}; // Skip leading/trailing white spaces - const auto key_val = trimWhiteSpaces(line); + ts::TextView key_val = line.trim_if(&isspace); // Skip empty or comment lines - if (key_val.length() == 0 || ('#' == key_val[0])) { + if (key_val.empty() || ('#' == key_val[0])) { continue; } // Identify the keys (and values if appropriate) - size_t eq_pos = key_val.find_first_of('='); - std::string key_str{trimWhiteSpaces(key_val.substr(0, eq_pos == std::string_view::npos ? key_val.size() : eq_pos))}; - std::string val_str{eq_pos == std::string_view::npos ? "" : trimWhiteSpaces(key_val.substr(eq_pos + 1, key_val.size()))}; + std::string key_str{key_val.split_prefix_at('=').trim_if(&isspace)}; + std::string val_str{key_val.trim_if(&isspace)}; if (key_str == "secret_key") { set_secret(val_str.c_str()); diff --git a/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.test_input b/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.test_input index b63c2480f97..3b963c485fb 100644 --- a/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.test_input +++ b/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.test_input @@ -20,10 +20,10 @@ # Test space in front access_key=1234567 -# Test space behind -secret_key=9999999 +# Test space in between +secret_key = 9999999 -# long line -session_token=hkMsi6/bfHyBKrSeM/H0hoXeyx8z1yZ/mJ0c+B/TqYx=tTJDjnQWtul38Z9iVJjeH1HB4VT2c=2o3yE3o=I9kmFs/lJDR85qWjB8e5asY/WbjyRpbAzmDipQpboIcYnUYg55bxrQFidV/q8gZa5A9MpR3n=op1C0lWjeBqcEJxpevNZxteSQTQfeGsi98Cdf+On=/SINVlKrNhMnmMsDOLMGx1YYt9d4UsRg1jtVrwxL4Vd/F7aHCZySAXKv+1rkhACR023wpa3dhp+xirGJxSO9LWwvcrTdM4xJo4RS8B40tGENOJ1NKixUJxwN/6og58Oft/u==uleR89Ja=7zszK2H7tX3DqmEYNvNDYQh/7VBRe5otghQtPwJzWpXAGk+Vme4hPPM5K6axH2LxipXzRiIV=oxNs0upKNu1FvuzbCQmkQdKQVmXl0344vngngrgN7wkEfrYtmKwICmpAS0cbW9jdSClgziVo4NaFc/hsIfok=4UA3hVtxIdw74lFNXD0RR7HKXkFPLIn85M7peOZsqMUCfO4gxr7KCfabszQQf0YcP/mt79XK50=WrSJG7oUyn+clUySPhlegqHAfT9a50uSK5WiQmOnGNGLF4wDO10sqKN1xRgQbYHPtwL+Ye0EMisvmYA3==kScorTSGaQWyibSWXAvxq9+IVGBYShVJ6S7DmTT=u/2d/fGEge+Xmbxlftza=cxJ=Md=k1Q71Lp6Boa56d7wtYRpK6tXHJ9I/2r7rN1E4OtwkFqb7SfWV3UXwyUrXyaaNPTIbqnAHnbgUGtuU6pgICpfREiIxVqvKBf6ErbxHRmMmAuYKxk5E9Mn6nnbxR4WTniweKYeDv2w39zge/tss+36Moeuio9d2eoyRFqXhq=rUGtDwX3fzXV0wV+dUojxOYQ57GQDl7+68PwHPcX794OIXuGOxBk83lNIYIcYz3Vc7qnGy6tFTz7f6S9+EZuSGN7TY5VKkT2eWye46DebrDF9Nwzs/FVpTzbPD/KGDIBtFIbazglhKoWe9txqb1QW8vFNNVOEhYa+cViO3g8ZmY1wG960US2zsnX5Eg8Q5a4h3+sxaJSJ4ONiXZWJuAgKRQzcrszu+M5C0ZVoCOv1goEgfNJeSm/yFc/3rx8wmeWLIJFtq65B7zF72HRKq1nthHAguaxXr20nguHpKkDpNBDVa=WwuJsbeGI +# long line, space behind +session_token=hkMsi6/bfHyBKrSeM/H0hoXeyx8z1yZ/mJ0c+B/TqYx=tTJDjnQWtul38Z9iVJjeH1HB4VT2c=2o3yE3o=I9kmFs/lJDR85qWjB8e5asY/WbjyRpbAzmDipQpboIcYnUYg55bxrQFidV/q8gZa5A9MpR3n=op1C0lWjeBqcEJxpevNZxteSQTQfeGsi98Cdf+On=/SINVlKrNhMnmMsDOLMGx1YYt9d4UsRg1jtVrwxL4Vd/F7aHCZySAXKv+1rkhACR023wpa3dhp+xirGJxSO9LWwvcrTdM4xJo4RS8B40tGENOJ1NKixUJxwN/6og58Oft/u==uleR89Ja=7zszK2H7tX3DqmEYNvNDYQh/7VBRe5otghQtPwJzWpXAGk+Vme4hPPM5K6axH2LxipXzRiIV=oxNs0upKNu1FvuzbCQmkQdKQVmXl0344vngngrgN7wkEfrYtmKwICmpAS0cbW9jdSClgziVo4NaFc/hsIfok=4UA3hVtxIdw74lFNXD0RR7HKXkFPLIn85M7peOZsqMUCfO4gxr7KCfabszQQf0YcP/mt79XK50=WrSJG7oUyn+clUySPhlegqHAfT9a50uSK5WiQmOnGNGLF4wDO10sqKN1xRgQbYHPtwL+Ye0EMisvmYA3==kScorTSGaQWyibSWXAvxq9+IVGBYShVJ6S7DmTT=u/2d/fGEge+Xmbxlftza=cxJ=Md=k1Q71Lp6Boa56d7wtYRpK6tXHJ9I/2r7rN1E4OtwkFqb7SfWV3UXwyUrXyaaNPTIbqnAHnbgUGtuU6pgICpfREiIxVqvKBf6ErbxHRmMmAuYKxk5E9Mn6nnbxR4WTniweKYeDv2w39zge/tss+36Moeuio9d2eoyRFqXhq=rUGtDwX3fzXV0wV+dUojxOYQ57GQDl7+68PwHPcX794OIXuGOxBk83lNIYIcYz3Vc7qnGy6tFTz7f6S9+EZuSGN7TY5VKkT2eWye46DebrDF9Nwzs/FVpTzbPD/KGDIBtFIbazglhKoWe9txqb1QW8vFNNVOEhYa+cViO3g8ZmY1wG960US2zsnX5Eg8Q5a4h3+sxaJSJ4ONiXZWJuAgKRQzcrszu+M5C0ZVoCOv1goEgfNJeSm/yFc/3rx8wmeWLIJFtq65B7zF72HRKq1nthHAguaxXr20nguHpKkDpNBDVa=WwuJsbeGI version=4 diff --git a/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py index 0753deaeecf..ff4d7c16c4c 100644 --- a/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py +++ b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py @@ -50,23 +50,14 @@ ts.Setup.CopyAs('rules/v4-parse-test.test_input', Test.RunDirectory) ts.Disk.remap_config.AddLine( - 'map http://www.example.com http://127.0.0.1:{0} \ + f'map http://www.example.com http://127.0.0.1:{server.Variables.Port} \ @plugin=s3_auth.so \ - @pparam=--config @pparam={1}/v4-parse-test.test_input' - .format(server.Variables.Port, Test.RunDirectory) -) - -# Commands to get the following response headers -# 1. make a request -# 2. modify the config -# 3. make another request -curlRequest = ( - 'curl -s -v -H "Host: www.example.com" http://127.0.0.1:{0}/s3-bucket;' + @pparam=--config @pparam={Test.RunDirectory}/v4-parse-test.test_input' ) # Test Case tr = Test.AddTestRun() -tr.Processes.Default.Command = curlRequest.format(ts.Variables.port, Test.RunDirectory) +tr.Processes.Default.Command = f'curl -s -v -H "Host: www.example.com" http://127.0.0.1:{ts.Variables.port}/s3-bucket;' tr.Processes.Default.ReturnCode = 0 tr.Processes.Default.StartBefore(server) tr.Processes.Default.StartBefore(ts) From 2aba621472fdcad1453548211f3c89c0bbb7ee01 Mon Sep 17 00:00:00 2001 From: Mo Chen Date: Tue, 20 Sep 2022 16:21:11 -0500 Subject: [PATCH 4/4] Remove spurious os import --- tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py index ff4d7c16c4c..5523ff63ad6 100644 --- a/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py +++ b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py @@ -17,8 +17,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os - ts = Test.MakeATSProcess("ts") server = Test.MakeOriginServer("server")