package com.leansoft.nanorest.client; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.NameValuePair; import org.apache.http.client.methods.HttpUriRequest; 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.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.message.BasicNameValuePair; 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 com.leansoft.nanorest.auth.AuthenticationProvider; import com.leansoft.nanorest.domain.ResponseStatus; import com.leansoft.nanorest.logger.ALog; import android.text.TextUtils; import android.util.Log; public abstract class BaseRestClient implements RestClient { public enum RequestMethod { GET, POST, PUT, DELETE } private static final String TAG = BaseRestClient.class .getSimpleName(); private static DefaultHttpClient innerHttpClient; private RequestMethod requestMethod = RequestMethod.GET; private final ArrayList<NameValuePair> headers; private final ArrayList<NameValuePair> params; private String url; private ResponseStatus responseStatus = new ResponseStatus(); private String response; private int connectionTimeout = 8000; private int socketTimeout = 12000; private AuthenticationProvider authProvider; private static AuthenticationProvider defaultAuthProvider; public BaseRestClient() { headers = new ArrayList<NameValuePair>(); params = new ArrayList<NameValuePair>(); } @Override public int getConnectionTimeout() { return connectionTimeout; } @Override public void setUrl(final String url) { this.url = url; } @Override public String getUrl() { return url; } @Override public void setConnectionTimeout(final int connectionTimeout) { this.connectionTimeout = connectionTimeout; } @Override public int getSocketTimeout() { return socketTimeout; } @Override public void setSocketTimeout(final int socketTimeout) { this.socketTimeout = socketTimeout; } @Override public String getResponse() { return response; } @Override public ResponseStatus getResponseStatus() { return responseStatus; } @Override public ArrayList<NameValuePair> getHeaders() { return headers; } @Override public ArrayList<NameValuePair> getParams() { return params; } @Override public void addHeader(final String name, final String value) { if (TextUtils.isEmpty(value) == false) { headers.add(new BasicNameValuePair(name, value)); } } @Override public void addParam(final String name, final String value) { if (TextUtils.isEmpty(value) == false) { params.add(new BasicNameValuePair(name, value)); } } @Override public void setAuthentication(AuthenticationProvider authProvider) { this.authProvider = authProvider; } @Override public void setRequestMethod(RequestMethod requestMethod) { this.requestMethod = requestMethod; } @Override public RequestMethod getRequestMethod() { return requestMethod; } public static void setDefaultAuthenticationProvider( AuthenticationProvider provider) { BaseRestClient.defaultAuthProvider = provider; } private void authenticateRequest() { if (authProvider != null) { authProvider.authenticateRequest(this); return; } if (defaultAuthProvider != null) { defaultAuthProvider.authenticateRequest(this); return; } //TokenAuthenticationProvider.getInstance().authenticateRequest(this); } @Override public void executeRequest(final HttpUriRequest request) throws IOException { authenticateRequest(); // add headers for (NameValuePair h : getHeaders()) { request.addHeader(h.getName(), h.getValue()); } final HttpParams httpParameters = new BasicHttpParams(); // Set the timeout in milliseconds until a connection is established. HttpConnectionParams.setConnectionTimeout(httpParameters, connectionTimeout); // Set the default socket timeout (SO_TIMEOUT) // in milliseconds which is the timeout for waiting for data. HttpConnectionParams.setSoTimeout(httpParameters, socketTimeout); getInnerHttpClient().setParams(httpParameters); HttpResponse httpResponse; InputStream instream = null; try { httpResponse = getInnerHttpClient().execute(request); responseStatus.setStatusCode(httpResponse.getStatusLine() .getStatusCode()); responseStatus.setStatusMessage(httpResponse.getStatusLine() .getReasonPhrase()); final HttpEntity entity = httpResponse.getEntity(); if (entity != null) { instream = entity.getContent(); response = StreamUtil.convertStreamToString(instream); ALog.d(TAG, "URL: " + url); ALog.d(TAG, "RESPONSE:"); ALog.debugLongMessage(TAG, response); } } catch (final IOException e) { throw e; } catch (final RuntimeException ex) { // In case of an unexpected exception you may want to abort // the HTTP request in order to shut down the underlying // connection immediately. request.abort(); throw ex; } finally { if (instream != null) { // Closing the input stream will trigger connection release StreamUtil.silentClose(instream); } } } public static DefaultHttpClient getInnerHttpClient() { if (innerHttpClient == null) { innerHttpClient = buildHttpClient(); } return innerHttpClient; } private static DefaultHttpClient buildHttpClient() { final HttpParams params = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(params, 20 * 1000); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); // Create and initialize scheme registry final SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); // Create a HttpClient with the ThreadSafeClientConnManager. // This connection manager must be used if more than one thread will // be using the HttpClient. final ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); final DefaultHttpClient httpClient = new DefaultHttpClient(cm, params); return httpClient; } static String generateParametersString( final ArrayList<NameValuePair> params) throws UnsupportedEncodingException { // add parameters String combinedParams = ""; if (params != null && !params.isEmpty()) { combinedParams += "?"; for (final NameValuePair p : params) { final String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(), "UTF-8"); if (combinedParams.length() > 1) { combinedParams += "&" + paramString; } else { combinedParams += paramString; } } } return combinedParams; } }