package nz.co.wetstone.http;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
/**
*
* @author davidm
* Thin wrapper/convenience class over Apache HTTPClient
*/
public class SimpleHTTPClient {
private CookieStore cookieStore;
private HttpContext localContext;
public static final int HTTP_POST = 1;
public static final int HTTP_GET = 0;
public static final int ENTITY_STRING = 1;
public static final int ENTITY_FORM = 2;
private static final String user_agent = "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.69 Safari/537.17";
private List<Header> headers = new ArrayList<Header>();
private InputStream is;
private DataInputStream in;
private InputStreamReader isr;
private BufferedReader br;
public SimpleHTTPClient() {
localContext = new BasicHttpContext();
cookieStore = new BasicCookieStore();
getThreadSafeClient().getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
}
private static DefaultHttpClient client;
public synchronized static DefaultHttpClient getThreadSafeClient() {
if (client != null)
return client;
client = new DefaultHttpClient();
ClientConnectionManager mgr = client.getConnectionManager();
HttpParams params = client.getParams();
client = new DefaultHttpClient(
new ThreadSafeClientConnManager(params,
mgr.getSchemeRegistry()), params);
return client;
}
public void addHeader(String name, String value) {
Header h = new Header();
h.setName(name);
h.setValue(value);
headers.add(h);
}
public InputStream grabRawStream(String url) throws IllegalStateException, IOException {
try {
if (url != null) {
HttpEntity responseEntity = doHTTPGet(new URI(url)).getEntity();
return responseEntity.getContent();
}
} catch (URISyntaxException ex) {
Logger.getLogger(SimpleHTTPClient.class.getName()).log(Level.SEVERE, "", ex);
}
return null;
}
public String grabPageHTML(int verb, URIParameterBuilder builder) throws IOException, URISyntaxException {
HttpResponse response;
AbstractHttpEntity entity = null;
URI uri = builder.buildURI();
switch (builder.getEntityType()) {
case ENTITY_STRING:
entity = builder.buildStringEntity();
break;
case ENTITY_FORM:
entity = builder.buildFormEntity();
break;
}
switch (verb) {
case HTTP_POST:
if(entity == null) {
throw new IllegalArgumentException("Entity must be non NULL when doing a POST");
}
response = doHTTPPost(uri, entity);
break;
case HTTP_GET:
response = doHTTPGet(uri);
break;
default:
response = doHTTPGet(uri);
break;
}
try {
String strLine;
HttpEntity responseEntity = response.getEntity();
is = responseEntity.getContent();
in = new DataInputStream(is);
isr = new InputStreamReader(in,"UTF-8");
br = new BufferedReader(isr);
StringBuilder strBuffer = new StringBuilder();
while ((strLine = br.readLine()) != null) {
strBuffer.append(strLine);
}
return strBuffer.toString();
}finally {
if(br != null) {
br.close();
}
if(isr != null) {
isr.close();
}
if(in != null) {
in.close();
}
if(is != null) {
is.close();
}
}
}
private HttpResponse doHTTPGet(URI uri) throws ClientProtocolException, IOException {
HttpGet httpRequest = new HttpGet(uri);
httpRequest.setHeader("User-Agent", user_agent);
for(Header header : headers) {
httpRequest.addHeader(header.getName(), header.getValue());
}
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpResponse response = getThreadSafeClient().execute(httpRequest, localContext);
return response;
}
private HttpResponse doHTTPPost(URI uri, AbstractHttpEntity entity) throws ClientProtocolException, IOException {
HttpPost httpRequest = new HttpPost(uri);
httpRequest.addHeader("User-Agent", user_agent);
for(Header header : headers) {
httpRequest.addHeader(header.getName(), header.getValue());
}
if (entity != null) {
httpRequest.setEntity(entity);
}
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpResponse response = getThreadSafeClient().execute(httpRequest, localContext);
return response;
}
public static class URIParameterBuilder {
private List<NameValuePair> parameterNameValuePairs;
private List<NameValuePair> entityNameValuePairs;
private String host;
private String stringEntity;
private int entityType;
public URIParameterBuilder() {
parameterNameValuePairs = new ArrayList<NameValuePair>();
entityNameValuePairs = new ArrayList<NameValuePair>();
}
public URIParameterBuilder setParameter(String name, String value) {
parameterNameValuePairs.add(new BasicNameValuePair(name, value));
return this;
}
public URIParameterBuilder setHost(String serviceEndPoint) {
host = serviceEndPoint;
return this;
}
public URI buildURI() throws URISyntaxException {
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
sb.append(host);
for (NameValuePair p : parameterNameValuePairs) {
if (isFirst) {
sb.append("?");
sb.append(p.getName()).append("=").append(p.getValue());
isFirst = false;
} else {
sb.append("&").append(p.getName()).append("=").append(p.getValue());
}
}
return new URI(sb.toString());
}
public UrlEncodedFormEntity buildFormEntity() throws UnsupportedEncodingException {
return new UrlEncodedFormEntity(entityNameValuePairs);
}
public URIParameterBuilder addFormEntity(String name, String value) {
entityType = SimpleHTTPClient.ENTITY_FORM;
entityNameValuePairs.add(new BasicNameValuePair(name, value));
return this;
}
public URIParameterBuilder addFormEntities(List<NameValuePair> params) {
entityType = SimpleHTTPClient.ENTITY_FORM;
entityNameValuePairs.addAll(params);
return this;
}
public URIParameterBuilder appendPath(String path) {
host = host + "/" + path;
return this;
}
public void setStringEntity(String str) {
entityType = SimpleHTTPClient.ENTITY_STRING;
stringEntity = str;
}
public StringEntity buildStringEntity() throws UnsupportedEncodingException {
return new StringEntity(stringEntity);
}
private int getEntityType() {
return entityType;
}
}
public static class Header {
String name;
String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}