3737-compile (export_all ).
3838
3939-define (LOCAL_PROXY_SCRIPT , " server_proxy.sh" ).
40+ -define (DUMMY_PROXY_SCRIPT , " dummy_proxy.sh" ).
4041-define (p (F , A ), % Debug printout
4142 begin
4243 io :format (
@@ -55,18 +56,24 @@ suite() ->
5556
5657all () ->
5758 [{group ,local_proxy },
58- {group ,local_proxy_https }].
59+ {group ,local_proxy_https },
60+ {group , remote_proxy },
61+ {group , remote_proxy_https },
62+ {group , dummy_proxy }].
5963
6064groups () ->
6165 [{local_proxy ,[],
6266 [http_emulate_lower_versions
63- |local_proxy_cases ()]},
67+ |proxy_cases ()]},
6468 {local_proxy_https ,[],
65- local_proxy_cases () ++ local_proxy_https_cases ()}].
69+ proxy_cases () ++ proxy_https_cases ()},
70+ {remote_proxy , [], proxy_cases ()},
71+ {remote_proxy_https , [], proxy_cases () ++ proxy_https_cases ()},
72+ {dummy_proxy , [], [proxy_upgrade_connect_error ]}].
6673
6774% % internal functions
6875
69- local_proxy_cases () ->
76+ proxy_cases () ->
7077 [http_head ,
7178 http_get ,
7279 http_options ,
@@ -81,7 +88,7 @@ local_proxy_cases() ->
8188 http_stream ,
8289 http_not_modified_otp_6821 ].
8390
84- local_proxy_https_cases () ->
91+ proxy_https_cases () ->
8592 [https_connect_error ,
8693 http_timeout ].
8794
@@ -110,20 +117,48 @@ suite_apps() ->
110117init_per_group (local_proxy , Config ) ->
111118 init_local_proxy ([{protocol ,http }|Config ]);
112119init_per_group (local_proxy_https , Config ) ->
113- init_local_proxy ([{protocol ,https }|Config ]).
120+ init_local_proxy ([{protocol ,https }|Config ]);
121+
122+ init_per_group (remote_proxy , Config ) ->
123+ Config1 = init_local_proxy ([{protocol ,http }|Config ]),
124+ {local ,{{" localhost" ,Port },[]}} = proplists :get_value (proxy , Config1 ),
125+ lists :keyreplace (proxy , 1 , Config1 , {proxy , {local , {{" 127.0.0.1" , Port }, []}}});
126+ init_per_group (remote_proxy_https , Config ) ->
127+ Config1 = init_local_proxy ([{protocol ,https }|Config ]),
128+ {local ,{{" localhost" ,Port },[]}} = proplists :get_value (proxy , Config1 ),
129+ lists :keyreplace (proxy , 1 , Config1 , {proxy , {local , {{" 127.0.0.1" , Port }, []}}});
130+
131+ init_per_group (dummy_proxy , Config ) ->
132+ ProxyPort = 8000 ,
133+ ProxyAddress = " 127.0.0.1" ,
134+ DummyPort = 8080 ,
135+ DummyServer = " localhost" ,
136+ [{proxy , {local , {{ProxyAddress , ProxyPort }, []}}}, {http , {DummyServer , DummyPort }} | Config ].
137+
114138
115139end_per_group (Group , Config )
116140 when
117141 Group =:= local_proxy ;
118- Group =:= local_proxy_https ->
142+ Group =:= local_proxy_https ;
143+ Group =:= remote_proxy ;
144+ Group =:= remote_proxy_https ->
119145 rcmd_local_proxy ([" stop" ], Config ),
120146 Config ;
121147end_per_group (_ , Config ) ->
122148 Config .
123149
124150% %--------------------------------------------------------------------
125151
126- init_per_testcase (Case , Config0 ) ->
152+ init_per_testcase (proxy_upgrade_connect_error = Case , Config ) ->
153+ Response = " HTTP/1.1 500" ,
154+ init_dummy_proxy (Response , Config ),
155+ do_init_per_testcase (Case , Config );
156+ init_per_testcase (Case , Config ) ->
157+ do_init_per_testcase (Case , Config ).
158+
159+ do_init_per_testcase (_ , {skip , _ } = Config ) ->
160+ Config ;
161+ do_init_per_testcase (Case , Config0 ) ->
127162 ct :timetrap ({seconds ,30 }),
128163 Apps = apps (Case , Config0 ),
129164 case init_apps (Apps , Config0 ) of
@@ -139,6 +174,12 @@ init_per_testcase(Case, Config0) ->
139174 E3
140175 end .
141176
177+ end_per_testcase (proxy_upgrade_connect_error , Config ) ->
178+ DataDir = proplists :get_value (data_dir , Config ),
179+ PrivDir = proplists :get_value (priv_dir , Config ),
180+ Script = filename :join (DataDir , ? DUMMY_PROXY_SCRIPT ),
181+ rcmd (Script , [" stop" ], [{cd , PrivDir }]),
182+ Config ;
142183end_per_testcase (_Case , Config ) ->
143184 app_stop (inets ),
144185 Config .
@@ -449,6 +490,26 @@ https_connect_error(Config) when is_list(Config) ->
449490 {error ,{failed_connect ,[_ ,{tls ,_ ,_ }]}} =
450491 httpc :request (Method , Request , HttpOpts , Opts ).
451492
493+ % %--------------------------------------------------------------------
494+ proxy_upgrade_connect_error (doc ) ->
495+ [" This targets verification of upgrade process
496+ when proxy sends back response code that is not 200" ];
497+ proxy_upgrade_connect_error (Config ) when is_list (Config ) ->
498+ {HttpServer ,HttpPort } = proplists :get_value (http , Config ),
499+ Method = get ,
500+ % % using HTTPS scheme to test upgrade connection
501+ URL = " https://" ++ HttpServer ++ " :" ++
502+ integer_to_list (HttpPort ) ++ " /index.html" ,
503+ Opts = [],
504+ HttpOpts = [? SSL_NO_VERIFY ],
505+ Request = {URL ,[]},
506+ % % This is a dummy proxy so no further connection will be established
507+ % % We are only interested in testing parsing of the proxy response
508+ {error ,{failed_connect ,[_ ,{_ ,_ ,econnrefused }]}} =
509+ httpc :request (Method , Request , HttpOpts , Opts ).
510+
511+
512+
452513% %--------------------------------------------------------------------
453514http_timeout (doc ) ->
454515 [" Test http/https connect and upgrade timeouts." ];
@@ -457,10 +518,11 @@ http_timeout(Config) when is_list(Config) ->
457518 URL = url (" /index.html" , Config ),
458519 Request = {URL ,[]},
459520 Timeout = timer :seconds (1 ),
521+ {_ ,{{ProxyAddr , ProxyPort }, []}} = proplists :get_value (proxy , Config ),
460522 HttpOpts1 = [{timeout , Timeout }, {connect_timeout , 0 }, ? SSL_NO_VERIFY ],
461523 {error ,
462524 {failed_connect ,
463- [{to_address ,{" localhost " , 8000 }},
525+ [{to_address ,{ProxyAddr , ProxyPort }},
464526 {inet ,[inet ],timeout }]}}
465527 = httpc :request (Method , Request , HttpOpts1 , []),
466528 ok .
@@ -540,6 +602,30 @@ url(AbsPath, Config) ->
540602
541603% %--------------------------------------------------------------------
542604
605+ init_dummy_proxy (Response , Config ) ->
606+ case os :type () of
607+ {unix , _ } ->
608+ case os :cmd (" which ncat" ) of
609+ [] ->
610+ {skip , " Ncat not available on the system" };
611+ _ ->
612+ Proxy = proplists :get_value (proxy , Config ),
613+ {_ , {{ProxyAddress , ProxyPort }, _ }} = Proxy ,
614+
615+ DataDir = proplists :get_value (data_dir , Config ),
616+ PrivDir = proplists :get_value (priv_dir , Config ),
617+ Script = filename :join (DataDir , ? DUMMY_PROXY_SCRIPT ),
618+
619+ spawn (fun () -> rcmd (Script , [" start" ,
620+ ProxyAddress ,
621+ integer_to_list (ProxyPort ),
622+ Response ], [{cd , PrivDir }])
623+ end )
624+ end ;
625+ _ ->
626+ {skip , " Platform cannot run dummy proxy script" }
627+ end .
628+
543629init_local_proxy (Config ) ->
544630 case os :type () of
545631 {unix ,_ } ->
0 commit comments