View Javadoc

1   package org.apache.maven.wagon.providers.webdav;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
5    * agreements. See the NOTICE file distributed with this work for additional information regarding
6    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance with the License. You may obtain a
8    * copy of the License at
9    * 
10   * http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software distributed under the License
13   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14   * or implied. See the License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  
18  import it.could.webdav.DAVServlet;
19  import org.apache.commons.httpclient.HttpException;
20  import org.apache.commons.httpclient.HttpMethod;
21  import org.apache.maven.wagon.ResourceDoesNotExistException;
22  import org.apache.maven.wagon.StreamingWagon;
23  import org.apache.maven.wagon.TransferFailedException;
24  import org.apache.maven.wagon.Wagon;
25  import org.apache.maven.wagon.http.HttpWagonTestCase;
26  import org.apache.maven.wagon.repository.Repository;
27  import org.apache.maven.wagon.resource.Resource;
28  import org.mortbay.jetty.Server;
29  import org.mortbay.jetty.servlet.Context;
30  import org.mortbay.jetty.servlet.ServletHolder;
31  
32  import java.io.File;
33  import java.io.IOException;
34  import java.net.SocketTimeoutException;
35  import java.util.List;
36  import java.util.Properties;
37  
38  /*
39   * WebDAV Wagon Test
40   * 
41   * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
42   * 
43   * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
44   */
45  public class WebDavWagonTest
46      extends HttpWagonTestCase
47  {
48      protected String getTestRepositoryUrl()
49          throws IOException
50      {
51          return getProtocol() + "://localhost:" + getTestRepositoryPort() + "/newfolder/folder2/";
52      }
53  
54      protected String getProtocol()
55      {
56          return "dav";
57      }
58  
59      protected void createContext( Server server, File repositoryDirectory )
60          throws IOException
61      {
62          Context dav = new Context( server, "/", Context.SESSIONS );
63          ServletHolder davServletHolder = new ServletHolder( new DAVServlet() );
64          davServletHolder.setInitParameter( "rootPath", repositoryDirectory.getAbsolutePath() );
65          davServletHolder.setInitParameter( "xmlOnly", "false" );
66          dav.addServlet( davServletHolder, "/*" );
67      }
68  
69      protected long getExpectedLastModifiedOnGet( Repository repository, Resource resource )
70      {
71          File file = new File( getDavRepository(), resource.getName() );
72          return ( file.lastModified() / 1000 ) * 1000;
73      }
74  
75  
76      private File getDavRepository()
77      {
78          return getTestFile( "target/test-output/http-repository/newfolder/folder2" );
79      }
80  
81      private void assertURL( String userUrl, String expectedUrl )
82      {
83          Repository repo = new Repository( "test-geturl", userUrl );
84          String actualUrl = ( new WebDavWagon() ).getURL( repo );
85          assertEquals( "WebDavWagon.getURL(" + userUrl + ")", expectedUrl, actualUrl );
86      }
87  
88      /**
89       * Tests the maven 2.0.x way to define a webdav URL without SSL.
90       */
91      public void testGetURLDavHttp()
92      {
93          assertURL( "dav:http://localhost:" + getTestRepositoryPort() + "/dav/",
94                     "http://localhost:" + getTestRepositoryPort() + "/dav/" );
95      }
96  
97      /**
98       * Tests the maven 2.0.x way to define a webdav URL with SSL.
99       */
100     public void testGetURLDavHttps()
101     {
102         assertURL( "dav:https://localhost:" + getTestRepositoryPort() + "/dav/",
103                    "https://localhost:" + getTestRepositoryPort() + "/dav/" );
104     }
105 
106     /**
107      * Tests the URI spec way of defining a webdav URL without SSL.
108      */
109     public void testGetURLDavUri()
110     {
111         assertURL( "dav://localhost:" + getTestRepositoryPort() + "/dav/",
112                    "http://localhost:" + getTestRepositoryPort() + "/dav/" );
113     }
114 
115     /**
116      * Tests the URI spec way of defining a webdav URL with SSL.
117      */
118     public void testGetURLDavUriWithSsl()
119     {
120         assertURL( "davs://localhost:" + getTestRepositoryPort() + "/dav/",
121                    "https://localhost:" + getTestRepositoryPort() + "/dav/" );
122     }
123 
124     /**
125      * Tests the URI spec way of defining a webdav URL without SSL.
126      */
127     public void testGetURLDavPlusHttp()
128     {
129         assertURL( "dav+https://localhost:" + getTestRepositoryPort() + "/dav/",
130                    "https://localhost:" + getTestRepositoryPort() + "/dav/" );
131     }
132 
133     /**
134      * Tests the URI spec way of defining a webdav URL with SSL.
135      */
136     public void testGetURLDavPlusHttps()
137     {
138         assertURL( "dav+https://localhost:" + getTestRepositoryPort() + "/dav/",
139                    "https://localhost:" + getTestRepositoryPort() + "/dav/" );
140     }
141 
142     public void testMkdirs()
143         throws Exception
144     {
145         setupRepositories();
146 
147         setupWagonTestingFixtures();
148 
149         WebDavWagon wagon = (WebDavWagon) getWagon();
150         wagon.connect( testRepository, getAuthInfo() );
151 
152         try
153         {
154             File dir = getRepositoryDirectory();
155 
156             // check basedir also doesn't exist and will need to be created
157             dir = new File( dir, testRepository.getBasedir() );
158             assertFalse( dir.exists() );
159 
160             // test leading /
161             assertFalse( new File( dir, "foo" ).exists() );
162             wagon.mkdirs( "/foo" );
163             assertTrue( new File( dir, "foo" ).exists() );
164 
165             // test trailing /
166             assertFalse( new File( dir, "bar" ).exists() );
167             wagon.mkdirs( "bar/" );
168             assertTrue( new File( dir, "bar" ).exists() );
169 
170             // test when already exists
171             wagon.mkdirs( "bar" );
172 
173             // test several parts
174             assertFalse( new File( dir, "1/2/3/4" ).exists() );
175             wagon.mkdirs( "1/2/3/4" );
176             assertTrue( new File( dir, "1/2/3/4" ).exists() );
177 
178             // test additional part and trailing /
179             assertFalse( new File( dir, "1/2/3/4/5" ).exists() );
180             wagon.mkdirs( "1/2/3/4/5/" );
181             assertTrue( new File( dir, "1/2/3/4" ).exists() );
182         }
183         finally
184         {
185             wagon.disconnect();
186 
187             tearDownWagonTestingFixtures();
188         }
189     }
190 
191     public void testMkdirsWithNoBasedir()
192         throws Exception
193     {
194         // WAGON-244
195         setupRepositories();
196 
197         setupWagonTestingFixtures();
198 
199         // reconstruct with no basedir
200         testRepository.setUrl(
201             testRepository.getProtocol() + "://" + testRepository.getHost() + ":" + testRepository.getPort() );
202 
203         WebDavWagon wagon = (WebDavWagon) getWagon();
204         wagon.connect( testRepository, getAuthInfo() );
205 
206         try
207         {
208             File dir = getRepositoryDirectory();
209 
210             // check basedir also doesn't exist and will need to be created
211             dir = new File( dir, testRepository.getBasedir() );
212             assertTrue( dir.exists() );
213 
214             // test leading /
215             assertFalse( new File( dir, "foo" ).exists() );
216             wagon.mkdirs( "/foo" );
217             assertTrue( new File( dir, "foo" ).exists() );
218         }
219         finally
220         {
221             wagon.disconnect();
222 
223             tearDownWagonTestingFixtures();
224         }
225     }
226 
227     protected void setHttpHeaders( StreamingWagon wagon, Properties properties )
228     {
229         ( (WebDavWagon) wagon ).setHttpHeaders( properties );
230     }
231 
232     /**
233      * Make sure wagon webdav can detect remote directory
234      *
235      * @throws Exception
236      */
237     public void testWagonWebDavGetFileList()
238         throws Exception
239     {
240         setupRepositories();
241 
242         setupWagonTestingFixtures();
243 
244         String dirName = "file-list";
245 
246         String filenames[] =
247             new String[]{ "test-resource.txt", "test-resource.pom", "test-resource b.txt", "more-resources.dat" };
248 
249         for ( int i = 0; i < filenames.length; i++ )
250         {
251             putFile( dirName + "/" + filenames[i], dirName + "/" + filenames[i], filenames[i] + "\n" );
252         }
253 
254         String dirnames[] = new String[]{ "test-dir1", "test-dir2" };
255 
256         for ( int i = 0; i < dirnames.length; i++ )
257         {
258             new File( getDavRepository(), dirName + "/" + dirnames[i] ).mkdirs();
259         }
260 
261         Wagon wagon = getWagon();
262 
263         wagon.connect( testRepository, getAuthInfo() );
264 
265         List<String> list = wagon.getFileList( dirName );
266 
267         assertNotNull( "file list should not be null.", list );
268         assertEquals( "file list should contain 6 items", 6, list.size() );
269 
270         for ( int i = 0; i < filenames.length; i++ )
271         {
272             assertTrue( "Filename '" + filenames[i] + "' should be in list.", list.contains( filenames[i] ) );
273         }
274 
275         for ( int i = 0; i < dirnames.length; i++ )
276         {
277             assertTrue( "Directory '" + dirnames[i] + "' should be in list.", list.contains( dirnames[i] + "/" ) );
278         }
279 
280         ///////////////////////////////////////////////////////////////////////////
281         list = wagon.getFileList( "" );
282         assertNotNull( "file list should not be null.", list );
283         assertEquals( "file list should contain 1 items", 1, list.size() );
284 
285         ///////////////////////////////////////////////////////////////////////////
286         list = wagon.getFileList( dirName + "/test-dir1" );
287         assertNotNull( "file list should not be null.", list );
288         assertEquals( "file list should contain 0 items", 0, list.size() );
289 
290         /////////////////////////////////////////////////////////////////////////////
291         try
292         {
293             list = wagon.getFileList( dirName + "/test-dir-bogus" );
294             fail( "Exception expected" );
295         }
296         catch ( ResourceDoesNotExistException e )
297         {
298 
299         }
300 
301         wagon.disconnect();
302 
303         tearDownWagonTestingFixtures();
304     }
305 
306 
307     public void testWagonFailsOnPutFailureByDefault()
308         throws Exception
309     {
310         setupRepositories();
311 
312         setupWagonTestingFixtures();
313 
314         File testFile = getTempFile();
315 
316         System.clearProperty( WebDavWagon.CONTINUE_ON_FAILURE_PROPERTY );
317 
318         WebDavWagon wagon = new TimeoutSimulatingWagon();
319         wagon.connect( testRepository, getAuthInfo() );
320 
321         try
322         {
323             String filename = TimeoutSimulatingWagon.TIMEOUT_TRIGGER + ".txt";
324 
325             try
326             {
327                 wagon.put( testFile, filename );
328                 fail( "Exception expected" );
329             }
330             catch ( TransferFailedException e )
331             {
332 
333             }
334         }
335         finally
336         {
337             wagon.disconnect();
338 
339             tearDownWagonTestingFixtures();
340         }
341     }
342 
343     private File getTempFile()
344         throws IOException
345     {
346         File inputFile = File.createTempFile( "test-resource", ".txt" );
347         inputFile.deleteOnExit();
348         return inputFile;
349     }
350 
351     private static class TimeoutSimulatingWagon
352         extends WebDavWagon
353     {
354         private static final String TIMEOUT_TRIGGER = "timeout";
355 
356         protected int execute( HttpMethod httpMethod )
357             throws HttpException, IOException
358         {
359             if ( httpMethod.getPath().contains( TIMEOUT_TRIGGER ) )
360             {
361                 throw new SocketTimeoutException( "Timeout triggered by request for '" + httpMethod.getPath() + "'" );
362             }
363             else
364             {
365                 return super.execute( httpMethod );
366             }
367         }
368     }
369 
370     public void testWagonContinuesOnPutFailureIfPropertySet()
371         throws Exception
372     {
373         setupRepositories();
374 
375         setupWagonTestingFixtures();
376 
377         File testFile = getTempFile();
378 
379         String continueOnFailureProperty = WebDavWagon.CONTINUE_ON_FAILURE_PROPERTY;
380         System.setProperty( continueOnFailureProperty, "true" );
381 
382         WebDavWagon wagon = new TimeoutSimulatingWagon();
383         wagon.connect( testRepository, getAuthInfo() );
384 
385         try
386         {
387             String filename = TimeoutSimulatingWagon.TIMEOUT_TRIGGER + ".txt";
388 
389             wagon.put( testFile, filename );
390         }
391         finally
392         {
393             wagon.disconnect();
394 
395             System.clearProperty( continueOnFailureProperty );
396 
397             tearDownWagonTestingFixtures();
398         }
399     }
400 
401     @Override
402     protected boolean supportPreemptiveAuthenticationPut()
403     {
404         return true;
405     }
406 
407     @Override
408     protected boolean supportPreemptiveAuthenticationGet()
409     {
410         return false;
411     }
412 
413     @Override
414     protected boolean supportProxyPreemptiveAuthentication()
415     {
416         return false;
417     }
418 
419     protected void testPreemptiveAuthenticationGet( TestSecurityHandler sh, boolean preemptive )
420     {
421         if ( preemptive )
422         {
423             assertEquals( "testPreemptiveAuthenticationGet not 1 security handler use " + sh.handlerRequestResponses, 1,
424                           sh.handlerRequestResponses.size() );
425             assertEquals( 200, sh.handlerRequestResponses.get( 0 ).responseCode );
426         }
427         else
428         {
429             assertEquals( "testPreemptiveAuthenticationGet not 2 security handler use " + sh.handlerRequestResponses, 2,
430                           sh.handlerRequestResponses.size() );
431             assertEquals( 401, sh.handlerRequestResponses.get( 0 ).responseCode );
432             assertEquals( 200, sh.handlerRequestResponses.get( 1 ).responseCode );
433         }
434     }
435 
436     protected void testPreemptiveAuthenticationPut( TestSecurityHandler sh, boolean preemptive )
437     {
438         if ( preemptive )
439         {
440             assertEquals( "testPreemptiveAuthenticationPut not 2 security handler use " + sh.handlerRequestResponses, 2,
441                           sh.handlerRequestResponses.size() );
442             assertEquals( 200, sh.handlerRequestResponses.get( 0 ).responseCode );
443         }
444         else
445         {
446             assertEquals( "testPreemptiveAuthenticationPut not 3 security handler use " + sh.handlerRequestResponses, 3,
447                           sh.handlerRequestResponses.size() );
448             assertEquals( 401, sh.handlerRequestResponses.get( 0 ).responseCode );
449             assertEquals( 200, sh.handlerRequestResponses.get( 1 ).responseCode );
450         }
451     }
452 
453 
454     @Override
455     protected void testPreemptiveAuthentication( TestSecurityHandler sh, boolean preemptive )
456     {
457         if ( preemptive )
458         {
459             assertEquals( "testPreemptiveAuthentication not 2 security handler use " + sh.handlerRequestResponses, 2,
460                           sh.handlerRequestResponses.size() );
461             assertEquals( 200, sh.handlerRequestResponses.get( 0 ).responseCode );
462         }
463         else
464         {
465             assertEquals( "testPreemptiveAuthentication not 3 security handler use " + sh.handlerRequestResponses, 3,
466                           sh.handlerRequestResponses.size() );
467             assertEquals( 401, sh.handlerRequestResponses.get( 0 ).responseCode );
468             assertEquals( 200, sh.handlerRequestResponses.get( 1 ).responseCode );
469             assertEquals( 200, sh.handlerRequestResponses.get( 2 ).responseCode );
470 
471         }
472     }
473 
474     protected void checkRequestResponseForRedirectPutFromStreamWithFullUrl( PutHandler putHandler,
475                                                                             RedirectHandler redirectHandler )
476     {
477         assertEquals( "found:" + putHandler.handlerRequestResponses, 1, putHandler.handlerRequestResponses.size() );
478         assertEquals( "found:" + putHandler.handlerRequestResponses, 201,
479                       putHandler.handlerRequestResponses.get( 0 ).responseCode );
480         assertEquals( "found:" + redirectHandler.handlerRequestResponses, 3,
481                       redirectHandler.handlerRequestResponses.size() );
482         assertEquals( "found:" + redirectHandler.handlerRequestResponses, 302,
483                       redirectHandler.handlerRequestResponses.get( 0 ).responseCode );
484     }
485 
486     protected void checkRequestResponseForRedirectPutFromStreamWithRelativeUrl( PutHandler putHandler,
487                                                                                 RedirectHandler redirectHandler )
488     {
489         assertEquals( "found:" + putHandler.handlerRequestResponses, 0, putHandler.handlerRequestResponses.size() );
490 
491         assertEquals( "found:" + redirectHandler.handlerRequestResponses, 4,
492                       redirectHandler.handlerRequestResponses.size() );
493         assertEquals( "found:" + redirectHandler.handlerRequestResponses, 302,
494                       redirectHandler.handlerRequestResponses.get( 0 ).responseCode );
495         assertEquals( "found:" + redirectHandler.handlerRequestResponses, 302,
496                       redirectHandler.handlerRequestResponses.get( 1 ).responseCode );
497         assertEquals( "found:" + redirectHandler.handlerRequestResponses, 201,
498                       redirectHandler.handlerRequestResponses.get( 3 ).responseCode );
499 
500     }
501 
502 }