com.bagdemir.eboda.utils.HttpUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.bagdemir.eboda.utils.HttpUtils.java

Source

/*
 *   Copyright (C) 2013 "Erhan Bagdemir"
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.bagdemir.eboda.utils;

import static com.bagdemir.eboda.utils.Statics.HTTP_BAD_REQUEST;
import static com.bagdemir.eboda.utils.Statics.HTTP_CONNECTION;
import static com.bagdemir.eboda.utils.Statics.HTTP_CONTENT_LENGTH;
import static com.bagdemir.eboda.utils.Statics.HTTP_CONTENT_TYPE;
import static com.bagdemir.eboda.utils.Statics.HTTP_ETAG;
import static com.bagdemir.eboda.utils.Statics.HTTP_GET;
import static com.bagdemir.eboda.utils.Statics.HTTP_HEAD;
import static com.bagdemir.eboda.utils.Statics.HTTP_KEEP_ALIVE;
import static com.bagdemir.eboda.utils.Statics.HTTP_MIME_TEXT_PLAIN;
import static com.bagdemir.eboda.utils.Statics.HTTP_NOT_FOUND;
import static com.bagdemir.eboda.utils.Statics.HTTP_NOT_IMPLEMENTED;
import static com.bagdemir.eboda.utils.Statics.HTTP_NOT_MODIFIED;
import static com.bagdemir.eboda.utils.Statics.HTTP_OK;
import static com.bagdemir.eboda.utils.Statics.HTTP_POST;
import static com.bagdemir.eboda.utils.Statics.HTTP_PRECONDITION_FAILED;
import static com.bagdemir.eboda.utils.Statics.UTF_8;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;

import com.bagdemir.eboda.ext.CacheManager;
import com.bagdemir.eboda.resource.DirectoryResource;
import com.bagdemir.eboda.resource.FileResource;
import com.bagdemir.eboda.resource.Resource;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;

/**
 * Some utility methods in order to process an HTTP request.
 */
public class HttpUtils {
    private static final Logger LOGGER = Logger.getLogger(HttpUtils.class);

    /**
     * The method returns whether the client sends Keep-Alive or not.
     *
     * @param httpExchange exchange object.
     * @return whether request headers contains Keep-Alive
     */
    public static boolean isKeepAlive(final HttpExchange httpExchange) {
        final Headers requestHeaders = httpExchange.getRequestHeaders();
        if (requestHeaders != null) {
            final List<String> connectionHeader = requestHeaders.get(HTTP_CONNECTION);
            if (CollectionUtils.isNotEmpty(connectionHeader) && isKeepAlive(connectionHeader)) {
                return true;
            }
        }
        return false;
    }

    private static boolean isKeepAlive(final List<String> connectionHeader) {
        return connectionHeader.get(0).trim().equalsIgnoreCase(Statics.HTTP_KEEP_ALIVE);
    }

    public static boolean isHeadRequest(final HttpExchange httpExchange) {
        return httpExchange.getRequestMethod().equalsIgnoreCase(HTTP_HEAD);
    }

    public static boolean isGetRequest(final HttpExchange httpExchange) {
        return httpExchange.getRequestMethod().equalsIgnoreCase(HTTP_GET);
    }

    public static boolean isPostRequest(final HttpExchange httpExchange) {
        return httpExchange.getRequestMethod().equalsIgnoreCase(HTTP_POST);
    }

    public static String getPathVariable(final HttpExchange httpExchange) {
        final String requestedUri = httpExchange.getRequestURI().toString();
        int posHttpQuery = requestedUri.indexOf("?");
        if (posHttpQuery >= 0) {
            return ServerUtils.urlDecode(requestedUri.substring(0, posHttpQuery));
        }
        return ServerUtils.urlDecode(requestedUri);
    }

    public static void responseWith200(final HttpExchange httpExchange, final Resource resource,
            final boolean headRequest) {
        final Map<String, String> headerInfo = new HashMap<>();
        headerInfo.put(HTTP_CONTENT_TYPE, resource.getContentType());
        headerInfo.put(HTTP_ETAG, CacheManager.newInstance().getETag(resource));
        /* keep alive behavior is default in HTTP 1.1. For the clients which don't support HTTP 1.1
         yet, always send Keep-Alive headers.
        * */
        if (isKeepAlive(httpExchange)) {
            headerInfo.put(HTTP_CONNECTION, HTTP_KEEP_ALIVE);
            headerInfo.put(HTTP_CONTENT_LENGTH, getContentLength(resource));
        }

        sendHttpOKHeaders(httpExchange, headerInfo);
        if (!headRequest) {
            sendBody(httpExchange, resource.getBytes());
        }
    }

    private static String getContentLength(final Resource requestedResource) {
        return Integer.toString(requestedResource.getBytes().length);
    }

    public static Resource getResource(final HttpExchange httpExchange, final File requestedFile) {
        if (requestedFile.isDirectory()) {
            final String pathVariable = getPathVariable(httpExchange);
            return new DirectoryResource(requestedFile, pathVariable);
        }
        return new FileResource(requestedFile);
    }

    public static void sendHttpOKHeaders(final HttpExchange httpExchange, final Map<String, String> headers) {
        final Headers responseHeaders = httpExchange.getResponseHeaders();
        for (final Map.Entry<String, String> header : headers.entrySet()) {
            responseHeaders.set(header.getKey(), header.getValue());
        }

        sendResponseHeaders(httpExchange, HTTP_OK);
    }

    public static void responseWith405(final HttpExchange httpExchange, final boolean headRequest) {
        Headers responseHeaders = httpExchange.getResponseHeaders();
        responseHeaders.set(HTTP_CONTENT_TYPE, HTTP_MIME_TEXT_PLAIN);
        sendResponseHeaders(httpExchange, Statics.HTTP_NOT_ALLOWED);
        if (!headRequest) {
            sendBody(httpExchange, "405 - Not Allowed.".getBytes());
        }
    }

    public static void responseWith501(final HttpExchange httpExchange, final boolean headRequest) {
        Headers responseHeaders = httpExchange.getResponseHeaders();
        responseHeaders.set(HTTP_CONTENT_TYPE, HTTP_MIME_TEXT_PLAIN);
        sendResponseHeaders(httpExchange, HTTP_NOT_IMPLEMENTED);
        if (!headRequest) {
            sendBody(httpExchange, "501 - Not Implemented.".getBytes());
        }
    }

    public static void responseWith400(final HttpExchange httpExchange, final boolean headRequest) {
        Headers responseHeaders = httpExchange.getResponseHeaders();
        responseHeaders.set(HTTP_CONTENT_TYPE, HTTP_MIME_TEXT_PLAIN);
        sendResponseHeaders(httpExchange, HTTP_BAD_REQUEST);
        if (!headRequest) {
            sendBody(httpExchange, "400 - Bad Request.".getBytes());
        }
    }

    public static void responseWith304(final HttpExchange httpExchange, final boolean headRequest) {
        Headers responseHeaders = httpExchange.getResponseHeaders();
        responseHeaders.set(HTTP_CONTENT_TYPE, HTTP_MIME_TEXT_PLAIN);
        sendResponseHeaders(httpExchange, HTTP_NOT_MODIFIED);
        if (!headRequest) {
            sendBody(httpExchange, "304 - Not Modified.".getBytes());
        }
    }

    public static void responseWith412(final HttpExchange httpExchange, final boolean headRequest) {
        Headers responseHeaders = httpExchange.getResponseHeaders();
        responseHeaders.set(HTTP_CONTENT_TYPE, HTTP_MIME_TEXT_PLAIN);
        sendResponseHeaders(httpExchange, HTTP_PRECONDITION_FAILED);
        if (!headRequest) {
            sendBody(httpExchange, "412 - Precondition failed.".getBytes());
        }
    }

    public static void responseWith404(final HttpExchange httpExchange, final boolean headRequest) {
        Headers responseHeaders = httpExchange.getResponseHeaders();
        responseHeaders.set(HTTP_CONTENT_TYPE, HTTP_MIME_TEXT_PLAIN);
        sendResponseHeaders(httpExchange, HTTP_NOT_FOUND);
        if (!headRequest) {
            sendBody(httpExchange, "404 - Not Found.".getBytes());
        }
    }

    private static void sendResponseHeaders(final HttpExchange httpExchange, final int status) {
        try {
            httpExchange.sendResponseHeaders(status, 0);
        } catch (IOException e) {
            LOGGER.error(e);
        }
    }

    public static void sendBody(final HttpExchange httpExchange, final byte[] content) {
        writeToStream(httpExchange.getResponseBody(), content);
    }

    private static void writeToStream(final OutputStream outputStream, final byte[] content) {
        try {
            outputStream.write(content);
            outputStream.flush();
        } catch (IOException e) {
            LOGGER.error(e);
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                LOGGER.error(e);
            }
        }
    }

    public static File getFileResource(final HttpExchange httpExchange, final File baseDir) {
        String requestedUri = HttpUtils.getPathVariable(httpExchange);
        return baseDir.toPath().resolve(requestedUri.substring(1)).toFile();
    }

    public static void parseGetParameters(HttpExchange exchange) throws UnsupportedEncodingException {
        final URI requestedUri = exchange.getRequestURI();
        final String query = requestedUri.getRawQuery();
        parseQuery(query, exchange);
    }

    public static void parsePostParameters(HttpExchange exchange) throws IOException {
        @SuppressWarnings("unchecked")
        final InputStreamReader isr = new InputStreamReader(exchange.getRequestBody(), UTF_8);
        final BufferedReader reader = new BufferedReader(isr);
        final String query = reader.readLine();
        parseQuery(query, exchange);
    }

    private static void parseQuery(String query, HttpExchange exchange) throws UnsupportedEncodingException {
        if (query != null) {
            String pairs[] = query.split("&");
            for (String pair : pairs) {
                String param[] = pair.split("=");
                String key = null;
                String value = null;
                if (param.length > 0) {
                    key = URLDecoder.decode(param[0], Statics.UTF_8);
                }
                if (param.length > 1) {
                    value = URLDecoder.decode(param[1], Statics.UTF_8);
                }
                exchange.setAttribute(key, value);
            }
        }
    }

}