package rhogenwizard;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpDownload
{
public static class HttpException extends IOException
{
private static final long serialVersionUID = -1018042761849715403L;
public HttpException(IOException e)
{
super(e);
}
}
public static class StreamException extends IOException
{
private static final long serialVersionUID = -3224144258724889642L;
public StreamException(IOException e)
{
super(e);
}
}
private class Downloader implements Runnable
{
@Override
public void run()
{
while (true)
{
try
{
InputStream stream = getInputStream();
if (stream == null)
{
return;
}
try
{
copy(stream, m_stream);
}
finally
{
close(stream);
}
break;
}
catch (HttpException e)
{
m_exception = e;
try
{
Thread.sleep(1000);
}
catch (InterruptedException e1)
{
break;
}
}
catch (StreamException e)
{
m_exception = e;
break;
}
}
}
private InputStream getInputStream() throws HttpException
{
try
{
HttpURLConnection connection = (HttpURLConnection) m_url.openConnection();
connection.setRequestProperty("Range", "bytes=" + m_downloaded + "-");
connection.connect();
m_responseCode = connection.getResponseCode();
if (!goodResponseCode())
{
return null;
}
long length = connection.getContentLength();
m_size = (length == -1) ? -1 : m_downloaded + length;
return connection.getInputStream();
}
catch (IOException e)
{
throw new HttpException(e);
}
}
private void close(InputStream is)
{
try
{
is.close();
}
catch (IOException e)
{
}
}
private void copy(InputStream is, OutputStream os) throws HttpException, StreamException
{
byte[] buffer = new byte[16 * 1024];
while (true)
{
int read;
try
{
read = is.read(buffer);
}
catch (IOException e)
{
throw new HttpException(e);
}
if (read == -1)
{
break;
}
try
{
os.write(buffer, 0, read);
}
catch (IOException e)
{
throw new StreamException(e);
}
m_downloaded += read;
}
}
}
private final URL m_url;
private final OutputStream m_stream;
private volatile long m_size = 0;
private volatile long m_downloaded = 0;
private volatile IOException m_exception = null;
private volatile int m_responseCode = 0;
private final Thread m_downloader;
public HttpDownload(URL url, OutputStream stream)
{
m_url = url;
m_stream = stream;
m_size = -1;
m_downloaded = 0;
m_exception = null;
m_responseCode = 0;
m_downloader = new Thread(new Downloader());
m_downloader.start();
}
public void stop()
{
m_downloader.interrupt();
}
public boolean isAlive()
{
return m_downloader.isAlive();
}
public void join(int millis) throws InterruptedException
{
m_downloader.join(millis);
}
public boolean ok()
{
return goodResponseCode() && m_exception == null;
}
public int getResponseCode()
{
return m_responseCode;
}
public IOException getException()
{
return m_exception;
}
public long getSize()
{
return m_size;
}
public long getDownloaded()
{
return m_downloaded;
}
private boolean goodResponseCode()
{
return m_responseCode == HttpURLConnection.HTTP_OK
|| m_responseCode == HttpURLConnection.HTTP_PARTIAL;
}
}