sit.web.client.HttpHelper.java Source code

Java tutorial

Introduction

Here is the source code for sit.web.client.HttpHelper.java

Source

/*
 * Copyright 2013 Simon Thiel
 *
 * This file is part of SitJar.
 *
 * SitJar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * SitJar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with SitJar. If not, see <http://www.gnu.org/licenses/lgpl.txt>.
 */
package sit.web.client;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.HttpsURLConnection;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
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.client.methods.HttpPut;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import sit.sstl.ByteBuilder;
import sit.tools.Base64;
import sit.web.HttpConstants;
import sit.web.MimeTypes;
import sit.web.multipart.MultipartContainer;

public class HttpHelper {

    private final static boolean USE_APACHE = true;

    private static final int BUFFER_SIZE = 1024 * 512;

    public static String getBase64UserNamePwdToken(String username, String password) {
        return Base64.encodeBytes((username + ":" + password).getBytes());
    }

    public static String encodeString(String myString) {
        if (myString == null) {
            throw new NullPointerException("encodeString: myString == null!");
        }
        try {
            return java.net.URLEncoder.encode(myString, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            throw new AssertionError("UTF-8 not supported");
        }
    }

    public static String decodeString(String myString) {
        if (myString == null) {
            throw new NullPointerException("decodeString: myString == null!");
        }
        try {
            return java.net.URLDecoder.decode(myString, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            throw new AssertionError("UTF-8 not supported");
        }
    }

    public static URI getURI(String host, int port, String path, boolean isHTTPS)
            throws MalformedURLException, URISyntaxException {

        String myUrl = isHTTPS ? "https" : "http";
        myUrl += "://" + host + ":" + port + path;

        return new URI(myUrl);
    }

    public static URL getURL(String host, int port, String path, boolean isHTTPS) throws MalformedURLException {

        String myUrl = isHTTPS ? "https" : "http";
        myUrl += "://" + host + ":" + port + path;

        return new URL(myUrl);
    }

    public HttpHelper() {
        HTTPTrustHelper.initAllTrustingManager("TLS"); //or "SSL"
    }

    public HttpHelper(String sslContext) {
        HTTPTrustHelper.initAllTrustingManager(sslContext);
    }

    public HTTPResponse postMultiPartContainer(String host, int port, String path, MultipartContainer mpc,
            boolean isHTTPS, String unamePword64) throws MalformedURLException, IOException, ProtocolException {

        if (mpc == null) { //make sure multipartContainer is initialized
            return null;
        }

        String contentType = mpc.getContentType();
        ByteBuilder bb = new ByteBuilder();
        OutputStream os = bb.getOutputStream();
        mpc.write(os);
        os.close();

        Logger.getLogger(HttpHelper.class.getName()).log(Level.INFO,
                "mpc length " + mpc.getContentLength() + " bb.size():" + bb.size());

        byte[] payload = bb.toByteArray();
        try {
            return doHTTPRequest(HttpConstants.HTTP_COMMAND_POST, host, port, path, payload, contentType, isHTTPS,
                    unamePword64);
        } catch (URISyntaxException ex) {
            Logger.getLogger(HttpHelper.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    /**
     *
     * convenient call, sets charSet automatically to
     * <code>Charset.defaultCharset()</code>
     *
     * @param method
     * @param host
     * @param port
     * @param path
     * @param payload
     * @param mimeType mimetype as string e.g. "application/json" will be added
     * to the content type of the http call
     * @param isHTTPS
     * @param unamePword64
     * @return
     * @throws MalformedURLException
     * @throws ProtocolException
     * @throws IOException
     */
    public HTTPResponse doHTTPRequest(String method, String host, int port, String path, String payload,
            String mimeType, boolean isHTTPS, String unamePword64)
            throws MalformedURLException, ProtocolException, IOException {

        return doHTTPRequest(method, host, port, path, payload, mimeType, Charset.defaultCharset(), isHTTPS,
                unamePword64);
    }

    /**
     *
     *
     * @param method
     * @param host
     * @param port
     * @param path
     * @param payload
     * @param mimeType mimetype as string e.g. "application/json" will be added
     * to the content type of the http call
     * @param charSet set charSet to null to omit sending a char flag (e.g. for
     * binary files)
     * @param isHTTPS
     * @param unamePword64
     * @return
     * @throws MalformedURLException
     * @throws ProtocolException
     * @throws IOException
     */
    public HTTPResponse doHTTPRequest(String method, String host, int port, String path, String payload,
            String mimeType, Charset charSet, boolean isHTTPS, String unamePword64)
            throws MalformedURLException, ProtocolException, IOException {

        if (mimeType == null || mimeType.length() == 0) {
            mimeType = MimeTypes.getMimeType(""); //get unknown mime type if mimetype not set
        }
        String contentType = mimeType;
        if (charSet != null) {
            contentType += HttpConstants.SUB_FIELD_SEPARATOR + HttpConstants.CHARSET_CONTENT_TYPE_TAG
                    + charSet.name(); //text/html; charset=utf-8
            //##CHARSET_MARKER##            
        } else {
            charSet = Charset.defaultCharset();
        }

        try {
            return doHTTPRequest(method, host, port, path, payload.getBytes(charSet), contentType, isHTTPS,
                    unamePword64);
        } catch (URISyntaxException ex) {

            throw new MalformedURLException(ex.getMessage());
        }

    }

    /**
     *
     *
     * @param method
     * @param host
     * @param port
     * @param path
     * @param payload
     * @param contentType content type e.g. "application/json"
     * @param isHTTPS
     * @param unamePword64
     * @return
     * @throws MalformedURLException
     * @throws ProtocolException
     * @throws IOException
     */
    public HTTPResponse doHTTPRequest(String method, String host, int port, String path, byte[] payload,
            String contentType, boolean isHTTPS, String unamePword64)
            throws MalformedURLException, ProtocolException, IOException, URISyntaxException {

        if (USE_APACHE) {
            return doApacheHTTPRequest(method, host, port, path, payload, contentType, isHTTPS, unamePword64);
        } //else

        return doHttpURLConnectionRequest(method, host, port, path, payload, contentType, isHTTPS, unamePword64);
    }

    /**
     *
     *
     * @param method
     * @param host
     * @param port
     * @param path
     * @param payload
     * @param contentType content type e.g. "application/json"
     * @param isHTTPS
     * @param unamePword64
     * @return
     * @throws MalformedURLException
     * @throws ProtocolException
     * @throws IOException
     * @throws URISyntaxException
     */
    public HTTPResponse doApacheHTTPRequest(String method, String host, int port, String path, byte[] payload,
            String contentType, boolean isHTTPS, String unamePword64)
            throws MalformedURLException, ProtocolException, IOException, URISyntaxException {

        if (payload == null) { //make sure payload is initialized
            payload = new byte[0];
        }

        URI url = getURI(host, port, path, isHTTPS);

        HttpClient httpclient;
        if (isHTTPS) {
            httpclient = HTTPTrustHelper.getNewHttpClient(Charset.defaultCharset(), port);
        } else {
            httpclient = new DefaultHttpClient();
        }

        HTTPResponse result = null;
        HttpResponse response = null;

        if (method.equalsIgnoreCase(HttpConstants.HTTP_COMMAND_GET)) {
            HttpGet request = new HttpGet(url);
            request.setHeader("Authorization", "Basic " + unamePword64);
            response = httpclient.execute(request);
        } else if (method.equalsIgnoreCase(HttpConstants.HTTP_COMMAND_POST)) {
            HttpPost request = new HttpPost(url);
            request.setHeader("Authorization", "Basic " + unamePword64);
            InputStreamEntity reqEntity = new InputStreamEntity(new ByteArrayInputStream(payload), payload.length);
            request.setEntity(reqEntity);
            reqEntity.setContentType(contentType);
            response = httpclient.execute(request);
        } else if (method.equalsIgnoreCase(HttpConstants.HTTP_COMMAND_PUT)) {
            HttpPut request = new HttpPut(url);
            request.setHeader("Authorization", "Basic " + unamePword64);
            InputStreamEntity reqEntity = new InputStreamEntity(new ByteArrayInputStream(payload), payload.length);
            request.setEntity(reqEntity);
            reqEntity.setContentType(contentType);
            response = httpclient.execute(request);
        } else if (method.equalsIgnoreCase(HttpConstants.HTTP_COMMAND_DELETE)) {
            HttpDelete request = new HttpDelete(url);
            request.setHeader("Authorization", "Basic " + unamePword64);
            response = httpclient.execute(request);
        } else {
            throw new RuntimeException("HTTP method not supported! Method:" + method);
        }

        result = new HTTPResponse(path, payload, Charset.defaultCharset());
        HttpEntity responseEntity = response.getEntity();
        if (responseEntity != null) {
            result.reply = EntityUtils.toString(responseEntity);
        }
        result.code = response.getStatusLine().getStatusCode();
        result.message = response.getStatusLine().getReasonPhrase();

        httpclient.getConnectionManager().shutdown();
        return result;
    }

    private static boolean isHTTPS(String downloadUrl) {
        return downloadUrl.startsWith("https");
    }

    public static void apacheDownload(String downloadUrl, File targetFile) throws IOException {

        URL url = new URL(downloadUrl);

        HttpClient httpclient;
        if (isHTTPS(downloadUrl)) {
            httpclient = HTTPTrustHelper.getNewHttpClient(Charset.defaultCharset(),
                    (url.getPort() != -1) ? url.getPort() : url.getDefaultPort());
        } else {
            httpclient = new DefaultHttpClient();
        }

        HttpGet request = new HttpGet(downloadUrl);
        HttpResponse response = httpclient.execute(request);

        InputStream is = response.getEntity().getContent();
        FileOutputStream writer = new FileOutputStream(targetFile);

        try {
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead = 0;
            while ((bytesRead = is.read(buffer, 0, buffer.length)) >= 0) {
                writer.write(buffer, 0, bytesRead);
            }
        } finally {
            writer.close();
            is.close();
            httpclient.getConnectionManager().shutdown();
        }
    }

    /**
     *
     *
     * @param method
     * @param host
     * @param port
     * @param path
     * @param payload
     * @param contentType content type e.g. "application/json"
     * @param isHTTPS
     * @param unamePword64
     * @return
     * @throws MalformedURLException
     * @throws ProtocolException
     * @throws IOException
     * @throws URISyntaxException
     */
    public HTTPResponse doHttpURLConnectionRequest(String method, String host, int port, String path,
            byte[] payload, String contentType, boolean isHTTPS, String unamePword64)
            throws MalformedURLException, ProtocolException, IOException, URISyntaxException {

        URL url = getURL(host, port, path, isHTTPS);

        return doHttpUrlConnectionRequest(url, method, contentType, payload, unamePword64);
    }

    public HTTPResponse doHttpUrlConnectionRequest(URL url, String method, String contentType, byte[] payload,
            String unamePword64) throws MalformedURLException, ProtocolException, IOException, URISyntaxException {

        if (payload == null) { //make sure payload is initialized
            payload = new byte[0];
        }

        boolean isHTTPS = url.getProtocol().equalsIgnoreCase("https");
        HttpURLConnection connection;

        if (isHTTPS) {
            connection = (HttpsURLConnection) url.openConnection();
        } else {
            connection = (HttpURLConnection) url.openConnection();
        }

        connection.setRequestMethod(method);
        connection.setRequestProperty("Host", url.getHost());
        connection.setRequestProperty("Content-Type", contentType);
        connection.setRequestProperty("Content-Length", String.valueOf(payload.length));

        if (isHTTPS) {
            connection.setRequestProperty("Authorization", "Basic " + unamePword64);
        }

        Logger.getLogger(HttpHelper.class.getName()).log(Level.FINER,
                "trying to connect:\n" + method + " " + url + "\nhttps:" + isHTTPS + "\nContentType:" + contentType
                        + "\nContent-Length:" + String.valueOf(payload.length));

        connection.setDoInput(true);
        if (payload.length > 0) {
            // open up the output stream of the connection
            connection.setDoOutput(true);
            FilterOutputStream output = new FilterOutputStream(connection.getOutputStream());

            // write out the data
            output.write(payload);
            output.close();
        }

        HTTPResponse response = new HTTPResponse(method + " " + url.toString(), payload, Charset.defaultCharset()); //TODO forward charset ot this method

        response.code = connection.getResponseCode();
        response.message = connection.getResponseMessage();

        Logger.getLogger(HttpHelper.class.getName()).log(Level.FINE,
                "received response: " + response.message + " with code: " + response.code);

        if (response.code != 500) {
            byte[] buffer = new byte[20480];

            ByteBuilder bytes = new ByteBuilder();

            // get ready to read the response from the cgi script
            DataInputStream input = new DataInputStream(connection.getInputStream());
            boolean done = false;
            while (!done) {
                int readBytes = input.read(buffer);
                done = (readBytes == -1);

                if (!done) {
                    bytes.append(buffer, readBytes);
                }
            }
            input.close();
            response.reply = bytes.toString(Charset.defaultCharset());
        }
        return response;
    }
}