ExternalSeedHTTPDownloaderpublic class ExternalSeedHTTPDownloader extends Object implements org.gudy.azureus2.core3.security.SEPasswordListener
Fields Summary |
---|
public static final String | NL | private URL | url | private String | user_agent | private int | last_response | private int | last_response_retry_after_secs |
Constructors Summary |
---|
public ExternalSeedHTTPDownloader(URL _url, String _user_agent)
url = _url;
user_agent = _user_agent;
|
Methods Summary |
---|
public void | clearPasswords()
| public void | download(int length, ExternalSeedHTTPDownloaderListener listener, boolean con_fail_is_perm_fail)
download( new String[0], new String[0], length, listener, con_fail_is_perm_fail );
| public void | download(java.lang.String[] prop_names, java.lang.String[] prop_values, int length, ExternalSeedHTTPDownloaderListener listener, boolean con_fail_is_perm_fail)
boolean connected = false;
InputStream is = null;
String outcome = "";
try{
SESecurityManager.setThreadPasswordHandler( this );
// System.out.println( "Connecting to " + url + ": " + Thread.currentThread().getId());
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty( "Connection", "Keep-Alive" );
connection.setRequestProperty( "User-Agent", user_agent );
for (int i=0;i<prop_names.length;i++){
connection.setRequestProperty( prop_names[i], prop_values[i] );
}
connection.connect();
connected = true;
int response = connection.getResponseCode();
last_response = response;
last_response_retry_after_secs = -1;
if ( response == 503 ){
// webseed support for temp unavail - read the retry_after
long retry_after_date = new Long(connection.getHeaderFieldDate("Retry-After", -1L)).longValue();
if ( retry_after_date <= -1 ){
last_response_retry_after_secs = connection.getHeaderFieldInt("Retry-After", -1);
}else{
last_response_retry_after_secs = (int)((retry_after_date - System.currentTimeMillis())/1000);
if ( last_response_retry_after_secs < 0 ){
last_response_retry_after_secs = -1;
}
}
}
is = connection.getInputStream();
if ( response == HttpURLConnection.HTTP_ACCEPTED ||
response == HttpURLConnection.HTTP_OK ||
response == HttpURLConnection.HTTP_PARTIAL ){
int pos = 0;
byte[] buffer = null;
int buffer_pos = 0;
int buffer_len = 0;
while( pos < length ){
if ( buffer == null ){
buffer = listener.getBuffer();
buffer_pos = listener.getBufferPosition();
buffer_len = listener.getBufferLength();
}
listener.setBufferPosition( buffer_pos );
int to_read = buffer_len - buffer_pos;
int permitted = listener.getPermittedBytes();
if ( permitted < to_read ){
to_read = permitted;
}
int len = is.read( buffer, buffer_pos, to_read );
if ( len < 0 ){
break;
}
listener.reportBytesRead( len );
pos += len;
buffer_pos += len;
if ( buffer_pos == buffer_len ){
listener.done();
buffer = null;
buffer_pos = 0;
}
}
if ( pos != length ){
String log_str;
if ( buffer == null ){
log_str = "No buffer assigned";
}else{
log_str = new String( buffer, 0, length );
if ( log_str.length() > 64 ){
log_str = log_str.substring( 0, 64 );
}
}
outcome = "Connection failed: data too short - " + length + "/" + pos + " [" + log_str + "]";
throw( new ExternalSeedException( outcome ));
}
outcome = "read " + pos + " bytes";
// System.out.println( "download length: " + pos );
}else{
outcome = "Connection failed: " + connection.getResponseMessage();
ExternalSeedException error = new ExternalSeedException( outcome );
error.setPermanentFailure( true );
throw( error );
}
}catch( IOException e ){
if ( con_fail_is_perm_fail && !connected ){
outcome = "Connection failed: " + e.getMessage();
ExternalSeedException error = new ExternalSeedException( outcome );
error.setPermanentFailure( true );
throw( error );
}else{
outcome = "Connection failed: " + Debug.getNestedExceptionMessage( e );
if ( last_response_retry_after_secs >= 0){
outcome += ", Retry-After: " + last_response_retry_after_secs + " seconds";
}
ExternalSeedException excep = new ExternalSeedException( outcome, e );
if ( e instanceof FileNotFoundException ){
excep.setPermanentFailure( true );
}
throw( excep );
}
}catch( Throwable e ){
if ( e instanceof ExternalSeedException ){
throw((ExternalSeedException)e);
}
outcome = "Connection failed: " + Debug.getNestedExceptionMessage( e );
throw( new ExternalSeedException("Connection failed", e ));
}finally{
SESecurityManager.unsetThreadPasswordHandler();
// System.out.println( "Done to " + url + ": " + Thread.currentThread().getId() + ", outcome=" + outcome );
if ( is != null ){
try{
is.close();
}catch( Throwable e ){
}
}
}
| public void | downloadRange(long offset, int length, ExternalSeedHTTPDownloaderListener listener, boolean con_fail_is_perm_fail)
download( new String[]{ "Range" }, new String[]{ "bytes=" + offset + "-" + (offset+length-1)},
length,
listener,
con_fail_is_perm_fail );
| public void | downloadSocket(int length, ExternalSeedHTTPDownloaderListener listener, boolean con_fail_is_perm_fail)
downloadSocket( new String[0], new String[0], length, listener, con_fail_is_perm_fail );
| public void | downloadSocket(java.lang.String[] prop_names, java.lang.String[] prop_values, int length, ExternalSeedHTTPDownloaderListener listener, boolean con_fail_is_perm_fail)
Socket socket = null;
boolean connected = false;
try{
String output_header =
"GET " + url.getPath() + "?" + url.getQuery() + " HTTP/1.1" + NL +
"Host: " + url.getHost() + (url.getPort()==-1?"":( ":" + url.getPort())) + NL +
"Accept: */*" + NL +
"Connection: Close" + NL + // if we want to support keep-alive we'll need to implement a socket cache etc.
"User-Agent: " + user_agent + NL;
for (int i=0;i<prop_names.length;i++){
output_header += prop_names[i] + ":" + prop_values[i] + NL;
}
output_header += NL;
System.out.println( "header: " + output_header );
socket = new Socket( url.getHost(), url.getPort()==-1?url.getDefaultPort():url.getPort());
connected = true;
OutputStream os = socket.getOutputStream();
os.write( output_header.getBytes( "ISO-8859-1" ));
os.flush();
InputStream is = socket.getInputStream();
try{
String input_header = "";
while( true ){
byte[] buffer = new byte[1];
int len = is.read( buffer );
if ( len < 0 ){
throw( new IOException( "input too short reading header" ));
}
input_header += (char)buffer[0];
if ( input_header.endsWith(NL+NL)){
break;
}
}
// HTTP/1.1 403 Forbidden
int line_end = input_header.indexOf(NL);
if ( line_end == -1 ){
throw( new IOException( "header too short" ));
}
String first_line = input_header.substring(0,line_end);
StringTokenizer tok = new StringTokenizer(first_line, " " );
tok.nextToken();
int response = Integer.parseInt( tok.nextToken());
last_response = response;
last_response_retry_after_secs = -1;
String response_str = tok.nextToken();
if ( response == HttpURLConnection.HTTP_ACCEPTED ||
response == HttpURLConnection.HTTP_OK ||
response == HttpURLConnection.HTTP_PARTIAL ){
byte[] buffer = null;
int buffer_pos = 0;
int buffer_len = 0;
int pos = 0;
while( pos < length ){
if ( buffer == null ){
buffer = listener.getBuffer();
buffer_pos = listener.getBufferPosition();
buffer_len = listener.getBufferLength();
}
int to_read = buffer_len - buffer_pos;
int permitted = listener.getPermittedBytes();
if ( permitted < to_read ){
to_read = permitted;
}
int len = is.read( buffer, buffer_pos, to_read );
if ( len < 0 ){
break;
}
listener.reportBytesRead( len );
pos += len;
buffer_pos += len;
if ( buffer_pos == buffer_len ){
listener.done();
buffer = null;
buffer_pos = 0;
}
}
if ( pos != length ){
String log_str;
if ( buffer == null ){
log_str = "No buffer assigned";
}else{
log_str = new String( buffer, 0, length );
if ( log_str.length() > 64 ){
log_str = log_str.substring( 0, 64 );
}
}
throw( new ExternalSeedException("Connection failed: data too short - " + length + "/" + pos + " [" + log_str + "]" ));
}
// System.out.println( "download length: " + pos );
}else if ( response == 503 ){
// webseed support for temp unavail - read the data
String data_str = "";
while( true ){
byte[] buffer = new byte[1];
int len = is.read( buffer );
if ( len < 0 ){
break;
}
data_str += (char)buffer[0];
}
last_response_retry_after_secs = Integer.parseInt( data_str );
// this gets trapped below and turned into an appropriate ExternalSeedException
throw( new IOException( "Server overloaded" ));
}else{
ExternalSeedException error = new ExternalSeedException("Connection failed: " + response_str );
error.setPermanentFailure( true );
throw( error );
}
}finally{
is.close();
}
}catch( IOException e ){
if ( con_fail_is_perm_fail && !connected ){
ExternalSeedException error = new ExternalSeedException("Connection failed: " + e.getMessage());
error.setPermanentFailure( true );
throw( error );
}else{
String outcome = "Connection failed: " + Debug.getNestedExceptionMessage( e );
if ( last_response_retry_after_secs >= 0 ){
outcome += ", Retry-After: " + last_response_retry_after_secs + " seconds";
}
throw( new ExternalSeedException( outcome, e ));
}
}catch( Throwable e ){
if ( e instanceof ExternalSeedException ){
throw((ExternalSeedException)e);
}
throw( new ExternalSeedException("Connection failed", e ));
}finally{
if ( socket != null ){
try{
socket.close();
}catch( Throwable e ){
}
}
}
| public java.net.PasswordAuthentication | getAuthentication(java.lang.String realm, java.net.URL tracker)
return( null );
| public int | getLast503RetrySecs()
return( last_response_retry_after_secs );
| public int | getLastResponse()
return( last_response );
| public java.net.URL | getURL()
return( url );
| public void | setAuthenticationOutcome(java.lang.String realm, java.net.URL tracker, boolean success)
|
|