From b14385f1eab9bc3778d7a61e9a169d04b333d6ac Mon Sep 17 00:00:00 2001 From: Zhengxi Li Date: Wed, 18 Jan 2023 19:08:57 +0000 Subject: [PATCH 1/3] Added a HTTP CONNECT test using proxy verifier --- tests/gold_tests/connect/connect.test.py | 59 +++++++++++++++++++ .../connect/replays/connect.replay.yaml | 51 ++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 tests/gold_tests/connect/replays/connect.replay.yaml diff --git a/tests/gold_tests/connect/connect.test.py b/tests/gold_tests/connect/connect.test.py index 3552b788a24..95b25958a7c 100644 --- a/tests/gold_tests/connect/connect.test.py +++ b/tests/gold_tests/connect/connect.test.py @@ -18,6 +18,7 @@ from enum import Enum import os +import re Test.Summary = 'Exercise HTTP CONNECT Method' Test.ContinueOnFail = True @@ -106,3 +107,61 @@ def run(self): ConnectTest().run() + + +class ConnectViaPVTest: + # This test also executes the CONNECT request but using proxy verifier to + # generate traffic + connectReplayFile = "replays/connect.replay.yaml" + + def __init__(self): + self.setupOriginServer() + self.setupTS() + + def setupOriginServer(self): + self.server = Test.MakeVerifierServerProcess( + "connect-verifier-server", + self.connectReplayFile) + # Verify server output + self.server.Streams.stdout += Testers.ExcludesExpression( + "uuid: 1", + "Verify the CONNECT request doesn't reach the server.") + self.server.Streams.stdout += Testers.ContainsExpression( + "GET /get HTTP/1.1\nuuid: 2", reflags=re.MULTILINE, + description="Verify the server gets the second request.") + + def setupTS(self): + self.ts = Test.MakeATSProcess("connect-ts") + + self.ts.Disk.records_config.update({ + 'proxy.config.diags.debug.enabled': 1, + 'proxy.config.diags.debug.tags': 'http', + 'proxy.config.http.server_ports': f"{self.ts.Variables.port}", + 'proxy.config.http.connect_ports': f"{self.server.Variables.http_port}", + }) + + self.ts.Disk.remap_config.AddLines([ + f"map / http://127.0.0.1:{self.server.Variables.http_port}/", + ]) + # Verify ts logs + self.ts.Disk.traffic_out.Content += Testers.ContainsExpression( + f"Proxy's Request.*\n.*\nCONNECT 127.0.0.1:{self.server.Variables.http_port} HTTP/1.1", reflags=re.MULTILINE, + description="Verify that ATS recognizes the CONNECT request.") + + def runTraffic(self): + tr = Test.AddTestRun("Verify correct handling of CONNECT request") + tr.AddVerifierClientProcess( + "connect-client", + self.connectReplayFile, + http_ports=[self.ts.Variables.port], + other_args='--thread-limit 1') + tr.Processes.Default.StartBefore(self.server) + tr.Processes.Default.StartBefore(self.ts) + tr.StillRunningAfter = self.server + tr.StillRunningAfter = self.ts + + def run(self): + self.runTraffic() + + +ConnectViaPVTest().run() diff --git a/tests/gold_tests/connect/replays/connect.replay.yaml b/tests/gold_tests/connect/replays/connect.replay.yaml new file mode 100644 index 00000000000..9d8d87a2ebf --- /dev/null +++ b/tests/gold_tests/connect/replays/connect.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. + +# +# This replay file executes a CONNECT request and a subsequent GET request +# +meta: + version: "1.0" + +sessions: + - transactions: + - client-request: + method: CONNECT + version: "1.1" + url: www.example.com:80 + headers: + fields: + - [uuid, 1] + - [Host, www.example.com:80] + # This is a CONNECT request so it should not reach the origin server + server-response: + status: 200 + + proxy-response: + status: 200 + + # Once the tunnel between client and server is established, subsequent + # requests will reach the server(via the tunnel) + - client-request: + method: GET + version: "1.1" + url: /get + headers: + fields: + - [uuid, 2] + - [Host, www.example.com] + server-response: + status: 200 From 545e2ba97a176fd223e3b1e880146f570327dc78 Mon Sep 17 00:00:00 2001 From: Zhengxi Li Date: Wed, 18 Jan 2023 19:18:41 +0000 Subject: [PATCH 2/3] Updated comment --- tests/gold_tests/connect/replays/connect.replay.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/gold_tests/connect/replays/connect.replay.yaml b/tests/gold_tests/connect/replays/connect.replay.yaml index 9d8d87a2ebf..f1dfe5ab9c0 100644 --- a/tests/gold_tests/connect/replays/connect.replay.yaml +++ b/tests/gold_tests/connect/replays/connect.replay.yaml @@ -34,6 +34,8 @@ sessions: server-response: status: 200 + # ATS returns a 200 responses to client when it establishes a tunnel + # between the client and server proxy-response: status: 200 From 0d339e862e56535bbbcb4a2642287f9892aee3c1 Mon Sep 17 00:00:00 2001 From: Zhengxi Li Date: Wed, 18 Jan 2023 20:31:45 +0000 Subject: [PATCH 3/3] added proxy-response verification --- tests/gold_tests/connect/replays/connect.replay.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/gold_tests/connect/replays/connect.replay.yaml b/tests/gold_tests/connect/replays/connect.replay.yaml index f1dfe5ab9c0..fd98ff304e1 100644 --- a/tests/gold_tests/connect/replays/connect.replay.yaml +++ b/tests/gold_tests/connect/replays/connect.replay.yaml @@ -51,3 +51,14 @@ sessions: - [Host, www.example.com] server-response: status: 200 + reason: OK + headers: + fields: + - [X-Response-1, response_tunnel] + + proxy-response: + status: 200 + headers: + field: + # make sure the client gets the X-Response header + - [X-Response-1, { value: response_tunnel, as: equal }]