All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.citrix.sharefile.api.https.SFHttpsCaller Maven / Gradle / Ivy

package com.citrix.sharefile.api.https;


import com.citrix.sharefile.api.SFConnectionManager;
import com.citrix.sharefile.api.authentication.SFOAuth2Token;
import com.citrix.sharefile.api.constants.SFKeywords;
import com.citrix.sharefile.api.enumerations.SFHttpMethod;
import com.citrix.sharefile.api.SFProvider;
import com.citrix.sharefile.api.exceptions.SFFormsAuthenticationCookies;
import com.citrix.sharefile.api.utils.Utils;
import com.citrix.sharefile.api.log.Logger;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.NameValuePair;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;

public class SFHttpsCaller 
{
	private static final String TAG = SFKeywords.TAG + "-SFHttpCaller";
	
	private static final String NO_AUTH_CHALLENGES = "No authentication challenges found";
	private static final String OUT_OF_MEMORY = "memory";
	private static final String ROOT_PARAM = "root";
	private static final String REDIRECT_URL_PARAM = "redirect_url";
	
	//private static CookieManager m_cookieManager = null;
		
	public static void setBasicAuth(URLConnection conn,String username,String password)
	{			
		String combinepass = username +SFKeywords.COLON + password;
		String basicAuth = "Basic " + new String(Base64.encodeBase64(combinepass.getBytes()));
		conn.setRequestProperty("Authorization", basicAuth);
	}
	
	public static void postBody(URLConnection conn, String body) throws IOException
	{		
		OutputStream os = conn.getOutputStream();
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, SFKeywords.UTF_8));
		writer.write(body);
		writer.flush();
		writer.close();
		os.close();
	}

	/**     
     grant_type=authorization_code&code=CvJ4LMgMDHuZGLXgJgJdDYR17Hd3b5&client_id=xyz&client_secret=abc
	 */
	public static String getBodyForWebLogin(List params) throws UnsupportedEncodingException
	{
	    StringBuilder result = new StringBuilder();
	    boolean first = true;

	    for (NameValuePair pair : params)
	    {
	        if (first)
	        {
	            first = false;
	        }
	        else
	        {
	            result.append(SFKeywords.CHAR_AMPERSAND); 
	        }

	        result.append(pair.getName());
	        result.append(SFKeywords.EQUALS);
	        result.append(pair.getValue());
	    }

	    return result.toString();
	}
	
	public static void setAcceptLanguage(URLConnection conn)
	{
		conn.setRequestProperty(SFKeywords.ACCEPT_LANGUAGE, Utils.getAcceptLanguageString());
	}
	
	private static void setRequestMethod(URLConnection conn, String method) throws ProtocolException
	{
		if(conn instanceof HttpsURLConnection)
		{
			((HttpsURLConnection) conn).setRequestMethod(method);
		}
		else if(conn instanceof HttpURLConnection)
		{
			((HttpURLConnection) conn).setRequestMethod(method);
		} 
	}
	
	public static void setPostMethod(URLConnection conn) throws ProtocolException
	{
		setRequestMethod(conn,SFHttpMethod.POST.toString());
		conn.setDoInput(true);
		conn.setDoOutput(true);
	}
	
	/**
	 * PATCH is not recognized by android. Use POST as surrogate
	 */
	private static final boolean overridePatchMethod(URLConnection conn,String methodName)
	{	
		boolean ret = false;
		
		if(methodName.equalsIgnoreCase(SFHttpMethod.PATCH.toString()))
		{			
			conn.setRequestProperty(SFKeywords.HTTP_METHOD_OVERRIDE, SFHttpMethod.PATCH.toString());
			
			ret = true;
		}
		
		return ret;
	}
	
	/**
	 * DELETE does not support setOutputTrue on Android. Use POST as surrogate instead on all systems.
	 */
	private static final boolean overrideDeleteMethod(URLConnection conn,String methodName, String optionalBody)
	{
		boolean ret = false;

		//Only use POST surrogates for DELETE which have non-empty BODY
		if(methodName.equalsIgnoreCase(SFHttpMethod.DELETE.toString()) && !Utils.isEmpty(optionalBody))
		{
			conn.setRequestProperty(SFKeywords.HTTP_METHOD_OVERRIDE, SFHttpMethod.DELETE.toString());

			ret = true;
		}

		return ret;
	}

	public static void setMethod(URLConnection conn,String methodName, String optionalBody) throws ProtocolException
	{		
		if(overridePatchMethod(conn, methodName))
		{
			methodName = SFHttpMethod.POST.toString();
		}

		if(overrideDeleteMethod(conn, methodName,optionalBody))
		{
			methodName = SFHttpMethod.POST.toString();
		}

		setRequestMethod(conn, methodName);
				 
		if(methodName.equalsIgnoreCase(SFHttpMethod.GET.toString()) ||
		   methodName.equalsIgnoreCase(SFHttpMethod.DELETE.toString()))
		{
			return;
		}
		
		conn.setDoInput(true);
		conn.setDoOutput(true); //POST, PUT, DELETE
	}
	
	public static int catchIfAuthException(IOException e) throws IOException
	{
		String errMessage = e.getLocalizedMessage();
		
		if(errMessage!=null)
		{
			if(errMessage.contains(NO_AUTH_CHALLENGES))
			{
				return HttpsURLConnection.HTTP_UNAUTHORIZED;
			}	
			else
			{
				throw e;
			}
		}
		else
		{
			throw e;
		}
		
		//return 0;
	}
	
	public static int catchIfOutOfMemoryException(Exception e,int origcode) 
	{
		String errMessage = e.getLocalizedMessage();
		
		if(errMessage!=null)
		{
			if(errMessage.contains(OUT_OF_MEMORY))
			{				
				Logger.d(TAG, "Gracefull catching out of memmory");
				return 500;
			}				
		}		
		
		return origcode;
	}
	
	/**
	 * The http functions sometimes respond with 401 error or sometimes throw and exception
	 * 

depending on what the server returns. So we need a generic way to get the error code. * @throws IOException * */ public static int safeGetResponseCode(URLConnection conn) throws IOException { int httpErrorCode; try { if(conn instanceof HttpsURLConnection) { httpErrorCode = ((HttpsURLConnection) conn).getResponseCode(); } else { httpErrorCode = ((HttpURLConnection) conn).getResponseCode(); } } catch (IOException e) //on wrong creds this throws exeption { httpErrorCode = catchIfAuthException(e); } Logger.d(TAG,"ERR_CODE: " + httpErrorCode); return httpErrorCode; } public static void getAndStoreCookies(URLConnection conn, URL url,SFCookieManager cookieManager) throws IOException { if(cookieManager!=null) { cookieManager.readCookiesFromConnection(conn); } } public static SFFormsAuthenticationCookies getFormsAuthResponseCookies(URL url, URLConnection connection, SFCookieManager cookieManager) throws IOException { if(cookieManager != null) { SFFormsAuthenticationCookies sfFormsAuthenticationCookies = cookieManager.readFormsAuthCookies(connection); if(sfFormsAuthenticationCookies != null) { String rootParam = getRootQueryParamter(url); //Adding the root parameter to the login and the token url String tokenURL = getTokenURL(sfFormsAuthenticationCookies.getToken(), rootParam); String loginURL = getLoginURL(sfFormsAuthenticationCookies.getLoginURL(), tokenURL, rootParam); sfFormsAuthenticationCookies.setLoginURL(loginURL); sfFormsAuthenticationCookies.setToken(tokenURL); return sfFormsAuthenticationCookies; } } return null; } private static String getTokenURL(String token, String root) { try { return addQueryParams(token, ROOT_PARAM, root); } catch (URISyntaxException ex) { Logger.e(TAG, "error: ", ex); return null; } } private static String getLoginURL(String login, String token, String root) { try { String loginURL = addQueryParams(login, ROOT_PARAM, root); return addQueryParams(loginURL, REDIRECT_URL_PARAM, token); } catch (URISyntaxException ex) { Logger.e(TAG, "error: ", ex); return null; } } private static String addQueryParams(String url, String name, String value) throws URISyntaxException { URI oldUri = new URI(url); String appendQuery = name + "=" + value; String newQuery = oldUri.getQuery(); if (newQuery == null) { newQuery = appendQuery; } else { newQuery += "&" + appendQuery; } URI newUri = new URI(oldUri.getScheme(), oldUri.getAuthority(), oldUri.getPath(), newQuery, oldUri.getFragment()); return newUri.toString(); } private static String getRootQueryParamter(URL url) { String[] pairs = url.toString().split("&"); //Root is the first query parameter int idx = pairs[0].indexOf("="); return URLDecoder.decode(pairs[0].substring(idx + 1)); } public static String readResponse(URLConnection conn) throws IOException { StringBuilder sb = new StringBuilder(); InputStream is = SFConnectionManager.getInputStream(conn); BufferedReader urlstream = new BufferedReader(new InputStreamReader(is)); String inputLine; try { while ((inputLine = urlstream.readLine()) != null) { sb.append(inputLine); } } catch (OutOfMemoryError e) { Logger.d(TAG, "Error: " , e); throw new IOException("Out of memory"); } urlstream.close(); String response = sb.toString(); Logger.d(TAG, "SUCCESS RESPONSE size: " + response.length()); return response; } public static String readErrorResponse(URLConnection conn) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader urlstream; //type cast correctly. if(conn instanceof HttpsURLConnection) { urlstream = new BufferedReader(new InputStreamReader(((HttpsURLConnection) conn).getErrorStream())); } else if(conn instanceof HttpURLConnection) { urlstream = new BufferedReader(new InputStreamReader(((HttpURLConnection) conn).getErrorStream())); } else { return ""; } String inputLine; while ((inputLine = urlstream.readLine()) != null) { sb.append(inputLine); } Logger.d(TAG, "ERROR RESPONSE SIZE: " + sb.length()); urlstream.close(); return sb.toString(); } public static void disconnect(URLConnection conn) { if(conn!=null) { if(conn instanceof HttpsURLConnection) { ((HttpsURLConnection) conn).disconnect(); } else if(conn instanceof HttpURLConnection) { ((HttpURLConnection) conn).disconnect(); } } } public static void addBearerAuthorizationHeader(URLConnection connection,SFOAuth2Token token) { connection.addRequestProperty("Authorization",String.format("Bearer %s", token.getAccessToken())); } /** We need a separate auth manager here to handle the setting of correct auth header based on the provider type and well as the user. * @throws IOException */ public static void addAuthenticationHeader(URLConnection connection,SFOAuth2Token token,String userName,String password, SFCookieManager cookieManager) throws IOException { if(cookieManager!=null) { cookieManager.setCookies(connection); } switch(SFProvider.getProviderType(connection.getURL())) { case SFProvider.PROVIDER_TYPE_SF: SFHttpsCaller.addBearerAuthorizationHeader(connection, token); break; default: if(userName!=null && password!=null) { setBasicAuth(connection, userName, password); } break; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy