Coverage Report - org.apache.maven.wagon.http.HttpWagonTestCase
 
Classes in this File Line Coverage Branch Coverage Complexity
HttpWagonTestCase
0 %
0/453
0 %
0/24
1,587
HttpWagonTestCase$1
N/A
N/A
1,587
HttpWagonTestCase$AuthorizingProxyHandler
0 %
0/12
0 %
0/2
1,587
HttpWagonTestCase$DeployedResource
0 %
0/10
N/A
1,587
HttpWagonTestCase$PutHandler
0 %
0/27
0 %
0/6
1,587
HttpWagonTestCase$SecurityHandlerRequestReponse
0 %
0/11
N/A
1,587
HttpWagonTestCase$StatusHandler
0 %
0/7
0 %
0/2
1,587
HttpWagonTestCase$TestHeaderHandler
0 %
0/13
0 %
0/2
1,587
HttpWagonTestCase$TestSecurityHandler
0 %
0/7
N/A
1,587
 
 1  
 package org.apache.maven.wagon.http;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 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.StringOutputStream;
 36  
 import org.codehaus.plexus.util.StringUtils;
 37  
 import org.mortbay.jetty.Handler;
 38  
 import org.mortbay.jetty.HttpConnection;
 39  
 import org.mortbay.jetty.Request;
 40  
 import org.mortbay.jetty.Response;
 41  
 import org.mortbay.jetty.Server;
 42  
 import org.mortbay.jetty.handler.AbstractHandler;
 43  
 import org.mortbay.jetty.handler.HandlerCollection;
 44  
 import org.mortbay.jetty.security.Constraint;
 45  
 import org.mortbay.jetty.security.ConstraintMapping;
 46  
 import org.mortbay.jetty.security.HashUserRealm;
 47  
 import org.mortbay.jetty.security.SecurityHandler;
 48  
 import org.mortbay.jetty.servlet.Context;
 49  
 import org.mortbay.jetty.servlet.DefaultServlet;
 50  
 import org.mortbay.jetty.servlet.ServletHolder;
 51  
 
 52  
 import javax.servlet.ServletException;
 53  
 import javax.servlet.ServletInputStream;
 54  
 import javax.servlet.http.HttpServletRequest;
 55  
 import javax.servlet.http.HttpServletResponse;
 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.zip.GZIPOutputStream;
 71  
 
 72  
 /**
 73  
  * @version $Id: LightweightHttpWagonTest.java 680764 2008-07-29 16:45:51Z brett $
 74  
  */
 75  0
 public abstract class HttpWagonTestCase
 76  
     extends StreamingWagonTestCase
 77  
 {
 78  
     private Server server;
 79  
 
 80  
     protected void setupWagonTestingFixtures()
 81  
         throws Exception
 82  
     {
 83  
         // File round trip testing
 84  
 
 85  0
         File file = FileTestUtils.createUniqueFile( "local-repository", "test-resource" );
 86  
 
 87  0
         file.delete();
 88  
 
 89  0
         file.getParentFile().mkdirs();
 90  
 
 91  0
         File repositoryDirectory = getRepositoryDirectory();
 92  0
         FileUtils.deleteDirectory( repositoryDirectory );
 93  0
         repositoryDirectory.mkdirs();
 94  
 
 95  0
         server = new Server( 0 );
 96  
 
 97  0
         PutHandler putHandler = new PutHandler( repositoryDirectory );
 98  0
         server.addHandler( putHandler );
 99  
 
 100  0
         createContext( server, repositoryDirectory );
 101  
 
 102  0
         addConnectors( server );
 103  
 
 104  0
         server.start();
 105  
 
 106  0
         testRepository.setUrl( getTestRepositoryUrl() );
 107  0
     }
 108  
 
 109  
     @Override
 110  
     protected final int getTestRepositoryPort()
 111  
     {
 112  0
         if ( server == null )
 113  
         {
 114  0
             return 0;
 115  
         }
 116  0
         return server.getConnectors()[0].getLocalPort();
 117  
     }
 118  
 
 119  
     protected void createContext( Server server, File repositoryDirectory )
 120  
         throws IOException
 121  
     {
 122  0
         Context root = new Context( server, "/", Context.SESSIONS );
 123  0
         root.setResourceBase( repositoryDirectory.getAbsolutePath() );
 124  0
         ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
 125  0
         root.addServlet( servletHolder, "/*" );
 126  0
     }
 127  
 
 128  
     protected void tearDownWagonTestingFixtures()
 129  
         throws Exception
 130  
     {
 131  0
         server.stop();
 132  0
     }
 133  
 
 134  
     public void testWagonGetFileList()
 135  
         throws Exception
 136  
     {
 137  0
         File dir = getRepositoryDirectory();
 138  0
         FileUtils.deleteDirectory( dir );
 139  
 
 140  0
         File f = new File( dir, "file-list" );
 141  0
         f.mkdirs();
 142  
 
 143  0
         super.testWagonGetFileList();
 144  0
     }
 145  
 
 146  
     public void testHttpHeaders()
 147  
         throws Exception
 148  
     {
 149  0
         Properties properties = new Properties();
 150  0
         properties.setProperty( "User-Agent", "Maven-Wagon/1.0" );
 151  
 
 152  0
         StreamingWagon wagon = (StreamingWagon) getWagon();
 153  
 
 154  0
         setHttpHeaders( wagon, properties );
 155  
 
 156  0
         Server server = new Server( 0 );
 157  0
         TestHeaderHandler handler = new TestHeaderHandler();
 158  0
         server.setHandler( handler );
 159  0
         addConnectors( server );
 160  0
         server.start();
 161  
 
 162  0
         wagon.connect(
 163  
             new Repository( "id", getProtocol() + "://localhost:" + server.getConnectors()[0].getLocalPort() ) );
 164  
 
 165  0
         wagon.getToStream( "resource", new StringOutputStream() );
 166  
 
 167  0
         wagon.disconnect();
 168  
 
 169  0
         server.stop();
 170  
 
 171  0
         assertEquals( "Maven-Wagon/1.0", handler.headers.get( "User-Agent" ) );
 172  0
     }
 173  
 
 174  
     /**
 175  
      * test set of User-Agent as it's done by aether wagon connector with using setHttpHeaders
 176  
      */
 177  
     public void testHttpHeadersWithCommonMethods()
 178  
         throws Exception
 179  
     {
 180  0
         Properties properties = new Properties();
 181  0
         properties.setProperty( "User-Agent", "Maven-Wagon/1.0" );
 182  
 
 183  0
         StreamingWagon wagon = (StreamingWagon) getWagon();
 184  
 
 185  0
         Method setHttpHeaders = wagon.getClass().getMethod( "setHttpHeaders", Properties.class );
 186  0
         setHttpHeaders.invoke( wagon, properties );
 187  
 
 188  0
         Server server = new Server( 0 );
 189  0
         TestHeaderHandler handler = new TestHeaderHandler();
 190  0
         server.setHandler( handler );
 191  0
         addConnectors( server );
 192  0
         server.start();
 193  
 
 194  0
         wagon.connect(
 195  
             new Repository( "id", getProtocol() + "://localhost:" + server.getConnectors()[0].getLocalPort() ) );
 196  
 
 197  0
         wagon.getToStream( "resource", new StringOutputStream() );
 198  
 
 199  0
         wagon.disconnect();
 200  
 
 201  0
         server.stop();
 202  
 
 203  0
         assertEquals( "Maven-Wagon/1.0", handler.headers.get( "User-Agent" ) );
 204  0
     }
 205  
 
 206  
     protected abstract void setHttpHeaders( StreamingWagon wagon, Properties properties );
 207  
 
 208  
     protected void addConnectors( Server server )
 209  
     {
 210  0
     }
 211  
 
 212  
     protected String getRepositoryUrl( Server server )
 213  
     {
 214  0
         int localPort = server.getConnectors()[0].getLocalPort();
 215  0
         return getProtocol() + "://localhost:" + localPort;
 216  
     }
 217  
 
 218  
     public void testGetForbidden()
 219  
         throws Exception
 220  
     {
 221  
         try
 222  
         {
 223  0
             runTestGet( HttpServletResponse.SC_FORBIDDEN );
 224  0
             fail();
 225  
         }
 226  0
         catch ( AuthorizationException e )
 227  
         {
 228  0
             assertTrue( true );
 229  0
         }
 230  0
     }
 231  
 
 232  
     public void testGet404()
 233  
         throws Exception
 234  
     {
 235  
         try
 236  
         {
 237  0
             runTestGet( HttpServletResponse.SC_NOT_FOUND );
 238  0
             fail();
 239  
         }
 240  0
         catch ( ResourceDoesNotExistException e )
 241  
         {
 242  0
             assertTrue( true );
 243  0
         }
 244  0
     }
 245  
 
 246  
     public void testGet500()
 247  
         throws Exception
 248  
     {
 249  
         try
 250  
         {
 251  0
             runTestGet( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
 252  0
             fail();
 253  
         }
 254  0
         catch ( TransferFailedException e )
 255  
         {
 256  0
             assertTrue( true );
 257  0
         }
 258  0
     }
 259  
 
 260  
     private void runTestGet( int status )
 261  
         throws Exception
 262  
     {
 263  0
         StreamingWagon wagon = (StreamingWagon) getWagon();
 264  
 
 265  0
         Server server = new Server( 0 );
 266  0
         StatusHandler handler = new StatusHandler();
 267  0
         handler.setStatusToReturn( status );
 268  0
         server.setHandler( handler );
 269  0
         addConnectors( server );
 270  0
         server.start();
 271  
 
 272  0
         wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
 273  
 
 274  
         try
 275  
         {
 276  0
             wagon.getToStream( "resource", new StringOutputStream() );
 277  0
             fail();
 278  
         }
 279  
         finally
 280  
         {
 281  0
             wagon.disconnect();
 282  
 
 283  0
             server.stop();
 284  0
         }
 285  0
     }
 286  
 
 287  
     public void testResourceExistsForbidden()
 288  
         throws Exception
 289  
     {
 290  
         try
 291  
         {
 292  0
             runTestResourceExists( HttpServletResponse.SC_FORBIDDEN );
 293  0
             fail();
 294  
         }
 295  0
         catch ( AuthorizationException e )
 296  
         {
 297  0
             assertTrue( true );
 298  0
         }
 299  0
     }
 300  
 
 301  
     public void testResourceExists404()
 302  
         throws Exception
 303  
     {
 304  
         try
 305  
         {
 306  0
             assertFalse( runTestResourceExists( HttpServletResponse.SC_NOT_FOUND ) );
 307  
         }
 308  0
         catch ( ResourceDoesNotExistException e )
 309  
         {
 310  0
             assertTrue( true );
 311  0
         }
 312  0
     }
 313  
 
 314  
     public void testResourceExists500()
 315  
         throws Exception
 316  
     {
 317  
         try
 318  
         {
 319  0
             runTestResourceExists( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
 320  0
             fail();
 321  
         }
 322  0
         catch ( TransferFailedException e )
 323  
         {
 324  0
             assertTrue( true );
 325  0
         }
 326  0
     }
 327  
 
 328  
     private boolean runTestResourceExists( int status )
 329  
         throws Exception
 330  
     {
 331  0
         StreamingWagon wagon = (StreamingWagon) getWagon();
 332  
 
 333  0
         Server server = new Server( 0 );
 334  0
         StatusHandler handler = new StatusHandler();
 335  0
         handler.setStatusToReturn( status );
 336  0
         server.setHandler( handler );
 337  0
         addConnectors( server );
 338  0
         server.start();
 339  
 
 340  0
         wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
 341  
 
 342  
         try
 343  
         {
 344  0
             return wagon.resourceExists( "resource" );
 345  
         }
 346  
         finally
 347  
         {
 348  0
             wagon.disconnect();
 349  
 
 350  0
             server.stop();
 351  
         }
 352  
     }
 353  
 
 354  
     protected long getExpectedLastModifiedOnGet( Repository repository, Resource resource )
 355  
     {
 356  0
         File file = new File( getRepositoryDirectory(), resource.getName() );
 357  0
         return ( file.lastModified() / 1000 ) * 1000;
 358  
     }
 359  
 
 360  
     protected File getRepositoryDirectory()
 361  
     {
 362  0
         return getTestFile( "target/test-output/http-repository" );
 363  
     }
 364  
 
 365  
     public void testGzipGet()
 366  
         throws Exception
 367  
     {
 368  0
         Server server = new Server( getTestRepositoryPort() );
 369  
 
 370  0
         String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
 371  0
         Context root = new Context( server, "/", Context.SESSIONS );
 372  0
         root.setResourceBase( localRepositoryPath );
 373  0
         ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
 374  0
         servletHolder.setInitParameter( "gzip", "true" );
 375  0
         root.addServlet( servletHolder, "/*" );
 376  0
         addConnectors( server );
 377  0
         server.start();
 378  
 
 379  
         try
 380  
         {
 381  0
             Wagon wagon = getWagon();
 382  
 
 383  0
             Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
 384  
 
 385  0
             File sourceFile = new File( localRepositoryPath + "/gzip" );
 386  
 
 387  0
             sourceFile.deleteOnExit();
 388  
 
 389  0
             String resName = "gzip-res.txt";
 390  0
             String sourceContent = writeTestFileGzip( sourceFile, resName );
 391  
 
 392  0
             wagon.connect( testRepository );
 393  
 
 394  0
             File destFile = FileTestUtils.createUniqueFile( getName(), getName() );
 395  
 
 396  0
             destFile.deleteOnExit();
 397  
 
 398  0
             wagon.get( "gzip/" + resName, destFile );
 399  
 
 400  0
             wagon.disconnect();
 401  
 
 402  0
             String destContent = FileUtils.fileRead( destFile );
 403  
 
 404  0
             assertEquals( sourceContent, destContent );
 405  
         }
 406  
         finally
 407  
         {
 408  0
             server.stop();
 409  0
         }
 410  0
     }
 411  
 
 412  
     public void testProxiedRequest()
 413  
         throws Exception
 414  
     {
 415  0
         ProxyInfo proxyInfo = createProxyInfo();
 416  0
         TestHeaderHandler handler = new TestHeaderHandler();
 417  
 
 418  0
         runTestProxiedRequest( proxyInfo, handler );
 419  0
     }
 420  
 
 421  
     public void testProxiedRequestWithAuthentication()
 422  
         throws Exception
 423  
     {
 424  0
         ProxyInfo proxyInfo = createProxyInfo();
 425  0
         proxyInfo.setUserName( "user" );
 426  0
         proxyInfo.setPassword( "secret" );
 427  0
         AuthorizingProxyHandler handler = new AuthorizingProxyHandler();
 428  
 
 429  0
         runTestProxiedRequest( proxyInfo, handler );
 430  
 
 431  0
         assertTrue( handler.headers.containsKey( "Proxy-Authorization" ) );
 432  
 
 433  0
         if ( supportProxyPreemptiveAuthentication() )
 434  
         {
 435  0
             assertEquals( 200, handler.securityHandlerRequestReponses.get( 0 ).responseCode );
 436  
         }
 437  
         else
 438  
         {
 439  0
             assertEquals( 407, handler.securityHandlerRequestReponses.get( 0 ).responseCode );
 440  0
             assertEquals( 200, handler.securityHandlerRequestReponses.get( 1 ).responseCode );
 441  
         }
 442  
 
 443  0
     }
 444  
 
 445  
     private void runTestProxiedRequest( ProxyInfo proxyInfo, TestHeaderHandler handler )
 446  
         throws Exception
 447  
     {
 448  
         // what an UGLY hack!
 449  
         // but apparently jetty needs some time to free up resources
 450  
         // <5s: broken test :(
 451  0
         Thread.sleep( 5001L );
 452  
 
 453  0
         Server proxyServer = new Server( 0 );
 454  
 
 455  0
         proxyServer.setHandler( handler );
 456  
 
 457  0
         proxyServer.start();
 458  
 
 459  0
         proxyInfo.setPort( proxyServer.getConnectors()[0].getLocalPort() );
 460  
 
 461  0
         System.out.println(
 462  
             "start proxy on host/port " + proxyInfo.getHost() + "/" + proxyInfo.getPort() + " with non proxyHosts "
 463  
                 + proxyInfo.getNonProxyHosts() );
 464  
 
 465  0
         while ( !proxyServer.isRunning() || !proxyServer.isStarted() )
 466  
         {
 467  0
             Thread.sleep( 10 );
 468  
         }
 469  
 
 470  
         try
 471  
         {
 472  0
             StreamingWagon wagon = (StreamingWagon) getWagon();
 473  
 
 474  0
             System.out.println( " wagon hashCode " + wagon.hashCode() );
 475  
 
 476  0
             Repository testRepository = new Repository( "id", "http://www.example.com/" );
 477  
 
 478  0
             String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
 479  0
             File sourceFile = new File( localRepositoryPath, "test-proxied-resource" );
 480  0
             FileUtils.fileWrite( sourceFile.getAbsolutePath(), "content" );
 481  
 
 482  0
             wagon.connect( testRepository, proxyInfo );
 483  
 
 484  0
             StringOutputStream out = new StringOutputStream();
 485  
             try
 486  
             {
 487  0
                 wagon.getToStream( "test-proxied-resource", out );
 488  
 
 489  0
                 assertTrue( handler.headers.containsKey( "Proxy-Connection" ) );
 490  
             }
 491  
             finally
 492  
             {
 493  0
                 System.setProperty( "http.proxyHost", "" );
 494  0
                 System.setProperty( "http.proxyPort", "" );
 495  0
                 wagon.disconnect();
 496  0
             }
 497  
         }
 498  
         finally
 499  
         {
 500  0
             proxyServer.stop();
 501  0
         }
 502  0
     }
 503  
 
 504  
     private ProxyInfo createProxyInfo()
 505  
     {
 506  0
         ProxyInfo proxyInfo = new ProxyInfo();
 507  0
         proxyInfo.setHost( "localhost" );
 508  0
         proxyInfo.setNonProxyHosts( null );
 509  0
         proxyInfo.setType( "http" );
 510  0
         return proxyInfo;
 511  
     }
 512  
 
 513  
     public void testSecuredGetUnauthorized()
 514  
         throws Exception
 515  
     {
 516  
         try
 517  
         {
 518  0
             runTestSecuredGet( null );
 519  0
             fail();
 520  
         }
 521  0
         catch ( AuthorizationException e )
 522  
         {
 523  0
             assertTrue( true );
 524  0
         }
 525  0
     }
 526  
 
 527  
     public void testSecuredGetWrongPassword()
 528  
         throws Exception
 529  
     {
 530  
         try
 531  
         {
 532  0
             AuthenticationInfo authInfo = new AuthenticationInfo();
 533  0
             authInfo.setUserName( "user" );
 534  0
             authInfo.setPassword( "admin" );
 535  0
             runTestSecuredGet( authInfo );
 536  0
             fail();
 537  
         }
 538  0
         catch ( AuthorizationException e )
 539  
         {
 540  0
             assertTrue( true );
 541  0
         }
 542  0
     }
 543  
 
 544  
     public void testSecuredGet()
 545  
         throws Exception
 546  
     {
 547  0
         AuthenticationInfo authInfo = new AuthenticationInfo();
 548  0
         authInfo.setUserName( "user" );
 549  0
         authInfo.setPassword( "secret" );
 550  0
         runTestSecuredGet( authInfo );
 551  0
     }
 552  
 
 553  
     public void runTestSecuredGet( AuthenticationInfo authInfo )
 554  
         throws Exception
 555  
     {
 556  0
         String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
 557  0
         Server server = createSecurityServer( localRepositoryPath );
 558  0
         server.start();
 559  
 
 560  
         try
 561  
         {
 562  0
             StreamingWagon wagon = (StreamingWagon) getWagon();
 563  
 
 564  0
             Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
 565  
 
 566  0
             File sourceFile = new File( localRepositoryPath, "test-secured-resource" );
 567  0
             FileUtils.fileWrite( sourceFile.getAbsolutePath(), "top secret" );
 568  
 
 569  0
             wagon.connect( testRepository, authInfo );
 570  
 
 571  0
             StringOutputStream out = new StringOutputStream();
 572  
             try
 573  
             {
 574  0
                 wagon.getToStream( "test-secured-resource", out );
 575  
             }
 576  
             finally
 577  
             {
 578  0
                 wagon.disconnect();
 579  0
             }
 580  
 
 581  0
             assertEquals( "top secret", out.toString() );
 582  
         }
 583  
         finally
 584  
         {
 585  0
             server.stop();
 586  0
         }
 587  0
     }
 588  
 
 589  
     public void testSecuredResourceExistsUnauthorized()
 590  
         throws Exception
 591  
     {
 592  
         try
 593  
         {
 594  0
             runTestSecuredResourceExists( null );
 595  0
             fail();
 596  
         }
 597  0
         catch ( AuthorizationException e )
 598  
         {
 599  0
             assertTrue( true );
 600  0
         }
 601  0
     }
 602  
 
 603  
     public void testSecuredResourceExistsWrongPassword()
 604  
         throws Exception
 605  
     {
 606  
         try
 607  
         {
 608  0
             AuthenticationInfo authInfo = new AuthenticationInfo();
 609  0
             authInfo.setUserName( "user" );
 610  0
             authInfo.setPassword( "admin" );
 611  0
             runTestSecuredResourceExists( authInfo );
 612  
         }
 613  0
         catch ( AuthorizationException e )
 614  
         {
 615  0
             assertTrue( true );
 616  0
         }
 617  0
     }
 618  
 
 619  
     public void testSecuredResourceExists()
 620  
         throws Exception
 621  
     {
 622  0
         AuthenticationInfo authInfo = new AuthenticationInfo();
 623  0
         authInfo.setUserName( "user" );
 624  0
         authInfo.setPassword( "secret" );
 625  0
         runTestSecuredResourceExists( authInfo );
 626  0
     }
 627  
 
 628  
     public void runTestSecuredResourceExists( AuthenticationInfo authInfo )
 629  
         throws Exception
 630  
     {
 631  0
         String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
 632  0
         Server server = createSecurityServer( localRepositoryPath );
 633  0
         server.start();
 634  
 
 635  
         try
 636  
         {
 637  0
             StreamingWagon wagon = (StreamingWagon) getWagon();
 638  
 
 639  0
             Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
 640  
 
 641  0
             File sourceFile = new File( localRepositoryPath, "test-secured-resource-exists" );
 642  0
             FileUtils.fileWrite( sourceFile.getAbsolutePath(), "top secret" );
 643  
 
 644  0
             wagon.connect( testRepository, authInfo );
 645  
 
 646  
             try
 647  
             {
 648  0
                 assertTrue( wagon.resourceExists( "test-secured-resource-exists" ) );
 649  
 
 650  0
                 assertFalse( wagon.resourceExists( "test-secured-resource-not-exists" ) );
 651  
             }
 652  
             finally
 653  
             {
 654  0
                 wagon.disconnect();
 655  0
             }
 656  
         }
 657  
         finally
 658  
         {
 659  0
             server.stop();
 660  0
         }
 661  0
     }
 662  
 
 663  
     private Server createSecurityServer( String localRepositoryPath )
 664  
     {
 665  0
         Server server = new Server( 0 );
 666  
 
 667  0
         SecurityHandler sh = createSecurityHandler();
 668  
 
 669  0
         Context root = new Context( Context.SESSIONS );
 670  0
         root.setContextPath( "/" );
 671  0
         root.addHandler( sh );
 672  0
         root.setResourceBase( localRepositoryPath );
 673  0
         ServletHolder servletHolder = new ServletHolder( new DefaultServlet() );
 674  0
         root.addServlet( servletHolder, "/*" );
 675  
 
 676  0
         server.setHandler( root );
 677  0
         addConnectors( server );
 678  0
         return server;
 679  
     }
 680  
 
 681  
 
 682  
     private String writeTestFileGzip( File parent, String child )
 683  
         throws IOException
 684  
     {
 685  0
         File file = new File( parent, child );
 686  0
         file.getParentFile().mkdirs();
 687  0
         file.deleteOnExit();
 688  0
         OutputStream out = new FileOutputStream( file );
 689  
         try
 690  
         {
 691  0
             out.write( child.getBytes() );
 692  
         }
 693  
         finally
 694  
         {
 695  0
             out.close();
 696  0
         }
 697  
 
 698  0
         file = new File( parent, child + ".gz" );
 699  0
         file.deleteOnExit();
 700  
         String content;
 701  0
         out = new FileOutputStream( file );
 702  0
         out = new GZIPOutputStream( out );
 703  
         try
 704  
         {
 705  
             // write out different data than non-gz file, so we can
 706  
             // assert the gz version was returned
 707  0
             content = file.getAbsolutePath();
 708  0
             out.write( content.getBytes() );
 709  
         }
 710  
         finally
 711  
         {
 712  0
             out.close();
 713  0
         }
 714  
 
 715  0
         return content;
 716  
     }
 717  
 
 718  
     public void testPutForbidden()
 719  
         throws Exception
 720  
     {
 721  
         try
 722  
         {
 723  0
             runTestPut( HttpServletResponse.SC_FORBIDDEN );
 724  0
             fail();
 725  
         }
 726  0
         catch ( AuthorizationException e )
 727  
         {
 728  0
             assertTrue( true );
 729  0
         }
 730  0
     }
 731  
 
 732  
     public void testPut404()
 733  
         throws Exception
 734  
     {
 735  
         try
 736  
         {
 737  0
             runTestPut( HttpServletResponse.SC_NOT_FOUND );
 738  0
             fail();
 739  
         }
 740  0
         catch ( ResourceDoesNotExistException e )
 741  
         {
 742  0
             assertTrue( true );
 743  0
         }
 744  0
     }
 745  
 
 746  
     public void testPut500()
 747  
         throws Exception
 748  
     {
 749  
         try
 750  
         {
 751  0
             runTestPut( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
 752  0
             fail();
 753  
         }
 754  0
         catch ( TransferFailedException e )
 755  
         {
 756  0
             assertTrue( true );
 757  0
         }
 758  0
     }
 759  
 
 760  
     private void runTestPut( int status )
 761  
         throws Exception
 762  
     {
 763  0
         StreamingWagon wagon = (StreamingWagon) getWagon();
 764  
 
 765  0
         Server server = new Server( 0 );
 766  0
         StatusHandler handler = new StatusHandler();
 767  0
         handler.setStatusToReturn( status );
 768  0
         server.setHandler( handler );
 769  0
         addConnectors( server );
 770  0
         server.start();
 771  
 
 772  0
         wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
 773  
 
 774  0
         File tempFile = File.createTempFile( "wagon", "tmp" );
 775  0
         tempFile.deleteOnExit();
 776  0
         FileUtils.fileWrite( tempFile.getAbsolutePath(), "content" );
 777  
 
 778  
         try
 779  
         {
 780  0
             wagon.put( tempFile, "resource" );
 781  0
             fail();
 782  
         }
 783  
         finally
 784  
         {
 785  0
             wagon.disconnect();
 786  
 
 787  0
             server.stop();
 788  
 
 789  0
             tempFile.delete();
 790  0
         }
 791  0
     }
 792  
 
 793  
     public void testSecuredPutUnauthorized()
 794  
         throws Exception
 795  
     {
 796  
         try
 797  
         {
 798  0
             runTestSecuredPut( null );
 799  0
             fail();
 800  
         }
 801  0
         catch ( TransferFailedException e )
 802  
         {
 803  0
             assertTrue( true );
 804  0
         }
 805  0
     }
 806  
 
 807  
     public void testSecuredPutWrongPassword()
 808  
         throws Exception
 809  
     {
 810  
         try
 811  
         {
 812  0
             AuthenticationInfo authInfo = new AuthenticationInfo();
 813  0
             authInfo.setUserName( "user" );
 814  0
             authInfo.setPassword( "admin" );
 815  0
             runTestSecuredPut( authInfo );
 816  0
             fail();
 817  
         }
 818  0
         catch ( TransferFailedException e )
 819  
         {
 820  0
             assertTrue( true );
 821  0
         }
 822  0
     }
 823  
 
 824  
     public void testSecuredPut()
 825  
         throws Exception
 826  
     {
 827  0
         AuthenticationInfo authInfo = new AuthenticationInfo();
 828  0
         authInfo.setUserName( "user" );
 829  0
         authInfo.setPassword( "secret" );
 830  0
         runTestSecuredPut( authInfo );
 831  0
     }
 832  
 
 833  
     public void runTestSecuredPut( AuthenticationInfo authInfo )
 834  
         throws Exception
 835  
     {
 836  0
         runTestSecuredPut( authInfo, 1 );
 837  0
     }
 838  
 
 839  
     public void runTestSecuredPut( AuthenticationInfo authInfo, int putNumber )
 840  
         throws Exception
 841  
     {
 842  0
         String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
 843  0
         Server server = new Server( 0 );
 844  
 
 845  0
         TestSecurityHandler sh = createSecurityHandler();
 846  
 
 847  0
         PutHandler putHandler = new PutHandler( new File( localRepositoryPath ) );
 848  
 
 849  0
         HandlerCollection handlers = new HandlerCollection();
 850  0
         handlers.setHandlers( new Handler[]{ sh, putHandler } );
 851  
 
 852  0
         server.setHandler( handlers );
 853  0
         addConnectors( server );
 854  0
         server.start();
 855  
 
 856  0
         StreamingWagon wagon = (StreamingWagon) getWagon();
 857  0
         Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
 858  0
         wagon.connect( testRepository, authInfo );
 859  
         try
 860  
         {
 861  0
             for ( int i = 0; i < putNumber; i++ )
 862  
             {
 863  0
                 File sourceFile = new File( localRepositoryPath, "test-secured-put-resource" );
 864  0
                 sourceFile.delete();
 865  0
                 assertFalse( sourceFile.exists() );
 866  
 
 867  0
                 File tempFile = File.createTempFile( "wagon", "tmp" );
 868  0
                 tempFile.deleteOnExit();
 869  0
                 FileUtils.fileWrite( tempFile.getAbsolutePath(), "put top secret" );
 870  
 
 871  
                 try
 872  
                 {
 873  0
                     wagon.put( tempFile, "test-secured-put-resource" );
 874  
                 }
 875  
                 finally
 876  
                 {
 877  0
                     tempFile.delete();
 878  0
                 }
 879  
 
 880  0
                 assertEquals( "put top secret", FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
 881  
             }
 882  
         }
 883  
         finally
 884  
         {
 885  0
             wagon.disconnect();
 886  0
             server.stop();
 887  0
         }
 888  0
         assertEquals( putNumber, putHandler.putCallNumber );
 889  0
         testPreemptiveAuthentication( sh );
 890  0
     }
 891  
 
 892  
     public void testNonSecuredPutFromStream()
 893  
         throws Exception
 894  
     {
 895  0
         AuthenticationInfo authInfo = new AuthenticationInfo();
 896  0
         authInfo.setUserName( "user" );
 897  0
         authInfo.setPassword( "secret" );
 898  0
         runTestSecuredPutFromStream( authInfo, 1, false );
 899  0
     }
 900  
 
 901  
     public void testSecuredPutFromStream()
 902  
         throws Exception
 903  
     {
 904  0
         AuthenticationInfo authInfo = new AuthenticationInfo();
 905  0
         authInfo.setUserName( "user" );
 906  0
         authInfo.setPassword( "secret" );
 907  0
         runTestSecuredPutFromStream( authInfo, 1, true );
 908  0
     }
 909  
 
 910  
     public void runTestSecuredPutFromStream( AuthenticationInfo authInfo, int putNumber, boolean addSecurityHandler )
 911  
         throws Exception
 912  
     {
 913  0
         String localRepositoryPath = FileTestUtils.getTestOutputDir().toString();
 914  0
         Server server = new Server( 0 );
 915  
 
 916  0
         TestSecurityHandler sh = createSecurityHandler();
 917  
 
 918  0
         PutHandler putHandler = new PutHandler( new File( localRepositoryPath ) );
 919  
 
 920  0
         HandlerCollection handlers = new HandlerCollection();
 921  0
         handlers.setHandlers( addSecurityHandler ? new Handler[]{ sh, putHandler } : new Handler[]{ putHandler } );
 922  
 
 923  0
         server.setHandler( handlers );
 924  0
         addConnectors( server );
 925  0
         server.start();
 926  
 
 927  0
         StreamingWagon wagon = (StreamingWagon) getWagon();
 928  0
         Repository testRepository = new Repository( "id", getRepositoryUrl( server ) );
 929  0
         if ( addSecurityHandler )
 930  
         {
 931  0
             wagon.connect( testRepository, authInfo );
 932  
         }
 933  
         else
 934  
         {
 935  0
             wagon.connect( testRepository );
 936  
         }
 937  
         try
 938  
         {
 939  0
             for ( int i = 0; i < putNumber; i++ )
 940  
             {
 941  0
                 File sourceFile = new File( localRepositoryPath, "test-secured-put-resource" );
 942  0
                 sourceFile.delete();
 943  0
                 assertFalse( sourceFile.exists() );
 944  
 
 945  0
                 File tempFile = File.createTempFile( "wagon", "tmp" );
 946  0
                 tempFile.deleteOnExit();
 947  0
                 String content = "put top secret";
 948  0
                 FileUtils.fileWrite( tempFile.getAbsolutePath(), content );
 949  
 
 950  0
                 FileInputStream fileInputStream = new FileInputStream( tempFile );
 951  
                 try
 952  
                 {
 953  0
                     wagon.putFromStream( fileInputStream, "test-secured-put-resource", content.length(), -1 );
 954  
                 }
 955  
                 finally
 956  
                 {
 957  0
                     fileInputStream.close();
 958  0
                     tempFile.delete();
 959  
 
 960  0
                 }
 961  
 
 962  0
                 assertEquals( content, FileUtils.fileRead( sourceFile.getAbsolutePath() ) );
 963  
             }
 964  
         }
 965  
         finally
 966  
         {
 967  0
             wagon.disconnect();
 968  0
             server.stop();
 969  0
         }
 970  0
         assertEquals( putNumber, putHandler.putCallNumber );
 971  0
         if ( addSecurityHandler )
 972  
         {
 973  0
             testPreemptiveAuthentication( sh );
 974  
         }
 975  
 
 976  
         // ensure we didn't use chunked transfer which doesn't work on ngnix
 977  0
         for ( DeployedResource deployedResource : putHandler.deployedResources )
 978  
         {
 979  0
             if ( StringUtils.equalsIgnoreCase( "chunked", deployedResource.transferEncoding ) )
 980  
             {
 981  0
                 fail( "deployedResource use chunked: " + deployedResource );
 982  
             }
 983  
         }
 984  0
     }
 985  
 
 986  
 
 987  
     protected abstract boolean supportPreemptiveAuthentication();
 988  
 
 989  
     protected boolean supportProxyPreemptiveAuthentication()
 990  
     {
 991  0
         return false;
 992  
     }
 993  
 
 994  
     protected void testPreemptiveAuthentication( TestSecurityHandler sh )
 995  
     {
 996  
 
 997  0
         if ( supportPreemptiveAuthentication() )
 998  
         {
 999  0
             assertEquals( "not 1 security handler use " + sh.securityHandlerRequestReponses, 1,
 1000  
                           sh.securityHandlerRequestReponses.size() );
 1001  0
             assertEquals( 200, sh.securityHandlerRequestReponses.get( 0 ).responseCode );
 1002  
         }
 1003  
         else
 1004  
         {
 1005  0
             assertEquals( "not 2 security handler use " + sh.securityHandlerRequestReponses, 2,
 1006  
                           sh.securityHandlerRequestReponses.size() );
 1007  0
             assertEquals( 401, sh.securityHandlerRequestReponses.get( 0 ).responseCode );
 1008  0
             assertEquals( 200, sh.securityHandlerRequestReponses.get( 1 ).responseCode );
 1009  
 
 1010  
         }
 1011  0
     }
 1012  
 
 1013  0
     static class StatusHandler
 1014  
         extends AbstractHandler
 1015  
     {
 1016  
         private int status;
 1017  
 
 1018  
         public void setStatusToReturn( int status )
 1019  
         {
 1020  0
             this.status = status;
 1021  0
         }
 1022  
 
 1023  
         public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
 1024  
             throws IOException, ServletException
 1025  
         {
 1026  0
             if ( status != 0 )
 1027  
             {
 1028  0
                 response.setStatus( status );
 1029  0
                 ( (Request) request ).setHandled( true );
 1030  
             }
 1031  0
         }
 1032  
     }
 1033  
 
 1034  
     static class DeployedResource
 1035  
     {
 1036  
         String httpMethod;
 1037  
 
 1038  
         String requestUri;
 1039  
 
 1040  
         String contentLength;
 1041  
 
 1042  
         String transferEncoding;
 1043  
 
 1044  
         public DeployedResource()
 1045  0
         {
 1046  
             // no op
 1047  0
         }
 1048  
 
 1049  
         @Override
 1050  
         public String toString()
 1051  
         {
 1052  0
             final StringBuilder sb = new StringBuilder();
 1053  0
             sb.append( "DeployedResource" );
 1054  0
             sb.append( "{httpMethod='" ).append( httpMethod ).append( '\'' );
 1055  0
             sb.append( ", requestUri='" ).append( requestUri ).append( '\'' );
 1056  0
             sb.append( ", contentLength='" ).append( contentLength ).append( '\'' );
 1057  0
             sb.append( ", transferEncoding='" ).append( transferEncoding ).append( '\'' );
 1058  0
             sb.append( '}' );
 1059  0
             return sb.toString();
 1060  
         }
 1061  
     }
 1062  
 
 1063  
     static class PutHandler
 1064  
         extends AbstractHandler
 1065  
     {
 1066  
         private final File resourceBase;
 1067  
 
 1068  0
         public List<DeployedResource> deployedResources = new ArrayList<DeployedResource>();
 1069  
 
 1070  0
         public int putCallNumber = 0;
 1071  
 
 1072  
         public PutHandler( File repositoryDirectory )
 1073  0
         {
 1074  0
             this.resourceBase = repositoryDirectory;
 1075  0
         }
 1076  
 
 1077  
         public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
 1078  
             throws IOException, ServletException
 1079  
         {
 1080  0
             Request base_request =
 1081  
                 request instanceof Request ? (Request) request : HttpConnection.getCurrentConnection().getRequest();
 1082  
 
 1083  0
             if ( base_request.isHandled() || !"PUT".equals( base_request.getMethod() ) )
 1084  
             {
 1085  0
                 return;
 1086  
             }
 1087  
 
 1088  0
             base_request.setHandled( true );
 1089  
 
 1090  0
             File file = new File( resourceBase, URLDecoder.decode( request.getPathInfo() ) );
 1091  0
             file.getParentFile().mkdirs();
 1092  0
             FileOutputStream out = new FileOutputStream( file );
 1093  0
             ServletInputStream in = request.getInputStream();
 1094  
             try
 1095  
             {
 1096  0
                 IOUtil.copy( in, out );
 1097  
             }
 1098  
             finally
 1099  
             {
 1100  0
                 in.close();
 1101  0
                 out.close();
 1102  0
             }
 1103  0
             System.out.println( "put file " + request.getPathInfo() );
 1104  0
             putCallNumber++;
 1105  0
             DeployedResource deployedResource = new DeployedResource();
 1106  
 
 1107  0
             deployedResource.httpMethod = request.getMethod();
 1108  0
             deployedResource.requestUri = request.getRequestURI();
 1109  0
             deployedResource.transferEncoding = request.getHeader( "Transfer-Encoding" );
 1110  0
             deployedResource.contentLength = request.getHeader( "Content-Length" );
 1111  0
             deployedResources.add( deployedResource );
 1112  
 
 1113  0
             response.setStatus( HttpServletResponse.SC_CREATED );
 1114  0
         }
 1115  
     }
 1116  
 
 1117  0
     private static class AuthorizingProxyHandler
 1118  
         extends TestHeaderHandler
 1119  
     {
 1120  
 
 1121  0
         List<SecurityHandlerRequestReponse> securityHandlerRequestReponses =
 1122  
             new ArrayList<SecurityHandlerRequestReponse>();
 1123  
 
 1124  
         public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
 1125  
             throws IOException, ServletException
 1126  
         {
 1127  0
             System.out.println( " handle proxy request" );
 1128  0
             if ( request.getHeader( "Proxy-Authorization" ) == null )
 1129  
             {
 1130  0
                 securityHandlerRequestReponses.add( new SecurityHandlerRequestReponse( request.getMethod(), 407 ) );
 1131  0
                 response.setStatus( 407 );
 1132  0
                 response.addHeader( "Proxy-Authenticate", "Basic realm=\"Squid proxy-caching web server\"" );
 1133  
 
 1134  0
                 ( (Request) request ).setHandled( true );
 1135  0
                 return;
 1136  
             }
 1137  0
             securityHandlerRequestReponses.add( new SecurityHandlerRequestReponse( request.getMethod(), 200 ) );
 1138  0
             super.handle( target, request, response, dispatch );
 1139  0
         }
 1140  
     }
 1141  
 
 1142  
     private static class TestHeaderHandler
 1143  
         extends AbstractHandler
 1144  
     {
 1145  0
         public Map headers = Collections.EMPTY_MAP;
 1146  
 
 1147  
         public TestHeaderHandler()
 1148  0
         {
 1149  0
         }
 1150  
 
 1151  
         public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
 1152  
             throws IOException, ServletException
 1153  
         {
 1154  0
             headers = new HashMap();
 1155  0
             for ( Enumeration e = request.getHeaderNames(); e.hasMoreElements(); )
 1156  
             {
 1157  0
                 String name = (String) e.nextElement();
 1158  0
                 headers.put( name, request.getHeader( name ) );
 1159  0
             }
 1160  
 
 1161  0
             response.setContentType( "text/plain" );
 1162  0
             response.setStatus( HttpServletResponse.SC_OK );
 1163  0
             response.getWriter().println( "Hello, World!" );
 1164  
 
 1165  0
             ( (Request) request ).setHandled( true );
 1166  0
         }
 1167  
 
 1168  
     }
 1169  
 
 1170  
     protected TestSecurityHandler createSecurityHandler()
 1171  
     {
 1172  0
         Constraint constraint = new Constraint();
 1173  0
         constraint.setName( Constraint.__BASIC_AUTH );
 1174  0
         constraint.setRoles( new String[]{ "admin" } );
 1175  0
         constraint.setAuthenticate( true );
 1176  
 
 1177  0
         ConstraintMapping cm = new ConstraintMapping();
 1178  0
         cm.setConstraint( constraint );
 1179  0
         cm.setPathSpec( "/*" );
 1180  
 
 1181  0
         TestSecurityHandler sh = new TestSecurityHandler();
 1182  0
         HashUserRealm hashUserRealm = new HashUserRealm( "MyRealm" );
 1183  0
         hashUserRealm.put( "user", "secret" );
 1184  0
         hashUserRealm.addUserToRole( "user", "admin" );
 1185  0
         sh.setUserRealm( hashUserRealm );
 1186  0
         sh.setConstraintMappings( new ConstraintMapping[]{ cm } );
 1187  0
         return sh;
 1188  
     }
 1189  
 
 1190  0
     public static class TestSecurityHandler
 1191  
         extends SecurityHandler
 1192  
     {
 1193  
 
 1194  0
         public List<SecurityHandlerRequestReponse> securityHandlerRequestReponses =
 1195  
             new ArrayList<SecurityHandlerRequestReponse>();
 1196  
 
 1197  
         @Override
 1198  
         public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
 1199  
             throws IOException, ServletException
 1200  
         {
 1201  0
             String method = request.getMethod();
 1202  0
             super.handle( target, request, response, dispatch );
 1203  0
             System.out.println( "method in SecurityHandler: " + method );
 1204  
 
 1205  0
             securityHandlerRequestReponses.add(
 1206  
                 new SecurityHandlerRequestReponse( method, ( (Response) response ).getStatus() ) );
 1207  0
         }
 1208  
 
 1209  
     }
 1210  
 
 1211  0
     public static class SecurityHandlerRequestReponse
 1212  
     {
 1213  
         public String method;
 1214  
 
 1215  
         public int responseCode;
 1216  
 
 1217  
         private SecurityHandlerRequestReponse( String method, int responseCode )
 1218  0
         {
 1219  0
             this.method = method;
 1220  0
             this.responseCode = responseCode;
 1221  0
         }
 1222  
 
 1223  
         @Override
 1224  
         public String toString()
 1225  
         {
 1226  0
             final StringBuilder sb = new StringBuilder();
 1227  0
             sb.append( "SecurityHandlerRequestReponse" );
 1228  0
             sb.append( "{method='" ).append( method ).append( '\'' );
 1229  0
             sb.append( ", responseCode=" ).append( responseCode );
 1230  0
             sb.append( '}' );
 1231  0
             return sb.toString();
 1232  
         }
 1233  
     }
 1234  
 }