View Javadoc

1   package org.apache.maven.it;
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.it.Verifier;
23  import org.apache.maven.it.util.ResourceExtractor;
24  
25  import java.io.File;
26  import java.io.IOException;
27  import java.io.PrintWriter;
28  import java.util.List;
29  import java.util.Properties;
30  
31  import javax.servlet.http.HttpServletRequest;
32  import javax.servlet.http.HttpServletResponse;
33  
34  import org.mortbay.jetty.Connector;
35  import org.mortbay.jetty.Handler;
36  import org.mortbay.jetty.Request;
37  import org.mortbay.jetty.Server;
38  import org.mortbay.jetty.handler.AbstractHandler;
39  import org.mortbay.jetty.security.SslSocketConnector;
40  
41  /**
42   * This is a test set for <a href="http://jira.codehaus.org/browse/MNG-4428">MNG-4428</a>.
43   * 
44   * @author Benjamin Bentmann
45   * @version $Id: MavenITmng4428FollowHttpRedirectTest.java 981712 2010-08-03 00:36:19Z bentmann $
46   */
47  public class MavenITmng4428FollowHttpRedirectTest
48      extends AbstractMavenIntegrationTestCase
49  {
50  
51      public MavenITmng4428FollowHttpRedirectTest()
52      {
53          super( "[2.0.3,3.0-alpha-1),(3.0-alpha-1,)" );
54      }
55  
56      /**
57       * Verify that redirects from HTTP to HTTP are getting followed.
58       */
59      public void testitHttpToHttp()
60          throws Exception
61      {
62          testit( true, true );
63      }
64  
65      /**
66       * Verify that redirects from HTTPS to HTTPS are getting followed.
67       */
68      public void testitHttpsToHttps()
69          throws Exception
70      {
71          testit( false, false );
72      }
73  
74      /**
75       * Verify that redirects from HTTP to HTTPS are getting followed.
76       */
77      public void testitHttpToHttps()
78          throws Exception
79      {
80          requiresMavenVersion( "[2.2.0]" );
81  
82          testit( true, false );
83      }
84  
85      /**
86       * Verify that redirects from HTTPS to HTTP are getting followed.
87       */
88      public void testitHttpsToHttp()
89          throws Exception
90      {
91          requiresMavenVersion( "[2.2.0]" );
92  
93          testit( false, true );
94      }
95  
96      /**
97       * Verify that redirects using a relative location URL are getting followed. While a relative URL violates the
98       * HTTP spec, popular HTTP clients do support them so we better do, too.
99       */
100     public void testitRelativeLocation()
101         throws Exception
102     {
103         testit( true, true, true );
104     }
105 
106     private void testit( boolean fromHttp, boolean toHttp )
107         throws Exception
108     {
109         testit( fromHttp, toHttp, false );
110     }
111 
112     private void testit( boolean fromHttp, boolean toHttp, boolean relativeLocation )
113         throws Exception
114     {
115         File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-4428" );
116 
117         Verifier verifier = newVerifier( testDir.getAbsolutePath() );
118 
119         // NOTE: trust store cannot be reliably configured for the current JVM
120         verifier.setForkJvm( true );
121 
122         // keytool -genkey -alias localhost -keypass key-passwd -keystore keystore -storepass store-passwd \
123         //   -validity 4096 -dname "cn=localhost, ou=None, L=Seattle, ST=Washington, o=ExampleOrg, c=US" -keyalg RSA
124         String storePath = new File( testDir, "keystore" ).getAbsolutePath();
125         String storePwd = "store-passwd";
126         String keyPwd = "key-passwd";
127 
128         Server server = new Server( 0 );
129         server.addConnector( newHttpsConnector( storePath, storePwd, keyPwd ) );
130         Connector from = server.getConnectors()[ fromHttp ? 0 : 1 ];
131         Connector to = server.getConnectors()[ toHttp ? 0 : 1 ];
132         server.setHandler( new RedirectHandler( toHttp ? "http" : "https", relativeLocation ? null : to ) );
133         server.start();
134 
135         try
136         {
137             verifier.setAutoclean( false );
138             verifier.deleteArtifacts( "org.apache.maven.its.mng4428" );
139             verifier.deleteDirectory( "target" );
140             Properties filterProps = verifier.newDefaultFilterProperties();
141             filterProps.setProperty( "@protocol@", fromHttp ? "http" : "https" );
142             filterProps.setProperty( "@port@", Integer.toString( from.getLocalPort() ) );
143             verifier.filterFile( "settings-template.xml", "settings.xml", "UTF-8", filterProps );
144             verifier.getCliOptions().add( "-X --settings" );
145             verifier.getCliOptions().add( "settings.xml" );
146             verifier.setSystemProperty( "javax.net.ssl.trustStore", storePath );
147             verifier.setSystemProperty( "javax.net.ssl.trustStorePassword", storePwd );
148             verifier.setLogFileName( "log-" + getName().substring( 6 ) + ".txt" );
149             verifier.executeGoal( "validate" );
150             verifier.verifyErrorFreeLog();
151             verifier.resetStreams();
152         }
153         finally
154         {
155             server.stop();
156         }
157 
158         List cp = verifier.loadLines( "target/classpath.txt", "UTF-8" );
159         assertTrue( cp.toString(), cp.contains( "dep-0.1.jar" ) );
160     }
161 
162     private Connector newHttpsConnector( String keystore, String storepwd, String keypwd )
163     {
164         SslSocketConnector connector = new SslSocketConnector();
165         connector.setPort( 0 );
166         connector.setKeystore( keystore );
167         connector.setPassword( storepwd );
168         connector.setKeyPassword( keypwd );
169         return connector;
170     }
171 
172     static class RedirectHandler extends AbstractHandler
173     {
174 
175         private final String protocol;
176 
177         private final Connector connector;
178 
179         public RedirectHandler( String protocol, Connector connector )
180         {
181             this.protocol = protocol;
182             this.connector = connector;
183         }
184 
185         public void handle( String target, HttpServletRequest request, HttpServletResponse response, int dispatch )
186             throws IOException
187         {
188             System.out.println( "Handling " + request.getMethod() + " " + request.getRequestURL() );
189 
190             PrintWriter writer = response.getWriter();
191 
192             String uri = request.getRequestURI();
193             if ( uri.startsWith( "/repo/" ) )
194             {
195                 String location = "/redirected/" + uri.substring( 6 );
196                 if ( protocol != null && connector != null )
197                 {
198                     location = protocol + "://localhost:" + connector.getLocalPort() + location;
199                 }
200                 if ( uri.endsWith( ".pom" ) )
201                 {
202                     response.setStatus( HttpServletResponse.SC_MOVED_TEMPORARILY );
203                 }
204                 else
205                 {
206                     response.setStatus( HttpServletResponse.SC_MOVED_PERMANENTLY );
207                 }
208                 response.setHeader( "Location", location );
209             }
210             else if ( uri.endsWith( ".pom" ) )
211             {
212                 writer.println( "<project>" );
213                 writer.println( "  <modelVersion>4.0.0</modelVersion>" );
214                 writer.println( "  <groupId>org.apache.maven.its.mng4428</groupId>" );
215                 writer.println( "  <artifactId>dep</artifactId>" );
216                 writer.println( "  <version>0.1</version>" );
217                 writer.println( "</project>" );
218                 response.setStatus( HttpServletResponse.SC_OK );
219             }
220             else if ( uri.endsWith( ".jar" ) )
221             {
222                 writer.println( "empty" );
223                 response.setStatus( HttpServletResponse.SC_OK );
224             }
225             else
226             {
227                 response.setStatus( HttpServletResponse.SC_NOT_FOUND );
228             }
229 
230             ( (Request) request ).setHandled( true );
231         }
232 
233     }
234 
235 }