You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2022/10/04 15:43:01 UTC

[trafficserver] branch 9.2.x updated: s3_auth: accept longer config lines (#9090)

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 9.2.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/9.2.x by this push:
     new c6c7fb4d3 s3_auth: accept longer config lines (#9090)
c6c7fb4d3 is described below

commit c6c7fb4d3fc477fd4bdb33a418d472659c1b7572
Author: Mo Chen <un...@gmail.com>
AuthorDate: Wed Sep 21 11:57:36 2022 -0500

    s3_auth: accept longer config lines (#9090)
    
    * s3_auth: accept longer config lines
    
    * Tell CI to ignore intentional trailing spaces
    
    Rename v4-parse-test.conf to .test_input
    
    * Address PR review comments
    
    * Remove spurious os import
    
    (cherry picked from commit cd712e05ca455c607f7dc3e274397d5d9e528e3c)
---
 plugins/s3_auth/s3_auth.cc                         | 41 +++++---------
 .../pluginTest/s3_auth/gold/s3_auth_parsing.gold   | 17 ++++++
 .../s3_auth/gold/s3_auth_parsing_ts.gold           |  5 ++
 .../s3_auth/rules/v4-parse-test.test_input         | 29 ++++++++++
 .../pluginTest/s3_auth/s3_auth_config.test.py      | 66 ++++++++++++++++++++++
 5 files changed, 131 insertions(+), 27 deletions(-)

diff --git a/plugins/s3_auth/s3_auth.cc b/plugins/s3_auth/s3_auth.cc
index df5c09077..e9ac6c53c 100644
--- a/plugins/s3_auth/s3_auth.cc
+++ b/plugins/s3_auth/s3_auth.cc
@@ -23,6 +23,7 @@
 #include <ctime>
 #include <cstring>
 #include <getopt.h>
+#include <ios>
 #include <sys/time.h>
 
 #include <cstdio>
@@ -47,6 +48,7 @@
 #include <ts/remap.h>
 #include <tscpp/util/TsSharedMutex.h>
 #include "tscore/ink_config.h"
+#include "tscpp/util/TextView.h"
 
 #include "aws_auth_v4.h"
 
@@ -523,41 +525,28 @@ 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);) {
+      ts::TextView line{buf};
 
-      // Skip leading white spaces
-      pos1 = line;
-      while (*pos1 && isspace(*pos1)) {
-        ++pos1;
-      }
-      if (!*pos1 || ('#' == *pos1)) {
-        continue;
-      }
+      // Skip leading/trailing white spaces
+      ts::TextView key_val = line.trim_if(&isspace);
 
-      // 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.empty() || ('#' == 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()));
+      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());
@@ -578,11 +567,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 000000000..50a707eb2
--- /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 000000000..d266d6a69
--- /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=oxNs0upKNu1FvuzbCQmkQdKQVm [...]
+``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.test_input b/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.test_input
new file mode 100644
index 000000000..3b963c485
--- /dev/null
+++ b/tests/gold_tests/pluginTest/s3_auth/rules/v4-parse-test.test_input
@@ -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 in between
+secret_key   =    9999999
+
+# 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=oxNs0upKNu1FvuzbCQmkQdKQVmXl0344vngngrgN7wkEfrYtmKwICmpAS0cbW9jdSCl [...]
+
+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 000000000..5523ff63a
--- /dev/null
+++ b/tests/gold_tests/pluginTest/s3_auth/s3_auth_config.test.py
@@ -0,0 +1,66 @@
+'''
+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=oxNs0upKNu1FvuzbCQmkQdKQVmXl0344vngngrgN7wkEfrYtmKwI [...]
+    "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.test_input', Test.RunDirectory)
+
+ts.Disk.remap_config.AddLine(
+    f'map http://www.example.com http://127.0.0.1:{server.Variables.Port} \
+        @plugin=s3_auth.so \
+            @pparam=--config @pparam={Test.RunDirectory}/v4-parse-test.test_input'
+)
+
+# Test Case
+tr = Test.AddTestRun()
+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)
+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