Coverage Report - org.codeforamerica.open311.internals.network.HTTPNetworkManager
 
Classes in this File Line Coverage Branch Coverage Complexity
HTTPNetworkManager
41%
17/41
0%
0/4
1.833
HTTPNetworkManager$MySSLSocketFactory
75%
6/8
N/A
1.833
HTTPNetworkManager$MySSLSocketFactory$1
25%
1/4
N/A
1.833
 
 1  
 package org.codeforamerica.open311.internals.network;
 2  
 
 3  
 import java.io.IOException;
 4  
 import java.io.UnsupportedEncodingException;
 5  
 import java.net.Socket;
 6  
 import java.net.URL;
 7  
 import java.net.UnknownHostException;
 8  
 import java.security.KeyManagementException;
 9  
 import java.security.KeyStore;
 10  
 import java.security.KeyStoreException;
 11  
 import java.security.NoSuchAlgorithmException;
 12  
 import java.security.UnrecoverableKeyException;
 13  
 import java.security.cert.CertificateException;
 14  
 import java.security.cert.X509Certificate;
 15  
 import java.util.ArrayList;
 16  
 import java.util.List;
 17  
 import java.util.Map;
 18  
 import java.util.Map.Entry;
 19  
 
 20  
 import javax.net.ssl.SSLContext;
 21  
 import javax.net.ssl.TrustManager;
 22  
 import javax.net.ssl.X509TrustManager;
 23  
 
 24  
 import org.apache.http.HttpEntity;
 25  
 import org.apache.http.HttpResponse;
 26  
 import org.apache.http.HttpVersion;
 27  
 import org.apache.http.NameValuePair;
 28  
 import org.apache.http.client.HttpClient;
 29  
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 30  
 import org.apache.http.client.methods.HttpGet;
 31  
 import org.apache.http.client.methods.HttpPost;
 32  
 import org.apache.http.conn.ClientConnectionManager;
 33  
 import org.apache.http.conn.scheme.PlainSocketFactory;
 34  
 import org.apache.http.conn.scheme.Scheme;
 35  
 import org.apache.http.conn.scheme.SchemeRegistry;
 36  
 import org.apache.http.conn.ssl.SSLSocketFactory;
 37  
 import org.apache.http.impl.client.DefaultHttpClient;
 38  
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
 39  
 import org.apache.http.message.BasicNameValuePair;
 40  
 import org.apache.http.params.BasicHttpParams;
 41  
 import org.apache.http.params.HttpConnectionParams;
 42  
 import org.apache.http.params.HttpParams;
 43  
 import org.apache.http.params.HttpProtocolParams;
 44  
 import org.apache.http.util.EntityUtils;
 45  
 import org.codeforamerica.open311.facade.Format;
 46  
 
 47  
 /**
 48  
  * Implementation using the <a href="http://hc.apache.org/">Apache
 49  
  * HttpComponents</> library.
 50  
  * 
 51  
  * @author Santiago Munín <santimunin@gmail.com>
 52  
  * 
 53  
  */
 54  
 public class HTTPNetworkManager implements NetworkManager {
 55  
         private HttpClient httpClient;
 56  
         private Format format;
 57  
         private static final int TIMEOUT = 5000;
 58  
         private static final String ACCEPT_HEADER = "Accept";
 59  
         private static final String CONTENT_TYPE_HEADER = "Content-Type";
 60  
 
 61  7
         public HTTPNetworkManager(Format format) {
 62  7
                 this.format = format;
 63  7
                 this.httpClient = getNewHttpClient();
 64  7
         }
 65  
 
 66  
         @Override
 67  
         public String doGet(URL url) throws IOException {
 68  
                 try {
 69  0
                         HttpGet httpGet = new HttpGet(url.toURI());
 70  0
                         httpGet.setHeader(ACCEPT_HEADER, format.getHTTPContentType());
 71  0
                         httpGet.setHeader(CONTENT_TYPE_HEADER, format.getHTTPContentType());
 72  0
                         HttpResponse response = httpClient.execute(httpGet);
 73  0
                         return EntityUtils.toString(response.getEntity(), CHARSET);
 74  0
                 } catch (Exception e) {
 75  0
                         throw new IOException(e.getMessage());
 76  
                 }
 77  
         }
 78  
 
 79  
         @Override
 80  
         public String doPost(URL url, Map<String, String> parameters)
 81  
                         throws IOException {
 82  
                 try {
 83  0
                         HttpPost httpPost = new HttpPost(url.toURI());
 84  0
                         httpPost.setHeader(ACCEPT_HEADER, format.getHTTPContentType());
 85  0
                         httpPost.setHeader("Content-Type", POST_CONTENT_TYPE);
 86  0
                         httpPost.setEntity(generateHttpEntityFromParameters(parameters));
 87  0
                         HttpResponse response = httpClient.execute(httpPost);
 88  0
                         return EntityUtils.toString(response.getEntity(), CHARSET);
 89  0
                 } catch (Exception e) {
 90  0
                         throw new IOException(e);
 91  
                 }
 92  
         }
 93  
 
 94  
         @Override
 95  
         public void setFormat(Format format) {
 96  0
                 this.format = format;
 97  0
         }
 98  
 
 99  
         /**
 100  
          * Builds an {@link HttpEntity} with all the given parameters.
 101  
          * 
 102  
          * @param parameters
 103  
          *            A list of parameters of a POST request.
 104  
          * @return An {@link UrlEncodedFormEntity} with the given parameters.
 105  
          * @throws UnsupportedEncodingException
 106  
          *             if the default encoding isn't supported.
 107  
          */
 108  
         private HttpEntity generateHttpEntityFromParameters(
 109  
                         Map<String, String> parameters) throws UnsupportedEncodingException {
 110  0
                 List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
 111  0
                 if (parameters != null) {
 112  0
                         for (Entry<String, String> parameterEntry : parameters.entrySet()) {
 113  0
                                 nameValuePairs.add(new BasicNameValuePair(parameterEntry
 114  
                                                 .getKey(), parameterEntry.getValue()));
 115  
                         }
 116  
                 }
 117  0
                 return new UrlEncodedFormEntity(nameValuePairs);
 118  
         }
 119  
 
 120  
         /**
 121  
          * Builds a {@link HttpClient} which allows non trusted SSL certificates.
 122  
          * 
 123  
          * @return {@link HttpClient} which allows non trusted SSL certificates.
 124  
          */
 125  
         private HttpClient getNewHttpClient() {
 126  
                 try {
 127  7
                         KeyStore trustStore = KeyStore.getInstance(KeyStore
 128  
                                         .getDefaultType());
 129  7
                         trustStore.load(null, null);
 130  
 
 131  7
                         SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
 132  7
                         sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
 133  
 
 134  7
                         HttpParams params = new BasicHttpParams();
 135  7
                         HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
 136  7
                         HttpProtocolParams.setContentCharset(params, CHARSET);
 137  7
                         HttpConnectionParams.setConnectionTimeout(params, TIMEOUT);
 138  
 
 139  7
                         SchemeRegistry registry = new SchemeRegistry();
 140  7
                         registry.register(new Scheme("http", PlainSocketFactory
 141  
                                         .getSocketFactory(), 80));
 142  7
                         registry.register(new Scheme("https", sf, 443));
 143  
 
 144  7
                         ClientConnectionManager ccm = new ThreadSafeClientConnManager(
 145  
                                         params, registry);
 146  7
                         return new DefaultHttpClient(ccm, params);
 147  0
                 } catch (Exception e) {
 148  0
                         return new DefaultHttpClient();
 149  
                 }
 150  
         }
 151  
 
 152  
         /**
 153  
          * A SSLSocketFactory which allows non trusted SSL certificates.
 154  
          * 
 155  
          * @author Santiago Munín <santimunin@gmail.com>
 156  
          * 
 157  
          */
 158  
         private class MySSLSocketFactory extends SSLSocketFactory {
 159  7
                 SSLContext sslContext = SSLContext.getInstance("TLS");
 160  
 
 161  
                 public MySSLSocketFactory(KeyStore truststore)
 162  
                                 throws NoSuchAlgorithmException, KeyManagementException,
 163  7
                                 KeyStoreException, UnrecoverableKeyException {
 164  7
                         super(truststore);
 165  
 
 166  7
                         TrustManager tm = new X509TrustManager() {
 167  
                                 public void checkClientTrusted(X509Certificate[] chain,
 168  
                                                 String authType) {
 169  0
                                 }
 170  
 
 171  
                                 public void checkServerTrusted(X509Certificate[] chain,
 172  
                                                 String authType) throws CertificateException {
 173  0
                                 }
 174  
 
 175  
                                 public X509Certificate[] getAcceptedIssuers() {
 176  0
                                         return null;
 177  
                                 }
 178  
                         };
 179  
 
 180  7
                         sslContext.init(null, new TrustManager[] { tm }, null);
 181  7
                 }
 182  
 
 183  
                 @Override
 184  
                 public Socket createSocket(Socket socket, String host, int port,
 185  
                                 boolean autoClose) throws IOException, UnknownHostException {
 186  0
                         return sslContext.getSocketFactory().createSocket(socket, host,
 187  
                                         port, autoClose);
 188  
                 }
 189  
 
 190  
                 @Override
 191  
                 public Socket createSocket() throws IOException {
 192  0
                         return sslContext.getSocketFactory().createSocket();
 193  
                 }
 194  
         }
 195  
 }