File 0692-Add-tests-for-remote-proxy.patch of Package erlang
From 74a94a99e4cbbf3cd8763e6000c17bb81438692e Mon Sep 17 00:00:00 2001
From: Konrad Pietrzak <konrad@erlang.org>
Date: Mon, 1 Dec 2025 12:10:54 +0100
Subject: [PATCH 2/2] Add tests for remote proxy
- Add "remote" proxy groups
- Add ncat as dummy proxy
---
lib/inets/test/httpc_proxy_SUITE.erl | 112 ++++++++++++++++--
.../httpc_proxy_SUITE_data/dummy_proxy.sh | 21 ++++
2 files changed, 124 insertions(+), 9 deletions(-)
create mode 100755 lib/inets/test/httpc_proxy_SUITE_data/dummy_proxy.sh
diff --git a/lib/inets/test/httpc_proxy_SUITE.erl b/lib/inets/test/httpc_proxy_SUITE.erl
index f7a97c09a9..bfe8791b5b 100644
--- a/lib/inets/test/httpc_proxy_SUITE.erl
+++ b/lib/inets/test/httpc_proxy_SUITE.erl
@@ -35,6 +35,7 @@
-compile(export_all).
-define(LOCAL_PROXY_SCRIPT, "server_proxy.sh").
+-define(DUMMY_PROXY_SCRIPT, "dummy_proxy.sh").
-define(p(F, A), % Debug printout
begin
io:format(
@@ -53,18 +54,24 @@ suite() ->
all() ->
[{group,local_proxy},
- {group,local_proxy_https}].
+ {group,local_proxy_https},
+ {group, remote_proxy},
+ {group, remote_proxy_https},
+ {group, dummy_proxy}].
groups() ->
[{local_proxy,[],
[http_emulate_lower_versions
- |local_proxy_cases()]},
+ |proxy_cases()]},
{local_proxy_https,[],
- local_proxy_cases() ++ local_proxy_https_cases()}].
+ proxy_cases() ++ proxy_https_cases()},
+ {remote_proxy, [], proxy_cases()},
+ {remote_proxy_https, [], proxy_cases() ++ proxy_https_cases()},
+ {dummy_proxy, [], [proxy_upgrade_connect_error]}].
%% internal functions
-local_proxy_cases() ->
+proxy_cases() ->
[http_head,
http_get,
http_options,
@@ -79,7 +86,7 @@ local_proxy_cases() ->
http_stream,
http_not_modified_otp_6821].
-local_proxy_https_cases() ->
+proxy_https_cases() ->
[https_connect_error,
http_timeout].
@@ -108,12 +115,39 @@ suite_apps() ->
init_per_group(local_proxy, Config) ->
init_local_proxy([{protocol,http}|Config]);
init_per_group(local_proxy_https, Config) ->
- init_local_proxy([{protocol,https}|Config]).
+ init_local_proxy([{protocol,https}|Config]);
+
+init_per_group(remote_proxy, Config) ->
+ Config1 = init_local_proxy([{protocol,http}|Config]),
+ case Config1 of
+ {skip, _} -> Config1;
+ _ ->
+ {local,{{"localhost",Port},[]}} = proplists:get_value(proxy, Config1),
+ lists:keyreplace(proxy, 1, Config1, {proxy, {local, {{"127.0.0.1", Port}, []}}})
+ end;
+init_per_group(remote_proxy_https, Config) ->
+ Config1 = init_local_proxy([{protocol,https}|Config]),
+ case Config1 of
+ {skip, _} -> Config1;
+ _ ->
+ {local,{{"localhost",Port},[]}} = proplists:get_value(proxy, Config1),
+ lists:keyreplace(proxy, 1, Config1, {proxy, {local, {{"127.0.0.1", Port}, []}}})
+ end;
+
+init_per_group(dummy_proxy, Config) ->
+ ProxyPort = 8000,
+ ProxyAddress = "127.0.0.1",
+ DummyPort = 8080,
+ DummyServer = "localhost",
+ [{proxy, {local, {{ProxyAddress, ProxyPort}, []}}}, {http, {DummyServer, DummyPort}} | Config].
+
end_per_group(Group, Config)
when
Group =:= local_proxy;
- Group =:= local_proxy_https ->
+ Group =:= local_proxy_https;
+ Group =:= remote_proxy;
+ Group =:= remote_proxy_https ->
rcmd_local_proxy(["stop"], Config),
Config;
end_per_group(_, Config) ->
@@ -121,7 +155,16 @@ end_per_group(_, Config) ->
%%--------------------------------------------------------------------
-init_per_testcase(Case, Config0) ->
+init_per_testcase(proxy_upgrade_connect_error = Case, Config) ->
+ Response = "HTTP/1.1 500",
+ init_dummy_proxy(Response, Config),
+ do_init_per_testcase(Case, Config);
+init_per_testcase(Case, Config) ->
+ do_init_per_testcase(Case, Config).
+
+do_init_per_testcase(_, {skip, _} = Config) ->
+ Config;
+do_init_per_testcase(Case, Config0) ->
ct:timetrap({seconds,30}),
Apps = apps(Case, Config0),
case init_apps(Apps, Config0) of
@@ -137,6 +180,12 @@ init_per_testcase(Case, Config0) ->
E3
end.
+end_per_testcase(proxy_upgrade_connect_error, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Script = filename:join(DataDir, ?DUMMY_PROXY_SCRIPT),
+ rcmd(Script, ["stop"], [{cd, PrivDir}]),
+ Config;
end_per_testcase(_Case, Config) ->
app_stop(inets),
Config.
@@ -447,6 +496,26 @@ https_connect_error(Config) when is_list(Config) ->
{error,{failed_connect,[_,{tls,_,_}]}} =
httpc:request(Method, Request, HttpOpts, Opts).
+%%--------------------------------------------------------------------
+proxy_upgrade_connect_error(doc) ->
+ ["This targets verification of upgrade process
+ when proxy sends back response code that is not 200"];
+proxy_upgrade_connect_error(Config) when is_list(Config) ->
+ {HttpServer,HttpPort} = proplists:get_value(http, Config),
+ Method = get,
+ %% using HTTPS scheme to test upgrade connection
+ URL = "https://" ++ HttpServer ++ ":" ++
+ integer_to_list(HttpPort) ++ "/index.html",
+ Opts = [],
+ HttpOpts = [?SSL_NO_VERIFY],
+ Request = {URL,[]},
+ %% This is a dummy proxy so no further connection will be established
+ %% We are only interested in testing parsing of the proxy response
+ {error,{failed_connect,[_,{_,_,econnrefused}]}} =
+ httpc:request(Method, Request, HttpOpts, Opts).
+
+
+
%%--------------------------------------------------------------------
http_timeout(doc) ->
["Test http/https connect and upgrade timeouts."];
@@ -455,10 +524,11 @@ http_timeout(Config) when is_list(Config) ->
URL = url("/index.html", Config),
Request = {URL,[]},
Timeout = timer:seconds(1),
+ {_,{{ProxyAddr, ProxyPort}, []}} = proplists:get_value(proxy, Config),
HttpOpts1 = [{timeout, Timeout}, {connect_timeout, 0}, ?SSL_NO_VERIFY],
{error,
{failed_connect,
- [{to_address,{"localhost",8000}},
+ [{to_address,{ProxyAddr, ProxyPort}},
{inet,[inet],timeout}]}}
= httpc:request(Method, Request, HttpOpts1, []),
ok.
@@ -538,6 +608,30 @@ url(AbsPath, Config) ->
%%--------------------------------------------------------------------
+init_dummy_proxy(Response, Config) ->
+ case os:type() of
+ {unix, _} ->
+ case os:cmd("which ncat") of
+ [] ->
+ {skip, "Ncat not available on the system"};
+ _ ->
+ Proxy = proplists:get_value(proxy, Config),
+ {_, {{ProxyAddress, ProxyPort}, _}} = Proxy,
+
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ Script = filename:join(DataDir, ?DUMMY_PROXY_SCRIPT),
+
+ spawn(fun() -> rcmd(Script, ["start",
+ ProxyAddress,
+ integer_to_list(ProxyPort),
+ Response], [{cd, PrivDir}])
+ end)
+ end;
+ _ ->
+ {skip, "Platform cannot run dummy proxy script"}
+ end.
+
init_local_proxy(Config) ->
case os:type() of
{unix,_} ->
diff --git a/lib/inets/test/httpc_proxy_SUITE_data/dummy_proxy.sh b/lib/inets/test/httpc_proxy_SUITE_data/dummy_proxy.sh
new file mode 100755
index 0000000000..7d64ebb328
--- /dev/null
+++ b/lib/inets/test/httpc_proxy_SUITE_data/dummy_proxy.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# %CopyrightBegin%
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Copyright Ericsson AB 2025. All Rights Reserved.
+#
+# %CopyrightEnd%
+
+case :"${1:?}" in
+ :start)
+ /bin/echo -ne "${4}\r\n\r\n" | ncat -l ${2} ${3} & echo $! > dummy_proxy.pid
+ ;;
+ :stop)
+ Pid=`pgrep -F dummy_proxy.pid`
+ if [ ! "$Pid" = "" ]; then
+ kill "$Pid" || true
+ fi
+ ;;
+esac
--
2.51.0