@@ -192,6 +192,140 @@ func TestAppProxy(t *testing.T) {
192192 }
193193}
194194
195+ func TestAppProxyFlag (t * testing.T ) {
196+ testcases := []struct {
197+ name string
198+ proxyURL string
199+ flag string
200+ }{
201+ {
202+ name : "http proxy via flag" ,
203+ proxyURL : "http://proxy:8080" ,
204+ flag : "--proxy" ,
205+ },
206+ {
207+ name : "https proxy via flag" ,
208+ proxyURL : "https://proxy:8443" ,
209+ flag : "--proxy" ,
210+ },
211+ {
212+ name : "socks5 proxy via flag" ,
213+ proxyURL : "socks5://proxy:1080" ,
214+ flag : "--proxy" ,
215+ },
216+ {
217+ name : "http proxy via short flag" ,
218+ proxyURL : "http://proxy:8080" ,
219+ flag : "-x" ,
220+ },
221+ {
222+ name : "proxy with no-verify-ssl flag" ,
223+ proxyURL : "http://proxy:8080" ,
224+ flag : "--proxy" ,
225+ },
226+ }
227+ for _ , tc := range testcases {
228+ tc := tc
229+ t .Run (tc .name , func (t * testing.T ) {
230+ const expectedReqs = 1
231+
232+ proxy := httpProxy {}
233+ pxyURL := setupProxy (t , & proxy )
234+
235+ // set endpoint scheme to 'http'
236+ if os .Getenv (s5cmdTestEndpointEnv ) != "" {
237+ origEndpoint := os .Getenv (s5cmdTestEndpointEnv )
238+ endpoint , err := url .Parse (origEndpoint )
239+ if err != nil {
240+ t .Fatal (err )
241+ }
242+ endpoint .Scheme = "http"
243+ os .Setenv (s5cmdTestEndpointEnv , endpoint .String ())
244+
245+ defer func () {
246+ os .Setenv (s5cmdTestEndpointEnv , origEndpoint )
247+ }()
248+ }
249+
250+ // Use the actual proxy URL from the test setup instead of the test case
251+ // since we need a real proxy server for the test
252+ _ , s5cmd := setup (t , withProxy ())
253+
254+ var cmd icmd.Cmd
255+ if strings .Contains (tc .name , "no-verify-ssl" ) {
256+ cmd = s5cmd (tc .flag , pxyURL , "--no-verify-ssl" , "ls" )
257+ } else {
258+ cmd = s5cmd (tc .flag , pxyURL , "ls" )
259+ }
260+
261+ result := icmd .RunCmd (cmd )
262+
263+ result .Assert (t , icmd .Success )
264+ assert .Assert (t , proxy .isSuccessful (expectedReqs ))
265+ })
266+ }
267+ }
268+
269+ func TestAppProxyEnvironmentVariable (t * testing.T ) {
270+ testcases := []struct {
271+ name string
272+ proxyURL string
273+ envVar string
274+ }{
275+ {
276+ name : "http proxy via S5CMD_PROXY env var" ,
277+ proxyURL : "http://proxy:8080" ,
278+ envVar : "S5CMD_PROXY" ,
279+ },
280+ {
281+ name : "https proxy via S5CMD_PROXY env var" ,
282+ proxyURL : "https://proxy:8443" ,
283+ envVar : "S5CMD_PROXY" ,
284+ },
285+ {
286+ name : "socks5 proxy via S5CMD_PROXY env var" ,
287+ proxyURL : "socks5://proxy:1080" ,
288+ envVar : "S5CMD_PROXY" ,
289+ },
290+ }
291+ for _ , tc := range testcases {
292+ tc := tc
293+ t .Run (tc .name , func (t * testing.T ) {
294+ const expectedReqs = 1
295+
296+ proxy := httpProxy {}
297+ pxyURL := setupProxy (t , & proxy )
298+
299+ // set endpoint scheme to 'http'
300+ if os .Getenv (s5cmdTestEndpointEnv ) != "" {
301+ origEndpoint := os .Getenv (s5cmdTestEndpointEnv )
302+ endpoint , err := url .Parse (origEndpoint )
303+ if err != nil {
304+ t .Fatal (err )
305+ }
306+ endpoint .Scheme = "http"
307+ os .Setenv (s5cmdTestEndpointEnv , endpoint .String ())
308+
309+ defer func () {
310+ os .Setenv (s5cmdTestEndpointEnv , origEndpoint )
311+ }()
312+ }
313+
314+ // Set the environment variable
315+ os .Setenv (tc .envVar , pxyURL )
316+ defer os .Unsetenv (tc .envVar )
317+
318+ _ , s5cmd := setup (t , withProxy ())
319+
320+ cmd := s5cmd ("ls" )
321+ result := icmd .RunCmd (cmd )
322+
323+ result .Assert (t , icmd .Success )
324+ assert .Assert (t , proxy .isSuccessful (expectedReqs ))
325+ })
326+ }
327+ }
328+
195329func TestAppUnknownCommand (t * testing.T ) {
196330 t .Parallel ()
197331
@@ -312,3 +446,213 @@ func TestAppEndpointShouldHaveScheme(t *testing.T) {
312446 })
313447 }
314448}
449+
450+ func TestAppProxyAuthentication (t * testing.T ) {
451+ testcases := []struct {
452+ name string
453+ proxyURL string
454+ flag string
455+ }{
456+ {
457+ name : "http proxy with auth via flag" ,
458+ proxyURL : "http://user:pass@proxy:8080" ,
459+ flag : "--proxy" ,
460+ },
461+ {
462+ name : "https proxy with auth via flag" ,
463+ proxyURL : "https://admin:secret@proxy:8443" ,
464+ flag : "--proxy" ,
465+ },
466+ {
467+ name : "socks5 proxy with auth via flag" ,
468+ proxyURL : "socks5://proxyuser:proxypass@proxy:1080" ,
469+ flag : "--proxy" ,
470+ },
471+ {
472+ name : "http proxy with auth via short flag" ,
473+ proxyURL : "http://user:pass@proxy:8080" ,
474+ flag : "-x" ,
475+ },
476+ {
477+ name : "proxy with auth and no-verify-ssl flag" ,
478+ proxyURL : "http://user:pass@proxy:8080" ,
479+ flag : "--proxy" ,
480+ },
481+ {
482+ name : "proxy with special chars in password" ,
483+ proxyURL : "http://user:pass@word@proxy:8080" ,
484+ flag : "--proxy" ,
485+ },
486+ {
487+ name : "proxy with empty password" ,
488+ proxyURL : "http://user@proxy:8080" ,
489+ flag : "--proxy" ,
490+ },
491+ {
492+ name : "proxy with empty username" ,
493+ proxyURL : "http://:pass@proxy:8080" ,
494+ flag : "--proxy" ,
495+ },
496+ }
497+ for _ , tc := range testcases {
498+ tc := tc
499+ t .Run (tc .name , func (t * testing.T ) {
500+ const expectedReqs = 1
501+
502+ proxy := httpProxy {}
503+ pxyURL := setupProxy (t , & proxy )
504+
505+ // set endpoint scheme to 'http'
506+ if os .Getenv (s5cmdTestEndpointEnv ) != "" {
507+ origEndpoint := os .Getenv (s5cmdTestEndpointEnv )
508+ endpoint , err := url .Parse (origEndpoint )
509+ if err != nil {
510+ t .Fatal (err )
511+ }
512+ endpoint .Scheme = "http"
513+ os .Setenv (s5cmdTestEndpointEnv , endpoint .String ())
514+
515+ defer func () {
516+ os .Setenv (s5cmdTestEndpointEnv , origEndpoint )
517+ }()
518+ }
519+
520+ // Use the actual proxy URL from the test setup instead of the test case
521+ // since we need a real proxy server for the test
522+ _ , s5cmd := setup (t , withProxy ())
523+
524+ var cmd icmd.Cmd
525+ if strings .Contains (tc .name , "no-verify-ssl" ) {
526+ cmd = s5cmd (tc .flag , pxyURL , "--no-verify-ssl" , "ls" )
527+ } else {
528+ cmd = s5cmd (tc .flag , pxyURL , "ls" )
529+ }
530+
531+ result := icmd .RunCmd (cmd )
532+
533+ result .Assert (t , icmd .Success )
534+ assert .Assert (t , proxy .isSuccessful (expectedReqs ))
535+ })
536+ }
537+ }
538+
539+ func TestAppProxyAuthenticationEnvironmentVariable (t * testing.T ) {
540+ testcases := []struct {
541+ name string
542+ proxyURL string
543+ envVar string
544+ }{
545+ {
546+ name : "http proxy with auth via S5CMD_PROXY env var" ,
547+ proxyURL : "http://user:pass@proxy:8080" ,
548+ envVar : "S5CMD_PROXY" ,
549+ },
550+ {
551+ name : "https proxy with auth via S5CMD_PROXY env var" ,
552+ proxyURL : "https://admin:secret@proxy:8443" ,
553+ envVar : "S5CMD_PROXY" ,
554+ },
555+ {
556+ name : "socks5 proxy with auth via S5CMD_PROXY env var" ,
557+ proxyURL : "socks5://proxyuser:proxypass@proxy:1080" ,
558+ envVar : "S5CMD_PROXY" ,
559+ },
560+ {
561+ name : "proxy with special chars in auth via env var" ,
562+ proxyURL : "http://user:pass@word@proxy:8080" ,
563+ envVar : "S5CMD_PROXY" ,
564+ },
565+ }
566+ for _ , tt := range testcases {
567+ tt := tt
568+ t .Run (tt .name , func (t * testing.T ) {
569+ const expectedReqs = 1
570+
571+ proxy := httpProxy {}
572+ pxyURL := setupProxy (t , & proxy )
573+
574+ // set endpoint scheme to 'http'
575+ if os .Getenv (s5cmdTestEndpointEnv ) != "" {
576+ origEndpoint := os .Getenv (s5cmdTestEndpointEnv )
577+ endpoint , err := url .Parse (origEndpoint )
578+ if err != nil {
579+ t .Fatal (err )
580+ }
581+ endpoint .Scheme = "http"
582+ os .Setenv (s5cmdTestEndpointEnv , endpoint .String ())
583+
584+ defer func () {
585+ os .Setenv (s5cmdTestEndpointEnv , origEndpoint )
586+ }()
587+ }
588+
589+ // Set the environment variable
590+ os .Setenv (tt .envVar , pxyURL )
591+ defer os .Unsetenv (tt .envVar )
592+
593+ _ , s5cmd := setup (t , withProxy ())
594+
595+ cmd := s5cmd ("ls" )
596+ result := icmd .RunCmd (cmd )
597+
598+ result .Assert (t , icmd .Success )
599+ assert .Assert (t , proxy .isSuccessful (expectedReqs ))
600+ })
601+ }
602+ }
603+
604+ func TestAppProxyAuthenticationErrors (t * testing.T ) {
605+ testcases := []struct {
606+ name string
607+ proxyURL string
608+ flag string
609+ expectError bool
610+ errorMsg string
611+ }{
612+ {
613+ name : "malformed proxy URL with triple colon" ,
614+ proxyURL : "http://user:pass:extra@proxy:8080" ,
615+ flag : "--proxy" ,
616+ expectError : true ,
617+ errorMsg : "invalid proxy URL" ,
618+ },
619+ {
620+ name : "proxy URL with invalid scheme" ,
621+ proxyURL : "://user:pass@proxy:8080" ,
622+ flag : "--proxy" ,
623+ expectError : true ,
624+ errorMsg : "invalid proxy URL" ,
625+ },
626+ {
627+ name : "proxy URL with missing host" ,
628+ proxyURL : "http://user:pass@" ,
629+ flag : "--proxy" ,
630+ expectError : true ,
631+ errorMsg : "invalid proxy URL" ,
632+ },
633+ {
634+ name : "proxy URL with invalid port" ,
635+ proxyURL : "http://user:pass@proxy:invalid" ,
636+ flag : "--proxy" ,
637+ expectError : true ,
638+ errorMsg : "invalid proxy URL" ,
639+ },
640+ }
641+ for _ , tc := range testcases {
642+ tc := tc
643+ t .Run (tc .name , func (t * testing.T ) {
644+ _ , s5cmd := setup (t )
645+
646+ cmd := s5cmd (tc .flag , tc .proxyURL , "ls" )
647+ result := icmd .RunCmd (cmd )
648+
649+ if tc .expectError {
650+ result .Assert (t , icmd.Expected {ExitCode : 1 })
651+ // Check that the error message contains the expected text
652+ assert .Assert (t , strings .Contains (result .Stderr (), tc .errorMsg ))
653+ } else {
654+ result .Assert (t , icmd .Success )
655+ }
656+ })
657+ }
658+ }
0 commit comments