Android Open Source - azure-activedirectory-library-for-android Http Web Request






From Project

Back to project page azure-activedirectory-library-for-android.

License

The source code is released under:

Apache License

If you think the Android project azure-activedirectory-library-for-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

// Copyright  Microsoft Open Technologies, Inc.
///*w  w  w.ja v  a  2s  .co  m*/
// All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
// ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
// PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
//
// See the Apache License, Version 2.0 for the specific language
// governing permissions and limitations under the License.

package com.microsoft.aad.adal;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;

import android.os.Build;

/**
 * Webrequest are called in background thread from API level. HttpWebRequest
 * does not create another thread.
 */
class HttpWebRequest {
    private static final String UNAUTHORIZED_ERROR_MESSAGE_PRE18 = "Received authentication challenge is null";

    private static final String TAG = "HttpWebRequest";

    static final String REQUEST_METHOD_POST = "POST";

    static final String REQUEST_METHOD_GET = "GET";

    static final String REQUEST_METHOD_PUT = "PUT";

    static final String REQUEST_METHOD_DELETE = "DELETE";

    static int CONNECT_TIME_OUT = AuthenticationSettings.INSTANCE.getConnectTimeOut();

    private static int READ_TIME_OUT = AuthenticationSettings.INSTANCE.getReadTimeOut();

    private static int sDebugSimulateDelay = 0;

    private boolean mUseCaches = false;

    private boolean mInstanceRedirectsFollow = true;

    private String mRequestMethod;

    URL mUrl;

    HttpURLConnection mConnection = null;

    byte[] mRequestContent = null;

    private String mRequestContentType = null;

    int mTimeOut = CONNECT_TIME_OUT;

    Exception mException = null;

    HashMap<String, String> mRequestHeaders = null;

    public HttpWebRequest(URL requestURL) {
        mUrl = requestURL;
        mRequestHeaders = new HashMap<String, String>();
        if (mUrl != null) {
            mRequestHeaders.put("Host", getURLAuthority(mUrl));
        }
    }

    public HttpWebRequest(URL requestURL, int timeout) {
        mUrl = requestURL;
        mRequestHeaders = new HashMap<String, String>();
        if (mUrl != null) {
            mRequestHeaders.put("Host", getURLAuthority(mUrl));
        }
        mTimeOut = timeout;
    }

    /**
     * setupConnection before sending the request.
     */
    private void setupConnection() {
        Logger.v(TAG, "HttpWebRequest setupConnection thread:" + android.os.Process.myTid());
        if (mUrl == null) {
            throw new IllegalArgumentException("requestURL");
        }
        if (!mUrl.getProtocol().equalsIgnoreCase("http")
                && !mUrl.getProtocol().equalsIgnoreCase("https")) {
            throw new IllegalArgumentException("requestURL");
        }
        HttpURLConnection.setFollowRedirects(true);
        mConnection = openConnection();
        // To prevent EOF exception.
        if (Build.VERSION.SDK_INT > 13) {
            mConnection.setRequestProperty("Connection", "close");
        }
    }

    /**
     * send the request.
     * 
     * @param contentType
     */
    public HttpWebResponse send() {

        Logger.v(TAG, "HttpWebRequest send thread:" + android.os.Process.myTid());
        setupConnection();
        HttpWebResponse response = new HttpWebResponse();

        if (mConnection != null) {
            try {
                // Apply the request headers
                final Iterator<String> headerKeys = mRequestHeaders.keySet().iterator();

                while (headerKeys.hasNext()) {
                    String header = headerKeys.next();
                    Logger.v(TAG, "Setting header: " + header);
                    mConnection.setRequestProperty(header, mRequestHeaders.get(header));
                }

                // Avoid reuse of existing sockets to avoid random EOF errors
                System.setProperty("http.keepAlive", "false");
                mConnection.setReadTimeout(READ_TIME_OUT);
                mConnection.setInstanceFollowRedirects(mInstanceRedirectsFollow);
                mConnection.setUseCaches(mUseCaches);
                mConnection.setRequestMethod(mRequestMethod);
                mConnection.setDoInput(true); // it will at least read status
                                              // code. Default is true.
                setRequestBody();

                byte[] responseBody = null;
                InputStream responseStream = null;

                try {
                    responseStream = mConnection.getInputStream();
                } catch (IOException ex) {
                    Logger.e(TAG, "IOException:" + ex.getMessage(), "", ADALError.SERVER_ERROR);
                    // If it does not get the error stream, it will return
                    // exception in the httpresponse
                    responseStream = mConnection.getErrorStream();
                    mException = ex;
                }

                // GET request should read status after getInputStream to make
                // this work for different SDKs
                getStatusCode(response);

                if (responseStream != null) {

                    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
                    byte[] buffer = new byte[4096];
                    int bytesRead = -1;

                    // Continue to read from stream if not cancelled and not EOF
                    while ((bytesRead = responseStream.read(buffer)) > 0) {
                        byteStream.write(buffer, 0, bytesRead);
                    }

                    responseBody = byteStream.toByteArray();
                }

                // It will only run in debugger and set from outside for testing
                if (android.os.Debug.isDebuggerConnected() && sDebugSimulateDelay > 0) {
                    // sleep background thread in debugging mode
                    Logger.v(TAG, "Sleeping to simulate slow network response");
                    Thread.sleep(sDebugSimulateDelay);
                }

                Logger.v(TAG, "Response is received");
                response.setBody(responseBody);
                response.setResponseHeaders(mConnection.getHeaderFields());
            } catch (Exception e) {
                Logger.e(TAG, "Exception:" + e.getMessage(), " Method:" + mRequestMethod,
                        ADALError.SERVER_ERROR, e);
                mException = e;
            } finally {
                mConnection.disconnect();
                mConnection = null;
            }
        }

        response.setResponseException(mException);
        return response;
    }

    private void getStatusCode(HttpWebResponse response) throws IOException {
        int statusCode = HttpURLConnection.HTTP_BAD_REQUEST;

        try {
            statusCode = mConnection.getResponseCode();
        } catch (IOException ex) {

            if (Build.VERSION.SDK_INT < 16) {
                // this exception is hardcoded in HttpUrlConnection class inside
                // Android source code for previous SDKs.
                // Status code handling is throwing exceptions if it does not
                // see challenge
                if (ex.getMessage() == UNAUTHORIZED_ERROR_MESSAGE_PRE18) {
                    statusCode = HttpURLConnection.HTTP_UNAUTHORIZED;
                }
            } else {
                // HttpUrlConnection does not understand Bearer challenge
                // Second time query will get the correct status.
                // it will throw, if it is a different status related to
                // connection problem
                statusCode = mConnection.getResponseCode();
            }

            // if status is 200 or 401 after reading again, it can read the
            // response body for messages
            if (statusCode != HttpURLConnection.HTTP_OK
                    && statusCode != HttpURLConnection.HTTP_UNAUTHORIZED) {
                throw ex;
            }
        }
        response.setStatusCode(statusCode);
        Logger.v(TAG, "Status code:" + statusCode);
    }

    /**
     * open connection. If there is any error, set exception inside the response
     * 
     * @param _response
     * @return
     */
    private HttpURLConnection openConnection() {
        HttpURLConnection connection = null;
        try {

            connection = (HttpURLConnection)mUrl.openConnection();
            connection.setConnectTimeout(mTimeOut);

        } catch (IOException e) {
            mException = e;
        }
        return connection;
    }

    private void setRequestBody() throws IOException {
        if (null != mRequestContent) {
            mConnection.setDoOutput(true);

            if (null != getRequestContentType() && !getRequestContentType().isEmpty()) {
                mConnection.setRequestProperty("Content-Type", getRequestContentType());
            }

            mConnection.setRequestProperty("Content-Length",
                    Integer.toString(mRequestContent.length));
            mConnection.setFixedLengthStreamingMode(mRequestContent.length);

            OutputStream out = mConnection.getOutputStream();
            out.write(mRequestContent);
            out.close();
        }
    }

    private static String getURLAuthority(URL requestURL) {
        // We assume that the parameter has already passed the tests in
        // validateRequestURI
        String authority = requestURL.getAuthority();

        if (requestURL.getPort() == -1) {
            // No port in the URI so append a default using the
            // scheme specified in the URI; only http and https are
            // supported
            if (requestURL.getProtocol().equalsIgnoreCase("http")) {
                authority = authority + ":80";
            } else if (requestURL.getProtocol().equalsIgnoreCase("https")) {
                authority = authority + ":443";
            }
        }

        return authority;
    }

    /**
     * The requests target URL.
     */
    URL getURL() {
        return mUrl;
    }

    /**
     * The request headers.
     */
    public HashMap<String, String> getRequestHeaders() {
        return mRequestHeaders;
    }

    void setRequestMethod(String requestMethod) {
        this.mRequestMethod = requestMethod;
    }

    String getRequestContentType() {
        return mRequestContentType;
    }

    void setRequestContentType(String requestContentType) {
        this.mRequestContentType = requestContentType;
    }

    void setRequestContent(byte[] data) {
        this.mRequestContent = data;
    }
}




Java Source Code List

com.microsoft.aad.adal.ADALError.java
com.microsoft.aad.adal.AuthenticationActivity.java
com.microsoft.aad.adal.AuthenticationCallback.java
com.microsoft.aad.adal.AuthenticationCancelError.java
com.microsoft.aad.adal.AuthenticationConstants.java
com.microsoft.aad.adal.AuthenticationContext.java
com.microsoft.aad.adal.AuthenticationDialog.java
com.microsoft.aad.adal.AuthenticationException.java
com.microsoft.aad.adal.AuthenticationParameters.java
com.microsoft.aad.adal.AuthenticationRequestState.java
com.microsoft.aad.adal.AuthenticationRequest.java
com.microsoft.aad.adal.AuthenticationResult.java
com.microsoft.aad.adal.AuthenticationSettings.java
com.microsoft.aad.adal.BasicWebViewClient.java
com.microsoft.aad.adal.BrokerProxy.java
com.microsoft.aad.adal.CacheKey.java
com.microsoft.aad.adal.ChallangeResponseBuilder.java
com.microsoft.aad.adal.ClientMetrics.java
com.microsoft.aad.adal.DefaultTokenCacheStore.java
com.microsoft.aad.adal.Discovery.java
com.microsoft.aad.adal.ExceptionExtensions.java
com.microsoft.aad.adal.FileTokenCacheStore.java
com.microsoft.aad.adal.HashMapExtensions.java
com.microsoft.aad.adal.HttpWebRequest.java
com.microsoft.aad.adal.HttpWebResponse.java
com.microsoft.aad.adal.IBrokerProxy.java
com.microsoft.aad.adal.IConnectionService.java
com.microsoft.aad.adal.IDeviceCertificate.java
com.microsoft.aad.adal.IDiscovery.java
com.microsoft.aad.adal.IJWSBuilder.java
com.microsoft.aad.adal.ITokenCacheStore.java
com.microsoft.aad.adal.ITokenStoreQuery.java
com.microsoft.aad.adal.IWebRequestHandler.java
com.microsoft.aad.adal.IWindowComponent.java
com.microsoft.aad.adal.IdToken.java
com.microsoft.aad.adal.JWSBuilder.java
com.microsoft.aad.adal.Logger.java
com.microsoft.aad.adal.MemoryTokenCacheStore.java
com.microsoft.aad.adal.Oauth2.java
com.microsoft.aad.adal.PRNGFixes.java
com.microsoft.aad.adal.PackageHelper.java
com.microsoft.aad.adal.PromptBehavior.java
com.microsoft.aad.adal.StorageHelper.java
com.microsoft.aad.adal.StringExtensions.java
com.microsoft.aad.adal.TokenCacheItem.java
com.microsoft.aad.adal.UrlExtensions.java
com.microsoft.aad.adal.UserInfo.java
com.microsoft.aad.adal.WebRequestHandler.java
com.microsoft.aad.adal.WebviewHelper.java
com.microsoft.aad.adal.hello.Constants.java
com.microsoft.aad.adal.hello.FragmentHolderActivity.java
com.microsoft.aad.adal.hello.LoginFragment.java
com.microsoft.aad.adal.hello.MainActivity.java
com.microsoft.aad.adal.hello.Utils.java
com.microsoft.aad.adal.package-info.java