Skip to content
Commits on Source (5)
wagon (3.3.4-1) unstable; urgency=medium
* Team upload.
* New upstream release
- Refreshed the patches
* Standards-Version updated to 4.5.0
-- Emmanuel Bourg <ebourg@apache.org> Mon, 27 Jan 2020 17:40:37 +0100
wagon (3.3.3-1) unstable; urgency=medium
* Team upload.
......
......@@ -27,7 +27,7 @@ Build-Depends:
libplexus-utils2-java,
libservlet3.1-java,
maven-debian-helper
Standards-Version: 4.4.0
Standards-Version: 4.5.0
Vcs-Git: https://salsa.debian.org/java-team/wagon.git
Vcs-Browser: https://salsa.debian.org/java-team/wagon
Homepage: http://maven.apache.org/wagon/
......
......@@ -3,7 +3,7 @@ Author: Emmanuel Bourg <ebourg@apache.org>
Forwarded: no
--- a/wagon-provider-test/src/main/java/org/apache/maven/wagon/http/HttpWagonTestCase.java
+++ b/wagon-provider-test/src/main/java/org/apache/maven/wagon/http/HttpWagonTestCase.java
@@ -2223,7 +2223,9 @@
@@ -2239,7 +2239,9 @@
TestSecurityHandler sh = new TestSecurityHandler();
HashLoginService hashLoginService = new HashLoginService( "MyRealm" );
......
Description: Disable network dependent test
Author: Eugene Zhukov <jevgeni.zh@gmail.com>
Bug-Debian: https://bugs.debian.org/761171
Last-Update: 2014-10-09
--- a/wagon-providers/wagon-http/src/test/java/org/apache/maven/wagon/providers/http/AbstractHttpClientWagonTest.java
+++ b/wagon-providers/wagon-http/src/test/java/org/apache/maven/wagon/providers/http/AbstractHttpClientWagonTest.java
@@ -55,7 +55,7 @@
public class AbstractHttpClientWagonTest
{
- @Test
+// @Test
public void test()
throws Exception
{
......@@ -2,5 +2,4 @@ do_not_build_ftp_tests.patch
do_not_run_http_tests.patch
no_mina_sshd.diff
no_itcould_webdav.diff
network_dependent_test_disabled.patch
jetty-compatibility.patch
......@@ -29,7 +29,7 @@ under the License.
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
<packaging>pom</packaging>
<name>Apache Maven Wagon</name>
......@@ -200,7 +200,7 @@ under the License.
<connection>scm:git:https://gitbox.apache.org/repos/asf/maven-wagon.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-wagon.git</developerConnection>
<url>https://github.com/apache/maven-wagon/tree/${project.scm.tag}</url>
<tag>wagon-3.3.3</tag>
<tag>wagon-3.3.4</tag>
</scm>
<issueManagement>
......
......@@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -42,10 +42,10 @@ public void testStreamingWagon()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
streamRoundTripTesting();
tearDownWagonTestingFixtures();
......@@ -55,10 +55,10 @@ public void testStreamingWagon()
public void testFailedGetToStream()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
message( "Getting test artifact from test repository " + testRepository );
StreamingWagon wagon = (StreamingWagon) getWagon();
......@@ -103,8 +103,9 @@ public void testWagonGetIfNewerToStreamIsNewer()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
int expectedSize = putFile();
// CHECKSTYLE_OFF: MagicNumber
getIfNewerToStream( getExpectedLastModifiedOnGet( testRepository, new Resource( resource ) ) + 30000, false,
......@@ -118,8 +119,8 @@ public void testWagonGetIfNewerToStreamIsOlder()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
int expectedSize = putFile();
getIfNewerToStream( new SimpleDateFormat( "yyyy-MM-dd" ).parse( "2006-01-01" ).getTime(), true,
expectedSize );
......@@ -131,8 +132,8 @@ public void testWagonGetIfNewerToStreamIsSame()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
int expectedSize = putFile();
getIfNewerToStream( getExpectedLastModifiedOnGet( testRepository, new Resource( resource ) ), false,
expectedSize );
......@@ -172,8 +173,8 @@ public void testFailedGetIfNewerToStream()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
message( "Getting test artifact from test repository " + testRepository );
StreamingWagon wagon = (StreamingWagon) getWagon();
wagon.addTransferListener( checksumObserver );
......
......@@ -42,7 +42,6 @@
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
......@@ -136,23 +135,6 @@ protected abstract String getTestRepositoryUrl()
*/
protected abstract String getProtocol();
public static ServerSocket newServerSocket( int... ports )
{
for ( int port : ports )
{
try
{
return new ServerSocket( port );
}
catch ( IOException ex )
{
continue;
}
}
throw new RuntimeException( "no port available" );
}
// ----------------------------------------------------------------------
// 1. Create a local file repository which mimic a users local file
// Repository.
......@@ -270,10 +252,10 @@ protected void message( String message )
public void testWagon()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
fileRoundTripTesting();
tearDownWagonTestingFixtures();
......@@ -284,8 +266,8 @@ public void testWagonGetIfNewerIsNewer()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
int expectedSize = putFile();
// CHECKSTYLE_OFF: MagicNumber
getIfNewer( getExpectedLastModifiedOnGet( testRepository, new Resource( resource ) ) + 30000, false,
......@@ -315,8 +297,8 @@ public void testWagonGetIfNewerIsSame()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
int expectedSize = putFile();
getIfNewer( getExpectedLastModifiedOnGet( testRepository, new Resource( resource ) ), false, expectedSize );
}
......@@ -327,8 +309,8 @@ public void testWagonGetIfNewerIsOlder()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
int expectedSize = putFile();
getIfNewer( new SimpleDateFormat( "yyyy-MM-dd" ).parse( "2006-01-01" ).getTime(), true, expectedSize );
}
......@@ -431,10 +413,10 @@ private void replaceMockForSkippedGetIfNewer( Wagon wagon, int expectedSize )
public void testWagonPutDirectory()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
Wagon wagon = getWagon();
if ( wagon.supportsDirectoryCopy() )
......@@ -479,10 +461,10 @@ public void testWagonPutDirectory()
public void testWagonPutDirectoryDeepDestination()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
Wagon wagon = getWagon();
if ( wagon.supportsDirectoryCopy() )
......@@ -533,10 +515,10 @@ public void testWagonPutDirectoryWhenDirectoryAlreadyExists()
final String[] resources = { "a/test-resource-2.txt", "a/b/test-resource-3.txt", "c/test-resource-4.txt" };
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
Wagon wagon = getWagon();
if ( wagon.supportsDirectoryCopy() )
......@@ -585,10 +567,10 @@ public void testWagonPutDirectoryForDot()
final String[] resources = { "a/test-resource-2.txt", "a/b/test-resource-3.txt", "c/test-resource-4.txt" };
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
Wagon wagon = getWagon();
if ( wagon.supportsDirectoryCopy() )
......@@ -688,10 +670,10 @@ private void writeTestFile( String child )
public void testFailedGet()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
message( "Getting test artifact from test repository " + testRepository );
Wagon wagon = getWagon();
......@@ -729,8 +711,8 @@ public void testFailedGetIfNewer()
{
if ( supportsGetIfNewer() )
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
message( "Getting test artifact from test repository " + testRepository );
Wagon wagon = getWagon();
wagon.addTransferListener( checksumObserver );
......@@ -767,10 +749,10 @@ public void testFailedGetIfNewer()
public void testWagonGetFileList()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
String dirName = "file-list";
String filenames[] =
......@@ -821,10 +803,10 @@ public void testWagonGetFileList()
public void testWagonGetFileListWhenDirectoryDoesNotExist()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
String dirName = "file-list-unexisting";
Wagon wagon = getWagon();
......@@ -857,10 +839,10 @@ public void testWagonGetFileListWhenDirectoryDoesNotExist()
public void testWagonResourceExists()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
Wagon wagon = getWagon();
putFile();
......@@ -883,10 +865,10 @@ public void testWagonResourceExists()
public void testWagonResourceNotExists()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
Wagon wagon = getWagon();
wagon.connect( testRepository, getAuthInfo() );
......
......@@ -25,6 +25,7 @@
import org.apache.maven.wagon.StreamingWagonTestCase;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.WagonException;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.proxy.ProxyInfo;
......@@ -34,6 +35,7 @@
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
......@@ -123,8 +125,6 @@ protected void setupWagonTestingFixtures()
server.setHandler( handlers );
server.start();
testRepository.setUrl( getTestRepositoryUrl() );
}
protected final int getTestRepositoryPort()
......@@ -403,20 +403,25 @@ private void runTestGet( int status )
{
StreamingWagon wagon = (StreamingWagon) getWagon();
Server server = new Server( );
StatusHandler handler = new StatusHandler();
handler.setStatusToReturn( status );
server.setHandler( handler );
addConnector( server );
Server server = createStatusServer( status );
server.start();
wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
String baseUrl = getRepositoryUrl( server );
String resourceName = "resource";
String serverReasonPhrase = HttpStatus.getCode( status ).getMessage();
wagon.connect( new Repository( "id", baseUrl ) );
try
{
wagon.getToStream( "resource", new ByteArrayOutputStream() );
fail();
}
catch ( Exception e )
{
verifyWagonExceptionMessage( e, status, baseUrl + "/" + resourceName, serverReasonPhrase );
throw e;
}
finally
{
wagon.disconnect();
......@@ -525,11 +530,7 @@ private boolean runTestResourceExists( int status )
{
StreamingWagon wagon = (StreamingWagon) getWagon();
Server server = new Server( );
StatusHandler handler = new StatusHandler();
handler.setStatusToReturn( status );
server.setHandler( handler );
addConnector( server );
Server server = createStatusServer( status );
server.start();
wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
......@@ -1595,6 +1596,16 @@ private Server createSecurityServer( String localRepositoryPath )
return server;
}
private Server createStatusServer( int status )
{
Server server = new Server( );
StatusHandler handler = new StatusHandler();
handler.setStatusToReturn( status );
server.setHandler( handler );
addConnector( server );
return server;
}
private String writeTestFile( File parent, String child, String compressionType )
throws IOException
......@@ -1758,11 +1769,7 @@ private void runTestPut( int status )
{
StreamingWagon wagon = (StreamingWagon) getWagon();
Server server = new Server( );
StatusHandler handler = new StatusHandler();
handler.setStatusToReturn( status );
server.setHandler( handler );
addConnector( server );
Server server = createStatusServer( status );
server.start();
wagon.connect( new Repository( "id", getRepositoryUrl( server ) ) );
......@@ -1771,11 +1778,20 @@ private void runTestPut( int status )
tempFile.deleteOnExit();
FileUtils.fileWrite( tempFile.getAbsolutePath(), "content" );
String baseUrl = getRepositoryUrl( server );
String resourceName = "resource";
String serverReasonPhrase = HttpStatus.getCode( status ).getMessage();
try
{
wagon.put( tempFile, "resource" );
wagon.put( tempFile, resourceName );
fail();
}
catch ( Exception e )
{
verifyWagonExceptionMessage( e, status, baseUrl + "/" + resourceName, serverReasonPhrase );
throw e;
}
finally
{
wagon.disconnect();
......@@ -2283,4 +2299,85 @@ public String toString()
return sb.toString();
}
}
/**
* Verify a WagonException message contains required format and context based on the status code we expected to
* trigger it in the first place.
* <p>
* This implementation represents the most desired assertions, but HttpWagonTestCase sub-classes could override
* this method if a specific wagon representation makes it impossible to meet these assertions.
*
* @param e an instance of {@link WagonException}
* @param forStatusCode the response status code that triggered the exception
* @param forUrl the url that triggered the exception
* @param forReasonPhrase the optional status line reason phrase the server returned
*/
protected void verifyWagonExceptionMessage( Exception e, int forStatusCode, String forUrl, String forReasonPhrase )
{
// TODO: handle AuthenticationException for Wagon.connect() calls
assertNotNull( e );
try
{
assertTrue( "only verify instances of WagonException", e instanceof WagonException );
String reasonPhrase;
String assertMessageForBadMessage = "exception message not described properly";
switch ( forStatusCode )
{
case HttpServletResponse.SC_NOT_FOUND:
// TODO: add test for 410: Gone?
assertTrue( "404 not found response should throw ResourceDoesNotExistException",
e instanceof ResourceDoesNotExistException );
reasonPhrase = StringUtils.isEmpty( forReasonPhrase ) ? " Not Found" : ( " " + forReasonPhrase );
assertEquals( assertMessageForBadMessage, "Resource missing at " + forUrl + " 404"
+ reasonPhrase, e.getMessage() );
break;
case HttpServletResponse.SC_UNAUTHORIZED:
// FIXME assumes Wagon.get()/put() returning 401 instead of Wagon.connect()
assertTrue( "401 Unauthorized should throw AuthorizationException since "
+ " AuthenticationException is not explicitly declared as thrown from wagon "
+ "methods",
e instanceof AuthorizationException );
reasonPhrase = StringUtils.isEmpty( forReasonPhrase ) ? " Unauthorized" : ( " " + forReasonPhrase );
assertEquals( assertMessageForBadMessage, "Authentication failed for " + forUrl + " 401"
+ reasonPhrase, e.getMessage() );
break;
case HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED:
assertTrue( "407 Proxy authentication required should throw AuthorizationException",
e instanceof AuthorizationException );
reasonPhrase = StringUtils.isEmpty( forReasonPhrase ) ? " Proxy Authentication Required"
: ( " " + forReasonPhrase );
assertEquals( assertMessageForBadMessage, "HTTP proxy server authentication failed for "
+ forUrl + " 407" + reasonPhrase, e.getMessage() );
break;
case HttpServletResponse.SC_FORBIDDEN:
assertTrue( "403 Forbidden should throw AuthorizationException",
e instanceof AuthorizationException );
reasonPhrase = StringUtils.isEmpty( forReasonPhrase ) ? " Forbidden" : ( " " + forReasonPhrase );
assertEquals( assertMessageForBadMessage, "Authorization failed for " + forUrl + " 403"
+ reasonPhrase, e.getMessage() );
break;
default:
assertTrue( "transfer failures should at least be wrapped in a TransferFailedException", e
instanceof TransferFailedException );
assertTrue( "expected status code for transfer failures should be >= 400",
forStatusCode >= HttpServletResponse.SC_BAD_REQUEST );
reasonPhrase = forReasonPhrase == null ? "" : " " + forReasonPhrase;
assertEquals( assertMessageForBadMessage, "Transfer failed for " + forUrl + " "
+ forStatusCode + reasonPhrase, e.getMessage() );
break;
}
}
catch ( AssertionError assertionError )
{
logger.error( "Exception which failed assertions: ", e );
throw assertionError;
}
}
}
......@@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-providers</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-providers</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -20,8 +20,6 @@
*/
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
......@@ -30,6 +28,7 @@
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.Listener;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
......@@ -49,30 +48,15 @@
public class FtpWagonTest
extends StreamingWagonTestCase
{
static private FtpServer server;
private FtpServer server;
// private static final int testRepositoryPort = 10023 + new Random().nextInt( 16 );
private static int testRepositoryPort;
private int testRepositoryPort;
protected String getProtocol()
{
return "ftp";
}
static
{
// claim number, release it again so it can be reclaimed by ftp server
try (ServerSocket socket = newServerSocket( 10023, 10024, 10025, 10026 ))
{
testRepositoryPort = socket.getLocalPort();
}
catch ( IOException e )
{
e.printStackTrace();
}
}
protected int getTestRepositoryPort() {
return testRepositoryPort;
}
......@@ -93,10 +77,11 @@ protected void setupWagonTestingFixtures()
ListenerFactory factory = new ListenerFactory();
// set the port of the listener
factory.setPort(getTestRepositoryPort());
factory.setPort( 0 );
// replace the default listener
serverFactory.addListener("default", factory.createListener());
Listener defaultListener = factory.createListener();
serverFactory.addListener("default", defaultListener );
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
UserManager um = userManagerFactory.createUserManager();
......@@ -122,6 +107,7 @@ protected void setupWagonTestingFixtures()
// start the server
server.start();
testRepositoryPort = defaultListener.getPort();
}
}
......@@ -207,10 +193,10 @@ public void testDefaultUserName()
public void testPutDirectoryCreation()
throws Exception
{
setupRepositories();
setupWagonTestingFixtures();
setupRepositories();
Wagon wagon = getWagon();
if ( wagon.supportsDirectoryCopy() )
......
......@@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-providers</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -50,9 +50,17 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.DeflaterInputStream;
import java.util.zip.GZIPInputStream;
import static java.lang.Integer.parseInt;
import static org.apache.maven.wagon.shared.http.HttpMessageUtils.UNKNOWN_STATUS_CODE;
import static org.apache.maven.wagon.shared.http.HttpMessageUtils.formatAuthorizationMessage;
import static org.apache.maven.wagon.shared.http.HttpMessageUtils.formatResourceDoesNotExistMessage;
import static org.apache.maven.wagon.shared.http.HttpMessageUtils.formatTransferFailedMessage;
/**
* LightweightHttpWagon, using JDK's HttpURLConnection.
*
......@@ -69,6 +77,9 @@ public class LightweightHttpWagon
private Proxy proxy = Proxy.NO_PROXY;
private static final Pattern IOEXCEPTION_MESSAGE_PATTERN = Pattern.compile( "Server returned HTTP response code: "
+ "(\\d\\d\\d) for URL: (.*)" );
public static final int MAX_REDIRECTS = 10;
/**
......@@ -105,20 +116,46 @@ public void fillInputData( InputData inputData )
Resource resource = inputData.getResource();
String visitingUrl = buildUrl( resource );
try
{
List<String> visitedUrls = new ArrayList<String>();
List<String> visitedUrls = new ArrayList<>();
for ( int redirectCount = 0; redirectCount < MAX_REDIRECTS; redirectCount++ )
{
if ( visitedUrls.contains( visitingUrl ) )
{
// TODO add a test for this message
throw new TransferFailedException( "Cyclic http redirect detected. Aborting! " + visitingUrl );
}
visitedUrls.add( visitingUrl );
URL url = new URL( visitingUrl );
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection( this.proxy );
URL url = null;
try
{
url = new URL( visitingUrl );
}
catch ( MalformedURLException e )
{
// TODO add test for this
throw new ResourceDoesNotExistException( "Invalid repository URL: " + e.getMessage(), e );
}
HttpURLConnection urlConnection = null;
try
{
urlConnection = ( HttpURLConnection ) url.openConnection( this.proxy );
}
catch ( IOException e )
{
// TODO: add test for this
String message = formatTransferFailedMessage( visitingUrl, UNKNOWN_STATUS_CODE,
null, getProxyInfo() );
// TODO include e.getMessage appended to main message?
throw new TransferFailedException( message, e );
}
try
{
urlConnection.setRequestProperty( "Accept-Encoding", "gzip,deflate" );
if ( !useCache )
......@@ -130,10 +167,13 @@ public void fillInputData( InputData inputData )
// TODO: handle all response codes
int responseCode = urlConnection.getResponseCode();
String reasonPhrase = urlConnection.getResponseMessage();
if ( responseCode == HttpURLConnection.HTTP_FORBIDDEN
|| responseCode == HttpURLConnection.HTTP_UNAUTHORIZED )
{
throw new AuthorizationException( "Access denied to: " + buildUrl( resource ) );
throw new AuthorizationException( formatAuthorizationMessage( buildUrl( resource ),
responseCode, reasonPhrase, getProxyInfo() ) );
}
if ( responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP )
......@@ -158,27 +198,22 @@ public void fillInputData( InputData inputData )
resource.setLastModified( urlConnection.getLastModified() );
resource.setContentLength( urlConnection.getContentLength() );
break;
}
}
catch ( MalformedURLException e )
{
throw new ResourceDoesNotExistException( "Invalid repository URL: " + e.getMessage(), e );
}
catch ( FileNotFoundException e )
{
throw new ResourceDoesNotExistException( "Unable to locate resource in repository", e );
// this could be 404 Not Found or 410 Gone - we don't have access to which it was.
// TODO: 2019-10-03 url used should list all visited/redirected urls, not just the original
throw new ResourceDoesNotExistException( formatResourceDoesNotExistMessage( buildUrl( resource ),
UNKNOWN_STATUS_CODE, null, getProxyInfo() ), e );
}
catch ( IOException e )
catch ( IOException originalIOException )
{
StringBuilder message = new StringBuilder( "Error transferring file: " );
message.append( e.getMessage() );
message.append( " from " + visitingUrl );
if ( getProxyInfo() != null && getProxyInfo().getHost() != null )
{
message.append( " with proxyInfo " ).append( getProxyInfo().toString() );
throw convertHttpUrlConnectionException( originalIOException, urlConnection, buildUrl( resource ) );
}
throw new TransferFailedException( message.toString(), e );
}
}
private void addHeaders( HttpURLConnection urlConnection )
......@@ -229,6 +264,7 @@ protected void finishPutTransfer( Resource resource, InputStream input, OutputSt
{
try
{
String reasonPhrase = putConnection.getResponseMessage();
int statusCode = putConnection.getResponseCode();
switch ( statusCode )
......@@ -240,23 +276,25 @@ protected void finishPutTransfer( Resource resource, InputStream input, OutputSt
case HttpURLConnection.HTTP_NO_CONTENT: // 204
break;
// TODO: handle 401 explicitly?
case HttpURLConnection.HTTP_FORBIDDEN:
throw new AuthorizationException( "Access denied to: " + buildUrl( resource ) );
throw new AuthorizationException( formatAuthorizationMessage( buildUrl( resource ), statusCode,
reasonPhrase, getProxyInfo() ) );
case HttpURLConnection.HTTP_NOT_FOUND:
throw new ResourceDoesNotExistException( "File: " + buildUrl( resource ) + " does not exist" );
throw new ResourceDoesNotExistException( formatResourceDoesNotExistMessage( buildUrl( resource ),
statusCode, reasonPhrase, getProxyInfo() ) );
// add more entries here
default:
throw new TransferFailedException(
"Failed to transfer file: " + buildUrl( resource ) + ". Return code is: " + statusCode );
throw new TransferFailedException( formatTransferFailedMessage( buildUrl( resource ),
statusCode, reasonPhrase, getProxyInfo() ) ) ;
}
}
catch ( IOException e )
{
fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
throw new TransferFailedException( "Error transferring file: " + e.getMessage(), e );
throw convertHttpUrlConnectionException( e, putConnection, buildUrl( resource ) );
}
}
......@@ -474,4 +512,73 @@ public void setAuthenticator( LightweightHttpWagonAuthenticator authenticator )
{
this.authenticator = authenticator;
}
/**
* Convert the IOException that is thrown for most transfer errors that HttpURLConnection encounters to the
* equivalent {@link TransferFailedException}.
* <p>
* Details are extracted from the error stream if possible, either directly or indirectly by way of supporting
* accessors. The returned exception will include the passed IOException as a cause and a message that is as
* descriptive as possible.
*
* @param originalIOException an IOException thrown from an HttpURLConnection operation
* @param urlConnection instance that triggered the IOException
* @param url originating url that triggered the IOException
* @return exception that is representative of the original cause
*/
private TransferFailedException convertHttpUrlConnectionException( IOException originalIOException,
HttpURLConnection urlConnection,
String url )
{
// javadoc of HttpUrlConnection, HTTP transfer errors throw IOException
// In that case, one may attempt to get the status code and reason phrase
// from the errorstream. We do this, but by way of the following code path
// getResponseCode()/getResponseMessage() - calls -> getHeaderFields()
// getHeaderFields() - calls -> getErrorStream()
try
{
// call getResponseMessage first since impl calls getResponseCode as part of that anyways
String errorResponseMessage = urlConnection.getResponseMessage(); // may be null
int errorResponseCode = urlConnection.getResponseCode(); // may be -1 if the code cannot be discerned
String message = formatTransferFailedMessage( url, errorResponseCode, errorResponseMessage,
getProxyInfo() );
return new TransferFailedException( message, originalIOException );
}
catch ( IOException errorStreamException )
{
// there was a problem using the standard methods, need to fall back to other options
}
// Attempt to parse the status code and URL which can be included in an IOException message
// https://github.com/AdoptOpenJDK/openjdk-jdk11/blame/999dbd4192d0f819cb5224f26e9e7fa75ca6f289/src/java
// .base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java#L1911L1913
String ioMsg = originalIOException.getMessage();
if ( ioMsg != null )
{
Matcher matcher = IOEXCEPTION_MESSAGE_PATTERN.matcher( ioMsg );
if ( matcher.matches() )
{
String codeStr = matcher.group( 1 );
String urlStr = matcher.group( 2 );
int code = UNKNOWN_STATUS_CODE;
try
{
code = parseInt( codeStr );
}
catch ( NumberFormatException nfe )
{
// if here there is a regex problem
}
String message = formatTransferFailedMessage( urlStr, code, null, getProxyInfo() );
return new TransferFailedException( message, originalIOException );
}
}
String message = formatTransferFailedMessage( url, UNKNOWN_STATUS_CODE, null, getProxyInfo() );
return new TransferFailedException( message, originalIOException );
}
}
......@@ -19,9 +19,17 @@
* under the License.
*/
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.StreamingWagon;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.WagonException;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.http.HttpWagonTestCase;
import org.codehaus.plexus.util.StringUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
/**
......@@ -63,4 +71,103 @@ protected boolean supportProxyPreemptiveAuthentication()
{
return false;
}
@Override
protected void verifyWagonExceptionMessage( Exception e, int forStatusCode, String forUrl, String forReasonPhrase )
{
// HttpUrlConnection prevents direct API access to the response code or reasonPhrase for any
// status code >= 400. So all we can do is check WagonException wraps the HttpUrlConnection
// thrown IOException / FileNotFoundException as a cause, if cause is not null
assertNotNull( e );
try
{
assertTrue( "only verify instances of WagonException", e instanceof WagonException );
String assertMessageForBadMessage = "exception message not described properly: ";
switch ( forStatusCode )
{
case HttpServletResponse.SC_GONE:
case HttpServletResponse.SC_NOT_FOUND:
assertTrue( "404 or 410 should throw ResourceDoesNotExistException",
e instanceof ResourceDoesNotExistException );
if ( e.getCause() != null )
{
assertTrue( "ResourceDoesNotExistException should have the expected cause",
e.getCause() instanceof FileNotFoundException );
// the status code and reason phrase cannot always be learned due to implementation limitations
// which means the message may not include them
assertEquals( assertMessageForBadMessage, "Resource missing at " + forUrl, e.getMessage() );
}
else
{
assertEquals( assertMessageForBadMessage, "Resource missing at " + forUrl
+ " " + forStatusCode + " " + forReasonPhrase, e.getMessage() );
}
break;
case HttpServletResponse.SC_FORBIDDEN:
assertTrue( "403 Forbidden throws AuthorizationException",
e instanceof AuthorizationException );
assertEquals( assertMessageForBadMessage, "Authorization failed for " + forUrl + " 403"
+ ( StringUtils.isEmpty( forReasonPhrase ) ? " Forbidden" : ( " " + forReasonPhrase ) ),
e.getMessage() );
break;
case HttpServletResponse.SC_UNAUTHORIZED:
assertTrue( "401 Unauthorized throws AuthorizationException",
e instanceof AuthorizationException );
assertEquals( assertMessageForBadMessage, "Authentication failed for " + forUrl + " 401"
+ ( StringUtils.isEmpty( forReasonPhrase ) ? " Unauthorized" :
( " " + forReasonPhrase ) ),
e.getMessage() );
break;
default:
assertTrue( "general exception must be TransferFailedException",
e instanceof TransferFailedException );
assertTrue( "expected status code for transfer failures should be >= 400, but none of "
+ " the already handled codes",
forStatusCode >= HttpServletResponse.SC_BAD_REQUEST );
if ( e.getCause() != null )
{
assertTrue( "TransferFailedException should have the original cause for diagnosis",
e.getCause() instanceof IOException );
}
// the status code and reason phrase cannot always be learned due to implementation limitations
// so the message may not include them, but the implementation should use a consistent format
assertTrue( "message should always include url",
e.getMessage().startsWith( "Transfer failed for " + forUrl ) );
if ( e.getMessage().length() > ( "Transfer failed for " + forUrl ).length() )
{
assertTrue( "message should include url and status code",
e.getMessage().startsWith( "Transfer failed for " + forUrl + " " + forStatusCode ) );
}
if ( e.getMessage().length() > ( "Transfer failed for " + forUrl + " " + forStatusCode ).length() )
{
assertEquals( "message should include url and status code and reason phrase",
"Transfer failed for " + forUrl + " " + forStatusCode + " " + forReasonPhrase,
e.getMessage() );
}
break;
}
}
catch ( AssertionError assertionError )
{
logger.error( "Exception which failed assertions: ", e );
throw assertionError;
}
}
}
......@@ -23,7 +23,7 @@ under the License.
<parent>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-providers</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -34,6 +34,7 @@
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.ServiceUnavailableRetryStrategy;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
......@@ -61,6 +62,7 @@
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.DefaultServiceUnavailableRetryStrategy;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
......@@ -105,6 +107,11 @@
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import static org.apache.maven.wagon.shared.http.HttpMessageUtils.formatAuthorizationMessage;
import static org.apache.maven.wagon.shared.http.HttpMessageUtils.formatResourceDoesNotExistMessage;
import static org.apache.maven.wagon.shared.http.HttpMessageUtils.formatTransferDebugMessage;
import static org.apache.maven.wagon.shared.http.HttpMessageUtils.formatTransferFailedMessage;
/**
* @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
* @author <a href="mailto:james@atlassian.com">James William Dumay</a>
......@@ -112,7 +119,7 @@
public abstract class AbstractHttpClientWagon
extends StreamWagon
{
private final class RequestEntityImplementation
private final class WagonHttpEntity
extends AbstractHttpEntity
{
private final Resource resource;
......@@ -127,7 +134,7 @@ private final class RequestEntityImplementation
private boolean repeatable;
private RequestEntityImplementation( final InputStream stream, final Resource resource, final Wagon wagon,
private WagonHttpEntity( final InputStream stream, final Resource resource, final Wagon wagon,
final File source )
throws TransferFailedException
{
......@@ -451,6 +458,55 @@ RETRY_HANDLER_COUNT, RETRY_HANDLER_REQUEST_SENT_ENABLED, getNonRetryableExceptio
}
}
/**
* The type of the serviceUnavailableRetryStrategy, defaults to {@code none}.
* Values can be {@link default DefaultServiceUnavailableRetryStrategy},
* or {@link standard StandardServiceUnavailableRetryStrategy}, or
* a fully qualified name class with a no-arg or none to not use a ServiceUnavailableRetryStrategy.
*/
private static final String SERVICE_UNAVAILABLE_RETRY_STRATEGY_CLASS =
System.getProperty( "maven.wagon.http.serviceUnavailableRetryStrategy.class", "none" );
/**
* Interval in milliseconds between retries when using a serviceUnavailableRetryStrategy.
* <b>1000 by default</b>
*/
private static final int SERVICE_UNAVAILABLE_RETRY_STRATEGY_RETRY_INTERVAL =
Integer.getInteger( "maven.wagon.http.serviceUnavailableRetryStrategy.retryInterval", 1000 );
/**
* Maximum number of retries when using a serviceUnavailableRetryStrategy.
* <b>5 by default</b>
*/
private static final int SERVICE_UNAVAILABLE_RETRY_STRATEGY_MAX_RETRIES =
Integer.getInteger( "maven.wagon.http.serviceUnavailableRetryStrategy.maxRetries", 5 );
private static ServiceUnavailableRetryStrategy createServiceUnavailableRetryStrategy()
{
switch ( SERVICE_UNAVAILABLE_RETRY_STRATEGY_CLASS )
{
case "none": return null;
case "default":
return new DefaultServiceUnavailableRetryStrategy(
SERVICE_UNAVAILABLE_RETRY_STRATEGY_MAX_RETRIES, SERVICE_UNAVAILABLE_RETRY_STRATEGY_RETRY_INTERVAL );
case "standard":
return new StandardServiceUnavailableRetryStrategy(
SERVICE_UNAVAILABLE_RETRY_STRATEGY_MAX_RETRIES, SERVICE_UNAVAILABLE_RETRY_STRATEGY_RETRY_INTERVAL );
default:
try
{
final ClassLoader classLoader = AbstractHttpClientWagon.class.getClassLoader();
return ServiceUnavailableRetryStrategy.class.cast(
classLoader.loadClass( SERVICE_UNAVAILABLE_RETRY_STRATEGY_CLASS )
.getConstructor().newInstance() );
}
catch ( final Exception e )
{
throw new IllegalArgumentException( e );
}
}
}
private static Registry<AuthSchemeProvider> createAuthSchemeRegistry()
{
return RegistryBuilder.<AuthSchemeProvider>create()
......@@ -487,6 +543,7 @@ private static CloseableHttpClient createClient()
.disableConnectionState() //
.setConnectionManager( httpClientConnectionManager ) //
.setRetryHandler( createRetryHandler() )
.setServiceUnavailableRetryStrategy( createServiceUnavailableRetryStrategy() )
.setDefaultAuthSchemeRegistry( createAuthSchemeRegistry() )
.build();
}
......@@ -643,7 +700,7 @@ public void putFromStream( final InputStream stream, String destination, long co
private void put( final InputStream stream, Resource resource, File source )
throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
{
put( resource, source, new RequestEntityImplementation( stream, resource, this, source ) );
put( resource, source, new WagonHttpEntity( stream, resource, this, source ) );
}
private void put( Resource resource, File source, HttpEntity httpEntity )
......@@ -660,9 +717,19 @@ private void put( Resource resource, File source, HttpEntity httpEntity )
*/
private String buildUrl( Resource resource )
{
return EncodingUtil.encodeURLToString( getRepository().getUrl(), resource.getName() );
return buildUrl( resource.getName() );
}
/**
* Builds a complete URL string from the repository URL and the relative path of the resource passed.
*
* @param resourceName the resourcerelative path
* @return the complete URL
*/
private String buildUrl( String resourceName )
{
return EncodingUtil.encodeURLToString( getRepository().getUrl(), resourceName );
}
private void put( Resource resource, File source, HttpEntity httpEntity, String url )
throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
......@@ -713,17 +780,9 @@ private void put( int wait, Resource resource, File source, HttpEntity httpEntit
CloseableHttpResponse response = execute( putMethod );
try
{
fireTransferDebug( formatTransferDebugMessage( url, response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), getProxyInfo() ) );
int statusCode = response.getStatusLine().getStatusCode();
String reasonPhrase = response.getStatusLine().getReasonPhrase();
StringBuilder debugMessage = new StringBuilder();
debugMessage.append( url );
debugMessage.append( " -- " );
debugMessage.append( "status code: " ).append( statusCode );
if ( StringUtils.isNotEmpty( reasonPhrase ) )
{
debugMessage.append( ", reason phrase: " ).append( reasonPhrase );
}
fireTransferDebug( debugMessage.toString() );
// Check that we didn't run out of retries.
switch ( statusCode )
......@@ -741,20 +800,26 @@ private void put( int wait, Resource resource, File source, HttpEntity httpEntit
case HttpStatus.SC_SEE_OTHER: // 303
put( resource, source, httpEntity, calculateRelocatedUrl( response ) );
return;
//case HttpStatus.SC_UNAUTHORIZED:
case HttpStatus.SC_FORBIDDEN:
fireSessionConnectionRefused();
throw new AuthorizationException( "Access denied to: " + url );
throw new AuthorizationException( formatAuthorizationMessage( url,
response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), getProxyInfo() ) );
case HttpStatus.SC_NOT_FOUND:
throw new ResourceDoesNotExistException( "File " + url + " does not exist" );
throw new ResourceDoesNotExistException( formatResourceDoesNotExistMessage( url,
response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), getProxyInfo() ) );
case SC_TOO_MANY_REQUESTS:
put( backoff( wait, url ), resource, source, httpEntity, url );
break;
//add more entries here
default:
TransferFailedException e = new TransferFailedException(
"Failed to transfer file " + url + " with status code " + statusCode );
TransferFailedException e = new TransferFailedException( formatTransferFailedMessage( url,
response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), getProxyInfo() ) );
fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
throw e;
}
......@@ -768,23 +833,11 @@ private void put( int wait, Resource resource, File source, HttpEntity httpEntit
response.close();
}
}
catch ( IOException e )
{
fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
throw new TransferFailedException( e.getMessage(), e );
}
catch ( HttpException e )
{
fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
throw new TransferFailedException( e.getMessage(), e );
}
catch ( InterruptedException e )
catch ( IOException | HttpException | InterruptedException e )
{
fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
throw new TransferFailedException( e.getMessage(), e );
throw new TransferFailedException( formatTransferFailedMessage( url, getProxyInfo() ), e );
}
}
......@@ -813,8 +866,7 @@ public boolean resourceExists( String resourceName )
private boolean resourceExists( int wait, String resourceName )
throws TransferFailedException, AuthorizationException
{
String repositoryUrl = getRepository().getUrl();
String url = repositoryUrl + ( repositoryUrl.endsWith( "/" ) ? "" : "/" ) + resourceName;
String url = buildUrl( resourceName );
HttpHead headMethod = new HttpHead( url );
try
{
......@@ -831,14 +883,13 @@ private boolean resourceExists( int wait, String resourceName )
case HttpStatus.SC_NOT_MODIFIED:
result = true;
break;
case HttpStatus.SC_FORBIDDEN:
throw new AuthorizationException( "Access denied to: " + url );
case HttpStatus.SC_FORBIDDEN:
case HttpStatus.SC_UNAUTHORIZED:
throw new AuthorizationException( "Not authorized" );
case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
throw new AuthorizationException( "Not authorized by proxy" );
throw new AuthorizationException( formatAuthorizationMessage( url,
response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), getProxyInfo() ) );
case HttpStatus.SC_NOT_FOUND:
result = false;
......@@ -849,8 +900,9 @@ private boolean resourceExists( int wait, String resourceName )
//add more entries here
default:
throw new TransferFailedException(
"Failed to transfer file " + url + " with status code " + statusCode );
throw new TransferFailedException( formatTransferFailedMessage( url,
response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), getProxyInfo() ) );
}
EntityUtils.consume( response.getEntity() );
......@@ -861,17 +913,9 @@ private boolean resourceExists( int wait, String resourceName )
response.close();
}
}
catch ( IOException e )
{
throw new TransferFailedException( e.getMessage(), e );
}
catch ( HttpException e )
{
throw new TransferFailedException( e.getMessage(), e );
}
catch ( InterruptedException e )
catch ( IOException | HttpException | InterruptedException e )
{
throw new TransferFailedException( e.getMessage(), e );
throw new TransferFailedException( formatTransferFailedMessage( url, getProxyInfo() ), e );
}
}
......@@ -1099,8 +1143,7 @@ private void fillInputData( int wait, InputData inputData )
{
Resource resource = inputData.getResource();
String repositoryUrl = getRepository().getUrl();
String url = repositoryUrl + ( repositoryUrl.endsWith( "/" ) ? "" : "/" ) + resource.getName();
String url = buildUrl( resource );
HttpGet getMethod = new HttpGet( url );
long timestamp = resource.getLastModified();
if ( timestamp > 0 )
......@@ -1116,17 +1159,10 @@ private void fillInputData( int wait, InputData inputData )
{
CloseableHttpResponse response = execute( getMethod );
closeable = response;
fireTransferDebug( formatTransferDebugMessage( url, response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), getProxyInfo() ) );
int statusCode = response.getStatusLine().getStatusCode();
String reasonPhrase = response.getStatusLine().getReasonPhrase();
StringBuilder debugMessage = new StringBuilder();
debugMessage.append( url );
debugMessage.append( " -- " );
debugMessage.append( "status code: " ).append( statusCode );
if ( StringUtils.isNotEmpty( reasonPhrase ) )
{
debugMessage.append( ", reason phrase: " ).append( reasonPhrase );
}
fireTransferDebug( debugMessage.toString() );
switch ( statusCode )
{
......@@ -1136,20 +1172,19 @@ private void fillInputData( int wait, InputData inputData )
case HttpStatus.SC_NOT_MODIFIED:
// return, leaving last modified set to original value so getIfNewer should return unmodified
return;
case HttpStatus.SC_FORBIDDEN:
fireSessionConnectionRefused();
throw new AuthorizationException( "Access denied to: " + url );
case HttpStatus.SC_FORBIDDEN:
case HttpStatus.SC_UNAUTHORIZED:
fireSessionConnectionRefused();
throw new AuthorizationException( "Not authorized" );
case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
fireSessionConnectionRefused();
throw new AuthorizationException( "Not authorized by proxy" );
throw new AuthorizationException( formatAuthorizationMessage( url,
response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(),
getProxyInfo() ) );
case HttpStatus.SC_NOT_FOUND:
throw new ResourceDoesNotExistException( "File " + url + " does not exist" );
throw new ResourceDoesNotExistException( formatResourceDoesNotExistMessage( url,
response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase(), getProxyInfo() ) );
case SC_TOO_MANY_REQUESTS:
fillInputData( backoff( wait, url ), inputData );
......@@ -1158,8 +1193,9 @@ private void fillInputData( int wait, InputData inputData )
// add more entries here
default:
cleanupGetTransfer( resource );
TransferFailedException e = new TransferFailedException(
"Failed to transfer file " + url + " with status code " + statusCode );
TransferFailedException e = new TransferFailedException( formatTransferFailedMessage( url,
response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase(),
getProxyInfo() ) );
fireTransferError( resource, e, TransferEvent.REQUEST_GET );
throw e;
}
......@@ -1199,23 +1235,11 @@ private void fillInputData( int wait, InputData inputData )
inputData.setInputStream( entity.getContent() );
}
}
catch ( IOException e )
{
fireTransferError( resource, e, TransferEvent.REQUEST_GET );
throw new TransferFailedException( e.getMessage(), e );
}
catch ( HttpException e )
{
fireTransferError( resource, e, TransferEvent.REQUEST_GET );
throw new TransferFailedException( e.getMessage(), e );
}
catch ( InterruptedException e )
catch ( IOException | HttpException | InterruptedException e )
{
fireTransferError( resource, e, TransferEvent.REQUEST_GET );
throw new TransferFailedException( e.getMessage(), e );
throw new TransferFailedException( formatTransferFailedMessage( url, getProxyInfo() ), e );
}
}
......