mirror of https://github.com/apache/maven.git
Upgrade HttpUtils from maven1
git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@162837 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
77b3707cf9
commit
07cac37dfe
|
@ -0,0 +1,386 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Copyright 2001-2004 The Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
// import org.apache.commons.logging.Log;
|
||||||
|
// import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode/Decode Base-64.
|
||||||
|
*
|
||||||
|
* @author John Casey
|
||||||
|
*/
|
||||||
|
public final class Base64
|
||||||
|
{
|
||||||
|
|
||||||
|
// private static final Log LOG = LogFactory.getLog( Base64.class );
|
||||||
|
|
||||||
|
private static final String CRLF = System.getProperty( "line.separator" );
|
||||||
|
|
||||||
|
private static final int LINE_END = 64;
|
||||||
|
|
||||||
|
public static String encode( byte[] data )
|
||||||
|
{
|
||||||
|
return Base64.encode( data, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode( byte[] data, boolean useLineDelimiter )
|
||||||
|
{
|
||||||
|
if ( data == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if ( data.length == 0 )
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int padding = 3 - ( data.length % 3 );
|
||||||
|
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "padding = " + padding + "characters." );
|
||||||
|
// }
|
||||||
|
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
|
||||||
|
for ( int i = 0; i < data.length; i += 3 )
|
||||||
|
{
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "iteration base offset = " + i );
|
||||||
|
// }
|
||||||
|
|
||||||
|
int neutral = ( data[i] < 0 ? data[i] + 256 : data[i] );
|
||||||
|
|
||||||
|
int block = ( neutral & 0xff );
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "after first byte, block = " + Integer.toBinaryString( block ) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
boolean inLastSegment = false;
|
||||||
|
|
||||||
|
block <<= 8;
|
||||||
|
if ( i + 1 < data.length )
|
||||||
|
{
|
||||||
|
neutral = ( data[i + 1] < 0 ? data[i + 1] + 256 : data[i + 1] );
|
||||||
|
block |= ( neutral & 0xff );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inLastSegment = true;
|
||||||
|
}
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "after second byte, block = " + Integer.toBinaryString( block ) + "; inLastSegment = "
|
||||||
|
// + inLastSegment );
|
||||||
|
// }
|
||||||
|
|
||||||
|
block <<= 8;
|
||||||
|
if ( i + 2 < data.length )
|
||||||
|
{
|
||||||
|
neutral = ( data[i + 2] < 0 ? data[i + 2] + 256 : data[i + 2] );
|
||||||
|
block |= ( neutral & 0xff );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inLastSegment = true;
|
||||||
|
}
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "after third byte, block = " + Integer.toBinaryString( block ) + "; inLastSegment = "
|
||||||
|
// + inLastSegment );
|
||||||
|
// }
|
||||||
|
|
||||||
|
char[] encoded = new char[4];
|
||||||
|
int encIdx = 0;
|
||||||
|
encoded[0] = toBase64Char( ( block >>> 18 ) & 0x3f );
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "first character = " + encoded[0] );
|
||||||
|
// }
|
||||||
|
|
||||||
|
encoded[1] = toBase64Char( ( block >>> 12 ) & 0x3f );
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "second character = " + encoded[1] );
|
||||||
|
// }
|
||||||
|
|
||||||
|
if ( inLastSegment && padding > 1 )
|
||||||
|
{
|
||||||
|
encoded[2] = '=';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
encoded[2] = toBase64Char( ( block >>> 6 ) & 0x3f );
|
||||||
|
}
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "third character = " + encoded[2] );
|
||||||
|
// }
|
||||||
|
|
||||||
|
if ( inLastSegment && padding > 0 )
|
||||||
|
{
|
||||||
|
encoded[3] = '=';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
encoded[3] = toBase64Char( block & 0x3f );
|
||||||
|
}
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "fourth character = " + encoded[3] );
|
||||||
|
// }
|
||||||
|
|
||||||
|
buffer.append( encoded );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( useLineDelimiter )
|
||||||
|
{
|
||||||
|
return canonicalize( buffer.toString() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decode( String src )
|
||||||
|
{
|
||||||
|
return Base64.decode( src, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decode( String src, boolean useLineDelimiter )
|
||||||
|
{
|
||||||
|
if ( src == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if ( src.length() < 1 )
|
||||||
|
{
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "pre-canonicalization = \n" + src );
|
||||||
|
// }
|
||||||
|
String data = src;
|
||||||
|
|
||||||
|
if ( useLineDelimiter )
|
||||||
|
{
|
||||||
|
data = deCanonicalize( src );
|
||||||
|
}
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "post-canonicalization = \n" + data );
|
||||||
|
// }
|
||||||
|
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
char[] input = data.toCharArray();
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for ( int i = 0; i < input.length; i += 4 )
|
||||||
|
{
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "iteration base offset = " + i );
|
||||||
|
// }
|
||||||
|
|
||||||
|
int block = ( toBase64Int( input[i] ) & 0x3f );
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "block after first char [" + input[i] + "] = " + Integer.toBinaryString( block ) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
block <<= 6;
|
||||||
|
block |= ( toBase64Int( input[i + 1] ) & 0x3f );
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "block after second char [" + input[i + 1] + "] = " + Integer.toBinaryString( block ) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
boolean inPadding = false;
|
||||||
|
boolean twoCharPadding = false;
|
||||||
|
block <<= 6;
|
||||||
|
if ( input[i + 2] != '=' )
|
||||||
|
{
|
||||||
|
block |= ( toBase64Int( input[i + 2] ) & 0x3f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
twoCharPadding = true;
|
||||||
|
inPadding = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "block after third char [" + input[i + 2] + "] = " + Integer.toBinaryString( block ) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
block <<= 6;
|
||||||
|
if ( input[i + 3] != '=' )
|
||||||
|
{
|
||||||
|
block |= ( toBase64Int( input[i + 3] ) & 0x3f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inPadding = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "block after fourth char [" + input[i + 3] + "] = " + Integer.toBinaryString( block ) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
baos.write( ( block >>> 16 ) & 0xff );
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "byte[" + ( index++ ) + "] = " + ( ( block >>> 16 ) & 0xff ) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
if ( !inPadding || !twoCharPadding )
|
||||||
|
{
|
||||||
|
baos.write( ( block >>> 8 ) & 0xff );
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "byte[" + ( index++ ) + "] = " + ( ( block >>> 8 ) & 0xff ) );
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !inPadding )
|
||||||
|
{
|
||||||
|
baos.write( block & 0xff );
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "byte[" + ( index++ ) + "] = " + ( block & 0xff ) );
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] result = baos.toByteArray();
|
||||||
|
// if ( LOG.isDebugEnabled() )
|
||||||
|
// {
|
||||||
|
// LOG.debug( "byte array is " + result.length + " bytes long." );
|
||||||
|
// }
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static char toBase64Char( int input )
|
||||||
|
{
|
||||||
|
if ( input > -1 && input < 26 )
|
||||||
|
{
|
||||||
|
return ( char ) ( 'A' + input );
|
||||||
|
}
|
||||||
|
else if ( input > 25 && input < 52 )
|
||||||
|
{
|
||||||
|
return ( char ) ( 'a' + input - 26 );
|
||||||
|
}
|
||||||
|
else if ( input > 51 && input < 62 )
|
||||||
|
{
|
||||||
|
return ( char ) ( '0' + input - 52 );
|
||||||
|
}
|
||||||
|
else if ( input == 62 )
|
||||||
|
{
|
||||||
|
return '+';
|
||||||
|
}
|
||||||
|
else if ( input == 63 )
|
||||||
|
{
|
||||||
|
return '/';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int toBase64Int( char input )
|
||||||
|
{
|
||||||
|
if ( input >= 'A' && input <= 'Z' )
|
||||||
|
{
|
||||||
|
return input - 'A';
|
||||||
|
}
|
||||||
|
else if ( input >= 'a' && input <= 'z' )
|
||||||
|
{
|
||||||
|
return input + 26 - 'a';
|
||||||
|
}
|
||||||
|
else if ( input >= '0' && input <= '9' )
|
||||||
|
{
|
||||||
|
return input + 52 - '0';
|
||||||
|
}
|
||||||
|
else if ( input == '+' )
|
||||||
|
{
|
||||||
|
return 62;
|
||||||
|
}
|
||||||
|
else if ( input == '/' )
|
||||||
|
{
|
||||||
|
return 63;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String deCanonicalize( String data )
|
||||||
|
{
|
||||||
|
if ( data == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer buffer = new StringBuffer( data.length() );
|
||||||
|
for ( int i = 0; i < data.length(); i++ )
|
||||||
|
{
|
||||||
|
char c = data.charAt( i );
|
||||||
|
if ( c != '\r' && c != '\n' )
|
||||||
|
{
|
||||||
|
buffer.append( c );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String canonicalize( String data )
|
||||||
|
{
|
||||||
|
StringBuffer buffer = new StringBuffer( ( int ) ( data.length() * 1.1 ) );
|
||||||
|
|
||||||
|
int col = 0;
|
||||||
|
for ( int i = 0; i < data.length(); i++ )
|
||||||
|
{
|
||||||
|
if ( col == LINE_END )
|
||||||
|
{
|
||||||
|
buffer.append( CRLF );
|
||||||
|
col = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.append( data.charAt( i ) );
|
||||||
|
col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.append( CRLF );
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,22 @@
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright 2001-2004 The Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -8,8 +26,31 @@ import java.net.PasswordAuthentication;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http utils for retrieving files.
|
||||||
|
*
|
||||||
|
* @author costin@dnt.ro
|
||||||
|
* @author gg@grtmail.com (Added Java 1.1 style HTTP basic auth)
|
||||||
|
* @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
|
||||||
|
*
|
||||||
|
* @todo Need to add a timeout so we can flip to a backup repository.
|
||||||
|
* @todo Download everything in a single session.
|
||||||
|
* @todo Throw meaningful exception when authentication fails.
|
||||||
|
*/
|
||||||
public class HttpUtils
|
public class HttpUtils
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Use a proxy to bypass the firewall with or without authentication
|
||||||
|
*
|
||||||
|
* @param proxyHost Proxy Host (if proxy is required), or null
|
||||||
|
* @param proxyPort Proxy Port (if proxy is required), or null
|
||||||
|
* @param proxyUserName Proxy Username (if authentification is required),
|
||||||
|
* or null
|
||||||
|
* @param proxyPassword Proxy Password (if authentification is required),
|
||||||
|
* or null
|
||||||
|
* @throws SecurityException if an operation is not authorized by the
|
||||||
|
* SecurityManager
|
||||||
|
*/
|
||||||
public static void useProxyUser( final String proxyHost,
|
public static void useProxyUser( final String proxyHost,
|
||||||
final String proxyPort,
|
final String proxyPort,
|
||||||
final String proxyUserName,
|
final String proxyUserName,
|
||||||
|
@ -35,6 +76,26 @@ public class HttpUtils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a remote file. Throws an Exception on errors unless the
|
||||||
|
* ifnoreErrors flag is set to True
|
||||||
|
*
|
||||||
|
* @param url the of the file to retrieve
|
||||||
|
* @param destinationFile where to store it
|
||||||
|
* @param ignoreErrors whether to ignore errors during I/O or throw an
|
||||||
|
* exception when they happen
|
||||||
|
* @param useTimestamp whether to check the modified timestamp on the
|
||||||
|
* <code>destinationFile</code> against the remote <code>source</code>
|
||||||
|
* @param proxyHost Proxy Host (if proxy is required), or null
|
||||||
|
* @param proxyPort Proxy Port (if proxy is required), or null
|
||||||
|
* @param proxyUserName Proxy Username (if authentification is required),
|
||||||
|
* or null.
|
||||||
|
* @param proxyPassword Proxy Password (if authentification is required),
|
||||||
|
* or null.
|
||||||
|
* @param useChecksum Flag to indicate the use of the checksum for the retrieved
|
||||||
|
* artifact if it is available.
|
||||||
|
* @throws IOException If an I/O exception occurs.
|
||||||
|
*/
|
||||||
public static void getFile( String url,
|
public static void getFile( String url,
|
||||||
File destinationFile,
|
File destinationFile,
|
||||||
boolean ignoreErrors,
|
boolean ignoreErrors,
|
||||||
|
@ -44,7 +105,7 @@ public class HttpUtils
|
||||||
String proxyUserName,
|
String proxyUserName,
|
||||||
String proxyPassword,
|
String proxyPassword,
|
||||||
boolean useChecksum )
|
boolean useChecksum )
|
||||||
throws Exception
|
throws IOException
|
||||||
{
|
{
|
||||||
// Get the requested file.
|
// Get the requested file.
|
||||||
getFile( url,
|
getFile( url,
|
||||||
|
@ -80,6 +141,24 @@ public class HttpUtils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a remote file. Throws an Exception on errors unless the
|
||||||
|
* ifnoreErrors flag is set to True
|
||||||
|
*
|
||||||
|
* @param url the of the file to retrieve
|
||||||
|
* @param destinationFile where to store it
|
||||||
|
* @param ignoreErrors whether to ignore errors during I/O or throw an
|
||||||
|
* exception when they happen
|
||||||
|
* @param useTimestamp whether to check the modified timestamp on the
|
||||||
|
* <code>destinationFile</code> against the remote <code>source</code>
|
||||||
|
* @param proxyHost Proxy Host (if proxy is required), or null
|
||||||
|
* @param proxyPort Proxy Port (if proxy is required), or null
|
||||||
|
* @param proxyUserName Proxy Username (if authentification is required),
|
||||||
|
* or null
|
||||||
|
* @param proxyPassword Proxy Password (if authentification is required),
|
||||||
|
* or null
|
||||||
|
* @throws IOException If an I/O exception occurs.
|
||||||
|
*/
|
||||||
public static void getFile( String url,
|
public static void getFile( String url,
|
||||||
File destinationFile,
|
File destinationFile,
|
||||||
boolean ignoreErrors,
|
boolean ignoreErrors,
|
||||||
|
@ -88,7 +167,58 @@ public class HttpUtils
|
||||||
String proxyPort,
|
String proxyPort,
|
||||||
String proxyUserName,
|
String proxyUserName,
|
||||||
String proxyPassword )
|
String proxyPassword )
|
||||||
throws Exception
|
throws IOException
|
||||||
|
{
|
||||||
|
//set the timestamp to the file date.
|
||||||
|
long timestamp = -1;
|
||||||
|
if ( useTimestamp && destinationFile.exists() )
|
||||||
|
{
|
||||||
|
timestamp = destinationFile.lastModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
getFile( url,
|
||||||
|
destinationFile,
|
||||||
|
timestamp,
|
||||||
|
proxyHost,
|
||||||
|
proxyPort,
|
||||||
|
proxyUserName,
|
||||||
|
proxyPassword );
|
||||||
|
}
|
||||||
|
catch ( IOException ex )
|
||||||
|
{
|
||||||
|
if ( !ignoreErrors )
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a remote file.
|
||||||
|
*
|
||||||
|
* @param url the URL of the file to retrieve
|
||||||
|
* @param destinationFile where to store it
|
||||||
|
* @param timestamp if provided, the remote URL is only retrieved if it was
|
||||||
|
* modified more recently than timestamp. Otherwise, negative value indicates that
|
||||||
|
* the remote URL should be retrieved unconditionally.
|
||||||
|
* @param proxyHost Proxy Host (if proxy is required), or null
|
||||||
|
* @param proxyPort Proxy Port (if proxy is required), or null
|
||||||
|
* @param proxyUserName Proxy Username (if authentification is required),
|
||||||
|
* or null
|
||||||
|
* @param proxyPassword Proxy Password (if authentification is required),
|
||||||
|
* or null
|
||||||
|
* @throws IOException If an I/O exception occurs.
|
||||||
|
*/
|
||||||
|
public static void getFile( String url,
|
||||||
|
File destinationFile,
|
||||||
|
long timestamp,
|
||||||
|
String proxyHost,
|
||||||
|
String proxyPort,
|
||||||
|
String proxyUserName,
|
||||||
|
String proxyPassword )
|
||||||
|
throws IOException
|
||||||
{
|
{
|
||||||
String[] s = parseUrl( url );
|
String[] s = parseUrl( url );
|
||||||
String username = s[0];
|
String username = s[0];
|
||||||
|
@ -97,23 +227,14 @@ public class HttpUtils
|
||||||
|
|
||||||
URL source = new URL( parsedUrl );
|
URL source = new URL( parsedUrl );
|
||||||
|
|
||||||
//set the timestamp to the file date.
|
|
||||||
long timestamp = 0;
|
|
||||||
boolean hasTimestamp = false;
|
|
||||||
if ( useTimestamp && destinationFile.exists() )
|
|
||||||
{
|
|
||||||
timestamp = destinationFile.lastModified();
|
|
||||||
hasTimestamp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//set proxy connection
|
//set proxy connection
|
||||||
useProxyUser( proxyHost, proxyPort, proxyUserName, proxyPassword );
|
useProxyUser( proxyHost, proxyPort, proxyUserName, proxyPassword );
|
||||||
|
|
||||||
//set up the URL connection
|
//set up the URL connection
|
||||||
URLConnection connection = source.openConnection();
|
URLConnection connection = source.openConnection();
|
||||||
|
|
||||||
//modify the headers
|
//modify the headers
|
||||||
//NB: things like user authentication could go in here too.
|
if ( timestamp >= 0 )
|
||||||
if ( useTimestamp && hasTimestamp )
|
|
||||||
{
|
{
|
||||||
connection.setIfModifiedSince( timestamp );
|
connection.setIfModifiedSince( timestamp );
|
||||||
}
|
}
|
||||||
|
@ -121,22 +242,7 @@ public class HttpUtils
|
||||||
if ( username != null || password != null )
|
if ( username != null || password != null )
|
||||||
{
|
{
|
||||||
String up = username + ":" + password;
|
String up = username + ":" + password;
|
||||||
String encoding = null;
|
String encoding = Base64.encode(up.getBytes(), false);
|
||||||
// check to see if sun's Base64 encoder is available.
|
|
||||||
try
|
|
||||||
{
|
|
||||||
sun.misc.BASE64Encoder encoder =
|
|
||||||
(sun.misc.BASE64Encoder) Class.forName(
|
|
||||||
"sun.misc.BASE64Encoder" ).newInstance();
|
|
||||||
|
|
||||||
encoding = encoder.encode( up.getBytes() );
|
|
||||||
}
|
|
||||||
catch ( Exception ex )
|
|
||||||
{
|
|
||||||
// Do nothing, as for MavenSession we will never use
|
|
||||||
// auth and we will eventually move over httpclient
|
|
||||||
// in the commons.
|
|
||||||
}
|
|
||||||
connection.setRequestProperty( "Authorization", "Basic " + encoding );
|
connection.setRequestProperty( "Authorization", "Basic " + encoding );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +252,14 @@ public class HttpUtils
|
||||||
if ( connection instanceof HttpURLConnection )
|
if ( connection instanceof HttpURLConnection )
|
||||||
{
|
{
|
||||||
HttpURLConnection httpConnection = (HttpURLConnection) connection;
|
HttpURLConnection httpConnection = (HttpURLConnection) connection;
|
||||||
|
// although HTTPUrlConnection javadocs says FileNotFoundException should be
|
||||||
|
// thrown on a 404 error, that certainly does not appear to be the case, so
|
||||||
|
// test for 404 ourselves, and throw FileNotFoundException as needed
|
||||||
|
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND)
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException(url.toString() + " (HTTP Error: "
|
||||||
|
+ httpConnection.getResponseCode() + " " + httpConnection.getResponseMessage() + ")");
|
||||||
|
}
|
||||||
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED )
|
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -153,7 +267,12 @@ public class HttpUtils
|
||||||
// test for 401 result (HTTP only)
|
// test for 401 result (HTTP only)
|
||||||
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED )
|
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED )
|
||||||
{
|
{
|
||||||
throw new Exception( "Not authorized." );
|
throw new IOException( "Not authorized." );
|
||||||
|
}
|
||||||
|
// test for 407 result (HTTP only)
|
||||||
|
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_PROXY_AUTH )
|
||||||
|
{
|
||||||
|
throw new IOException( "Not authorized by proxy." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +282,7 @@ public class HttpUtils
|
||||||
// Some protocols (FTP) dont include dates, of course.
|
// Some protocols (FTP) dont include dates, of course.
|
||||||
|
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
|
IOException isException = null;
|
||||||
for ( int i = 0; i < 3; i++ )
|
for ( int i = 0; i < 3; i++ )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -172,18 +292,18 @@ public class HttpUtils
|
||||||
}
|
}
|
||||||
catch ( IOException ex )
|
catch ( IOException ex )
|
||||||
{
|
{
|
||||||
// do nothing
|
isException = ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( is == null )
|
if ( is == null )
|
||||||
{
|
{
|
||||||
if ( ignoreErrors )
|
throw isException;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will never happen with maven's use of this class.
|
if ( connection.getLastModified() <= timestamp &&
|
||||||
throw new Exception( "Can't get " + destinationFile.getName() + " to " + destinationFile );
|
connection.getLastModified() != 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOutputStream fos = new FileOutputStream( destinationFile );
|
FileOutputStream fos = new FileOutputStream( destinationFile );
|
||||||
|
@ -204,10 +324,9 @@ public class HttpUtils
|
||||||
// if (and only if) the use file time option is set, then the
|
// if (and only if) the use file time option is set, then the
|
||||||
// saved file now has its timestamp set to that of the downloaded
|
// saved file now has its timestamp set to that of the downloaded
|
||||||
// file
|
// file
|
||||||
if ( useTimestamp )
|
if ( timestamp >= 0 )
|
||||||
{
|
{
|
||||||
long remoteTimestamp = connection.getLastModified();
|
long remoteTimestamp = connection.getLastModified();
|
||||||
|
|
||||||
if ( remoteTimestamp != 0 )
|
if ( remoteTimestamp != 0 )
|
||||||
{
|
{
|
||||||
touchFile( destinationFile, remoteTimestamp );
|
touchFile( destinationFile, remoteTimestamp );
|
||||||
|
@ -215,6 +334,15 @@ public class HttpUtils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse an url which might contain a username and password. If the
|
||||||
|
* given url doesn't contain a username and password then return the
|
||||||
|
* origin url unchanged.
|
||||||
|
*
|
||||||
|
* @param url The url to parse.
|
||||||
|
* @return The username, password and url.
|
||||||
|
* @throws RuntimeException if the url is (very) invalid
|
||||||
|
*/
|
||||||
static String[] parseUrl( String url )
|
static String[] parseUrl( String url )
|
||||||
{
|
{
|
||||||
String[] parsedUrl = new String[3];
|
String[] parsedUrl = new String[3];
|
||||||
|
@ -231,18 +359,28 @@ public class HttpUtils
|
||||||
int i = url.indexOf( "@" );
|
int i = url.indexOf( "@" );
|
||||||
if ( i > 0 )
|
if ( i > 0 )
|
||||||
{
|
{
|
||||||
String s = url.substring( 7, i );
|
String protocol = url.substring( 0, url.indexOf("://") ) + "://";
|
||||||
|
String s = url.substring( protocol.length(), i );
|
||||||
int j = s.indexOf( ":" );
|
int j = s.indexOf( ":" );
|
||||||
parsedUrl[0] = s.substring( 0, j );
|
parsedUrl[0] = s.substring( 0, j );
|
||||||
parsedUrl[1] = s.substring( j + 1 );
|
parsedUrl[1] = s.substring( j + 1 );
|
||||||
parsedUrl[2] = "http://" + url.substring( i + 1 );
|
parsedUrl[2] = protocol + url.substring( i + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsedUrl;
|
return parsedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the timestamp of a named file to a specified time.
|
||||||
|
*
|
||||||
|
* @param file the file to touch
|
||||||
|
* @param timemillis in milliseconds since the start of the era
|
||||||
|
* @return true if it succeeded. False means that this is a java1.1 system
|
||||||
|
* and that file times can not be set
|
||||||
|
* @throws RuntimeException Thrown in unrecoverable error. Likely this
|
||||||
|
* comes from file access failures.
|
||||||
|
*/
|
||||||
private static boolean touchFile( File file, long timemillis )
|
private static boolean touchFile( File file, long timemillis )
|
||||||
throws Exception
|
|
||||||
{
|
{
|
||||||
long modifiedTime;
|
long modifiedTime;
|
||||||
|
|
||||||
|
@ -256,7 +394,6 @@ public class HttpUtils
|
||||||
}
|
}
|
||||||
|
|
||||||
file.setLastModified( modifiedTime );
|
file.setLastModified( modifiedTime );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue