package org.rr.commons.io;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
public class HttpInputStream extends InputStream {
private final static ExecutorService pool = Executors.newCachedThreadPool();
private Future<byte[]> futureContentBytes;
private ByteArrayInputStream in;
public HttpInputStream(URL url) {
futureContentBytes = getFutureContent(url);
}
private Future<byte[]> getFutureContent(final URL url) {
Callable<byte[]> futureBytes = new Callable<byte[]>() {
@Override
public byte[] call() throws Exception {
return getContent(url);
}
};
Future<byte[]> submit = pool.submit(futureBytes);
return submit;
}
@Override
public int read() throws IOException {
try {
if(in == null) {
in = new ByteArrayInputStream(futureContentBytes.get());
}
return in.read();
} catch (Exception e) {
throw new IOException(e);
}
}
private byte[] getContent(URL url) throws IOException {
try {
return getContent(url.toURI());
} catch (URISyntaxException e) {
throw new IOException(e);
}
}
private byte[] getContent(URI url) throws IOException {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpParams httpParams = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
httpclient.setParams(httpParams);
HttpGet httpGet;
httpGet = new HttpGet(url);
HttpResponse response1 = httpclient.execute(httpGet);
// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
// the user MUST either fully consume the response content or abort request
// execution by calling HttpGet#releaseConnection().
if(response1.getStatusLine().getStatusCode() != 200) {
throw new IOException(response1.getStatusLine().toString());
}
HttpEntity entity1 = response1.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
byte[] byteArray = EntityUtils.toByteArray(entity1);
entity1.consumeContent();
return byteArray;
}
}