package com.github.andlyticsproject.console.v2;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.HttpVersion;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.HttpEntityWrapper;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
public class HttpClientFactory {
private static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
private static final String ENCODING_GZIP = "gzip";
private static final String HEADER_CACHE_CONTROL = "Cache-Control";
private static final String HEADER_PRAGMA = "Pragma";
private static final String NO_CACHE = "no-cache";
private static final String ANDROID_BROWSER_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.2; en-gb; Nexus One Build/FRF50) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
private static final String ACCEPT_VALUE = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
private static final String ACCEPT_LANG_VALUE = "en-us,en;q=0.5";
private static final String ACCEPT_CHARSET_VALUE = "ISO-8859-1,utf-8;q=0.7,*;q=0.7";
// TODO do we need this?
private static final String KEEP_ALIVE_VALUE = "115";
private HttpClientFactory() {
}
public static DefaultHttpClient createDevConsoleHttpClient(int timeoutMillis) {
DefaultHttpClient result = createDefaultClient(timeoutMillis);
result.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(HttpRequest request, HttpContext context) {
addCommonHeaders(request);
}
});
addGzipInterceptor(result);
return result;
}
private static DefaultHttpClient createDefaultClient(int timeoutMillis) {
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, timeoutMillis);
HttpConnectionParams.setSoTimeout(params, timeoutMillis);
HttpProtocolParams.setUserAgent(params, ANDROID_BROWSER_USER_AGENT);
HttpClientParams.setRedirecting(params, true);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(params, false);
HttpConnectionParams.setSoTimeout(params, timeoutMillis);
HttpConnectionParams.setConnectionTimeout(params, timeoutMillis);
SSLSocketFactory sf = SSLSocketFactory.getSocketFactory();
sf.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
return new DefaultHttpClient(new ThreadSafeClientConnManager(params, registry), params);
}
private static void addGzipInterceptor(DefaultHttpClient result) {
result.addResponseInterceptor(new HttpResponseInterceptor() {
public void process(HttpResponse response, HttpContext context) {
// Inflate any responses compressed with gzip
final HttpEntity entity = response.getEntity();
final Header encoding = entity.getContentEncoding();
if (encoding != null) {
for (HeaderElement element : encoding.getElements()) {
if (element.getName().equalsIgnoreCase(ENCODING_GZIP)) {
response.setEntity(new InflatingEntity(response.getEntity()));
break;
}
}
}
}
});
}
public static ResponseHandler<String> createResponseHandler() {
return new BasicResponseHandler();
}
private static void addCommonHeaders(HttpRequest request) {
if (!request.containsHeader(HEADER_ACCEPT_ENCODING)) {
request.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
}
if (!request.containsHeader(HEADER_CACHE_CONTROL)) {
request.addHeader(HEADER_CACHE_CONTROL, NO_CACHE);
}
if (!request.containsHeader(HEADER_PRAGMA)) {
request.addHeader(HEADER_PRAGMA, NO_CACHE);
}
// overwrite?
request.addHeader("Accept", ACCEPT_VALUE);
request.addHeader("Accept-Language", ACCEPT_LANG_VALUE);
request.addHeader("Accept-Charset", ACCEPT_CHARSET_VALUE);
request.addHeader("Keep-Alive", KEEP_ALIVE_VALUE);
}
static class InflatingEntity extends HttpEntityWrapper {
public InflatingEntity(HttpEntity wrapped) {
super(wrapped);
}
@Override
public InputStream getContent() throws IOException {
return new GZIPInputStream(wrappedEntity.getContent());
}
@Override
public long getContentLength() {
return -1;
}
}
}