1 package org.apache.maven.wagon.http;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.wagon.FileTestUtils;
23 import org.apache.maven.wagon.ResourceDoesNotExistException;
24 import org.apache.maven.wagon.StreamingWagon;
25 import org.apache.maven.wagon.StreamingWagonTestCase;
26 import org.apache.maven.wagon.TransferFailedException;
27 import org.apache.maven.wagon.Wagon;
28 import org.apache.maven.wagon.WagonException;
29 import org.apache.maven.wagon.authentication.AuthenticationInfo;
30 import org.apache.maven.wagon.authorization.AuthorizationException;
31 import org.apache.maven.wagon.proxy.ProxyInfo;
32 import org.apache.maven.wagon.proxy.ProxyInfoProvider;
33 import org.apache.maven.wagon.repository.Repository;
34 import org.apache.maven.wagon.resource.Resource;
35 import org.codehaus.plexus.util.FileUtils;
36 import org.codehaus.plexus.util.IOUtil;
37 import org.codehaus.plexus.util.StringUtils;
38 import org.eclipse.jetty.http.HttpStatus;
39 import org.eclipse.jetty.security.ConstraintMapping;
40 import org.eclipse.jetty.security.ConstraintSecurityHandler;
41 import org.eclipse.jetty.security.HashLoginService;
42 import org.eclipse.jetty.security.SecurityHandler;
43 import org.eclipse.jetty.security.authentication.BasicAuthenticator;
44 import org.eclipse.jetty.server.Connector;
45 import org.eclipse.jetty.server.HttpConfiguration;
46 import org.eclipse.jetty.server.HttpConnectionFactory;
47 import org.eclipse.jetty.server.Request;
48 import org.eclipse.jetty.server.Response;
49 import org.eclipse.jetty.server.Server;
50 import org.eclipse.jetty.server.ServerConnector;
51 import org.eclipse.jetty.server.handler.AbstractHandler;
52 import org.eclipse.jetty.server.handler.HandlerCollection;
53 import org.eclipse.jetty.servlet.DefaultServlet;
54 import org.eclipse.jetty.servlet.ServletContextHandler;
55 import org.eclipse.jetty.servlet.ServletHolder;
56 import org.eclipse.jetty.util.security.Constraint;
57 import org.eclipse.jetty.util.security.Password;
58
59 import javax.servlet.ServletException;
60 import javax.servlet.http.HttpServletRequest;
61 import javax.servlet.http.HttpServletResponse;
62
63 import java.io.ByteArrayOutputStream;
64 import java.io.File;
65 import java.io.FileInputStream;
66 import java.io.FileOutputStream;
67 import java.io.IOException;
68 import java.io.InputStream;
69 import java.io.OutputStream;
70 import java.lang.reflect.Method;
71 import java.net.URLDecoder;
72 import java.util.ArrayList;
73 import java.util.Collections;
74 import java.util.Enumeration;
75 import java.util.HashMap;
76 import java.util.List;
77 import java.util.Map;
78 import java.util.Properties;
79 import java.util.concurrent.atomic.AtomicBoolean;
80 import java.util.zip.DeflaterOutputStream;
81 import java.util.zip.GZIPOutputStream;
82
83
84
85
86 public abstract class HttpWagonTestCase
87 extends StreamingWagonTestCase
88 {
89 public static final int SC_TOO_MANY_REQUESTS = 429;
90
91 private Server server;
92 private ServerConnector connector;
93
94 protected int getLocalPort( Server server )
95 {
96 Connector connector = server.getConnectors()[0];
97 return ( ( ServerConnector ) connector ).getLocalPort();
98 }
99
100 protected void setupWagonTestingFixtures()
101 throws Exception
102 {
103
104
105 File file = FileTestUtils.createUniqueFile( "local-repository", "test-resource" );
106
107 file.delete();
108
109 file.getParentFile().mkdirs();
110
111 File repositoryDirectory = getRepositoryDirectory();
112 FileUtils.deleteDirectory( repositoryDirectory );
113 repositoryDirectory.mkdirs();
114
115 server = new Server( );
116
117
118 connector = addConnector( server );
119
120 PutHandler putHandler = new PutHandler( repositoryDirectory );
121
122 ServletContextHandler context = createContext( server, repositoryDirectory );
123 HandlerCollection handlers = new HandlerCollection();
124 handlers.addHandler( putHandler );
125 handlers.addHandler( context );
126 server.setHandler( handlers );
127
128 server.start();
129 }
130
131 protected final int getTestRepositoryPort()
132 {
133 if ( server == null )
134 {
135 return 0;
136 }
137 return connector.getLocalPort();
138 }
139
140 protected ServletContextHandler createContext( Server server, File repositoryDirectory )
141 throws IOException
142 {
143 ServletContextHandler root = new ServletContextHandler( ServletContextHandler.SESSIONS );
144 root.setResourceBase( repositoryDirectory.getAbsolutePath() );
145 ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
146 root.addServlet( servletHolder, "/*" );
147 return root;
148 }
149
150 protected void tearDownWagonTestingFixtures()
151 throws Exception
152 {
153 server.stop();
154 }
155
156 public void testWagonGetFileList()
157 throws Exception
158 {
159 File dir = getRepositoryDirectory();
160 FileUtils.deleteDirectory( dir );
161
162 File f = new File( dir, "file-list" );
163 f.mkdirs();
164
165 super.testWagonGetFileList();
166 }
167
168 public void testHttpHeaders()
169 throws Exception
170 {
171 Properties headers = new Properties();
172 headers.setProperty( "User-Agent", "Maven-Wagon/1.0" );
173
174 StreamingWagon wagon = (StreamingWagon) getWagon();
175
176 setHttpConfiguration( wagon, headers, new Properties() );
177
178 Server server = new Server( );
179 TestHeaderHandler handler = new TestHeaderHandler();
180 server.setHandler( handler );
181 ServerConnector serverConnector = addConnector( server );
182 server.start();
183
184 wagon.connect(
185 new Repository( "id", getProtocol() + "://localhost:" + serverConnector.getLocalPort() ) );
186
187 wagon.getToStream( "resource", new ByteArrayOutputStream() );
188
189 wagon.disconnect();
190
191 server.stop();
192
193 assertEquals( "Maven-Wagon/1.0", handler.headers.get( "User-Agent" ) );
194 }
195
196
197
198
199 public void testHttpHeadersWithCommonMethods()
200 throws Exception
201 {
202 Properties properties = new Properties();
203 properties.setProperty( "User-Agent", "Maven-Wagon/1.0" );
204
205 StreamingWagon wagon = (StreamingWagon) getWagon();
206
207 Method setHttpHeaders = wagon.getClass().getMethod( "setHttpHeaders", Properties.class );
208 setHttpHeaders.invoke( wagon, properties );
209
210 Server server = new Server( );
211 ServerConnector serverConnector = addConnector( server );
212 TestHeaderHandler handler = new TestHeaderHandler();
213 server.setHandler( handler );
214 addConnector( server );
215 server.start();
216
217 wagon.connect(
218 new Repository( "id", getProtocol() + "://localhost:" + serverConnector.getLocalPort() ) );
219
220 wagon.getToStream( "resource", new ByteArrayOutputStream() );
221
222 wagon.disconnect();
223
224 server.stop();
225
226 assertEquals( "Maven-Wagon/1.0", handler.headers.get( "User-Agent" ) );
227 }
228
229 public void testUserAgentHeaderIsPresentByDefault()
230 throws Exception
231 {
232 StreamingWagon wagon = (StreamingWagon) getWagon();
233 Server server = new Server( );
234 TestHeaderHandler handler = new TestHeaderHandler();
235 server.setHandler( handler );
236 addConnector( server );
237 server.start();
238 wagon.connect( new Repository( "id", getProtocol() + "://localhost:" + getLocalPort( server ) ) );
239 wagon.getToStream( "resource", new ByteArrayOutputStream() );
240 wagon.disconnect();
241 server.stop();
242
243 assertNotNull( "default User-Agent header of wagon provider should be present",
244 handler.headers.get( "User-Agent" ) );
245 }
246
247 public void testUserAgentHeaderIsPresentOnlyOnceIfSetMultipleTimes()
248 throws Exception
249 {
250 StreamingWagon wagon = (StreamingWagon) getWagon();
251
252
253 Properties headers1 = new Properties();
254 headers1.setProperty( "User-Agent", "test-user-agent" );
255 setHttpConfiguration( wagon, headers1, new Properties() );
256
257
258 Properties headers2 = new Properties();
259 headers2.setProperty( "User-Agent", "test-user-agent" );
260 Method setHttpHeaders = wagon.getClass().getMethod( "setHttpHeaders", Properties.class );
261 setHttpHeaders.invoke( wagon, headers2 );
262
263 Server server = new Server( );
264 TestHeaderHandler handler = new TestHeaderHandler();
265 server.setHandler( handler );
266 addConnector( server );
267 server.start();
268 wagon.connect( new Repository( "id", getProtocol() + "://localhost:" + getLocalPort( server ) ) );
269 wagon.getToStream( "resource", new ByteArrayOutputStream() );
270 wagon.disconnect();
271 server.stop();
272
273 assertEquals( "test-user-agent", handler.headers.get( "User-Agent" ) );
274
275 }
276
277 protected abstract void setHttpConfiguration( StreamingWagon wagon, Properties headers, Properties params );
278
279 protected ServerConnector addConnector( Server server )
280 {
281 ServerConnector serverConnector =
282 new ServerConnector( server, new HttpConnectionFactory( new HttpConfiguration() ) );
283 server.addConnector( serverConnector );
284 return serverConnector;
285 }
286
287 protected String getRepositoryUrl( Server server )
288 {
289 int localPort = getLocalPort( server );
290 return getProtocol() + "://localhost:" + localPort;
291 }
292
293 public void testGetForbidden()
294 throws Exception
295 {
296 try
297 {
298 runTestGet( HttpServletResponse.SC_FORBIDDEN );
299 fail();
300 }
301 catch ( AuthorizationException e )
302 {
303 assertTrue( true );
304 }
305 }
306
307 public void testGet404()
308 throws Exception
309 {
310 try
311 {
312 runTestGet( HttpServletResponse.SC_NOT_FOUND );
313 fail();
314 }
315 catch ( ResourceDoesNotExistException e )
316 {
317 assertTrue( true );
318 }
319 }
320
321 public void testList429()
322 throws Exception
323 {
324 StreamingWagon wagon = (StreamingWagon) getWagon();
325 try
326 {
327
328 Server server = new Server( );
329 final AtomicBoolean called = new AtomicBoolean();
330
331 AbstractHandler handler = new AbstractHandler()
332 {
333 public void handle( String target, Request baseRequest, HttpServletRequest request,
334 HttpServletResponse response ) throws IOException, ServletException
335 {
336 if ( called.get() )
337 {
338 response.setStatus( HttpServletResponse.SC_OK );
339 baseRequest.setHandled( true );
340 }
341 else
342 {
343 called.set( true );
344 response.setStatus( SC_TOO_MANY_REQUESTS );
345 baseRequest.setHandled( true );
346
347 }
348 }
349 };
350
351 server.setHandler( handler );
352 addConnector( server );
353 server.start();
354
355 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
356
357 try
358 {
359 wagon.getFileList( "resource" );
360 }
361 finally
362 {
363 wagon.disconnect();
364
365 server.stop();
366 }
367
368 }
369 catch ( ResourceDoesNotExistException e )
370 {
371 assertTrue( true );
372 }
373 catch ( TransferFailedException e )
374 {
375 if ( wagon.getClass().getName().contains( "Lightweight" ) )
376 {
377
378 assertTrue( true );
379 }
380 else
381 {
382 fail();
383 }
384
385 }
386 }
387
388 public void testGet500()
389 throws Exception
390 {
391 try
392 {
393 runTestGet( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
394 fail();
395 }
396 catch ( TransferFailedException e )
397 {
398 assertTrue( true );
399 }
400 }
401
402 private void runTestGet( int status )
403 throws Exception
404 {
405 StreamingWagon wagon = (StreamingWagon) getWagon();
406
407 Server server = createStatusServer( status );
408 server.start();
409
410 String baseUrl = getRepositoryUrl( server );
411 String resourceName = "resource";
412 String serverReasonPhrase = HttpStatus.getCode( status ).getMessage();
413
414 wagon.connect( new Repository( "id", baseUrl ) );
415
416 try
417 {
418 wagon.getToStream( "resource", new ByteArrayOutputStream() );
419 fail();
420 }
421 catch ( Exception e )
422 {
423 verifyWagonExceptionMessage( e, status, baseUrl + "/" + resourceName, serverReasonPhrase );
424 throw e;
425 }
426 finally
427 {
428 wagon.disconnect();
429
430 server.stop();
431 }
432 }
433
434 public void testResourceExistsForbidden()
435 throws Exception
436 {
437 try
438 {
439 runTestResourceExists( HttpServletResponse.SC_FORBIDDEN );
440 fail();
441 }
442 catch ( AuthorizationException e )
443 {
444 assertTrue( true );
445 }
446 }
447
448 public void testResourceExists404()
449 throws Exception
450 {
451 try
452 {
453 assertFalse( runTestResourceExists( HttpServletResponse.SC_NOT_FOUND ) );
454 }
455 catch ( ResourceDoesNotExistException e )
456 {
457 assertTrue( true );
458 }
459 }
460
461 public void testResourceExists500()
462 throws Exception
463 {
464 try
465 {
466 runTestResourceExists( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
467 fail();
468 }
469 catch ( TransferFailedException e )
470 {
471 assertTrue( true );
472 }
473 }
474
475 public void testResourceExists429()
476 throws Exception
477 {
478 try
479 {
480
481 final AtomicBoolean called = new AtomicBoolean();
482
483 AbstractHandler handler = new AbstractHandler()
484 {
485 public void handle( String target, Request baseRequest, HttpServletRequest request,
486 HttpServletResponse response ) throws IOException, ServletException
487 {
488 if ( called.get() )
489 {
490 response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
491 baseRequest.setHandled( true );
492 }
493 else
494 {
495 called.set( true );
496 response.setStatus( SC_TOO_MANY_REQUESTS );
497 baseRequest.setHandled( true );
498 }
499 }
500 };
501
502 StreamingWagon wagon = (StreamingWagon) getWagon();
503 Server server = new Server( );
504 server.setHandler( handler );
505 addConnector( server );
506 server.start();
507 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
508
509 try
510 {
511 wagon.resourceExists( "resource" );
512 }
513 finally
514 {
515 wagon.disconnect();
516
517 server.stop();
518 }
519
520 fail();
521 }
522 catch ( TransferFailedException e )
523 {
524 assertTrue( true );
525 }
526 }
527
528
529 private boolean runTestResourceExists( int status )
530 throws Exception
531 {
532 StreamingWagon wagon = (StreamingWagon) getWagon();
533
534 Server server = createStatusServer( status );
535 server.start();
536
537 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
538
539 try
540 {
541 return wagon.resourceExists( "resource" );
542 }
543 finally
544 {
545 wagon.disconnect();
546
547 server.stop();
548 }
549 }
550
551 protected long getExpectedLastModifiedOnGet( Repository repository, Resource resource )
552 {
553 File file = new File( getRepositoryDirectory(), resource.getName() );
554 return ( file.lastModified() / 1000 ) * 1000;
555 }
556
557 protected File getRepositoryDirectory()
558 {
559 return getTestFile( "target/test-output/http-repository" );
560 }
561
562 public void testGzipGet()
563 throws Exception
564 {
565 Server server = new Server( );
566
567 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
568 ServletContextHandler root = new ServletContextHandler( ServletContextHandler.SESSIONS );
569 root.setResourceBase( localRepositoryPath );
570 ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
571 servletHolder.setInitParameter( "gzip", "true" );
572 root.addServlet( servletHolder, "/*" );
573 addConnector( server );
574 server.setHandler( root );
575 server.start();
576
577 try
578 {
579 Wagon wagon = getWagon();
580
581 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
582
583 File sourceFile = new File( localRepositoryPath + "/gzip" );
584
585 sourceFile.deleteOnExit();
586
587 String resName = "gzip-res.txt";
588 String sourceContent = writeTestFile( sourceFile, resName, "gzip" );
589
590 wagon.connect( testRepository );
591
592 File destFile = FileTestUtils.createUniqueFile( getName(), getName() );
593
594 destFile.deleteOnExit();
595
596 wagon.get( "gzip/" + resName, destFile );
597
598 wagon.disconnect();
599
600 String destContent = FileUtils.fileRead( destFile );
601
602 assertEquals( sourceContent, destContent );
603 }
604 finally
605 {
606 server.stop();
607 }
608 }
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660 public void testProxiedRequest()
661 throws Exception
662 {
663 ProxyInfo proxyInfo = createProxyInfo();
664 TestHeaderHandler handler = new TestHeaderHandler();
665
666 runTestProxiedRequest( proxyInfo, handler );
667 }
668
669 public void testProxiedRequestWithAuthentication()
670 throws Exception
671 {
672 ProxyInfo proxyInfo = createProxyInfo();
673 proxyInfo.setUserName( "user" );
674 proxyInfo.setPassword( "secret" );
675 AuthorizingProxyHandler handler = new AuthorizingProxyHandler();
676
677 runTestProxiedRequest( proxyInfo, handler );
678
679 assertTrue( handler.headers.containsKey( "Proxy-Authorization" ) );
680
681 if ( supportProxyPreemptiveAuthentication() )
682 {
683 assertEquals( HttpServletResponse.SC_OK, handler.handlerRequestResponses.get( 0 ).responseCode );
684 }
685 else
686 {
687 assertEquals( HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED,
688 handler.handlerRequestResponses.get( 0 ).responseCode );
689 assertEquals( HttpServletResponse.SC_OK, handler.handlerRequestResponses.get( 1 ).responseCode );
690 }
691
692 }
693
694 public void testProxiedRequestWithAuthenticationWithProvider()
695 throws Exception
696 {
697 final ProxyInfo proxyInfo = createProxyInfo();
698 proxyInfo.setUserName( "user" );
699 proxyInfo.setPassword( "secret" );
700 AuthorizingProxyHandler handler = new AuthorizingProxyHandler();
701
702 ProxyInfoProvider proxyInfoProvider = new ProxyInfoProvider()
703 {
704 public ProxyInfo getProxyInfo( String protocol )
705 {
706 return proxyInfo;
707 }
708 };
709 runTestProxiedRequestWithProvider( proxyInfoProvider, handler );
710
711 assertTrue( handler.headers.containsKey( "Proxy-Authorization" ) );
712
713 if ( supportProxyPreemptiveAuthentication() )
714 {
715 assertEquals( HttpServletResponse.SC_OK, handler.handlerRequestResponses.get( 0 ).responseCode );
716 }
717 else
718 {
719 assertEquals( HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED,
720 handler.handlerRequestResponses.get( 0 ).responseCode );
721 assertEquals( HttpServletResponse.SC_OK, handler.handlerRequestResponses.get( 1 ).responseCode );
722 }
723
724 }
725
726 public void testRedirectGetToStream()
727 throws Exception
728 {
729 StreamingWagon wagon = (StreamingWagon) getWagon();
730
731 Server realServer = new Server( );
732 TestHeaderHandler handler = new TestHeaderHandler();
733
734 realServer.setHandler( handler );
735 addConnector( realServer );
736 realServer.start();
737
738 Server redirectServer = new Server( );
739
740 addConnector( redirectServer );
741
742 String protocol = getProtocol();
743
744
745 if ( protocol.equals( "dav" ) )
746 {
747 protocol = "http";
748 }
749
750 if ( protocol.equals( "davs" ) )
751 {
752 protocol = "https";
753 }
754
755 String redirectUrl = protocol + "://localhost:" + getLocalPort( realServer );
756
757 RedirectHandler redirectHandler =
758 new RedirectHandler( "See Other", HttpServletResponse.SC_SEE_OTHER, redirectUrl, null );
759
760 redirectServer.setHandler( redirectHandler );
761
762 redirectServer.start();
763
764 wagon.connect( new Repository( "id", getRepositoryUrl( redirectServer ) ) );
765
766 File tmpResult = File.createTempFile( "foo", "get" );
767
768 try ( FileOutputStream fileOutputStream = new FileOutputStream( tmpResult ) )
769 {
770 wagon.getToStream( "resource", fileOutputStream );
771 fileOutputStream.flush();
772 fileOutputStream.close();
773 String found = FileUtils.fileRead( tmpResult );
774 assertEquals( "found:'" + found + "'", "Hello, World!", found );
775
776 checkHandlerResult( redirectHandler.handlerRequestResponses, HttpServletResponse.SC_SEE_OTHER );
777 checkHandlerResult( handler.handlerRequestResponses, HttpServletResponse.SC_OK );
778 }
779 finally
780 {
781 wagon.disconnect();
782
783 redirectServer.stop();
784 realServer.stop();
785
786 tmpResult.delete();
787 }
788 }
789
790 public void testRedirectGet()
791 throws Exception
792 {
793 StreamingWagon wagon = (StreamingWagon) getWagon();
794
795 Server realServer = new Server( );
796 TestHeaderHandler handler = new TestHeaderHandler();
797
798 realServer.setHandler( handler );
799 addConnector( realServer );
800 realServer.start();
801
802 Server redirectServer = new Server( );
803
804 addConnector( redirectServer );
805
806 String protocol = getProtocol();
807
808
809 if ( protocol.equals( "dav" ) )
810 {
811 protocol = "http";
812 }
813
814 if ( protocol.equals( "davs" ) )
815 {
816 protocol = "https";
817 }
818
819 String redirectUrl = protocol + "://localhost:" + getLocalPort( realServer );
820
821 RedirectHandler redirectHandler =
822 new RedirectHandler( "See Other", HttpServletResponse.SC_SEE_OTHER, redirectUrl, null );
823
824 redirectServer.setHandler( redirectHandler );
825
826 redirectServer.start();
827
828 wagon.connect( new Repository( "id", getRepositoryUrl( redirectServer ) ) );
829
830 File tmpResult = File.createTempFile( "foo", "get" );
831
832 try
833 {
834 wagon.get( "resource", tmpResult );
835 String found = FileUtils.fileRead( tmpResult );
836 assertEquals( "found:'" + found + "'", "Hello, World!", found );
837
838 checkHandlerResult( redirectHandler.handlerRequestResponses, HttpServletResponse.SC_SEE_OTHER );
839 checkHandlerResult( handler.handlerRequestResponses, HttpServletResponse.SC_OK );
840 }
841 finally
842 {
843 wagon.disconnect();
844
845 redirectServer.stop();
846 realServer.stop();
847
848 tmpResult.delete();
849 }
850 }
851
852
853 public void testRedirectPutFromStreamWithFullUrl()
854 throws Exception
855 {
856 Server realServer = new Server( );
857
858 addConnector( realServer );
859
860 File repositoryDirectory = getRepositoryDirectory();
861 FileUtils.deleteDirectory( repositoryDirectory );
862 repositoryDirectory.mkdirs();
863
864 PutHandler putHandler = new PutHandler( repositoryDirectory );
865
866 realServer.setHandler( putHandler );
867
868 realServer.start();
869
870 Server redirectServer = new Server( );
871
872 addConnector( redirectServer );
873
874 String protocol = getProtocol();
875
876
877 if ( protocol.equals( "dav" ) )
878 {
879 protocol = "http";
880 }
881
882 if ( protocol.equals( "davs" ) )
883 {
884 protocol = "https";
885 }
886
887 String redirectUrl = protocol + "://localhost:" + getLocalPort( realServer );
888
889 RedirectHandler redirectHandler =
890 new RedirectHandler( "See Other", HttpServletResponse.SC_SEE_OTHER, redirectUrl, repositoryDirectory );
891
892 redirectServer.setHandler( redirectHandler );
893
894 redirectServer.start();
895
896 try
897 {
898 StreamingWagon wagon = (StreamingWagon) getWagon();
899 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
900 wagon.connect( repository );
901
902 File sourceFile = new File( repositoryDirectory, "test-secured-put-resource" );
903 sourceFile.delete();
904 assertFalse( sourceFile.exists() );
905
906 File tempFile = File.createTempFile( "wagon", "tmp" );
907 tempFile.deleteOnExit();
908 String content = "put top secret";
909 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
910
911 try ( FileInputStream fileInputStream = new FileInputStream( tempFile ) )
912 {
913 wagon.putFromStream( fileInputStream, "test-secured-put-resource", content.length(), -1 );
914 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
915
916 checkRequestResponseForRedirectPutWithFullUrl( redirectHandler, putHandler );
917 }
918 finally
919 {
920 wagon.disconnect();
921 tempFile.delete();
922 }
923
924 }
925 finally
926 {
927 realServer.stop();
928 redirectServer.stop();
929 }
930 }
931
932 protected void checkRequestResponseForRedirectPutWithFullUrl( RedirectHandler redirectHandler,
933 PutHandler putHandler )
934 {
935 checkHandlerResult( redirectHandler.handlerRequestResponses, HttpServletResponse.SC_SEE_OTHER );
936 checkHandlerResult( putHandler.handlerRequestResponses, HttpServletResponse.SC_CREATED );
937 }
938
939 public void testRedirectPutFromStreamRelativeUrl()
940 throws Exception
941 {
942 Server realServer = new Server( );
943 addConnector( realServer );
944 File repositoryDirectory = getRepositoryDirectory();
945 FileUtils.deleteDirectory( repositoryDirectory );
946 repositoryDirectory.mkdirs();
947
948 PutHandler putHandler = new PutHandler( repositoryDirectory );
949
950 realServer.setHandler( putHandler );
951
952 realServer.start();
953
954 Server redirectServer = new Server( );
955
956 addConnector( redirectServer );
957
958 RedirectHandler redirectHandler =
959 new RedirectHandler( "See Other", HttpServletResponse.SC_SEE_OTHER, "/redirectRequest/foo",
960 repositoryDirectory );
961
962 redirectServer.setHandler( redirectHandler );
963
964 redirectServer.start();
965
966 try
967 {
968 StreamingWagon wagon = (StreamingWagon) getWagon();
969 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
970 wagon.connect( repository );
971
972 File sourceFile = new File( repositoryDirectory, "/redirectRequest/foo/test-secured-put-resource" );
973 sourceFile.delete();
974 assertFalse( sourceFile.exists() );
975
976 File tempFile = File.createTempFile( "wagon", "tmp" );
977 tempFile.deleteOnExit();
978 String content = "put top secret";
979 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
980
981 try ( FileInputStream fileInputStream = new FileInputStream( tempFile ) )
982 {
983 wagon.putFromStream( fileInputStream, "test-secured-put-resource", content.length(), -1 );
984 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
985
986 checkRequestResponseForRedirectPutWithRelativeUrl( redirectHandler, putHandler );
987 }
988 finally
989 {
990 wagon.disconnect();
991 tempFile.delete();
992 }
993
994 }
995 finally
996 {
997 realServer.stop();
998 redirectServer.stop();
999 }
1000 }
1001
1002 protected void checkRequestResponseForRedirectPutWithRelativeUrl( RedirectHandler redirectHandler,
1003 PutHandler putHandler )
1004 {
1005 checkHandlerResult( redirectHandler.handlerRequestResponses, HttpServletResponse.SC_SEE_OTHER,
1006 HttpServletResponse.SC_CREATED );
1007 checkHandlerResult( putHandler.handlerRequestResponses );
1008 }
1009
1010 protected void checkHandlerResult( List<HandlerRequestResponse> handlerRequestResponses,
1011 int... expectedResponseCodes )
1012 {
1013 boolean success = true;
1014 if ( handlerRequestResponses.size() == expectedResponseCodes.length )
1015 {
1016 for ( int i = 0; i < expectedResponseCodes.length; i++ )
1017 {
1018 success &= ( expectedResponseCodes[i] == handlerRequestResponses.get( i ).responseCode );
1019 }
1020 }
1021
1022 if ( !success )
1023 {
1024 fail( "expected " + expectedResponseCodes + ", got " + handlerRequestResponses );
1025 }
1026 }
1027
1028 public void testRedirectPutFileWithFullUrl()
1029 throws Exception
1030 {
1031 Server realServer = new Server( );
1032
1033 addConnector( realServer );
1034
1035 File repositoryDirectory = getRepositoryDirectory();
1036 FileUtils.deleteDirectory( repositoryDirectory );
1037 repositoryDirectory.mkdirs();
1038
1039 PutHandler putHandler = new PutHandler( repositoryDirectory );
1040
1041 realServer.setHandler( putHandler );
1042
1043 realServer.start();
1044
1045 Server redirectServer = new Server( );
1046
1047 addConnector( redirectServer );
1048
1049 String protocol = getProtocol();
1050
1051
1052 if ( protocol.equals( "dav" ) )
1053 {
1054 protocol = "http";
1055 }
1056
1057 if ( protocol.equals( "davs" ) )
1058 {
1059 protocol = "https";
1060 }
1061
1062 String redirectUrl = protocol + "://localhost:" + getLocalPort( realServer );
1063
1064 RedirectHandler redirectHandler =
1065 new RedirectHandler( "See Other", HttpServletResponse.SC_SEE_OTHER, redirectUrl, repositoryDirectory );
1066
1067 redirectServer.setHandler( redirectHandler );
1068
1069 redirectServer.start();
1070
1071 try
1072 {
1073 StreamingWagon wagon = (StreamingWagon) getWagon();
1074 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
1075 wagon.connect( repository );
1076
1077 File sourceFile = new File( repositoryDirectory, "test-secured-put-resource" );
1078 sourceFile.delete();
1079 assertFalse( sourceFile.exists() );
1080
1081 File tempFile = File.createTempFile( "wagon", "tmp" );
1082 tempFile.deleteOnExit();
1083 String content = "put top secret";
1084 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
1085
1086 try
1087 {
1088 wagon.put( tempFile, "test-secured-put-resource" );
1089 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
1090
1091 checkRequestResponseForRedirectPutWithFullUrl( redirectHandler, putHandler );
1092 }
1093 finally
1094 {
1095 wagon.disconnect();
1096 tempFile.delete();
1097 }
1098
1099 }
1100 finally
1101 {
1102 realServer.stop();
1103 redirectServer.stop();
1104 }
1105 }
1106
1107
1108 public void testRedirectPutFileRelativeUrl()
1109 throws Exception
1110 {
1111 Server realServer = new Server( );
1112 addConnector( realServer );
1113 File repositoryDirectory = getRepositoryDirectory();
1114 FileUtils.deleteDirectory( repositoryDirectory );
1115 repositoryDirectory.mkdirs();
1116
1117 PutHandler putHandler = new PutHandler( repositoryDirectory );
1118
1119 realServer.setHandler( putHandler );
1120
1121 realServer.start();
1122
1123 Server redirectServer = new Server( );
1124
1125 addConnector( redirectServer );
1126
1127 RedirectHandler redirectHandler =
1128 new RedirectHandler( "See Other", HttpServletResponse.SC_SEE_OTHER, "/redirectRequest/foo",
1129 repositoryDirectory );
1130
1131 redirectServer.setHandler( redirectHandler );
1132
1133 redirectServer.start();
1134
1135 try
1136 {
1137 StreamingWagon wagon = (StreamingWagon) getWagon();
1138 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
1139 wagon.connect( repository );
1140
1141 File sourceFile = new File( repositoryDirectory, "/redirectRequest/foo/test-secured-put-resource" );
1142 sourceFile.delete();
1143 assertFalse( sourceFile.exists() );
1144
1145 File tempFile = File.createTempFile( "wagon", "tmp" );
1146 tempFile.deleteOnExit();
1147 String content = "put top secret";
1148 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
1149
1150 try
1151 {
1152 wagon.put( tempFile, "test-secured-put-resource" );
1153 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
1154
1155 checkRequestResponseForRedirectPutWithRelativeUrl( redirectHandler, putHandler );
1156 }
1157 finally
1158 {
1159 wagon.disconnect();
1160 tempFile.delete();
1161 }
1162
1163 }
1164 finally
1165 {
1166 realServer.stop();
1167 redirectServer.stop();
1168 }
1169 }
1170
1171 public void testRedirectPutFailureNonRepeatableStream()
1172 throws Exception
1173 {
1174 File repositoryDirectory = getRepositoryDirectory();
1175 FileUtils.deleteDirectory( repositoryDirectory );
1176 repositoryDirectory.mkdirs();
1177
1178 Server redirectServer = new Server( );
1179
1180 addConnector( redirectServer );
1181
1182 RedirectHandler redirectHandler =
1183 new RedirectHandler( "See Other", HttpServletResponse.SC_SEE_OTHER, "/redirectRequest/foo",
1184 null );
1185
1186 redirectServer.setHandler( redirectHandler );
1187
1188 redirectServer.start();
1189
1190 try
1191 {
1192 StreamingWagon wagon = (StreamingWagon) getWagon();
1193
1194 Properties params = new Properties();
1195 params.put( "http.protocol.expect-continue", "%b,false" );
1196 setHttpConfiguration( wagon, new Properties(), params );
1197 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
1198 wagon.connect( repository );
1199
1200 File sourceFile = new File( repositoryDirectory, "/redirectRequest/foo/test-secured-put-resource" );
1201 sourceFile.delete();
1202 assertFalse( sourceFile.exists() );
1203
1204 File tempFile = File.createTempFile( "wagon", "tmp" );
1205 tempFile.deleteOnExit();
1206 String content = "put top secret";
1207 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
1208
1209 try ( FileInputStream fileInputStream = new FileInputStream( tempFile ) )
1210 {
1211 wagon.putFromStream( fileInputStream, "test-secured-put-resource", content.length(), -1 );
1212
1213 if ( wagon.getClass().getName().contains( "Lightweight" ) )
1214 {
1215 assertTrue( true );
1216 }
1217 else
1218 {
1219 fail();
1220 }
1221 }
1222 catch ( TransferFailedException e )
1223 {
1224 assertTrue( true );
1225 }
1226 finally
1227 {
1228 wagon.disconnect();
1229 tempFile.delete();
1230 }
1231
1232 }
1233 finally
1234 {
1235 redirectServer.stop();
1236 }
1237 }
1238
1239
1240
1241
1242 @SuppressWarnings( "checkstyle:visibilitymodifier" )
1243 public static class RedirectHandler
1244 extends AbstractHandler
1245 {
1246 String reason;
1247
1248 int retCode;
1249
1250 String redirectUrl;
1251
1252 File repositoryDirectory;
1253
1254 public List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
1255
1256 RedirectHandler( String reason, int retCode, String redirectUrl, File repositoryDirectory )
1257 {
1258 this.reason = reason;
1259 this.retCode = retCode;
1260 this.redirectUrl = redirectUrl;
1261 this.repositoryDirectory = repositoryDirectory;
1262 }
1263
1264 public void handle( String target, Request baseRequest, HttpServletRequest request,
1265 HttpServletResponse response ) throws IOException, ServletException
1266 {
1267 if ( request.getRequestURI().contains( "redirectRequest" ) )
1268 {
1269 PutHandler putHandler = new PutHandler( this.repositoryDirectory );
1270 putHandler.handle( target, baseRequest, request, response );
1271 handlerRequestResponses.add(
1272 new HandlerRequestResponse( request.getMethod(), response.getStatus(),
1273 request.getRequestURI() ) );
1274 return;
1275 }
1276 response.setStatus( this.retCode );
1277 response.setHeader( "Location", this.redirectUrl + request.getRequestURI() );
1278 baseRequest.setHandled( true );
1279
1280 handlerRequestResponses.add(
1281 new HandlerRequestResponse( request.getMethod(), response.getStatus(),
1282 request.getRequestURI() ) );
1283 }
1284
1285
1286 }
1287
1288
1289 private void runTestProxiedRequest( ProxyInfo proxyInfo, TestHeaderHandler handler )
1290 throws Exception
1291 {
1292
1293
1294
1295
1296 Thread.sleep( 5001L );
1297
1298
1299 Server proxyServer = new Server( );
1300 ServerConnector serverConnector =
1301 new ServerConnector( proxyServer, new HttpConnectionFactory( new HttpConfiguration() ) );
1302 proxyServer.addConnector( serverConnector );
1303 proxyServer.setHandler( handler );
1304
1305 proxyServer.start();
1306
1307 proxyInfo.setPort( getLocalPort( proxyServer ) );
1308
1309 System.out.println(
1310 "start proxy on host/port " + proxyInfo.getHost() + "/" + proxyInfo.getPort() + " with non proxyHosts "
1311 + proxyInfo.getNonProxyHosts() );
1312
1313 while ( !proxyServer.isRunning() || !proxyServer.isStarted() )
1314 {
1315 Thread.sleep( 10 );
1316 }
1317
1318 try
1319 {
1320 StreamingWagon wagon = (StreamingWagon) getWagon();
1321
1322 Repository testRepository = new Repository( "id", "http://www.example.com/" );
1323
1324 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1325 File sourceFile = new File( localRepositoryPath, "test-proxied-resource" );
1326 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "content" );
1327
1328 wagon.connect( testRepository, proxyInfo );
1329
1330 try
1331 {
1332 wagon.getToStream( "test-proxied-resource", new ByteArrayOutputStream() );
1333
1334 assertTrue( handler.headers.containsKey( "Proxy-Connection" ) );
1335 }
1336 finally
1337 {
1338 System.setProperty( "http.proxyHost", "" );
1339 System.setProperty( "http.proxyPort", "" );
1340 wagon.disconnect();
1341 }
1342 }
1343 finally
1344 {
1345 proxyServer.stop();
1346 }
1347 }
1348
1349 private void runTestProxiedRequestWithProvider( ProxyInfoProvider proxyInfoProvider, TestHeaderHandler handler )
1350 throws Exception
1351 {
1352
1353
1354
1355
1356 Thread.sleep( 5001L );
1357
1358
1359 Server proxyServer = new Server( );
1360 ServerConnector serverConnector =
1361 new ServerConnector( proxyServer, new HttpConnectionFactory( new HttpConfiguration() ) );
1362 proxyServer.addConnector( serverConnector );
1363
1364 proxyServer.setHandler( handler );
1365
1366 proxyServer.start();
1367
1368 proxyInfoProvider.getProxyInfo( null ).setPort( getLocalPort( proxyServer ) );
1369
1370 System.out.println( "start proxy on host/port " + proxyInfoProvider.getProxyInfo( null ).getHost() + "/"
1371 + proxyInfoProvider.getProxyInfo( null ).getPort() + " with non proxyHosts "
1372 + proxyInfoProvider.getProxyInfo( null ).getNonProxyHosts() );
1373
1374 while ( !proxyServer.isRunning() || !proxyServer.isStarted() )
1375 {
1376 Thread.sleep( 10 );
1377 }
1378
1379 try
1380 {
1381 StreamingWagon wagon = (StreamingWagon) getWagon();
1382
1383 Repository testRepository = new Repository( "id", "http://www.example.com/" );
1384
1385 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1386 File sourceFile = new File( localRepositoryPath, "test-proxied-resource" );
1387 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "content" );
1388
1389 wagon.connect( testRepository, proxyInfoProvider );
1390
1391 try
1392 {
1393 wagon.getToStream( "test-proxied-resource", new ByteArrayOutputStream() );
1394
1395 assertTrue( handler.headers.containsKey( "Proxy-Connection" ) );
1396 }
1397 finally
1398 {
1399 System.setProperty( "http.proxyHost", "" );
1400 System.setProperty( "http.proxyPort", "" );
1401 wagon.disconnect();
1402 }
1403 }
1404 finally
1405 {
1406 proxyServer.stop();
1407 }
1408 }
1409
1410 private ProxyInfo createProxyInfo()
1411 {
1412 ProxyInfo proxyInfo = new ProxyInfo();
1413 proxyInfo.setHost( "localhost" );
1414 proxyInfo.setNonProxyHosts( null );
1415 proxyInfo.setType( "http" );
1416 return proxyInfo;
1417 }
1418
1419 public void testSecuredGetUnauthorized()
1420 throws Exception
1421 {
1422 try
1423 {
1424 runTestSecuredGet( null );
1425 fail();
1426 }
1427 catch ( AuthorizationException e )
1428 {
1429 assertTrue( true );
1430 }
1431 }
1432
1433 public void testSecuredGetWrongPassword()
1434 throws Exception
1435 {
1436 try
1437 {
1438 AuthenticationInfo authInfo = new AuthenticationInfo();
1439 authInfo.setUserName( "user" );
1440 authInfo.setPassword( "admin" );
1441 runTestSecuredGet( authInfo );
1442 fail();
1443 }
1444 catch ( AuthorizationException e )
1445 {
1446 assertTrue( true );
1447 }
1448 }
1449
1450 public void testSecuredGet()
1451 throws Exception
1452 {
1453 AuthenticationInfo authInfo = new AuthenticationInfo();
1454 authInfo.setUserName( "user" );
1455 authInfo.setPassword( "secret" );
1456 runTestSecuredGet( authInfo );
1457 }
1458
1459
1460 public void runTestSecuredGet( AuthenticationInfo authInfo )
1461 throws Exception
1462 {
1463 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1464 Server server = createSecurityServer( localRepositoryPath );
1465
1466 server.start();
1467
1468 try
1469 {
1470 StreamingWagon wagon = (StreamingWagon) getWagon();
1471
1472 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1473
1474 File sourceFile = new File( localRepositoryPath, "test-secured-resource" );
1475 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "top secret" );
1476
1477 wagon.connect( testRepository, authInfo );
1478
1479 File file = File.createTempFile( "wagon-test", "txt" );
1480
1481 try
1482 {
1483 wagon.get( "test-secured-resource", file );
1484 }
1485 finally
1486 {
1487 wagon.disconnect();
1488 }
1489
1490 FileInputStream in = new FileInputStream( file );
1491
1492 assertEquals( "top secret", IOUtil.toString( in ) );
1493
1494
1495
1496
1497
1498
1499
1500
1501 Thread.sleep ( 2000L );
1502
1503
1504 TestSecurityHandler securityHandler = server.getChildHandlerByClass( TestSecurityHandler.class );
1505 testPreemptiveAuthenticationGet( securityHandler, supportPreemptiveAuthenticationGet() );
1506
1507 }
1508 finally
1509 {
1510 server.stop();
1511 }
1512 }
1513
1514
1515 public void testSecuredGetToStream()
1516 throws Exception
1517 {
1518 AuthenticationInfo authInfo = new AuthenticationInfo();
1519 authInfo.setUserName( "user" );
1520 authInfo.setPassword( "secret" );
1521 runTestSecuredGetToStream( authInfo );
1522 }
1523
1524 public void runTestSecuredGetToStream( AuthenticationInfo authInfo )
1525 throws Exception
1526 {
1527 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1528 Server server = createSecurityServer( localRepositoryPath );
1529
1530 server.start();
1531
1532 try
1533 {
1534 StreamingWagon wagon = (StreamingWagon) getWagon();
1535
1536 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1537
1538 File sourceFile = new File( localRepositoryPath, "test-secured-resource" );
1539 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "top secret" );
1540
1541 wagon.connect( testRepository, authInfo );
1542
1543 ByteArrayOutputStream out = new ByteArrayOutputStream();
1544 try
1545 {
1546 wagon.getToStream( "test-secured-resource", out );
1547 }
1548 finally
1549 {
1550 wagon.disconnect();
1551 }
1552
1553 assertEquals( "top secret", out.toString( "US-ASCII" ) );
1554
1555
1556
1557
1558
1559
1560
1561
1562 Thread.sleep ( 2000L );
1563
1564
1565 TestSecurityHandler securityHandler = server.getChildHandlerByClass( TestSecurityHandler.class );
1566 testPreemptiveAuthenticationGet( securityHandler, supportPreemptiveAuthenticationGet() );
1567 }
1568 finally
1569 {
1570 server.stop();
1571 }
1572 }
1573
1574 public void testSecuredResourceExistsUnauthorized()
1575 throws Exception
1576 {
1577 try
1578 {
1579 runTestSecuredResourceExists( null );
1580 fail();
1581 }
1582 catch ( AuthorizationException e )
1583 {
1584 assertTrue( true );
1585 }
1586 }
1587
1588 public void testSecuredResourceExistsWrongPassword()
1589 throws Exception
1590 {
1591 try
1592 {
1593 AuthenticationInfo authInfo = new AuthenticationInfo();
1594 authInfo.setUserName( "user" );
1595 authInfo.setPassword( "admin" );
1596 runTestSecuredResourceExists( authInfo );
1597 }
1598 catch ( AuthorizationException e )
1599 {
1600 assertTrue( true );
1601 }
1602 }
1603
1604 public void testSecuredResourceExists()
1605 throws Exception
1606 {
1607 AuthenticationInfo authInfo = new AuthenticationInfo();
1608 authInfo.setUserName( "user" );
1609 authInfo.setPassword( "secret" );
1610 runTestSecuredResourceExists( authInfo );
1611 }
1612
1613 public void runTestSecuredResourceExists( AuthenticationInfo authInfo )
1614 throws Exception
1615 {
1616 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1617 Server server = createSecurityServer( localRepositoryPath );
1618
1619 server.start();
1620
1621 try
1622 {
1623 StreamingWagon wagon = (StreamingWagon) getWagon();
1624
1625 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1626
1627 File sourceFile = new File( localRepositoryPath, "test-secured-resource-exists" );
1628 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "top secret" );
1629
1630 wagon.connect( testRepository, authInfo );
1631
1632 try
1633 {
1634 assertTrue( wagon.resourceExists( "test-secured-resource-exists" ) );
1635
1636 assertFalse( wagon.resourceExists( "test-secured-resource-not-exists" ) );
1637 }
1638 finally
1639 {
1640 wagon.disconnect();
1641 }
1642 }
1643 finally
1644 {
1645 server.stop();
1646 }
1647 }
1648
1649 private Server createSecurityServer( String localRepositoryPath )
1650 {
1651 Server server = new Server( );
1652
1653 SecurityHandler sh = createSecurityHandler();
1654
1655 ServletContextHandler root = new ServletContextHandler( ServletContextHandler.SESSIONS
1656 | ServletContextHandler.SECURITY );
1657 root.setResourceBase( localRepositoryPath );
1658 root.setSecurityHandler( sh );
1659 ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
1660 root.addServlet( servletHolder, "/*" );
1661
1662 server.setHandler( root );
1663 addConnector( server );
1664 return server;
1665 }
1666
1667 private Server createStatusServer( int status )
1668 {
1669 Server server = new Server( );
1670 StatusHandler handler = new StatusHandler();
1671 handler.setStatusToReturn( status );
1672 server.setHandler( handler );
1673 addConnector( server );
1674 return server;
1675 }
1676
1677
1678 private String writeTestFile( File parent, String child, String compressionType )
1679 throws IOException
1680 {
1681 File file = new File( parent, child );
1682 file.getParentFile().mkdirs();
1683 file.deleteOnExit();
1684 OutputStream out = new FileOutputStream( file );
1685 try
1686 {
1687 out.write( child.getBytes() );
1688 }
1689 finally
1690 {
1691 out.close();
1692 }
1693
1694 String ext = "";
1695 if ( "gzip".equals( compressionType ) )
1696 {
1697 ext = ".gz";
1698 }
1699 if ( "deflate".equals( compressionType ) )
1700 {
1701 ext = ".deflate";
1702 }
1703
1704 file = new File( parent, child + ext );
1705 file.deleteOnExit();
1706 String content;
1707 out = new FileOutputStream( file );
1708 if ( "gzip".equals( compressionType ) )
1709 {
1710 out = new GZIPOutputStream( out );
1711 }
1712 if ( "deflate".equals( compressionType ) )
1713 {
1714 out = new DeflaterOutputStream( out );
1715 }
1716 try
1717 {
1718
1719
1720 content = file.getAbsolutePath();
1721 out.write( content.getBytes() );
1722 }
1723 finally
1724 {
1725 out.close();
1726 }
1727
1728 return content;
1729 }
1730
1731 public void testPutForbidden()
1732 throws Exception
1733 {
1734 try
1735 {
1736 runTestPut( HttpServletResponse.SC_FORBIDDEN );
1737 fail();
1738 }
1739 catch ( AuthorizationException e )
1740 {
1741 assertTrue( true );
1742 }
1743 }
1744
1745 public void testPut404()
1746 throws Exception
1747 {
1748 try
1749 {
1750 runTestPut( HttpServletResponse.SC_NOT_FOUND );
1751 fail();
1752 }
1753 catch ( ResourceDoesNotExistException e )
1754 {
1755 assertTrue( true );
1756 }
1757 }
1758
1759 public void testPut500()
1760 throws Exception
1761 {
1762 try
1763 {
1764 runTestPut( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
1765 fail();
1766 }
1767 catch ( TransferFailedException e )
1768 {
1769 assertTrue( true );
1770 }
1771 }
1772
1773 public void testPut429()
1774 throws Exception
1775 {
1776
1777 try
1778 {
1779
1780 StreamingWagon wagon = (StreamingWagon) getWagon();
1781 Server server = new Server( );
1782 final AtomicBoolean called = new AtomicBoolean();
1783
1784 AbstractHandler handler = new AbstractHandler()
1785 {
1786 public void handle( String target, Request baseRequest, HttpServletRequest request,
1787 HttpServletResponse response ) throws IOException, ServletException
1788 {
1789 if ( called.get() )
1790 {
1791 response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
1792 baseRequest.setHandled( true );
1793 }
1794 else
1795 {
1796 called.set( true );
1797 response.setStatus( SC_TOO_MANY_REQUESTS );
1798 baseRequest.setHandled( true );
1799 }
1800 }
1801 };
1802
1803 server.setHandler( handler );
1804 addConnector( server );
1805 server.start();
1806
1807 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
1808
1809 File tempFile = File.createTempFile( "wagon", "tmp" );
1810 tempFile.deleteOnExit();
1811 FileUtils.fileWrite( tempFile.getAbsolutePath(), "content" );
1812
1813 try
1814 {
1815 wagon.put( tempFile, "resource" );
1816 fail();
1817 }
1818 finally
1819 {
1820 wagon.disconnect();
1821
1822 server.stop();
1823
1824 tempFile.delete();
1825 }
1826
1827 }
1828 catch ( TransferFailedException e )
1829 {
1830 assertTrue( true );
1831 }
1832 }
1833
1834
1835 private void runTestPut( int status )
1836 throws Exception
1837 {
1838 StreamingWagon wagon = (StreamingWagon) getWagon();
1839
1840 Server server = createStatusServer( status );
1841 server.start();
1842
1843 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
1844
1845 File tempFile = File.createTempFile( "wagon", "tmp" );
1846 tempFile.deleteOnExit();
1847 FileUtils.fileWrite( tempFile.getAbsolutePath(), "content" );
1848
1849 String baseUrl = getRepositoryUrl( server );
1850 String resourceName = "resource";
1851 String serverReasonPhrase = HttpStatus.getCode( status ).getMessage();
1852
1853 try
1854 {
1855 wagon.put( tempFile, resourceName );
1856 fail();
1857 }
1858 catch ( Exception e )
1859 {
1860 verifyWagonExceptionMessage( e, status, baseUrl + "/" + resourceName, serverReasonPhrase );
1861 throw e;
1862 }
1863 finally
1864 {
1865 wagon.disconnect();
1866
1867 server.stop();
1868
1869 tempFile.delete();
1870 }
1871 }
1872
1873 public void testSecuredPutUnauthorized()
1874 throws Exception
1875 {
1876 try
1877 {
1878 runTestSecuredPut( null );
1879 fail();
1880 }
1881 catch ( AuthorizationException e )
1882 {
1883 assertTrue( true );
1884 }
1885 }
1886
1887 public void testSecuredPutWrongPassword()
1888 throws Exception
1889 {
1890 try
1891 {
1892 AuthenticationInfo authInfo = new AuthenticationInfo();
1893 authInfo.setUserName( "user" );
1894 authInfo.setPassword( "admin" );
1895 runTestSecuredPut( authInfo );
1896 fail();
1897 }
1898 catch ( AuthorizationException e )
1899 {
1900 assertTrue( true );
1901 }
1902 }
1903
1904 public void testSecuredPut()
1905 throws Exception
1906 {
1907 AuthenticationInfo authInfo = new AuthenticationInfo();
1908 authInfo.setUserName( "user" );
1909 authInfo.setPassword( "secret" );
1910 runTestSecuredPut( authInfo );
1911 }
1912
1913 public void runTestSecuredPut( AuthenticationInfo authInfo )
1914 throws Exception
1915 {
1916 runTestSecuredPut( authInfo, 1 );
1917 }
1918
1919 public void runTestSecuredPut( AuthenticationInfo authInfo, int putNumber )
1920 throws Exception
1921 {
1922 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1923 Server server = new Server( );
1924
1925 TestSecurityHandler sh = createSecurityHandler();
1926
1927 PutHandler putHandler = new PutHandler( new File( localRepositoryPath ) );
1928
1929 sh.setHandler( putHandler );
1930 server.setHandler( sh );
1931 addConnector( server );
1932 server.start();
1933
1934 StreamingWagon wagon = (StreamingWagon) getWagon();
1935 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1936 wagon.connect( testRepository, authInfo );
1937 try
1938 {
1939 for ( int i = 0; i < putNumber; i++ )
1940 {
1941 File sourceFile = new File( localRepositoryPath, "test-secured-put-resource" );
1942 sourceFile.delete();
1943 assertFalse( sourceFile.exists() );
1944
1945 File tempFile = File.createTempFile( "wagon", "tmp" );
1946 tempFile.deleteOnExit();
1947 FileUtils.fileWrite( tempFile.getAbsolutePath(), "put top secret" );
1948
1949 try
1950 {
1951 wagon.put( tempFile, "test-secured-put-resource" );
1952 }
1953 finally
1954 {
1955 tempFile.delete();
1956 }
1957
1958 assertEquals( "put top secret", FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
1959 }
1960 }
1961 finally
1962 {
1963 wagon.disconnect();
1964 server.stop();
1965 }
1966 assertEquals( putNumber, putHandler.putCallNumber );
1967 testPreemptiveAuthenticationPut( sh, supportPreemptiveAuthenticationPut() );
1968 }
1969
1970 public void testNonSecuredPutFromStream()
1971 throws Exception
1972 {
1973 AuthenticationInfo authInfo = new AuthenticationInfo();
1974 authInfo.setUserName( "user" );
1975 authInfo.setPassword( "secret" );
1976 runTestSecuredPutFromStream( authInfo, 1, false );
1977 }
1978
1979 public void testSecuredPutFromStream()
1980 throws Exception
1981 {
1982 AuthenticationInfo authInfo = new AuthenticationInfo();
1983 authInfo.setUserName( "user" );
1984 authInfo.setPassword( "secret" );
1985 runTestSecuredPutFromStream( authInfo, 1, true );
1986 }
1987
1988 public void runTestSecuredPutFromStream( AuthenticationInfo authInfo, int putNumber, boolean addSecurityHandler )
1989 throws Exception
1990 {
1991 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1992 Server server = new Server( );
1993
1994 TestSecurityHandler sh = createSecurityHandler();
1995
1996 PutHandler putHandler = new PutHandler( new File( localRepositoryPath ) );
1997
1998 if ( addSecurityHandler )
1999 {
2000 sh.setHandler( putHandler );
2001 server.setHandler( sh );
2002 }
2003 else
2004 {
2005 server.setHandler( putHandler );
2006 }
2007 addConnector( server );
2008 server.start();
2009
2010 StreamingWagon wagon = (StreamingWagon) getWagon();
2011 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
2012 if ( addSecurityHandler )
2013 {
2014 wagon.connect( testRepository, authInfo );
2015 }
2016 else
2017 {
2018 wagon.connect( testRepository );
2019 }
2020 try
2021 {
2022 for ( int i = 0; i < putNumber; i++ )
2023 {
2024 File sourceFile = new File( localRepositoryPath, "test-secured-put-resource" );
2025 sourceFile.delete();
2026 assertFalse( sourceFile.exists() );
2027
2028 File tempFile = File.createTempFile( "wagon", "tmp" );
2029 tempFile.deleteOnExit();
2030 String content = "put top secret";
2031 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
2032
2033 try ( FileInputStream fileInputStream = new FileInputStream( tempFile ) )
2034 {
2035 wagon.putFromStream( fileInputStream, "test-secured-put-resource", content.length(), -1 );
2036 }
2037 finally
2038 {
2039 tempFile.delete();
2040 }
2041
2042 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
2043 }
2044 }
2045 finally
2046 {
2047 wagon.disconnect();
2048 server.stop();
2049 }
2050 assertEquals( putNumber, putHandler.putCallNumber );
2051 if ( addSecurityHandler )
2052 {
2053 testPreemptiveAuthenticationPut( sh, supportPreemptiveAuthenticationPut() );
2054 }
2055
2056
2057 for ( DeployedResource deployedResource : putHandler.deployedResources )
2058 {
2059 if ( StringUtils.equalsIgnoreCase( "chunked", deployedResource.transferEncoding ) )
2060 {
2061 fail( "deployedResource use chunked: " + deployedResource );
2062 }
2063 }
2064 }
2065
2066
2067 protected abstract boolean supportPreemptiveAuthenticationPut();
2068
2069 protected abstract boolean supportPreemptiveAuthenticationGet();
2070
2071 protected abstract boolean supportProxyPreemptiveAuthentication();
2072
2073 protected void testPreemptiveAuthenticationGet( TestSecurityHandler sh, boolean preemptive )
2074 {
2075 testPreemptiveAuthentication( sh, preemptive, HttpServletResponse.SC_OK );
2076 }
2077
2078 protected void testPreemptiveAuthenticationPut( TestSecurityHandler sh, boolean preemptive )
2079 {
2080 testPreemptiveAuthentication( sh, preemptive, HttpServletResponse.SC_CREATED );
2081 }
2082
2083 protected void testPreemptiveAuthentication( TestSecurityHandler sh, boolean preemptive, int statusCode )
2084 {
2085
2086 if ( preemptive )
2087 {
2088 assertEquals( "not 1 security handler use " + sh.handlerRequestResponses, 1,
2089 sh.handlerRequestResponses.size() );
2090 assertEquals( statusCode, sh.handlerRequestResponses.get( 0 ).responseCode );
2091 }
2092 else
2093 {
2094 assertEquals( "not 2 security handler use " + sh.handlerRequestResponses, 2,
2095 sh.handlerRequestResponses.size() );
2096 assertEquals( HttpServletResponse.SC_UNAUTHORIZED, sh.handlerRequestResponses.get( 0 ).responseCode );
2097 assertEquals( statusCode, sh.handlerRequestResponses.get( 1 ).responseCode );
2098
2099 }
2100 }
2101
2102 static class StatusHandler
2103 extends AbstractHandler
2104 {
2105 private int status;
2106
2107 public void setStatusToReturn( int status )
2108 {
2109 this.status = status;
2110 }
2111
2112 public void handle( String target, Request baseRequest, HttpServletRequest request,
2113 HttpServletResponse response ) throws IOException, ServletException
2114 {
2115 if ( status != 0 )
2116 {
2117 response.setStatus( status );
2118 baseRequest.setHandled( true );
2119 }
2120 }
2121 }
2122
2123 static class DeployedResource
2124 {
2125 String httpMethod;
2126
2127 String requestUri;
2128
2129 String contentLength;
2130
2131 String transferEncoding;
2132
2133 DeployedResource()
2134 {
2135
2136 }
2137
2138 @Override
2139 public String toString()
2140 {
2141 final StringBuilder sb = new StringBuilder();
2142 sb.append( "DeployedResource" );
2143 sb.append( "{httpMethod='" ).append( httpMethod ).append( '\'' );
2144 sb.append( ", requestUri='" ).append( requestUri ).append( '\'' );
2145 sb.append( ", contentLength='" ).append( contentLength ).append( '\'' );
2146 sb.append( ", transferEncoding='" ).append( transferEncoding ).append( '\'' );
2147 sb.append( '}' );
2148 return sb.toString();
2149 }
2150 }
2151
2152
2153
2154
2155 @SuppressWarnings( "checkstyle:visibilitymodifier" )
2156 public static class PutHandler
2157 extends AbstractHandler
2158 {
2159 private final File resourceBase;
2160
2161 public List<DeployedResource> deployedResources = new ArrayList<DeployedResource>();
2162
2163 public int putCallNumber = 0;
2164
2165 public List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
2166
2167 public PutHandler( File repositoryDirectory )
2168 {
2169 this.resourceBase = repositoryDirectory;
2170 }
2171
2172 public void handle( String target, Request baseRequest, HttpServletRequest request,
2173 HttpServletResponse response ) throws IOException, ServletException
2174 {
2175 if ( baseRequest.isHandled() || !"PUT".equals( baseRequest.getMethod() ) )
2176 {
2177 return;
2178 }
2179
2180 baseRequest.setHandled( true );
2181
2182 File file = new File( resourceBase, URLDecoder.decode( request.getPathInfo() ) );
2183 file.getParentFile().mkdirs();
2184 OutputStream out = null;
2185 InputStream in = null;
2186 try
2187 {
2188 in = request.getInputStream();
2189 out = new FileOutputStream( file );
2190 IOUtil.copy( in, out );
2191 out.close();
2192 out = null;
2193 in.close();
2194 in = null;
2195 }
2196 finally
2197 {
2198 IOUtil.close( in );
2199 IOUtil.close( out );
2200 }
2201 putCallNumber++;
2202 DeployedResource deployedResource = new DeployedResource();
2203
2204 deployedResource.httpMethod = request.getMethod();
2205 deployedResource.requestUri = request.getRequestURI();
2206 deployedResource.transferEncoding = request.getHeader( "Transfer-Encoding" );
2207 deployedResource.contentLength = request.getHeader( "Content-Length" );
2208 deployedResources.add( deployedResource );
2209
2210 response.setStatus( HttpServletResponse.SC_CREATED );
2211
2212 handlerRequestResponses.add(
2213 new HandlerRequestResponse( request.getMethod(), ( (Response) response ).getStatus(),
2214 request.getRequestURI() ) );
2215 }
2216 }
2217
2218 private static class AuthorizingProxyHandler
2219 extends TestHeaderHandler
2220 {
2221
2222 List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
2223
2224 public void handle( String target, Request baseRequest, HttpServletRequest request,
2225 HttpServletResponse response ) throws IOException, ServletException
2226 {
2227 System.out.println( " handle proxy request" );
2228 if ( request.getHeader( "Proxy-Authorization" ) == null )
2229 {
2230 handlerRequestResponses.add(
2231 new HandlerRequestResponse( request.getMethod(),
2232 HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED,
2233 request.getRequestURI() ) );
2234 response.setStatus( HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED );
2235 response.addHeader( "Proxy-Authenticate", "Basic realm=\"Squid proxy-caching web server\"" );
2236
2237 baseRequest.setHandled( true );
2238 return;
2239 }
2240 handlerRequestResponses.add(
2241 new HandlerRequestResponse( request.getMethod(), HttpServletResponse.SC_OK, request.getRequestURI() ) );
2242 super.handle( target, baseRequest, request, response );
2243 }
2244 }
2245
2246
2247
2248
2249 @SuppressWarnings( "checkstyle:visibilitymodifier" )
2250 private static class TestHeaderHandler
2251 extends AbstractHandler
2252 {
2253 public Map<String, String> headers = Collections.emptyMap();
2254
2255 public List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
2256
2257 TestHeaderHandler()
2258 {
2259 }
2260
2261 public void handle( String target, Request baseRrequest, HttpServletRequest request,
2262 HttpServletResponse response ) throws IOException, ServletException
2263 {
2264 headers = new HashMap<String, String>();
2265 for ( Enumeration<String> e = baseRrequest.getHeaderNames(); e.hasMoreElements(); )
2266 {
2267 String name = e.nextElement();
2268 Enumeration headerValues = baseRrequest.getHeaders( name );
2269
2270
2271
2272 StringBuffer combinedHeaderValue = new StringBuffer();
2273 for ( int i = 0; headerValues.hasMoreElements(); i++ )
2274 {
2275 if ( i > 0 )
2276 {
2277 combinedHeaderValue.append( "," );
2278 }
2279 combinedHeaderValue.append( headerValues.nextElement() );
2280 }
2281 headers.put( name, combinedHeaderValue.toString() );
2282 }
2283
2284 response.setContentType( "text/plain" );
2285 response.setStatus( HttpServletResponse.SC_OK );
2286 response.getWriter().print( "Hello, World!" );
2287
2288 handlerRequestResponses.add(
2289 new HandlerRequestResponse( baseRrequest.getMethod(), ( (Response) response ).getStatus(),
2290 baseRrequest.getRequestURI() ) );
2291
2292 baseRrequest.setHandled( true );
2293 }
2294
2295 }
2296
2297 protected TestSecurityHandler createSecurityHandler()
2298 {
2299 Constraint constraint = new Constraint();
2300 constraint.setName( Constraint.__BASIC_AUTH );
2301 constraint.setRoles( new String[]{ "admin" } );
2302 constraint.setAuthenticate( true );
2303
2304 ConstraintMapping cm = new ConstraintMapping();
2305 cm.setConstraint( constraint );
2306 cm.setPathSpec( "/*" );
2307
2308 TestSecurityHandler sh = new TestSecurityHandler();
2309 HashLoginService hashLoginService = new HashLoginService( "MyRealm" );
2310 hashLoginService.putUser( "user", new Password( "secret" ), new String[] { "admin" } );
2311 sh.setLoginService( hashLoginService );
2312 sh.setConstraintMappings( new ConstraintMapping[]{ cm } );
2313 sh.setAuthenticator ( new BasicAuthenticator() );
2314 return sh;
2315 }
2316
2317
2318
2319
2320 @SuppressWarnings( "checkstyle:visibilitymodifier" )
2321 public static class TestSecurityHandler
2322 extends ConstraintSecurityHandler
2323 {
2324
2325 public List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
2326
2327 @Override
2328 public void handle( String target, Request baseRequest, HttpServletRequest request,
2329 HttpServletResponse response ) throws IOException, ServletException
2330 {
2331 String method = request.getMethod();
2332 super.handle( target, baseRequest, request, response );
2333
2334 handlerRequestResponses.add(
2335 new HandlerRequestResponse( method, ( (Response) response ).getStatus(), request.getRequestURI() ) );
2336 }
2337 }
2338
2339
2340
2341
2342 @SuppressWarnings( "checkstyle:visibilitymodifier" )
2343 public static class HandlerRequestResponse
2344 {
2345 public String method;
2346
2347 public int responseCode;
2348
2349 public String requestUri;
2350
2351 private HandlerRequestResponse( String method, int responseCode, String requestUri )
2352 {
2353 this.method = method;
2354 this.responseCode = responseCode;
2355 this.requestUri = requestUri;
2356 }
2357
2358 @Override
2359 public String toString()
2360 {
2361 final StringBuilder sb = new StringBuilder();
2362 sb.append( "HandlerRequestResponse" );
2363 sb.append( "{method='" ).append( method ).append( '\'' );
2364 sb.append( ", responseCode=" ).append( responseCode );
2365 sb.append( ", requestUri='" ).append( requestUri ).append( '\'' );
2366 sb.append( '}' );
2367 return sb.toString();
2368 }
2369 }
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383 protected void verifyWagonExceptionMessage( Exception e, int forStatusCode, String forUrl, String forReasonPhrase )
2384 {
2385
2386 assertNotNull( e );
2387 try
2388 {
2389 assertTrue( "only verify instances of WagonException", e instanceof WagonException );
2390
2391 String reasonPhrase;
2392 String assertMessageForBadMessage = "exception message not described properly";
2393 switch ( forStatusCode )
2394 {
2395 case HttpServletResponse.SC_NOT_FOUND:
2396
2397 assertTrue( "404 not found response should throw ResourceDoesNotExistException",
2398 e instanceof ResourceDoesNotExistException );
2399 reasonPhrase = StringUtils.isEmpty( forReasonPhrase ) ? " Not Found" : ( " " + forReasonPhrase );
2400 assertEquals( assertMessageForBadMessage, "resource missing at " + forUrl + ", status: 404"
2401 + reasonPhrase, e.getMessage() );
2402 break;
2403
2404 case HttpServletResponse.SC_UNAUTHORIZED:
2405
2406 assertTrue( "401 Unauthorized should throw AuthorizationException since "
2407 + " AuthenticationException is not explicitly declared as thrown from wagon "
2408 + "methods",
2409 e instanceof AuthorizationException );
2410 reasonPhrase = StringUtils.isEmpty( forReasonPhrase ) ? " Unauthorized" : ( " " + forReasonPhrase );
2411 assertEquals( assertMessageForBadMessage, "authentication failed for " + forUrl + ", status: 401"
2412 + reasonPhrase, e.getMessage() );
2413 break;
2414
2415 case HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED:
2416 assertTrue( "407 Proxy authentication required should throw AuthorizationException",
2417 e instanceof AuthorizationException );
2418 reasonPhrase = StringUtils.isEmpty( forReasonPhrase ) ? " Proxy Authentication Required"
2419 : ( " " + forReasonPhrase );
2420 assertEquals( assertMessageForBadMessage, "proxy authentication failed for "
2421 + forUrl + ", status: 407" + reasonPhrase, e.getMessage() );
2422 break;
2423
2424 case HttpServletResponse.SC_FORBIDDEN:
2425 assertTrue( "403 Forbidden should throw AuthorizationException",
2426 e instanceof AuthorizationException );
2427 reasonPhrase = StringUtils.isEmpty( forReasonPhrase ) ? " Forbidden" : ( " " + forReasonPhrase );
2428 assertEquals( assertMessageForBadMessage, "authorization failed for " + forUrl + ", status: 403"
2429 + reasonPhrase, e.getMessage() );
2430 break;
2431
2432 default:
2433 assertTrue( "transfer failures should at least be wrapped in a TransferFailedException", e
2434 instanceof TransferFailedException );
2435 assertTrue( "expected status code for transfer failures should be >= 400",
2436 forStatusCode >= HttpServletResponse.SC_BAD_REQUEST );
2437 reasonPhrase = forReasonPhrase == null ? "" : " " + forReasonPhrase;
2438 assertEquals( assertMessageForBadMessage, "transfer failed for " + forUrl + ", status: "
2439 + forStatusCode + reasonPhrase, e.getMessage() );
2440 break;
2441 }
2442 }
2443 catch ( AssertionError assertionError )
2444 {
2445 logger.error( "Exception which failed assertions: ", e );
2446 throw assertionError;
2447 }
2448
2449 }
2450
2451 }