int retry_secs = http_downloader.getLast503RetrySecs();
setReconnectDelay( retry_secs * 1000, true );
throw( new ExternalSeedException( "Server temporarily unavailable, retrying in " + retry_secs + " seconds" ));
}else{
throw(ese);
}
}
}else{
long request_end = request_start + request_length;
// System.out.println( "Req: start=" + request_start + ", len=" + request_length );
final byte[][] overlap_buffer = { null };
final int[] overlap_buffer_position = { 0 };
// we've got to multiplex the (possible) multiple request buffers onto (possible) multi files
for (int i=0;i<http_downloaders.length;i++){
long this_start = downloader_offsets[i];
long this_end = this_start + downloader_lengths[i];
if ( this_end <= request_start ){
continue;
}
if ( this_start >= request_end ){
break;
}
long sub_request_start = Math.max( request_start, this_start );
long sub_request_end = Math.min( request_end, this_end );
final int sub_len = (int)( sub_request_end - sub_request_start );
if ( sub_len == 0 ){
continue;
}
ExternalSeedHTTPDownloader http_downloader = http_downloaders[i];
// System.out.println( " sub_req: start=" + sub_request_start + ", len=" + sub_len + ",url=" + http_downloader.getURL());
ExternalSeedHTTPDownloaderListener sub_request =
new ExternalSeedHTTPDownloaderListener()
{
private int bytes_read;
private byte[] current_buffer = overlap_buffer[0];
private int current_buffer_position = overlap_buffer_position[0];
private int current_buffer_length = current_buffer==null?-1:Math.min( current_buffer.length, current_buffer_position + sub_len );
public byte[]
getBuffer()
throws ExternalSeedException
{
if ( current_buffer == null ){
current_buffer = listener.getBuffer();
current_buffer_position = 0;
current_buffer_length = Math.min( current_buffer.length, sub_len - bytes_read );
}
return( current_buffer );
}
public void
setBufferPosition(
int position )
{
current_buffer_position = position;
listener.setBufferPosition( position );
}
public int
getBufferPosition()
{
return( current_buffer_position );
}
public int
getBufferLength()
{
return( current_buffer_length );
}
public int
getPermittedBytes()
throws ExternalSeedException
{
return( listener.getPermittedBytes());
}
public int
getPermittedTime()
{
return( listener.getPermittedTime());
}
public void
reportBytesRead(
int num )
{
bytes_read += num;
listener.reportBytesRead( num );
}
public boolean
isCancelled()
{
return( listener.isCancelled());
}
public void
done()
{
// the current buffer is full up to the declared length
int rem = current_buffer.length - current_buffer_length;
if ( bytes_read == sub_len ){
// this request is complete. save any partial buffer for
// next request
if ( rem == 0 ){
overlap_buffer[0] = null;
overlap_buffer_position[0] = 0;
}else{
overlap_buffer[0] = current_buffer;
overlap_buffer_position[0] = current_buffer_length;
}
}
// prepare for next buffer if needed
current_buffer = null;
if ( rem == 0 ){
listener.done();
}
}
};
try{
http_downloader.downloadRange(
sub_request_start - this_start,
sub_len,
sub_request,
isTransient());
}catch( ExternalSeedException ese ){
if ( http_downloader.getLastResponse() == 503 && http_downloader.getLast503RetrySecs() >= 0 ){
int retry_secs = http_downloader.getLast503RetrySecs();
setReconnectDelay( retry_secs * 1000, true );
throw( new ExternalSeedException( "Server temporarily unavailable, retrying in " + retry_secs + " seconds" ));
}else{
throw(ese);
}