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,56 @@ 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+ case Config1 of
125+ {skip , _ } -> Config1 ;
126+ _ ->
127+ {local ,{{" localhost" ,Port },[]}} = proplists :get_value (proxy , Config1 ),
128+ lists :keyreplace (proxy , 1 , Config1 , {proxy , {local , {{" 127.0.0.1" , Port }, []}}})
129+ end ;
130+ init_per_group (remote_proxy_https , Config ) ->
131+ Config1 = init_local_proxy ([{protocol ,https }|Config ]),
132+ case Config1 of
133+ {skip , _ } -> Config1 ;
134+ _ ->
135+ {local ,{{" localhost" ,Port },[]}} = proplists :get_value (proxy , Config1 ),
136+ lists :keyreplace (proxy , 1 , Config1 , {proxy , {local , {{" 127.0.0.1" , Port }, []}}})
137+ end ;
138+
139+ init_per_group (dummy_proxy , Config ) ->
140+ ProxyPort = 8000 ,
141+ ProxyAddress = " 127.0.0.1" ,
142+ DummyPort = 8080 ,
143+ DummyServer = " localhost" ,
144+ [{proxy , {local , {{ProxyAddress , ProxyPort }, []}}}, {http , {DummyServer , DummyPort }} | Config ].
145+
114146
115147end_per_group (Group , Config )
116148 when
117149 Group =:= local_proxy ;
118- Group =:= local_proxy_https ->
150+ Group =:= local_proxy_https ;
151+ Group =:= remote_proxy ;
152+ Group =:= remote_proxy_https ->
119153 rcmd_local_proxy ([" stop" ], Config ),
120154 Config ;
121155end_per_group (_ , Config ) ->
122156 Config .
123157
124158% %--------------------------------------------------------------------
125159
126- init_per_testcase (Case , Config0 ) ->
160+ init_per_testcase (proxy_upgrade_connect_error = Case , Config ) ->
161+ Response = " HTTP/1.1 500" ,
162+ init_dummy_proxy (Response , Config ),
163+ do_init_per_testcase (Case , Config );
164+ init_per_testcase (Case , Config ) ->
165+ do_init_per_testcase (Case , Config ).
166+
167+ do_init_per_testcase (_ , {skip , _ } = Config ) ->
168+ Config ;
169+ do_init_per_testcase (Case , Config0 ) ->
127170 ct :timetrap ({seconds ,30 }),
128171 Apps = apps (Case , Config0 ),
129172 case init_apps (Apps , Config0 ) of
@@ -139,6 +182,12 @@ init_per_testcase(Case, Config0) ->
139182 E3
140183 end .
141184
185+ end_per_testcase (proxy_upgrade_connect_error , Config ) ->
186+ DataDir = proplists :get_value (data_dir , Config ),
187+ PrivDir = proplists :get_value (priv_dir , Config ),
188+ Script = filename :join (DataDir , ? DUMMY_PROXY_SCRIPT ),
189+ rcmd (Script , [" stop" ], [{cd , PrivDir }]),
190+ Config ;
142191end_per_testcase (_Case , Config ) ->
143192 app_stop (inets ),
144193 Config .
@@ -449,6 +498,26 @@ https_connect_error(Config) when is_list(Config) ->
449498 {error ,{failed_connect ,[_ ,{tls ,_ ,_ }]}} =
450499 httpc :request (Method , Request , HttpOpts , Opts ).
451500
501+ % %--------------------------------------------------------------------
502+ proxy_upgrade_connect_error (doc ) ->
503+ [" This targets verification of upgrade process
504+ when proxy sends back response code that is not 200" ];
505+ proxy_upgrade_connect_error (Config ) when is_list (Config ) ->
506+ {HttpServer ,HttpPort } = proplists :get_value (http , Config ),
507+ Method = get ,
508+ % % using HTTPS scheme to test upgrade connection
509+ URL = " https://" ++ HttpServer ++ " :" ++
510+ integer_to_list (HttpPort ) ++ " /index.html" ,
511+ Opts = [],
512+ HttpOpts = [? SSL_NO_VERIFY ],
513+ Request = {URL ,[]},
514+ % % This is a dummy proxy so no further connection will be established
515+ % % We are only interested in testing parsing of the proxy response
516+ {error ,{failed_connect ,[_ ,{_ ,_ ,econnrefused }]}} =
517+ httpc :request (Method , Request , HttpOpts , Opts ).
518+
519+
520+
452521% %--------------------------------------------------------------------
453522http_timeout (doc ) ->
454523 [" Test http/https connect and upgrade timeouts." ];
@@ -457,10 +526,11 @@ http_timeout(Config) when is_list(Config) ->
457526 URL = url (" /index.html" , Config ),
458527 Request = {URL ,[]},
459528 Timeout = timer :seconds (1 ),
529+ {_ ,{{ProxyAddr , ProxyPort }, []}} = proplists :get_value (proxy , Config ),
460530 HttpOpts1 = [{timeout , Timeout }, {connect_timeout , 0 }, ? SSL_NO_VERIFY ],
461531 {error ,
462532 {failed_connect ,
463- [{to_address ,{" localhost " , 8000 }},
533+ [{to_address ,{ProxyAddr , ProxyPort }},
464534 {inet ,[inet ],timeout }]}}
465535 = httpc :request (Method , Request , HttpOpts1 , []),
466536 ok .
@@ -540,6 +610,30 @@ url(AbsPath, Config) ->
540610
541611% %--------------------------------------------------------------------
542612
613+ init_dummy_proxy (Response , Config ) ->
614+ case os :type () of
615+ {unix , _ } ->
616+ case os :cmd (" which ncat" ) of
617+ [] ->
618+ {skip , " Ncat not available on the system" };
619+ _ ->
620+ Proxy = proplists :get_value (proxy , Config ),
621+ {_ , {{ProxyAddress , ProxyPort }, _ }} = Proxy ,
622+
623+ DataDir = proplists :get_value (data_dir , Config ),
624+ PrivDir = proplists :get_value (priv_dir , Config ),
625+ Script = filename :join (DataDir , ? DUMMY_PROXY_SCRIPT ),
626+
627+ spawn (fun () -> rcmd (Script , [" start" ,
628+ ProxyAddress ,
629+ integer_to_list (ProxyPort ),
630+ Response ], [{cd , PrivDir }])
631+ end )
632+ end ;
633+ _ ->
634+ {skip , " Platform cannot run dummy proxy script" }
635+ end .
636+
543637init_local_proxy (Config ) ->
544638 case os :type () of
545639 {unix ,_ } ->
0 commit comments