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..fd98ff304e1 --- /dev/null +++ b/tests/gold_tests/connect/replays/connect.replay.yaml @@ -0,0 +1,64 @@ +# 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 + + # ATS returns a 200 responses to client when it establishes a tunnel + # between the client and server + 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 + 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 }]