Author: olamy Date: Fri Mar 16 23:35:32 2012 New Revision: 1301824 URL: http://svn.apache.org/viewvc?rev=1301824&view=rev Log: [MTOMCAT-116] handle redirect response when deploying a war
Modified: tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java Modified: tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java?rev=1301824&r1=1301823&r2=1301824&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java (original) +++ tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java Fri Mar 16 23:35:32 2012 @@ -22,8 +22,10 @@ package org.apache.tomcat.maven.common.d import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; +import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; @@ -36,10 +38,11 @@ import org.apache.http.entity.AbstractHt import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.BasicClientConnectionManager; +import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.apache.http.protocol.BasicHttpContext; -import org.apache.maven.plugin.logging.Log; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -162,7 +165,9 @@ public class TomcatManager this.password = password; this.charset = charset; - this.httpClient = new DefaultHttpClient( new BasicClientConnectionManager() ); + PoolingClientConnectionManager poolingClientConnectionManager = new PoolingClientConnectionManager(); + poolingClientConnectionManager.setMaxTotal( 5 ); + this.httpClient = new DefaultHttpClient( poolingClientConnectionManager ); if ( StringUtils.isNotEmpty( username ) && StringUtils.isNotEmpty( password ) ) { Credentials creds = new UsernamePasswordCredentials( username, password ); @@ -305,7 +310,7 @@ public class TomcatManager * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ - public TomcatManagerResponse deploy( String path, InputStream war ) + public TomcatManagerResponse deploy( String path, File war ) throws TomcatManagerException, IOException { return deploy( path, war, false ); @@ -322,7 +327,7 @@ public class TomcatManager * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ - public TomcatManagerResponse deploy( String path, InputStream war, boolean update ) + public TomcatManagerResponse deploy( String path, File war, boolean update ) throws TomcatManagerException, IOException { return deploy( path, war, update, null ); @@ -340,7 +345,7 @@ public class TomcatManager * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ - public TomcatManagerResponse deploy( String path, InputStream war, boolean update, String tag ) + public TomcatManagerResponse deploy( String path, File war, boolean update, String tag ) throws TomcatManagerException, IOException { return deployImpl( path, null, null, war, update, tag ); @@ -357,7 +362,7 @@ public class TomcatManager * @throws IOException * @since 2.0 */ - public TomcatManagerResponse deploy( String path, InputStream war, boolean update, String tag, long length ) + public TomcatManagerResponse deploy( String path, File war, boolean update, String tag, long length ) throws TomcatManagerException, IOException { return deployImpl( path, null, null, war, update, tag, length ); @@ -631,8 +636,7 @@ public class TomcatManager // Private Methods // ---------------------------------------------------------------------- - private TomcatManagerResponse deployImpl( String path, URL config, URL war, InputStream data, boolean update, - String tag ) + private TomcatManagerResponse deployImpl( String path, URL config, URL war, File data, boolean update, String tag ) throws TomcatManagerException, IOException { return deployImpl( path, config, war, data, update, tag, -1 ); @@ -644,15 +648,15 @@ public class TomcatManager * @param path the webapp context path to deploy to * @param config the URL of the context XML configuration to deploy, or null for none * @param war the URL of the WAR to deploy, or null to use <code>data</code> - * @param data an input stream to the WAR to deploy, or null to use <code>war</code> + * @param data WAR file to deploy, or null to use <code>war</code> * @param update whether to first undeploy the webapp if it already exists * @param tag the tag name to use * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ - private TomcatManagerResponse deployImpl( String path, URL config, URL war, InputStream data, boolean update, - String tag, long length ) + private TomcatManagerResponse deployImpl( String path, URL config, URL war, File data, boolean update, String tag, + long length ) throws TomcatManagerException, IOException { StringBuilder buffer = new StringBuilder( "/deploy" ); @@ -686,12 +690,12 @@ public class TomcatManager * Invokes Tomcat manager with the specified command and content data. * * @param path the Tomcat manager command to invoke - * @param data an input stream to the content data + * @param data file to deploy * @return the Tomcat manager response * @throws TomcatManagerException if the Tomcat manager request fails * @throws IOException if an i/o error occurs */ - protected TomcatManagerResponse invoke( String path, InputStream data, long length ) + protected TomcatManagerResponse invoke( String path, File data, long length ) throws TomcatManagerException, IOException { @@ -717,12 +721,38 @@ public class TomcatManager HttpResponse response = httpClient.execute( httpRequestBase, localContext ); + int statusCode = response.getStatusLine().getStatusCode(); + + switch ( statusCode ) + { + // Success Codes + case HttpStatus.SC_OK: // 200 + case HttpStatus.SC_CREATED: // 201 + case HttpStatus.SC_ACCEPTED: // 202 + break; + // handle all redirect even if http specs says " the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user" + case HttpStatus.SC_MOVED_PERMANENTLY: // 301 + case HttpStatus.SC_MOVED_TEMPORARILY: // 302 + case HttpStatus.SC_SEE_OTHER: // 303 + String relocateUrl = calculateRelocatedUrl( response ); + this.url = new URL( relocateUrl ); + return invoke( path, data, length ); + } + return new TomcatManagerResponse().setStatusCode( response.getStatusLine().getStatusCode() ).setReasonPhrase( response.getStatusLine().getReasonPhrase() ).setHttpResponseBody( IOUtils.toString( response.getEntity().getContent() ) ); } + protected String calculateRelocatedUrl( HttpResponse response ) + { + Header locationHeader = response.getFirstHeader( "Location" ); + String locationField = locationHeader.getValue(); + // is it a relative Location or a full ? + return locationField.startsWith( "http" ) ? locationField : url.toString() + '/' + locationField; + } + /** * Gets the HTTP Basic Authorization header value for the supplied username and password. @@ -748,7 +778,7 @@ public class TomcatManager private final static int BUFFER_SIZE = 2048; - private InputStream stream; + private File file; PrintStream out = System.out; @@ -760,28 +790,28 @@ public class TomcatManager private long startTime; - private RequestEntityImplementation( final InputStream stream, long length, String url ) + private RequestEntityImplementation( final File file, long length, String url ) { - this.stream = stream; + this.file = file; this.length = length; this.url = url; } public long getContentLength() { - return length >= 0 ? length : -1; + return length >= 0 ? length : ( file.length() >= 0 ? file.length() : -1 ); } public InputStream getContent() throws IOException, IllegalStateException { - return this.stream; + return new FileInputStream( this.file ); } public boolean isRepeatable() { - return false; + return true; } @@ -793,11 +823,13 @@ public class TomcatManager { throw new IllegalArgumentException( "Output stream may not be null" ); } + FileInputStream stream = new FileInputStream( this.file ); transferInitiated( this.url ); this.startTime = System.currentTimeMillis(); try { byte[] buffer = new byte[BUFFER_SIZE]; + int l; if ( this.length < 0 ) { Modified: tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java?rev=1301824&r1=1301823&r2=1301824&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java (original) +++ tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java Fri Mar 16 23:35:32 2012 @@ -23,6 +23,7 @@ import org.apache.catalina.Context; import org.apache.catalina.startup.Tomcat; import org.apache.commons.io.IOUtils; import org.apache.tomcat.maven.common.deployer.TomcatManager; +import org.apache.tomcat.maven.common.deployer.TomcatManagerResponse; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -46,10 +47,16 @@ public class TomcatManagerTest Tomcat tomcat; + Tomcat redirectTomcat; + UploadServlet uploadServlet; + RedirectServlet redirectServlet; + int port; + int redirectPort; + public static String getBasedir() { return System.getProperty( "basedir" ); @@ -74,6 +81,18 @@ public class TomcatManagerTest port = tomcat.getConnector().getLocalPort(); System.out.println( "Tomcat started on port:" + port ); + + redirectTomcat = new Tomcat(); + redirectTomcat.setBaseDir( System.getProperty( "java.io.tmpdir" ) ); + redirectTomcat.setPort( 0 ); + context = redirectTomcat.addContext( "", System.getProperty( "java.io.tmpdir" ) ); + redirectServlet = new RedirectServlet(); + redirectTomcat.addServlet( context, "foo", redirectServlet ); + context.addServletMapping( "/*", "foo" ); + redirectTomcat.start(); + redirectPort = redirectTomcat.getConnector().getLocalPort(); + + System.out.println( "redirect Tomcat started on port:" + redirectPort ); } @Override @@ -88,13 +107,82 @@ public class TomcatManagerTest public void testDeployWar() throws Exception { + uploadServlet.uploadedResources.clear(); TomcatManager tomcatManager = new TomcatManager( new URL( "http://localhost:" + this.port + "/foo/bar" ) ); - tomcatManager.deploy( "foo", new FileInputStream( new File( getBasedir(), "src/test/resources/test.txt" ) ) ); - StringWriter sw = new StringWriter(); + TomcatManagerResponse response = + tomcatManager.deploy( "foo", new File( getBasedir(), "src/test/resources/test.txt" ) ); + + assertEquals( 200, response.getStatusCode() ); + assertEquals( 1, uploadServlet.uploadedResources.size() ); + assertEquals( "/foo/bar/deploy", uploadServlet.uploadedResources.get( 0 ).requestUri ); + FileInputStream fileInputStream = new FileInputStream( uploadServlet.uploadedResources.get( 0 ).uploadedFile ); + try + { + StringWriter sw = new StringWriter(); + IOUtils.copy( fileInputStream, sw ); + assertTrue( sw.toString().contains( "Apache Tomcat rocks!!" ) ); + } + finally + { + fileInputStream.close(); + } + } + + public void testDeployWarWithRedirect() + throws Exception + { + uploadServlet.uploadedResources.clear(); + TomcatManager tomcatManager = + new TomcatManager( new URL( "http://localhost:" + this.redirectPort + "/foo/bar" ) ); + redirectServlet.redirectPath = "http://localhost:" + this.port + "/foo/bar/redirected"; + TomcatManagerResponse response = + tomcatManager.deploy( "foo", new File( getBasedir(), "src/test/resources/test.txt" ) ); + + assertEquals( 200, response.getStatusCode() ); + + assertEquals( "no request to redirect servlet", 1, redirectServlet.uploadedResources.size() ); + assertEquals( "/foo/bar/deploy", redirectServlet.uploadedResources.get( 0 ).requestUri ); + assertEquals( "no redirected request to upload servlet", 1, uploadServlet.uploadedResources.size() ); + + assertEquals( "/foo/bar/deploy", redirectServlet.uploadedResources.get( 0 ).requestUri ); + FileInputStream fileInputStream = new FileInputStream( uploadServlet.uploadedResources.get( 0 ).uploadedFile ); try { + StringWriter sw = new StringWriter(); + IOUtils.copy( fileInputStream, sw ); + assertTrue( sw.toString().contains( "Apache Tomcat rocks!!" ) ); + } + finally + { + fileInputStream.close(); + } + } + + public void testDeployWarWithRedirectRelative() + throws Exception + { + uploadServlet.uploadedResources.clear(); + TomcatManager tomcatManager = + new TomcatManager( new URL( "http://localhost:" + this.redirectPort + "/foo/bar" ) ); + redirectServlet.redirectPath = "redirectrelative/foo"; + TomcatManagerResponse response = + tomcatManager.deploy( "foo", new File( getBasedir(), "src/test/resources/test.txt" ) ); + + assertEquals( 200, response.getStatusCode() ); + + assertEquals( "no request to redirect servlet", 2, redirectServlet.uploadedResources.size() ); + assertEquals( "/foo/bar/deploy", redirectServlet.uploadedResources.get( 0 ).requestUri ); + assertEquals( "found redirected request to upload servlet", 0, uploadServlet.uploadedResources.size() ); + + assertEquals( "/foo/bar/deploy", redirectServlet.uploadedResources.get( 0 ).requestUri ); + + FileInputStream fileInputStream = + new FileInputStream( redirectServlet.uploadedResources.get( 1 ).uploadedFile ); + try + { + StringWriter sw = new StringWriter(); IOUtils.copy( fileInputStream, sw ); assertTrue( sw.toString().contains( "Apache Tomcat rocks!!" ) ); } @@ -132,10 +220,37 @@ public class TomcatManagerTest throws ServletException, IOException { System.out.println( "put ok:" + req.getRequestURI() ); - super.doPut( req, resp ); File file = File.createTempFile( "tomcat-unit-test", "tmp" ); uploadedResources.add( new UploadedResource( req.getRequestURI(), file ) ); IOUtils.copy( req.getInputStream(), new FileOutputStream( file ) ); } } + + public class RedirectServlet + extends HttpServlet + { + int redirectPort = 0; + + String redirectPath; + + public List<UploadedResource> uploadedResources = new ArrayList<UploadedResource>(); + + @Override + protected void doPut( HttpServletRequest req, HttpServletResponse resp ) + throws ServletException, IOException + { + System.out.println( "RedirectServlet put ok:" + req.getRequestURI() ); + if ( req.getRequestURI().contains( "redirectrelative" ) ) + { + File file = File.createTempFile( "tomcat-unit-test", "tmp" ); + uploadedResources.add( new UploadedResource( req.getRequestURI(), file ) ); + IOUtils.copy( req.getInputStream(), new FileOutputStream( file ) ); + return; + } + uploadedResources.add( new UploadedResource( req.getRequestURI(), null ) ); + String redirectUri = + redirectPort > 0 ? "http://localhost:" + redirectPort + "/" + redirectPath : redirectPath; + resp.sendRedirect( redirectUri ); + } + } } Modified: tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt?rev=1301824&r1=1301823&r2=1301824&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt (original) +++ tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt Fri Mar 16 23:35:32 2012 @@ -1,2 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + Apache Tomcat rocks!! hey Apache Maven rocks too :P \ No newline at end of file Modified: tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java?rev=1301824&r1=1301823&r2=1301824&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java (original) +++ tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java Fri Mar 16 23:35:32 2012 @@ -23,7 +23,6 @@ import org.apache.maven.plugin.MojoExecu import org.apache.tomcat.maven.common.deployer.TomcatManagerException; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; /** @@ -84,7 +83,6 @@ public class AbstractDeployWarMojo getLog().info( messagesProvider.getMessage( "AbstractDeployMojo.deployingWar", getDeployedURL() ) ); - log( getManager().deploy( getPath(), new FileInputStream( warFile ), isUpdate(), getTag(), - warFile.length() ).getHttpResponseBody() ); + log( getManager().deploy( getPath(), warFile, isUpdate(), getTag(), warFile.length() ).getHttpResponseBody() ); } } Modified: tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java?rev=1301824&r1=1301823&r2=1301824&view=diff ============================================================================== --- tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java (original) +++ tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java Fri Mar 16 23:35:32 2012 @@ -24,7 +24,6 @@ import org.apache.tomcat.maven.common.de import org.apache.tomcat.maven.common.deployer.TomcatManagerResponse; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; /** @@ -86,7 +85,7 @@ public class AbstractDeployWarMojo getLog().info( messagesProvider.getMessage( "AbstractDeployMojo.deployingWar", getDeployedURL() ) ); TomcatManagerResponse tomcatManagerResponse = - getManager().deploy( getPath(), new FileInputStream( warFile ), isUpdate(), getTag(), warFile.length() ); + getManager().deploy( getPath(), warFile, isUpdate(), getTag(), warFile.length() ); getLog().info( "tomcatManager status code:" + tomcatManagerResponse.getStatusCode() + ", ReasonPhrase:" + tomcatManagerResponse.getReasonPhrase() ); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org