package com.insta4j.instagram.http; import com.insta4j.instagram.Client; import com.insta4j.instagram.InstaProp; import com.insta4j.instagram.exception.InstagramException; import com.insta4j.instagram.util.Constants; import com.insta4j.instagram.util.InstagramUtil; import com.insta4j.instagram.util.JSONToObjectTransformer; import org.apache.http.Consts; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.auth.AuthScope; import org.apache.http.auth.Credentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; /** * APICaller will make http requests, obtain that response and return it without processing. Basically, the raw response is returned by every method. * * @author nischal.shetty */ public class APICaller implements APICallerInterface { private static final APICaller caller = new APICaller(); private static HttpClient httpClient = null; private Client instagramClient = null; private static final Logger logger = Logger.getLogger(APICaller.class.getName()); private APICaller() { } private synchronized static HttpClient getHttpClient() throws InstagramException { if (null == httpClient) { PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(); connectionManager.setMaxTotal(50); connectionManager.setDefaultMaxPerRoute(20); httpClient = new DefaultHttpClient(connectionManager); String username = null; String password = null; String host = null; int port = -1; Credentials credentials = null; //Check if username and password exists in any resource file try { InputStream inputStream = ClassLoader.getSystemResourceAsStream("insta4j.properties"); if (inputStream != null) { Properties properties = new Properties(); properties.load(inputStream); inputStream.close(); username = properties.getProperty("client.proxy.username"); password = properties.getProperty("client.proxy.password"); host = properties.getProperty("client.proxy.host"); if (properties.getProperty("client.proxy.port") != null) { port = Integer.parseInt(properties.getProperty("client.proxy.port")); } } } catch (FileNotFoundException e) { throw new InstagramException(-1, e.getMessage(), "Undefined", e); } catch (IOException e) { throw new InstagramException(-1, e.getMessage(), "Undefined", e); } if (username != null || password != null) { credentials = new UsernamePasswordCredentials(username, password); ((DefaultHttpClient) httpClient).getCredentialsProvider() .setCredentials(AuthScope.ANY, credentials); } if (username != null || password != null || host != null || port > -1) { try { ((DefaultHttpClient) httpClient).getCredentialsProvider() .setCredentials(new AuthScope(host, port), credentials); } finally { } } } return httpClient; } /*public static void main(String[] args) { InputStream inputStream = ClassLoader.getSystemResourceAsStream("face4j.properties"); try { Properties properties = new Properties(); properties.load(inputStream); inputStream.close(); Enumeration enuKeys = properties.keys(); while (enuKeys.hasMoreElements()) { String key = (String) enuKeys.nextElement(); String value = properties.getProperty(key); System.out.println(key + " : " + value); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }*/ public static APICaller getInstance() { return caller; } public Map<String, Object> getData(String url, NameValuePair[] nameValuePairs) throws InstagramException { HttpClient client = APICaller.getHttpClient(); String response = null; String signature = getEndpoint(url); String clientSecret = null; if (instagramClient != null){ clientSecret = instagramClient.getClientSecret(); } //This part is when the nameValuePairs is null indicating the params are most probably in the url String urlSplit[] = null; HttpParams httpParams = null; if (nameValuePairs != null) { //Sort the name value pairs based on the name Arrays.sort(nameValuePairs, new Comparator<NameValuePair>() { @Override public int compare(NameValuePair o1, NameValuePair o2) { return o1.getName().compareTo(o2.getName()); } }); //Adding the name value pairs to the signature for (NameValuePair pair : nameValuePairs) { signature = signature + "|" + pair.getName() + "=" + pair.getValue(); } signature = InstagramUtil.createSHAKey(signature,clientSecret); boolean isFirst = true; for (NameValuePair pair : nameValuePairs) { if (isFirst) { url += "?"; isFirst = false; } else { url += "&"; } try { url += pair.getName() + "=" + URLEncoder.encode(pair.getValue(), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } url = url + "&sig=" + signature; HttpGet getMethod = new HttpGet(url); int retry = Constants.NETWORK_FAILURE_RETRY_COUNT; String strRetryCount = InstaProp.get(Constants.KEY_NETWORK_FAILURE_RETRY_COUNT); if (strRetryCount != null) { retry = Integer.parseInt(strRetryCount); } int statusCode = -1; while (retry > 0) { try { HttpResponse httpResponse = client.execute(getMethod); statusCode = httpResponse.getStatusLine().getStatusCode(); response = EntityUtils.toString(httpResponse.getEntity()); break; } catch (IOException ex) { retry--; if (retry <= 0) { throw new InstagramException(-1, ex.getMessage(), "Undefined", ex); } } } if (statusCode != HttpStatus.SC_OK) { logger.log(Level.SEVERE, "Response is " + response + " and status code is" + statusCode); throw new InstagramException(JSONToObjectTransformer.getError(response, statusCode)); } ObjectMapper mapper = new ObjectMapper(); Map<String, Object> responseMap = null; try { responseMap = mapper.readValue(response, Map.class); } catch (JsonParseException e) { throw new InstagramException(-1, e.getMessage(), "Undefined", e); } catch (JsonMappingException e) { throw new InstagramException(-1, e.getMessage(), "Undefined", e); } catch (IOException e) { throw new InstagramException(-1, e.getMessage(), "Undefined", e); } return responseMap; } public String postData(String url, NameValuePair[] nameValuePairs) throws InstagramException { List<NameValuePair> nameValuePairsList = new ArrayList<NameValuePair>(); HttpClient client = APICaller.getHttpClient(); String response = null; //client secret from instagramClient object String clientSecret = null; if (instagramClient != null){ clientSecret = instagramClient.getClientSecret(); } HttpPost postMethod = null; postMethod = new HttpPost(url); int statusCode = -1; int retry = Constants.NETWORK_FAILURE_RETRY_COUNT; String strRetryCount = InstaProp.get(Constants.KEY_NETWORK_FAILURE_RETRY_COUNT); if (strRetryCount != null) { retry = Integer.parseInt(strRetryCount); } //If Ipaddress is there we are signing request String ipAddress = null; if (nameValuePairs != null) { for (NameValuePair pair : nameValuePairs) { if (pair.getName().equals(Constants.PARAM_IPADDRESS)) { ipAddress = pair.getValue(); } } if (ipAddress != null) { String digest = InstagramUtil.createSHAKey(ipAddress, clientSecret); postMethod.setHeader("X-Insta-Forwarded-For", ipAddress + "|" + digest); } } Arrays.sort(nameValuePairs, new Comparator<NameValuePair>() { @Override public int compare(NameValuePair o1, NameValuePair o2) { return o1.getName().compareTo(o2.getName()); } }); String signature = getEndpoint(url); while (retry > 0) { try { if (nameValuePairs != null) { //HttpParams httpParams = new BasicHttpParams(); for (NameValuePair pair : nameValuePairs) { nameValuePairsList.add(new BasicNameValuePair(pair.getName(), pair.getValue())); signature = signature + "|" + pair.getName() + "=" + pair.getValue(); } signature = InstagramUtil.createSHAKey(signature, clientSecret); nameValuePairsList.add(new BasicNameValuePair("sig", signature)); UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(nameValuePairsList, Consts.UTF_8); postMethod.setEntity(encodedFormEntity); } HttpResponse httpResponse = client.execute(postMethod); statusCode = httpResponse.getStatusLine().getStatusCode(); response = EntityUtils.toString(httpResponse.getEntity()); break; } catch (IOException ex) { retry--; if (retry <= 0) { throw new InstagramException(-1, ex.getMessage(), "Undefined", ex); } } } if (statusCode != HttpStatus.SC_OK) { throw new InstagramException(JSONToObjectTransformer.getError(response, statusCode)); } return response; } public String deleteData(String url, NameValuePair[] nameValuePairs) throws InstagramException { HttpClient client = APICaller.getHttpClient(); String response = null; HttpDelete deleteMethod = null; try { deleteMethod = new HttpDelete(url); if (nameValuePairs != null) { HttpParams httpParams = new BasicHttpParams(); for (NameValuePair pair : nameValuePairs) { httpParams.setParameter(pair.getName(), pair.getValue()); } deleteMethod.setParams(httpParams); } HttpResponse httpResponse = client.execute(deleteMethod); int statusCode = httpResponse.getStatusLine().getStatusCode(); response = EntityUtils.toString(httpResponse.getEntity()); if (statusCode != HttpStatus.SC_OK) { throw new InstagramException(JSONToObjectTransformer.getError(response, statusCode)); } } catch (IOException e) { throw new InstagramException(-1, e.getMessage(), "Undefined", e); } return response; } private NameValuePair[] getNameValuePairs(String urlParams) { String[] params = urlParams.split("&"); NameValuePair[] nameValuePair = new NameValuePair[params.length]; NameValuePair valuePair = null; String[] tempParamPair = null; for (int i = 0; i < params.length; i++) { tempParamPair = params[i].split("="); valuePair = new BasicNameValuePair(tempParamPair[0], tempParamPair[1]); nameValuePair[i] = valuePair; } return nameValuePair; } private HttpParams getHttpParams(String urlParams) { String[] params = urlParams.split("&"); HttpParams httpParams = new BasicHttpParams(); String[] tempParamPair = null; for (int i = 0; i < params.length; i++) { tempParamPair = params[i].split("="); httpParams.setParameter(tempParamPair[0], tempParamPair[1]); } return httpParams; } public String getEndpoint(String url) { return url.split("api.instagram.com/")[1].replaceFirst("v1/", "/"); } public void setClient(Client client){ this.instagramClient = new Client (client.getClientId(), client.getClientSecret()); } }