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.authentication.AuthenticationInfo;
29 import org.apache.maven.wagon.authorization.AuthorizationException;
30 import org.apache.maven.wagon.proxy.ProxyInfo;
31 import org.apache.maven.wagon.repository.Repository;
32 import org.apache.maven.wagon.resource.Resource;
33 import org.codehaus.plexus.util.FileUtils;
34 import org.codehaus.plexus.util.IOUtil;
35 import org.codehaus.plexus.util.StringUtils;
36 import org.mortbay.jetty.Handler;
37 import org.mortbay.jetty.HttpConnection;
38 import org.mortbay.jetty.Request;
39 import org.mortbay.jetty.Response;
40 import org.mortbay.jetty.Server;
41 import org.mortbay.jetty.handler.AbstractHandler;
42 import org.mortbay.jetty.handler.HandlerCollection;
43 import org.mortbay.jetty.security.Constraint;
44 import org.mortbay.jetty.security.ConstraintMapping;
45 import org.mortbay.jetty.security.HashUserRealm;
46 import org.mortbay.jetty.security.SecurityHandler;
47 import org.mortbay.jetty.servlet.Context;
48 import org.mortbay.jetty.servlet.DefaultServlet;
49 import org.mortbay.jetty.servlet.ServletHolder;
50
51 import javax.servlet.ServletException;
52 import javax.servlet.ServletInputStream;
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletResponse;
55 import java.io.ByteArrayOutputStream;
56 import java.io.File;
57 import java.io.FileInputStream;
58 import java.io.FileOutputStream;
59 import java.io.IOException;
60 import java.io.OutputStream;
61 import java.lang.reflect.Method;
62 import java.net.URLDecoder;
63 import java.util.ArrayList;
64 import java.util.Collections;
65 import java.util.Enumeration;
66 import java.util.HashMap;
67 import java.util.List;
68 import java.util.Map;
69 import java.util.Properties;
70 import java.util.concurrent.atomic.AtomicBoolean;
71 import java.util.zip.GZIPOutputStream;
72
73
74
75
76 public abstract class HttpWagonTestCase
77 extends StreamingWagonTestCase
78 {
79 private Server server;
80
81 protected void setupWagonTestingFixtures()
82 throws Exception
83 {
84
85
86 File file = FileTestUtils.createUniqueFile( "local-repository", "test-resource" );
87
88 file.delete();
89
90 file.getParentFile().mkdirs();
91
92 File repositoryDirectory = getRepositoryDirectory();
93 FileUtils.deleteDirectory( repositoryDirectory );
94 repositoryDirectory.mkdirs();
95
96 server = new Server( 0 );
97
98 PutHandler putHandler = new PutHandler( repositoryDirectory );
99 server.addHandler( putHandler );
100
101 createContext( server, repositoryDirectory );
102
103 addConnectors( server );
104
105 server.start();
106
107 testRepository.setUrl( getTestRepositoryUrl() );
108 }
109
110 @Override
111 protected final int getTestRepositoryPort()
112 {
113 if ( server == null )
114 {
115 return 0;
116 }
117 return server.getConnectors()[0].getLocalPort();
118 }
119
120 protected void createContext( Server server, File repositoryDirectory )
121 throws IOException
122 {
123 Context root = new Context( server, "/", Context.SESSIONS );
124 root.setResourceBase( repositoryDirectory.getAbsolutePath() );
125 ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
126 root.addServlet( servletHolder, "/*" );
127 }
128
129 protected void tearDownWagonTestingFixtures()
130 throws Exception
131 {
132 server.stop();
133 }
134
135 public void testWagonGetFileList()
136 throws Exception
137 {
138 File dir = getRepositoryDirectory();
139 FileUtils.deleteDirectory( dir );
140
141 File f = new File( dir, "file-list" );
142 f.mkdirs();
143
144 super.testWagonGetFileList();
145 }
146
147 public void testHttpHeaders()
148 throws Exception
149 {
150 Properties properties = new Properties();
151 properties.setProperty( "User-Agent", "Maven-Wagon/1.0" );
152
153 StreamingWagon wagon = (StreamingWagon) getWagon();
154
155 setHttpHeaders( wagon, properties );
156
157 Server server = new Server( 0 );
158 TestHeaderHandler handler = new TestHeaderHandler();
159 server.setHandler( handler );
160 addConnectors( server );
161 server.start();
162
163 wagon.connect(
164 new Repository( "id", getProtocol() + "://localhost:" + server.getConnectors()[0].getLocalPort() ) );
165
166 wagon.getToStream( "resource", new ByteArrayOutputStream() );
167
168 wagon.disconnect();
169
170 server.stop();
171
172 assertEquals( "Maven-Wagon/1.0", handler.headers.get( "User-Agent" ) );
173 }
174
175
176
177
178 public void testHttpHeadersWithCommonMethods()
179 throws Exception
180 {
181 Properties properties = new Properties();
182 properties.setProperty( "User-Agent", "Maven-Wagon/1.0" );
183
184 StreamingWagon wagon = (StreamingWagon) getWagon();
185
186 Method setHttpHeaders = wagon.getClass().getMethod( "setHttpHeaders", Properties.class );
187 setHttpHeaders.invoke( wagon, properties );
188
189 Server server = new Server( 0 );
190 TestHeaderHandler handler = new TestHeaderHandler();
191 server.setHandler( handler );
192 addConnectors( server );
193 server.start();
194
195 wagon.connect(
196 new Repository( "id", getProtocol() + "://localhost:" + server.getConnectors()[0].getLocalPort() ) );
197
198 wagon.getToStream( "resource", new ByteArrayOutputStream() );
199
200 wagon.disconnect();
201
202 server.stop();
203
204 assertEquals( "Maven-Wagon/1.0", handler.headers.get( "User-Agent" ) );
205 }
206
207 protected abstract void setHttpHeaders( StreamingWagon wagon, Properties properties );
208
209 protected void addConnectors( Server server )
210 {
211 }
212
213 protected String getRepositoryUrl( Server server )
214 {
215 int localPort = server.getConnectors()[0].getLocalPort();
216 return getProtocol() + "://localhost:" + localPort;
217 }
218
219 public void testGetForbidden()
220 throws Exception
221 {
222 try
223 {
224 runTestGet( HttpServletResponse.SC_FORBIDDEN );
225 fail();
226 }
227 catch ( AuthorizationException e )
228 {
229 assertTrue( true );
230 }
231 }
232
233 public void testGet404()
234 throws Exception
235 {
236 try
237 {
238 runTestGet( HttpServletResponse.SC_NOT_FOUND );
239 fail();
240 }
241 catch ( ResourceDoesNotExistException e )
242 {
243 assertTrue( true );
244 }
245 }
246
247 public void testList429()
248 throws Exception
249 {
250 StreamingWagon wagon = (StreamingWagon) getWagon();
251 try
252 {
253
254 Server server = new Server( 0 );
255 final AtomicBoolean called = new AtomicBoolean();
256
257 AbstractHandler handler = new AbstractHandler()
258 {
259 public void handle( String s, HttpServletRequest request, HttpServletResponse response, int i )
260 throws IOException, ServletException
261 {
262 if ( called.get() )
263 {
264 response.setStatus( 200 );
265 ( (Request) request ).setHandled( true );
266 }
267 else
268 {
269 called.set( true );
270 response.setStatus( 429 );
271 ( (Request) request ).setHandled( true );
272
273 }
274 }
275 };
276
277 server.setHandler( handler );
278 addConnectors( server );
279 server.start();
280
281 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
282
283 try
284 {
285 wagon.getFileList( "resource" );
286 }
287 finally
288 {
289 wagon.disconnect();
290
291 server.stop();
292 }
293
294 }
295 catch ( ResourceDoesNotExistException e )
296 {
297 assertTrue( true );
298 }
299 catch ( TransferFailedException e )
300 {
301 if ( wagon.getClass().getName().contains( "Lightweight" ) )
302 {
303
304 assertTrue( true );
305 }
306 else
307 {
308 fail();
309 }
310
311 }
312 }
313
314 public void testGet500()
315 throws Exception
316 {
317 try
318 {
319 runTestGet( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
320 fail();
321 }
322 catch ( TransferFailedException e )
323 {
324 assertTrue( true );
325 }
326 }
327
328 private void runTestGet( int status )
329 throws Exception
330 {
331 StreamingWagon wagon = (StreamingWagon) getWagon();
332
333 Server server = new Server( 0 );
334 StatusHandler handler = new StatusHandler();
335 handler.setStatusToReturn( status );
336 server.setHandler( handler );
337 addConnectors( server );
338 server.start();
339
340 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
341
342 try
343 {
344 wagon.getToStream( "resource", new ByteArrayOutputStream() );
345 fail();
346 }
347 finally
348 {
349 wagon.disconnect();
350
351 server.stop();
352 }
353 }
354
355 public void testResourceExistsForbidden()
356 throws Exception
357 {
358 try
359 {
360 runTestResourceExists( HttpServletResponse.SC_FORBIDDEN );
361 fail();
362 }
363 catch ( AuthorizationException e )
364 {
365 assertTrue( true );
366 }
367 }
368
369 public void testResourceExists404()
370 throws Exception
371 {
372 try
373 {
374 assertFalse( runTestResourceExists( HttpServletResponse.SC_NOT_FOUND ) );
375 }
376 catch ( ResourceDoesNotExistException e )
377 {
378 assertTrue( true );
379 }
380 }
381
382 public void testResourceExists500()
383 throws Exception
384 {
385 try
386 {
387 runTestResourceExists( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
388 fail();
389 }
390 catch ( TransferFailedException e )
391 {
392 assertTrue( true );
393 }
394 }
395
396 public void testResourceExists429()
397 throws Exception
398 {
399 try
400 {
401
402 final AtomicBoolean called = new AtomicBoolean();
403
404 AbstractHandler handler = new AbstractHandler()
405 {
406 public void handle( String s, HttpServletRequest request, HttpServletResponse response, int i )
407 throws IOException, ServletException
408 {
409 if ( called.get() )
410 {
411 response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
412 ( (Request) request ).setHandled( true );
413 }
414 else
415 {
416 called.set( true );
417 response.setStatus( 429 );
418 ( (Request) request ).setHandled( true );
419 }
420 }
421 };
422
423 StreamingWagon wagon = (StreamingWagon) getWagon();
424 Server server = new Server( 0 );
425 server.setHandler( handler );
426 addConnectors( server );
427 server.start();
428 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
429
430 try
431 {
432 wagon.resourceExists( "resource" );
433 }
434 finally
435 {
436 wagon.disconnect();
437
438 server.stop();
439 }
440
441 fail();
442 }
443 catch ( TransferFailedException e )
444 {
445 assertTrue( true );
446 }
447 }
448
449
450 private boolean runTestResourceExists( int status )
451 throws Exception
452 {
453 StreamingWagon wagon = (StreamingWagon) getWagon();
454
455 Server server = new Server( 0 );
456 StatusHandler handler = new StatusHandler();
457 handler.setStatusToReturn( status );
458 server.setHandler( handler );
459 addConnectors( server );
460 server.start();
461
462 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
463
464 try
465 {
466 return wagon.resourceExists( "resource" );
467 }
468 finally
469 {
470 wagon.disconnect();
471
472 server.stop();
473 }
474 }
475
476 protected long getExpectedLastModifiedOnGet( Repository repository, Resource resource )
477 {
478 File file = new File( getRepositoryDirectory(), resource.getName() );
479 return ( file.lastModified() / 1000 ) * 1000;
480 }
481
482 protected File getRepositoryDirectory()
483 {
484 return getTestFile( "target/test-output/http-repository" );
485 }
486
487 public void testGzipGet()
488 throws Exception
489 {
490 Server server = new Server( getTestRepositoryPort() );
491
492 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
493 Context root = new Context( server, "/", Context.SESSIONS );
494 root.setResourceBase( localRepositoryPath );
495 ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
496 servletHolder.setInitParameter( "gzip", "true" );
497 root.addServlet( servletHolder, "/*" );
498 addConnectors( server );
499 server.start();
500
501 try
502 {
503 Wagon wagon = getWagon();
504
505 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
506
507 File sourceFile = new File( localRepositoryPath + "/gzip" );
508
509 sourceFile.deleteOnExit();
510
511 String resName = "gzip-res.txt";
512 String sourceContent = writeTestFileGzip( sourceFile, resName );
513
514 wagon.connect( testRepository );
515
516 File destFile = FileTestUtils.createUniqueFile( getName(), getName() );
517
518 destFile.deleteOnExit();
519
520 wagon.get( "gzip/" + resName, destFile );
521
522 wagon.disconnect();
523
524 String destContent = FileUtils.fileRead( destFile );
525
526 assertEquals( sourceContent, destContent );
527 }
528 finally
529 {
530 server.stop();
531 }
532 }
533
534 public void testProxiedRequest()
535 throws Exception
536 {
537 ProxyInfo proxyInfo = createProxyInfo();
538 TestHeaderHandler handler = new TestHeaderHandler();
539
540 runTestProxiedRequest( proxyInfo, handler );
541 }
542
543 public void testProxiedRequestWithAuthentication()
544 throws Exception
545 {
546 ProxyInfo proxyInfo = createProxyInfo();
547 proxyInfo.setUserName( "user" );
548 proxyInfo.setPassword( "secret" );
549 AuthorizingProxyHandler handler = new AuthorizingProxyHandler();
550
551 runTestProxiedRequest( proxyInfo, handler );
552
553 assertTrue( handler.headers.containsKey( "Proxy-Authorization" ) );
554
555 if ( supportProxyPreemptiveAuthentication() )
556 {
557 assertEquals( 200, handler.handlerRequestResponses.get( 0 ).responseCode );
558 }
559 else
560 {
561 assertEquals( 407, handler.handlerRequestResponses.get( 0 ).responseCode );
562 assertEquals( 200, handler.handlerRequestResponses.get( 1 ).responseCode );
563 }
564
565 }
566
567 public void testRedirectGetToStream()
568 throws Exception
569 {
570 StreamingWagon wagon = (StreamingWagon) getWagon();
571
572 Server server = new Server( 0 );
573 TestHeaderHandler handler = new TestHeaderHandler();
574
575 server.setHandler( handler );
576 addConnectors( server );
577 server.start();
578
579 Server redirectServer = new Server( 0 );
580
581 addConnectors( redirectServer );
582
583 String protocol = getProtocol();
584
585
586 if ( protocol.equals( "dav" ) )
587 {
588 protocol = "http";
589 }
590
591 if ( protocol.equals( "davs" ) )
592 {
593 protocol = "https";
594 }
595
596 String redirectUrl = protocol + "://localhost:" + server.getConnectors()[0].getLocalPort();
597
598 RedirectHandler redirectHandler = new RedirectHandler( "Found", 303, redirectUrl, null );
599
600 redirectServer.setHandler( redirectHandler );
601
602 redirectServer.start();
603
604 wagon.connect( new Repository( "id", getRepositoryUrl( redirectServer ) ) );
605
606 File tmpResult = File.createTempFile( "foo", "get" );
607
608 FileOutputStream fileOutputStream = new FileOutputStream( tmpResult );
609
610 try
611 {
612 wagon.getToStream( "resource", fileOutputStream );
613 fileOutputStream.flush();
614 fileOutputStream.close();
615 String found = FileUtils.fileRead( tmpResult );
616 assertEquals( "found:'" + found + "'", "Hello, World!", found );
617
618 assertEquals( 1, handler.handlerRequestResponses.size() );
619 assertEquals( 200, handler.handlerRequestResponses.get( 0 ).responseCode );
620 assertEquals( 1, redirectHandler.handlerRequestResponses.size() );
621 assertEquals( 302, redirectHandler.handlerRequestResponses.get( 0 ).responseCode );
622 }
623 finally
624 {
625 wagon.disconnect();
626
627 server.stop();
628
629 tmpResult.delete();
630 }
631 }
632
633 public void testRedirectGet()
634 throws Exception
635 {
636 StreamingWagon wagon = (StreamingWagon) getWagon();
637
638 Server server = new Server( 0 );
639 TestHeaderHandler handler = new TestHeaderHandler();
640
641 server.setHandler( handler );
642 addConnectors( server );
643 server.start();
644
645 Server redirectServer = new Server( 0 );
646
647 addConnectors( redirectServer );
648
649 String protocol = getProtocol();
650
651
652 if ( protocol.equals( "dav" ) )
653 {
654 protocol = "http";
655 }
656
657 if ( protocol.equals( "davs" ) )
658 {
659 protocol = "https";
660 }
661
662 String redirectUrl = protocol + "://localhost:" + server.getConnectors()[0].getLocalPort();
663
664 RedirectHandler redirectHandler = new RedirectHandler( "Found", 303, redirectUrl, null );
665
666 redirectServer.setHandler( redirectHandler );
667
668 redirectServer.start();
669
670 wagon.connect( new Repository( "id", getRepositoryUrl( redirectServer ) ) );
671
672 File tmpResult = File.createTempFile( "foo", "get" );
673
674 try
675 {
676 wagon.get( "resource", tmpResult );
677 String found = FileUtils.fileRead( tmpResult );
678 assertEquals( "found:'" + found + "'", "Hello, World!", found );
679
680 assertEquals( 1, handler.handlerRequestResponses.size() );
681 assertEquals( 200, handler.handlerRequestResponses.get( 0 ).responseCode );
682 assertEquals( 1, redirectHandler.handlerRequestResponses.size() );
683 assertEquals( 302, redirectHandler.handlerRequestResponses.get( 0 ).responseCode );
684 }
685 finally
686 {
687 wagon.disconnect();
688
689 server.stop();
690
691 tmpResult.delete();
692 }
693 }
694
695
696 public void testRedirectPutFromStreamWithFullUrl()
697 throws Exception
698 {
699 Server realServer = new Server( 0 );
700
701 addConnectors( realServer );
702
703 File repositoryDirectory = getRepositoryDirectory();
704 FileUtils.deleteDirectory( repositoryDirectory );
705 repositoryDirectory.mkdirs();
706
707 PutHandler putHandler = new PutHandler( repositoryDirectory );
708
709 realServer.setHandler( putHandler );
710
711 realServer.start();
712
713 Server redirectServer = new Server( 0 );
714
715 addConnectors( redirectServer );
716
717 String protocol = getProtocol();
718
719
720 if ( protocol.equals( "dav" ) )
721 {
722 protocol = "http";
723 }
724
725 if ( protocol.equals( "davs" ) )
726 {
727 protocol = "https";
728 }
729
730 String redirectUrl = protocol + "://localhost:" + realServer.getConnectors()[0].getLocalPort();
731
732 RedirectHandler redirectHandler = new RedirectHandler( "Found", 303, redirectUrl, repositoryDirectory );
733
734 redirectServer.setHandler( redirectHandler );
735
736 redirectServer.start();
737
738 try
739 {
740 StreamingWagon wagon = (StreamingWagon) getWagon();
741 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
742 wagon.connect( repository );
743
744 File sourceFile = new File( repositoryDirectory, "test-secured-put-resource" );
745 sourceFile.delete();
746 assertFalse( sourceFile.exists() );
747
748 File tempFile = File.createTempFile( "wagon", "tmp" );
749 tempFile.deleteOnExit();
750 String content = "put top secret";
751 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
752
753 FileInputStream fileInputStream = new FileInputStream( tempFile );
754 try
755 {
756 wagon.putFromStream( fileInputStream, "test-secured-put-resource", content.length(), -1 );
757 }
758 finally
759 {
760 fileInputStream.close();
761 tempFile.delete();
762
763 }
764
765 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
766
767 checkRequestResponseForRedirectPutFromStreamWithFullUrl( putHandler, redirectHandler );
768 }
769 finally
770 {
771 realServer.stop();
772 redirectServer.stop();
773 }
774 }
775
776 protected void checkRequestResponseForRedirectPutFromStreamWithFullUrl( PutHandler putHandler,
777 RedirectHandler redirectHandler )
778 {
779 assertEquals( "found:" + putHandler.handlerRequestResponses, 1, putHandler.handlerRequestResponses.size() );
780 assertEquals( "found:" + putHandler.handlerRequestResponses, 201,
781 putHandler.handlerRequestResponses.get( 0 ).responseCode );
782 assertEquals( "found:" + redirectHandler.handlerRequestResponses, 1,
783 redirectHandler.handlerRequestResponses.size() );
784 assertEquals( "found:" + redirectHandler.handlerRequestResponses, 302,
785 redirectHandler.handlerRequestResponses.get( 0 ).responseCode );
786 }
787
788 public void testRedirectPutFromStreamRelativeUrl()
789 throws Exception
790 {
791 Server realServer = new Server( 0 );
792 addConnectors( realServer );
793 File repositoryDirectory = getRepositoryDirectory();
794 FileUtils.deleteDirectory( repositoryDirectory );
795 repositoryDirectory.mkdirs();
796
797 PutHandler putHandler = new PutHandler( repositoryDirectory );
798
799 realServer.setHandler( putHandler );
800
801 realServer.start();
802
803 Server redirectServer = new Server( 0 );
804
805 addConnectors( redirectServer );
806
807 RedirectHandler redirectHandler =
808 new RedirectHandler( "Found", 303, "/redirectRequest/foo", repositoryDirectory );
809
810 redirectServer.setHandler( redirectHandler );
811
812 redirectServer.start();
813
814 try
815 {
816 StreamingWagon wagon = (StreamingWagon) getWagon();
817 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
818 wagon.connect( repository );
819
820 File sourceFile = new File( repositoryDirectory, "/redirectRequest/foo/test-secured-put-resource" );
821 sourceFile.delete();
822 assertFalse( sourceFile.exists() );
823
824 File tempFile = File.createTempFile( "wagon", "tmp" );
825 tempFile.deleteOnExit();
826 String content = "put top secret";
827 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
828
829 FileInputStream fileInputStream = new FileInputStream( tempFile );
830 try
831 {
832 wagon.putFromStream( fileInputStream, "test-secured-put-resource", content.length(), -1 );
833 }
834 finally
835 {
836 fileInputStream.close();
837 tempFile.delete();
838
839 }
840
841 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
842
843 checkRequestResponseForRedirectPutFromStreamWithRelativeUrl( putHandler, redirectHandler );
844
845 }
846 finally
847 {
848 realServer.stop();
849 redirectServer.stop();
850 }
851 }
852
853 protected void checkRequestResponseForRedirectPutFromStreamWithRelativeUrl( PutHandler putHandler,
854 RedirectHandler redirectHandler )
855 {
856 assertEquals( "found:" + putHandler.handlerRequestResponses, 0, putHandler.handlerRequestResponses.size() );
857
858 assertEquals( "found:" + redirectHandler.handlerRequestResponses, 2,
859 redirectHandler.handlerRequestResponses.size() );
860 assertEquals( "found:" + redirectHandler.handlerRequestResponses, 302,
861 redirectHandler.handlerRequestResponses.get( 0 ).responseCode );
862 assertEquals( "found:" + redirectHandler.handlerRequestResponses, 201,
863 redirectHandler.handlerRequestResponses.get( 1 ).responseCode );
864
865 }
866
867 public void testRedirectPutFileWithFullUrl()
868 throws Exception
869 {
870 Server realServer = new Server( 0 );
871
872 addConnectors( realServer );
873
874 File repositoryDirectory = getRepositoryDirectory();
875 FileUtils.deleteDirectory( repositoryDirectory );
876 repositoryDirectory.mkdirs();
877
878 PutHandler putHandler = new PutHandler( repositoryDirectory );
879
880 realServer.setHandler( putHandler );
881
882 realServer.start();
883
884 Server redirectServer = new Server( 0 );
885
886 addConnectors( redirectServer );
887
888 String protocol = getProtocol();
889
890
891 if ( protocol.equals( "dav" ) )
892 {
893 protocol = "http";
894 }
895
896 if ( protocol.equals( "davs" ) )
897 {
898 protocol = "https";
899 }
900
901 String redirectUrl = protocol + "://localhost:" + realServer.getConnectors()[0].getLocalPort();
902
903 RedirectHandler redirectHandler = new RedirectHandler( "Found", 303, redirectUrl, repositoryDirectory );
904
905 redirectServer.setHandler( redirectHandler );
906
907 redirectServer.start();
908
909 try
910 {
911 StreamingWagon wagon = (StreamingWagon) getWagon();
912 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
913 wagon.connect( repository );
914
915 File sourceFile = new File( repositoryDirectory, "test-secured-put-resource" );
916 sourceFile.delete();
917 assertFalse( sourceFile.exists() );
918
919 File tempFile = File.createTempFile( "wagon", "tmp" );
920 tempFile.deleteOnExit();
921 String content = "put top secret";
922 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
923
924 try
925 {
926 wagon.put( tempFile, "test-secured-put-resource" );
927 }
928 finally
929 {
930 tempFile.delete();
931 }
932
933 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
934
935 }
936 finally
937 {
938 realServer.stop();
939 redirectServer.stop();
940 }
941 }
942
943
944 public void testRedirectPutFileRelativeUrl()
945 throws Exception
946 {
947 Server realServer = new Server( 0 );
948 addConnectors( realServer );
949 File repositoryDirectory = getRepositoryDirectory();
950 FileUtils.deleteDirectory( repositoryDirectory );
951 repositoryDirectory.mkdirs();
952
953 PutHandler putHandler = new PutHandler( repositoryDirectory );
954
955 realServer.setHandler( putHandler );
956
957 realServer.start();
958
959 Server redirectServer = new Server( 0 );
960
961 addConnectors( redirectServer );
962
963 RedirectHandler redirectHandler =
964 new RedirectHandler( "Found", 303, "/redirectRequest/foo", repositoryDirectory );
965
966 redirectServer.setHandler( redirectHandler );
967
968 redirectServer.start();
969
970 try
971 {
972 StreamingWagon wagon = (StreamingWagon) getWagon();
973 Repository repository = new Repository( "foo", getRepositoryUrl( redirectServer ) );
974 wagon.connect( repository );
975
976 File sourceFile = new File( repositoryDirectory, "/redirectRequest/foo/test-secured-put-resource" );
977 sourceFile.delete();
978 assertFalse( sourceFile.exists() );
979
980 File tempFile = File.createTempFile( "wagon", "tmp" );
981 tempFile.deleteOnExit();
982 String content = "put top secret";
983 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
984
985 try
986 {
987 wagon.put( tempFile, "test-secured-put-resource" );
988 }
989 finally
990 {
991 tempFile.delete();
992 }
993
994 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
995
996 }
997 finally
998 {
999 realServer.stop();
1000 redirectServer.stop();
1001 }
1002 }
1003
1004
1005 public static class RedirectHandler
1006 extends AbstractHandler
1007 {
1008 String reason;
1009
1010 int retCode;
1011
1012 String redirectUrl;
1013
1014 File repositoryDirectory;
1015
1016 public List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
1017
1018 RedirectHandler( String reason, int retCode, String redirectUrl, File repositoryDirectory )
1019 {
1020 this.reason = reason;
1021 this.retCode = retCode;
1022 this.redirectUrl = redirectUrl;
1023 this.repositoryDirectory = repositoryDirectory;
1024 }
1025
1026 public void handle( String s, HttpServletRequest req, HttpServletResponse resp, int i )
1027 throws IOException, ServletException
1028 {
1029 if ( req.getRequestURI().contains( "redirectRequest" ) )
1030 {
1031 PutHandler putHandler = new PutHandler( this.repositoryDirectory );
1032 putHandler.handle( s, req, resp, i );
1033 handlerRequestResponses.add(
1034 new HandlerRequestResponse( req.getMethod(), ( (Response) resp ).getStatus(),
1035 req.getRequestURI() ) );
1036 return;
1037 }
1038 resp.setStatus( this.retCode );
1039 resp.sendRedirect( this.redirectUrl + "/" + req.getRequestURI() );
1040 handlerRequestResponses.add(
1041 new HandlerRequestResponse( req.getMethod(), ( (Response) resp ).getStatus(), req.getRequestURI() ) );
1042 }
1043 }
1044
1045
1046 private void runTestProxiedRequest( ProxyInfo proxyInfo, TestHeaderHandler handler )
1047 throws Exception
1048 {
1049
1050
1051
1052 Thread.sleep( 5001L );
1053
1054 Server proxyServer = new Server( 0 );
1055
1056 proxyServer.setHandler( handler );
1057
1058 proxyServer.start();
1059
1060 proxyInfo.setPort( proxyServer.getConnectors()[0].getLocalPort() );
1061
1062 System.out.println(
1063 "start proxy on host/port " + proxyInfo.getHost() + "/" + proxyInfo.getPort() + " with non proxyHosts "
1064 + proxyInfo.getNonProxyHosts() );
1065
1066 while ( !proxyServer.isRunning() || !proxyServer.isStarted() )
1067 {
1068 Thread.sleep( 10 );
1069 }
1070
1071 try
1072 {
1073 StreamingWagon wagon = (StreamingWagon) getWagon();
1074
1075 Repository testRepository = new Repository( "id", "http://www.example.com/" );
1076
1077 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1078 File sourceFile = new File( localRepositoryPath, "test-proxied-resource" );
1079 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "content" );
1080
1081 wagon.connect( testRepository, proxyInfo );
1082
1083 try
1084 {
1085 wagon.getToStream( "test-proxied-resource", new ByteArrayOutputStream() );
1086
1087 assertTrue( handler.headers.containsKey( "Proxy-Connection" ) );
1088 }
1089 finally
1090 {
1091 System.setProperty( "http.proxyHost", "" );
1092 System.setProperty( "http.proxyPort", "" );
1093 wagon.disconnect();
1094 }
1095 }
1096 finally
1097 {
1098 proxyServer.stop();
1099 }
1100 }
1101
1102 private ProxyInfo createProxyInfo()
1103 {
1104 ProxyInfo proxyInfo = new ProxyInfo();
1105 proxyInfo.setHost( "localhost" );
1106 proxyInfo.setNonProxyHosts( null );
1107 proxyInfo.setType( "http" );
1108 return proxyInfo;
1109 }
1110
1111 public void testSecuredGetUnauthorized()
1112 throws Exception
1113 {
1114 try
1115 {
1116 runTestSecuredGet( null );
1117 fail();
1118 }
1119 catch ( AuthorizationException e )
1120 {
1121 assertTrue( true );
1122 }
1123 }
1124
1125 public void testSecuredGetWrongPassword()
1126 throws Exception
1127 {
1128 try
1129 {
1130 AuthenticationInfo authInfo = new AuthenticationInfo();
1131 authInfo.setUserName( "user" );
1132 authInfo.setPassword( "admin" );
1133 runTestSecuredGet( authInfo );
1134 fail();
1135 }
1136 catch ( AuthorizationException e )
1137 {
1138 assertTrue( true );
1139 }
1140 }
1141
1142 public void testSecuredGet()
1143 throws Exception
1144 {
1145 AuthenticationInfo authInfo = new AuthenticationInfo();
1146 authInfo.setUserName( "user" );
1147 authInfo.setPassword( "secret" );
1148 runTestSecuredGet( authInfo );
1149 }
1150
1151
1152 public void runTestSecuredGet( AuthenticationInfo authInfo )
1153 throws Exception
1154 {
1155 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1156 Server server = createSecurityServer( localRepositoryPath );
1157
1158 server.start();
1159
1160 try
1161 {
1162 StreamingWagon wagon = (StreamingWagon) getWagon();
1163
1164 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1165
1166 File sourceFile = new File( localRepositoryPath, "test-secured-resource" );
1167 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "top secret" );
1168
1169 wagon.connect( testRepository, authInfo );
1170
1171 File file = File.createTempFile( "wagon-test", "txt" );
1172
1173 try
1174 {
1175 wagon.get( "test-secured-resource", file );
1176 }
1177 finally
1178 {
1179 wagon.disconnect();
1180 }
1181
1182 FileInputStream in = new FileInputStream( file );
1183
1184 assertEquals( "top secret", IOUtil.toString( in ) );
1185
1186 TestSecurityHandler securityHandler = (TestSecurityHandler) ( (Context) server.getHandler() ).getHandler();
1187 testPreemptiveAuthenticationGet( securityHandler, supportPreemptiveAuthenticationGet() );
1188
1189 }
1190 finally
1191 {
1192 server.stop();
1193 }
1194 }
1195
1196
1197 public void testSecuredGetToStream()
1198 throws Exception
1199 {
1200 AuthenticationInfo authInfo = new AuthenticationInfo();
1201 authInfo.setUserName( "user" );
1202 authInfo.setPassword( "secret" );
1203 runTestSecuredGetToStream( authInfo );
1204 }
1205
1206 public void runTestSecuredGetToStream( AuthenticationInfo authInfo )
1207 throws Exception
1208 {
1209 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1210 Server server = createSecurityServer( localRepositoryPath );
1211
1212 server.start();
1213
1214 try
1215 {
1216 StreamingWagon wagon = (StreamingWagon) getWagon();
1217
1218 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1219
1220 File sourceFile = new File( localRepositoryPath, "test-secured-resource" );
1221 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "top secret" );
1222
1223 wagon.connect( testRepository, authInfo );
1224
1225 ByteArrayOutputStream out = new ByteArrayOutputStream();
1226 try
1227 {
1228 wagon.getToStream( "test-secured-resource", out );
1229 }
1230 finally
1231 {
1232 wagon.disconnect();
1233 }
1234
1235 assertEquals( "top secret", out.toString( "US-ASCII" ) );
1236
1237 TestSecurityHandler securityHandler = (TestSecurityHandler) ( (Context) server.getHandler() ).getHandler();
1238 testPreemptiveAuthenticationGet( securityHandler, supportPreemptiveAuthenticationGet() );
1239 }
1240 finally
1241 {
1242 server.stop();
1243 }
1244 }
1245
1246 public void testSecuredResourceExistsUnauthorized()
1247 throws Exception
1248 {
1249 try
1250 {
1251 runTestSecuredResourceExists( null );
1252 fail();
1253 }
1254 catch ( AuthorizationException e )
1255 {
1256 assertTrue( true );
1257 }
1258 }
1259
1260 public void testSecuredResourceExistsWrongPassword()
1261 throws Exception
1262 {
1263 try
1264 {
1265 AuthenticationInfo authInfo = new AuthenticationInfo();
1266 authInfo.setUserName( "user" );
1267 authInfo.setPassword( "admin" );
1268 runTestSecuredResourceExists( authInfo );
1269 }
1270 catch ( AuthorizationException e )
1271 {
1272 assertTrue( true );
1273 }
1274 }
1275
1276 public void testSecuredResourceExists()
1277 throws Exception
1278 {
1279 AuthenticationInfo authInfo = new AuthenticationInfo();
1280 authInfo.setUserName( "user" );
1281 authInfo.setPassword( "secret" );
1282 runTestSecuredResourceExists( authInfo );
1283 }
1284
1285 public void runTestSecuredResourceExists( AuthenticationInfo authInfo )
1286 throws Exception
1287 {
1288 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1289 Server server = createSecurityServer( localRepositoryPath );
1290
1291 server.start();
1292
1293 try
1294 {
1295 StreamingWagon wagon = (StreamingWagon) getWagon();
1296
1297 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1298
1299 File sourceFile = new File( localRepositoryPath, "test-secured-resource-exists" );
1300 FileUtils.fileWrite( sourceFile.getAbsolutePath(), "top secret" );
1301
1302 wagon.connect( testRepository, authInfo );
1303
1304 try
1305 {
1306 assertTrue( wagon.resourceExists( "test-secured-resource-exists" ) );
1307
1308 assertFalse( wagon.resourceExists( "test-secured-resource-not-exists" ) );
1309 }
1310 finally
1311 {
1312 wagon.disconnect();
1313 }
1314 }
1315 finally
1316 {
1317 server.stop();
1318 }
1319 }
1320
1321 private Server createSecurityServer( String localRepositoryPath )
1322 {
1323 Server server = new Server( 0 );
1324
1325 SecurityHandler sh = createSecurityHandler();
1326
1327 Context root = new Context( Context.SESSIONS );
1328 root.setContextPath( "/" );
1329 root.addHandler( sh );
1330 root.setResourceBase( localRepositoryPath );
1331 ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
1332 root.addServlet( servletHolder, "/*" );
1333
1334 server.setHandler( root );
1335 addConnectors( server );
1336 return server;
1337 }
1338
1339
1340 private String writeTestFileGzip( File parent, String child )
1341 throws IOException
1342 {
1343 File file = new File( parent, child );
1344 file.getParentFile().mkdirs();
1345 file.deleteOnExit();
1346 OutputStream out = new FileOutputStream( file );
1347 try
1348 {
1349 out.write( child.getBytes() );
1350 }
1351 finally
1352 {
1353 out.close();
1354 }
1355
1356 file = new File( parent, child + ".gz" );
1357 file.deleteOnExit();
1358 String content;
1359 out = new FileOutputStream( file );
1360 out = new GZIPOutputStream( out );
1361 try
1362 {
1363
1364
1365 content = file.getAbsolutePath();
1366 out.write( content.getBytes() );
1367 }
1368 finally
1369 {
1370 out.close();
1371 }
1372
1373 return content;
1374 }
1375
1376 public void testPutForbidden()
1377 throws Exception
1378 {
1379 try
1380 {
1381 runTestPut( HttpServletResponse.SC_FORBIDDEN );
1382 fail();
1383 }
1384 catch ( AuthorizationException e )
1385 {
1386 assertTrue( true );
1387 }
1388 }
1389
1390 public void testPut404()
1391 throws Exception
1392 {
1393 try
1394 {
1395 runTestPut( HttpServletResponse.SC_NOT_FOUND );
1396 fail();
1397 }
1398 catch ( ResourceDoesNotExistException e )
1399 {
1400 assertTrue( true );
1401 }
1402 }
1403
1404 public void testPut500()
1405 throws Exception
1406 {
1407 try
1408 {
1409 runTestPut( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
1410 fail();
1411 }
1412 catch ( TransferFailedException e )
1413 {
1414 assertTrue( true );
1415 }
1416 }
1417
1418 public void testPut429()
1419 throws Exception
1420 {
1421
1422 try
1423 {
1424
1425 StreamingWagon wagon = (StreamingWagon) getWagon();
1426 Server server = new Server( 0 );
1427 final AtomicBoolean called = new AtomicBoolean();
1428
1429 AbstractHandler handler = new AbstractHandler()
1430 {
1431 public void handle( String s, HttpServletRequest request, HttpServletResponse response, int i )
1432 throws IOException, ServletException
1433 {
1434 if ( called.get() )
1435 {
1436 response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
1437 ( (Request) request ).setHandled( true );
1438 }
1439 else
1440 {
1441 called.set( true );
1442 response.setStatus( 429 );
1443 ( (Request) request ).setHandled( true );
1444 }
1445 }
1446 };
1447
1448 server.setHandler( handler );
1449 addConnectors( server );
1450 server.start();
1451
1452 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
1453
1454 File tempFile = File.createTempFile( "wagon", "tmp" );
1455 tempFile.deleteOnExit();
1456 FileUtils.fileWrite( tempFile.getAbsolutePath(), "content" );
1457
1458 try
1459 {
1460 wagon.put( tempFile, "resource" );
1461 fail();
1462 }
1463 finally
1464 {
1465 wagon.disconnect();
1466
1467 server.stop();
1468
1469 tempFile.delete();
1470 }
1471
1472 }
1473 catch ( TransferFailedException e )
1474 {
1475 assertTrue( true );
1476 }
1477 }
1478
1479
1480 private void runTestPut( int status )
1481 throws Exception
1482 {
1483 StreamingWagon wagon = (StreamingWagon) getWagon();
1484
1485 Server server = new Server( 0 );
1486 StatusHandler handler = new StatusHandler();
1487 handler.setStatusToReturn( status );
1488 server.setHandler( handler );
1489 addConnectors( server );
1490 server.start();
1491
1492 wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
1493
1494 File tempFile = File.createTempFile( "wagon", "tmp" );
1495 tempFile.deleteOnExit();
1496 FileUtils.fileWrite( tempFile.getAbsolutePath(), "content" );
1497
1498 try
1499 {
1500 wagon.put( tempFile, "resource" );
1501 fail();
1502 }
1503 finally
1504 {
1505 wagon.disconnect();
1506
1507 server.stop();
1508
1509 tempFile.delete();
1510 }
1511 }
1512
1513 public void testSecuredPutUnauthorized()
1514 throws Exception
1515 {
1516 try
1517 {
1518 runTestSecuredPut( null );
1519 fail();
1520 }
1521 catch ( TransferFailedException e )
1522 {
1523 assertTrue( true );
1524 }
1525 }
1526
1527 public void testSecuredPutWrongPassword()
1528 throws Exception
1529 {
1530 try
1531 {
1532 AuthenticationInfo authInfo = new AuthenticationInfo();
1533 authInfo.setUserName( "user" );
1534 authInfo.setPassword( "admin" );
1535 runTestSecuredPut( authInfo );
1536 fail();
1537 }
1538 catch ( TransferFailedException e )
1539 {
1540 assertTrue( true );
1541 }
1542 }
1543
1544 public void testSecuredPut()
1545 throws Exception
1546 {
1547 AuthenticationInfo authInfo = new AuthenticationInfo();
1548 authInfo.setUserName( "user" );
1549 authInfo.setPassword( "secret" );
1550 runTestSecuredPut( authInfo );
1551 }
1552
1553 public void runTestSecuredPut( AuthenticationInfo authInfo )
1554 throws Exception
1555 {
1556 runTestSecuredPut( authInfo, 1 );
1557 }
1558
1559 public void runTestSecuredPut( AuthenticationInfo authInfo, int putNumber )
1560 throws Exception
1561 {
1562 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1563 Server server = new Server( 0 );
1564
1565 TestSecurityHandler sh = createSecurityHandler();
1566
1567 PutHandler putHandler = new PutHandler( new File( localRepositoryPath ) );
1568
1569 HandlerCollection handlers = new HandlerCollection();
1570 handlers.setHandlers( new Handler[]{ sh, putHandler } );
1571
1572 server.setHandler( handlers );
1573 addConnectors( server );
1574 server.start();
1575
1576 StreamingWagon wagon = (StreamingWagon) getWagon();
1577 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1578 wagon.connect( testRepository, authInfo );
1579 try
1580 {
1581 for ( int i = 0; i < putNumber; i++ )
1582 {
1583 File sourceFile = new File( localRepositoryPath, "test-secured-put-resource" );
1584 sourceFile.delete();
1585 assertFalse( sourceFile.exists() );
1586
1587 File tempFile = File.createTempFile( "wagon", "tmp" );
1588 tempFile.deleteOnExit();
1589 FileUtils.fileWrite( tempFile.getAbsolutePath(), "put top secret" );
1590
1591 try
1592 {
1593 wagon.put( tempFile, "test-secured-put-resource" );
1594 }
1595 finally
1596 {
1597 tempFile.delete();
1598 }
1599
1600 assertEquals( "put top secret", FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
1601 }
1602 }
1603 finally
1604 {
1605 wagon.disconnect();
1606 server.stop();
1607 }
1608 assertEquals( putNumber, putHandler.putCallNumber );
1609 testPreemptiveAuthenticationPut( sh, supportPreemptiveAuthenticationPut() );
1610 }
1611
1612 public void testNonSecuredPutFromStream()
1613 throws Exception
1614 {
1615 AuthenticationInfo authInfo = new AuthenticationInfo();
1616 authInfo.setUserName( "user" );
1617 authInfo.setPassword( "secret" );
1618 runTestSecuredPutFromStream( authInfo, 1, false );
1619 }
1620
1621 public void testSecuredPutFromStream()
1622 throws Exception
1623 {
1624 AuthenticationInfo authInfo = new AuthenticationInfo();
1625 authInfo.setUserName( "user" );
1626 authInfo.setPassword( "secret" );
1627 runTestSecuredPutFromStream( authInfo, 1, true );
1628 }
1629
1630 public void runTestSecuredPutFromStream( AuthenticationInfo authInfo, int putNumber, boolean addSecurityHandler )
1631 throws Exception
1632 {
1633 String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
1634 Server server = new Server( 0 );
1635
1636 TestSecurityHandler sh = createSecurityHandler();
1637
1638 PutHandler putHandler = new PutHandler( new File( localRepositoryPath ) );
1639
1640 HandlerCollection handlers = new HandlerCollection();
1641 handlers.setHandlers( addSecurityHandler ? new Handler[]{ sh, putHandler } : new Handler[]{ putHandler } );
1642
1643 server.setHandler( handlers );
1644 addConnectors( server );
1645 server.start();
1646
1647 StreamingWagon wagon = (StreamingWagon) getWagon();
1648 Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
1649 if ( addSecurityHandler )
1650 {
1651 wagon.connect( testRepository, authInfo );
1652 }
1653 else
1654 {
1655 wagon.connect( testRepository );
1656 }
1657 try
1658 {
1659 for ( int i = 0; i < putNumber; i++ )
1660 {
1661 File sourceFile = new File( localRepositoryPath, "test-secured-put-resource" );
1662 sourceFile.delete();
1663 assertFalse( sourceFile.exists() );
1664
1665 File tempFile = File.createTempFile( "wagon", "tmp" );
1666 tempFile.deleteOnExit();
1667 String content = "put top secret";
1668 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
1669
1670 FileInputStream fileInputStream = new FileInputStream( tempFile );
1671 try
1672 {
1673 wagon.putFromStream( fileInputStream, "test-secured-put-resource", content.length(), -1 );
1674 }
1675 finally
1676 {
1677 fileInputStream.close();
1678 tempFile.delete();
1679
1680 }
1681
1682 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
1683 }
1684 }
1685 finally
1686 {
1687 wagon.disconnect();
1688 server.stop();
1689 }
1690 assertEquals( putNumber, putHandler.putCallNumber );
1691 if ( addSecurityHandler )
1692 {
1693 testPreemptiveAuthenticationPut( sh, supportPreemptiveAuthenticationPut() );
1694 }
1695
1696
1697 for ( DeployedResource deployedResource : putHandler.deployedResources )
1698 {
1699 if ( StringUtils.equalsIgnoreCase( "chunked", deployedResource.transferEncoding ) )
1700 {
1701 fail( "deployedResource use chunked: " + deployedResource );
1702 }
1703 }
1704 }
1705
1706
1707 protected abstract boolean supportPreemptiveAuthenticationPut();
1708
1709 protected abstract boolean supportPreemptiveAuthenticationGet();
1710
1711 protected abstract boolean supportProxyPreemptiveAuthentication();
1712
1713 protected void testPreemptiveAuthenticationGet( TestSecurityHandler sh, boolean preemptive )
1714 {
1715 testPreemptiveAuthentication( sh, preemptive );
1716 }
1717
1718 protected void testPreemptiveAuthenticationPut( TestSecurityHandler sh, boolean preemptive )
1719 {
1720 testPreemptiveAuthentication( sh, preemptive );
1721 }
1722
1723 protected void testPreemptiveAuthentication( TestSecurityHandler sh, boolean preemptive )
1724 {
1725
1726 if ( preemptive )
1727 {
1728 assertEquals( "not 1 security handler use " + sh.handlerRequestResponses, 1,
1729 sh.handlerRequestResponses.size() );
1730 assertEquals( 200, sh.handlerRequestResponses.get( 0 ).responseCode );
1731 }
1732 else
1733 {
1734 assertEquals( "not 2 security handler use " + sh.handlerRequestResponses, 2,
1735 sh.handlerRequestResponses.size() );
1736 assertEquals( 401, sh.handlerRequestResponses.get( 0 ).responseCode );
1737 assertEquals( 200, sh.handlerRequestResponses.get( 1 ).responseCode );
1738
1739 }
1740 }
1741
1742 static class StatusHandler
1743 extends AbstractHandler
1744 {
1745 private int status;
1746
1747 public void setStatusToReturn( int status )
1748 {
1749 this.status = status;
1750 }
1751
1752 public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
1753 throws IOException, ServletException
1754 {
1755 if ( status != 0 )
1756 {
1757 response.setStatus( status );
1758 ( (Request) request ).setHandled( true );
1759 }
1760 }
1761 }
1762
1763 static class DeployedResource
1764 {
1765 String httpMethod;
1766
1767 String requestUri;
1768
1769 String contentLength;
1770
1771 String transferEncoding;
1772
1773 public DeployedResource()
1774 {
1775
1776 }
1777
1778 @Override
1779 public String toString()
1780 {
1781 final StringBuilder sb = new StringBuilder();
1782 sb.append( "DeployedResource" );
1783 sb.append( "{httpMethod='" ).append( httpMethod ).append( '\'' );
1784 sb.append( ", requestUri='" ).append( requestUri ).append( '\'' );
1785 sb.append( ", contentLength='" ).append( contentLength ).append( '\'' );
1786 sb.append( ", transferEncoding='" ).append( transferEncoding ).append( '\'' );
1787 sb.append( '}' );
1788 return sb.toString();
1789 }
1790 }
1791
1792 public static class PutHandler
1793 extends AbstractHandler
1794 {
1795 private final File resourceBase;
1796
1797 public List<DeployedResource> deployedResources = new ArrayList<DeployedResource>();
1798
1799 public int putCallNumber = 0;
1800
1801 public List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
1802
1803 public PutHandler( File repositoryDirectory )
1804 {
1805 this.resourceBase = repositoryDirectory;
1806 }
1807
1808 public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
1809 throws IOException, ServletException
1810 {
1811 Request base_request =
1812 request instanceof Request ? (Request) request : HttpConnection.getCurrentConnection().getRequest();
1813
1814 if ( base_request.isHandled() || !"PUT".equals( base_request.getMethod() ) )
1815 {
1816 return;
1817 }
1818
1819 base_request.setHandled( true );
1820
1821 File file = new File( resourceBase, URLDecoder.decode( request.getPathInfo() ) );
1822 file.getParentFile().mkdirs();
1823 FileOutputStream out = new FileOutputStream( file );
1824 ServletInputStream in = request.getInputStream();
1825 try
1826 {
1827 IOUtil.copy( in, out );
1828 }
1829 finally
1830 {
1831 in.close();
1832 out.close();
1833 }
1834 putCallNumber++;
1835 DeployedResource deployedResource = new DeployedResource();
1836
1837 deployedResource.httpMethod = request.getMethod();
1838 deployedResource.requestUri = request.getRequestURI();
1839 deployedResource.transferEncoding = request.getHeader( "Transfer-Encoding" );
1840 deployedResource.contentLength = request.getHeader( "Content-Length" );
1841 deployedResources.add( deployedResource );
1842
1843 response.setStatus( HttpServletResponse.SC_CREATED );
1844
1845 handlerRequestResponses.add(
1846 new HandlerRequestResponse( request.getMethod(), ( (Response) response ).getStatus(),
1847 request.getRequestURI() ) );
1848 }
1849 }
1850
1851 private static class AuthorizingProxyHandler
1852 extends TestHeaderHandler
1853 {
1854
1855 List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
1856
1857 public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
1858 throws IOException, ServletException
1859 {
1860 System.out.println( " handle proxy request" );
1861 if ( request.getHeader( "Proxy-Authorization" ) == null )
1862 {
1863 handlerRequestResponses.add(
1864 new HandlerRequestResponse( request.getMethod(), 407, request.getRequestURI() ) );
1865 response.setStatus( 407 );
1866 response.addHeader( "Proxy-Authenticate", "Basic realm=\"Squid proxy-caching web server\"" );
1867
1868 ( (Request) request ).setHandled( true );
1869 return;
1870 }
1871 handlerRequestResponses.add(
1872 new HandlerRequestResponse( request.getMethod(), 200, request.getRequestURI() ) );
1873 super.handle( target, request, response, dispatch );
1874 }
1875 }
1876
1877 private static class TestHeaderHandler
1878 extends AbstractHandler
1879 {
1880 public Map<String, String> headers = Collections.emptyMap();
1881
1882 public List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
1883
1884 public TestHeaderHandler()
1885 {
1886 }
1887
1888 public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
1889 throws IOException, ServletException
1890 {
1891 headers = new HashMap<String, String>();
1892 for ( Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements(); )
1893 {
1894 String name = e.nextElement();
1895 headers.put( name, request.getHeader( name ) );
1896 }
1897
1898 response.setContentType( "text/plain" );
1899 response.setStatus( HttpServletResponse.SC_OK );
1900 response.getWriter().print( "Hello, World!" );
1901
1902 handlerRequestResponses.add(
1903 new HandlerRequestResponse( request.getMethod(), ( (Response) response ).getStatus(),
1904 request.getRequestURI() ) );
1905
1906 ( (Request) request ).setHandled( true );
1907 }
1908
1909 }
1910
1911 protected TestSecurityHandler createSecurityHandler()
1912 {
1913 Constraint constraint = new Constraint();
1914 constraint.setName( Constraint.__BASIC_AUTH );
1915 constraint.setRoles( new String[]{ "admin" } );
1916 constraint.setAuthenticate( true );
1917
1918 ConstraintMapping cm = new ConstraintMapping();
1919 cm.setConstraint( constraint );
1920 cm.setPathSpec( "/*" );
1921
1922 TestSecurityHandler sh = new TestSecurityHandler();
1923 HashUserRealm hashUserRealm = new HashUserRealm( "MyRealm" );
1924 hashUserRealm.put( "user", "secret" );
1925 hashUserRealm.addUserToRole( "user", "admin" );
1926 sh.setUserRealm( hashUserRealm );
1927 sh.setConstraintMappings( new ConstraintMapping[]{ cm } );
1928 return sh;
1929 }
1930
1931 public static class TestSecurityHandler
1932 extends SecurityHandler
1933 {
1934
1935 public List<HandlerRequestResponse> handlerRequestResponses = new ArrayList<HandlerRequestResponse>();
1936
1937 @Override
1938 public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
1939 throws IOException, ServletException
1940 {
1941 String method = request.getMethod();
1942 super.handle( target, request, response, dispatch );
1943
1944 handlerRequestResponses.add(
1945 new HandlerRequestResponse( method, ( (Response) response ).getStatus(), request.getRequestURI() ) );
1946 }
1947
1948 }
1949
1950 public static class HandlerRequestResponse
1951 {
1952 public String method;
1953
1954 public int responseCode;
1955
1956 public String requestUri;
1957
1958 private HandlerRequestResponse( String method, int responseCode, String requestUri )
1959 {
1960 this.method = method;
1961 this.responseCode = responseCode;
1962 this.requestUri = requestUri;
1963 }
1964
1965 @Override
1966 public String toString()
1967 {
1968 final StringBuilder sb = new StringBuilder();
1969 sb.append( "HandlerRequestResponse" );
1970 sb.append( "{method='" ).append( method ).append( '\'' );
1971 sb.append( ", responseCode=" ).append( responseCode );
1972 sb.append( ", requestUri='" ).append( requestUri ).append( '\'' );
1973 sb.append( '}' );
1974 return sb.toString();
1975 }
1976 }
1977 }