package com.apigee.monitoring; import android.os.AsyncTask; import com.apigee.sdk.apm.android.AppMonNet; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URLConnection; import javax.net.ssl.HttpsURLConnection; public class HttpRequestTask extends AsyncTask<String, String, String> { private NetworkResponseListener listener; private boolean responseIsSuccess; private Exception exception; private boolean useHttpURLConnection; private int timeoutMillis; private HttpClient httpClient; private HttpURLConnection httpURLConnection; private HttpsURLConnection httpsURLConnection; private HttpGet httpGet; private boolean connectionTimedOut; private String url; private int httpClientMethodToUse; public HttpRequestTask(String connectionType, int timeoutMillis, int httpClientMethodToUse) { useHttpURLConnection = true; if( connectionType != null ) { if( connectionType.equalsIgnoreCase("HttpClient") ) { useHttpURLConnection = false; } else if( connectionType.equalsIgnoreCase("HttpURLConnection") ) { useHttpURLConnection = true; } } this.timeoutMillis = timeoutMillis; connectionTimedOut = false; httpURLConnection = null; httpsURLConnection = null; this.httpClientMethodToUse = httpClientMethodToUse; } public void setNetworkResponseListener(NetworkResponseListener listener) { this.listener = listener; } public String getStringResponse(HttpResponse response) { String responseString = null; if (response != null) { StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() == HttpStatus.SC_OK) { responseIsSuccess = true; ByteArrayOutputStream out = new ByteArrayOutputStream(); try { response.getEntity().writeTo(out); } catch (IOException e) { } finally { if (out != null) { try { out.close(); } catch (IOException ignored) { } } } responseString = out.toString(); } else { //Closes the connection. HttpEntity entity = response.getEntity(); if( entity != null ) { InputStream contentStream = null; try { contentStream = entity.getContent(); } catch (IOException e) { } finally { if (contentStream != null) { try { contentStream.close(); } catch (IOException ignored) { } } } } } } return responseString; } public String callUsingHttpClient(String uri,int overloadedMethodIndex) { url = uri; responseIsSuccess = false; exception = null; //DOCSNIPPET_START // Ask the Apigee App Monitoring mobile agent for an http client // (that has the instrumentation hooks in it) instead of creating // a typical DefaultHttpClient instance // typical code would do this: //this.httpClient = new org.apache.http.impl.client.DefaultHttpClient(); // to get network performance metrics, do this instead: this.httpClient = AppMonNet.getHttpClient(); //DOCSNIPPET_END HttpResponse response = null; String responseString = null; try { HttpParams httpParameters = new BasicHttpParams(); // Set the timeout in milliseconds until a connection is established. // The default value is zero, that means the timeout is not used. int timeoutConnection = timeoutMillis; HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); // Set the default socket timeout (SO_TIMEOUT) // in milliseconds which is the timeout for waiting for data. int timeoutSocket = timeoutMillis; HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); HttpGet getOperation = new HttpGet(uri); getOperation.setParams(httpParameters); httpGet = getOperation; HttpContext httpContext = new BasicHttpContext(); String host = ""; String scheme = "http"; if (uri.startsWith("https://")) { scheme = "https"; host = uri.substring(8); } else if (uri.startsWith("http://")) { scheme = "http"; host = uri.substring(7); } HttpHost target = new HttpHost(host,80,scheme); ResponseHandler<String> responseHandler = null; if (overloadedMethodIndex < 0) { overloadedMethodIndex = 0; } else if (overloadedMethodIndex > 7) { overloadedMethodIndex = 7; } //String tag = "HttpRequestTask"; if (overloadedMethodIndex == 0) { //execute(HttpHost target, HttpRequest request) //Log.d(tag,"0: execute(HttpHost target, HttpRequest request)"); response = httpClient.execute(target, getOperation); } else if (overloadedMethodIndex == 1) { //execute(HttpHost target, HttpRequest request, HttpContext context) //Log.d(tag,"1: execute(HttpHost target, HttpRequest request, HttpContext context)"); response = httpClient.execute(target, getOperation, httpContext); } else if (overloadedMethodIndex == 2) { //execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) //Log.d(tag,"2: execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler)"); responseHandler = new BasicResponseHandler(); responseString = httpClient.execute(target, getOperation, responseHandler); } else if (overloadedMethodIndex == 3) { //execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) //Log.d(tag,"3: execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context)"); responseHandler = new BasicResponseHandler(); responseString = httpClient.execute(target, getOperation, responseHandler, httpContext); } else if (overloadedMethodIndex == 4) { //execute(HttpUriRequest request) //Log.d(tag,"4: execute(HttpUriRequest request)"); response = httpClient.execute(getOperation); } else if (overloadedMethodIndex == 5) { //execute(HttpUriRequest request, HttpContext context) //Log.d(tag,"5: execute(HttpUriRequest request, HttpContext context)"); response = httpClient.execute(getOperation, httpContext); } else if (overloadedMethodIndex == 6) { //execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) //Log.d(tag,"6: execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler)"); responseHandler = new BasicResponseHandler(); responseString = httpClient.execute(getOperation, responseHandler); } else if (overloadedMethodIndex == 7) { //execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) //Log.d(tag,"7: execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context)"); responseHandler = new BasicResponseHandler(); responseString = httpClient.execute(getOperation, responseHandler, httpContext); } if (responseString != null) { if (responseString.length() > 0) { this.responseIsSuccess = true; } } else { if ((responseHandler == null) && (response != null)) { responseString = this.getStringResponse(response); } } } catch (java.net.SocketTimeoutException e) { exception = e; responseString = null; } catch (IOException e) { exception = e; responseString = null; } finally { this.httpClient = null; } return responseString; } public String callUsingHttpURLConnection(String uri) { url = uri; responseIsSuccess = false; exception = null; String responseString = null; InputStream inputStream = null; this.httpURLConnection = null; this.httpsURLConnection = null; try { //DOCSNIPPET_START //If using, HttpURLConnection, you would normally do this: //java.net.URL url = new java.net.URL(uri); // To have network performance metrics collected, do this instead: com.apigee.sdk.apm.android.URLWrapper url = AppMonNet.urlForUri(uri); //The InstaOpsURL class wraps an instance of java.net.URL. The //InstaOpsURL does not extend java.net.URL because that class //is a 'final' class (cannot be extended). If you need access //to the real (wrapped) URL object, you can call the following //method on InstaOpsURL: // public java.net.URL getRealURL() //DOCSNIPPET_END URLConnection connection = url.openConnection(); if( connection != null ) { if( connection instanceof HttpsURLConnection ) { httpURLConnection = null; httpsURLConnection = (HttpsURLConnection) connection; httpsURLConnection.setRequestMethod("GET"); httpsURLConnection.setConnectTimeout(timeoutMillis); httpsURLConnection.setReadTimeout(timeoutMillis); } else if( connection instanceof HttpURLConnection ) { httpsURLConnection = null; httpURLConnection = (HttpURLConnection) connection; httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(timeoutMillis); httpURLConnection.setReadTimeout(timeoutMillis); } // one last check to see if someone's tried to cancel us if( ! this.isCancelled() ) { if( httpURLConnection != null ) { httpURLConnection.connect(); } else { httpsURLConnection.connect(); } int responseCode; if( httpURLConnection != null ) { responseCode = httpURLConnection.getResponseCode(); } else { responseCode = httpsURLConnection.getResponseCode(); } if( responseCode == HttpStatus.SC_OK ) { responseIsSuccess = true; if( httpURLConnection != null ) { inputStream = httpURLConnection.getInputStream(); } else { inputStream = httpsURLConnection.getInputStream(); } BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); int bytesAvailable = inputStream.available(); if( bytesAvailable < 16 ) { bytesAvailable = 16; } StringBuilder sb = new StringBuilder(bytesAvailable); String line; while ((line = reader.readLine()) != null) { sb.append(line + '\n'); } responseString = sb.toString(); } else { //Closes the connection. if( connectionTimedOut ) { responseString = "Connection timed out"; } else { if( httpURLConnection != null ) { throw new IOException(httpURLConnection.getResponseMessage()); } else { throw new IOException(httpsURLConnection.getResponseMessage()); } } } } } } catch (IOException e) { if( connectionTimedOut ) { responseString = "Connection timed out"; } else { exception = e; responseString = null; } } finally { if( inputStream != null ) { try { inputStream.close(); } catch (IOException ignored) { } } if( httpURLConnection != null ) { httpURLConnection.disconnect(); } else { httpsURLConnection.disconnect(); } httpURLConnection = null; httpsURLConnection = null; } return responseString; } @Override protected String doInBackground(String... uri) { String uriToCall = uri[0]; // if we still have any connection lingering, try to get rid of it if( (this.httpClient != null) && (httpGet != null) ) { httpGet.abort(); httpGet = null; this.httpClient = null; } if( this.httpURLConnection != null ) { this.httpURLConnection.disconnect(); this.httpURLConnection = null; } String httpResponse = null; if( useHttpURLConnection ) { httpResponse = callUsingHttpURLConnection(uriToCall); } else { httpResponse = callUsingHttpClient(uriToCall,httpClientMethodToUse); } return httpResponse; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if( (listener != null) && ! this.isCancelled() ) { if( responseIsSuccess ) { listener.notifyNetworkResponseSuccess(result); } else { listener.notifyNetworkResponseFailure(exception,result); } } } }