org.mangelp.fakeSmtpWeb.httpServer.HttpServer.java Source code

Java tutorial

Introduction

Here is the source code for org.mangelp.fakeSmtpWeb.httpServer.HttpServer.java

Source

/**
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with this file, You can obtain one at
 * https://mozilla.org/MPL/2.0/.
 */
package org.mangelp.fakeSmtpWeb.httpServer;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;

import org.apache.commons.lang.StringUtils;
import org.mangelp.fakeSmtpWeb.httpServer.mvc.Dispatcher;
import org.mangelp.fakeSmtpWeb.httpServer.mvc.IMvcResult;
import org.mangelp.fakeSmtpWeb.httpServer.mvc.MvcResultTypes;
import org.mangelp.fakeSmtpWeb.httpServer.mvc.action.ActionResult;
import org.mangelp.fakeSmtpWeb.httpServer.mvc.controller.ActionResultHandler;
import org.mangelp.fakeSmtpWeb.httpServer.mvc.resources.BundledResourceResult;
import org.mangelp.fakeSmtpWeb.httpServer.mvc.resources.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoHTTPD.Response.Status;

/**
 * @author mangelp
 *
 */
public class HttpServer extends NanoHTTPD {

    private static final Logger logger = LoggerFactory.getLogger(HttpServer.class);

    private int serverPort = 0;
    private String serverAddr = "";

    public HttpServer(InetAddress addr, int port) {
        super(addr != null ? addr.getHostName() : null, port);
        this.serverPort = port;
        this.serverAddr = addr != null ? addr.toString() : "";
    }

    public HttpServer(String hostName, int port) throws UnknownHostException {
        this(InetAddress.getByName(hostName), port);
    }

    public HttpServer(int port) {
        super(port);
        this.serverPort = port;
        this.serverAddr = "localhost";
    }

    private String getLogPrefix() {
        return String.format("HTTP server %s:%d", this.serverAddr, this.serverPort);
    }

    @Override
    public void start(int timeout, boolean daemon) throws IOException {

        HttpServer.logger.info(this.getLogPrefix() + " starting");

        super.start(timeout, daemon);

        HttpServer.logger.info(this.getLogPrefix() + " started");
    }

    @Override
    public void stop() {

        HttpServer.logger.info(this.getLogPrefix() + " stopping");

        super.stop();

        HttpServer.logger.info(this.getLogPrefix() + " stopped");
    }

    protected void logRequest(HttpGetRequest request) {
        StringBuilder sb = new StringBuilder();

        sb.append(request.getClientAddress() + " GET " + request.getRequestUri());

        if (!StringUtils.isBlank(request.getQueryString())) {
            sb.append("?" + request.getQueryString());
        }

        sb.append(" ");

        HttpServer.logger.debug(sb.toString());
    }

    @Override
    public Response serve(IHTTPSession session) {

        String mimeType = NanoHTTPD.MIME_HTML;

        if (session.getMethod() != Method.GET) {
            HttpServer.logger.warn("Invalid request method " + session.getMethod().name());
            return NanoHTTPD.newFixedLengthResponse(Status.BAD_REQUEST, mimeType, "");
        }

        Dispatcher dispatcher = new Dispatcher();

        IMvcResult result = null;
        HttpGetRequest getRequest = null;

        try {
            getRequest = new HttpGetRequest(session);
            this.logRequest(getRequest);
            result = dispatcher.dispatch(getRequest);
        } catch (Exception e) {
            HttpServer.logger.error("Failed to dispatch request", e);
            return NanoHTTPD.newFixedLengthResponse(Status.NOT_FOUND, mimeType, "");
        }

        Status status = Status.OK;

        if (!result.isSuccess()) {
            if (result.getError() != null) {
                switch (result.getError()) {
                case INVALID_ACTION:
                    // fall through
                case INVALID_PARAMS:
                    // fall through
                case INVALID_CONTROLLER:
                    status = Status.BAD_REQUEST;
                    break;
                case UNHANDLED_ACTION_ERROR:
                case UNHANDLED_CONTROLLER_ERROR:
                case UNHANDLED_ERROR:
                    status = Status.INTERNAL_ERROR;
                    break;
                case RESOURCE_NOT_FOUND:
                    status = Status.NOT_FOUND;
                    break;
                default:
                    status = Status.NOT_IMPLEMENTED;
                    break;
                }
            } else {
                status = Status.INTERNAL_ERROR;
            }

            return NanoHTTPD.newFixedLengthResponse(status, mimeType, result.getErrorMsg());
        }

        if (result instanceof ActionResult) {
            ActionResult actionResult = (ActionResult) result;

            if (actionResult.getType() == MvcResultTypes.VIEW) {
                ActionResultHandler resultHandler = new ActionResultHandler(actionResult);

                return NanoHTTPD.newFixedLengthResponse(status, mimeType, resultHandler.render());
            } else if (actionResult.getType() == MvcResultTypes.RESOURCE) {
                Resource resource = actionResult.getResource();

                return NanoHTTPD.newFixedLengthResponse(status, resource.getMime(), resource.getInputStream(), -1);
            } else {
                throw new RuntimeException("Invalid result type " + actionResult.getType());
            }
        } else if (result instanceof BundledResourceResult) {
            BundledResourceResult resourceResult = (BundledResourceResult) result;

            Resource resource = resourceResult.getResource();
            InputStream inputStream = resourceResult.getAsStream();
            return NanoHTTPD.newFixedLengthResponse(status, resource.getMime(), inputStream, -1);
        } else {
            throw new RuntimeException("Invalid result class " + result.getClass().getSimpleName());
        }
    }
}