Package org.jboss.as.domain.http.server

Source Code of org.jboss.as.domain.http.server.ConsoleHandler

/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This 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 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.domain.http.server;


import org.jboss.as.domain.management.SecurityRealm;
import org.jboss.com.sun.net.httpserver.Headers;
import org.jboss.com.sun.net.httpserver.HttpExchange;
import org.jboss.com.sun.net.httpserver.HttpServer;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;

import static org.jboss.as.domain.http.server.Constants.*;

/**
* @author Heiko Braun
* @date 3/14/11
*/
public class ConsoleHandler implements ManagementHttpHandler {

    public  static final String CONTEXT = "/console";
    private static final String HOST_HEADER = "Host";
    private static final String EXPIRES_HEADER = "Expires";
    private static final String NOCACHE_JS = ".nocache.js";
    private static final String WILDCARD = "*";
    private static final String DATEFORMAT_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z";
    private static final String GMT = "GMT";

    private ClassLoader loader = null;

    private static Map<String, String> contentTypeMapping = new ConcurrentHashMap<String, String>();

    private long lastExpiryDate = 0;
    private String lastExpiryHeader = null;

    static {
        contentTypeMapping.put(".js",   APPLICATION_JAVASCRIPT);
        contentTypeMapping.put(".html", TEXT_HTML);
        contentTypeMapping.put(".htm",  TEXT_HTML);
        contentTypeMapping.put(".css",  TEXT_CSS);
        contentTypeMapping.put(".gif",  IMAGE_GIF);
        contentTypeMapping.put(".png",  IMAGE_PNG);
        contentTypeMapping.put(".jpeg", IMAGE_JPEG);
    }

    public ConsoleHandler() {
    }

    public ConsoleHandler(ClassLoader loader) {
        this.loader = loader;
    }

    public void handle(HttpExchange http) throws IOException {
        final URI uri = http.getRequestURI();
        final String requestMethod = http.getRequestMethod();

        // only GET supported
        if (!GET.equals(requestMethod)) {
            http.sendResponseHeaders(METHOD_NOT_ALLOWED, -1);
            return;
        }

        // normalize to request resource
        String path = uri.getPath();
        String resource = path.substring(CONTEXT.length(), path.length());
        if(resource.startsWith("/")) resource = resource.substring(1);


        if(resource.equals("")) {
            // "/console" request redirect to "/console/index.html"

            InetSocketAddress address = http.getHttpContext().getServer().getAddress();
            String hostName = address.getHostName();
            int port = address.getPort();

            // Use Host header value if available
            String hostHeader = http.getRequestHeaders().getFirst(HOST_HEADER);
            if (hostHeader != null) {
                // Parse the hostHeader using URI
                try {
                    URI hostURI = new URI("http://" + hostHeader);
                    if (hostURI.getHost() != null) {
                        hostName = hostURI.getHost();
                    }
                    if (hostURI.getPort() != -1) {
                        port = hostURI.getPort();
                    }
                } catch (java.net.URISyntaxException ex) {
                    // invalid Host header value, just ignore
                }
            }

            final Headers responseHeaders = http.getResponseHeaders();
            responseHeaders.add(CONTENT_TYPE, TEXT_HTML);
            responseHeaders.add(LOCATION, "http://"+hostName + ":"+port+"/console/index.html");
            http.sendResponseHeaders(FOUND, 0);

            OutputStream outputStream = http.getResponseBody();
            outputStream.flush();
            safeClose(outputStream);

            return;
        } else if(resource.indexOf(".")==-1) {
            respond404(http);
        }

        // load resource
        InputStream inputStream = getLoader().getResourceAsStream(resource);

        if(inputStream!=null) {

            final Headers responseHeaders = http.getResponseHeaders();
            responseHeaders.add(CONTENT_TYPE, resolveContentType(path));
            responseHeaders.add(ACCESS_CONTROL_ALLOW_ORIGIN, WILDCARD);


            boolean skipcache = resource.endsWith(NOCACHE_JS);
            if(!skipcache){
                // provide 'Expires' headers for GWT files

                if(System.currentTimeMillis()>lastExpiryDate) {
                    lastExpiryDate = calculateExpiryDate();
                    lastExpiryHeader = htmlExpiresDateFormat().format(new Date(lastExpiryDate));
                }

                responseHeaders.add(EXPIRES_HEADER, lastExpiryHeader);
            }

            http.sendResponseHeaders(OK, 0);

            // nio write
            OutputStream outputStream = http.getResponseBody();
            fastChannelCopy(inputStream, outputStream);
            outputStream.flush();

            safeClose(outputStream);
            safeClose(inputStream);

        } else {
            respond404(http);
        }

    }

    private static long calculateExpiryDate() {
        Calendar cal = Calendar.getInstance();
        cal.roll(Calendar.MONTH, 1);
        return cal.getTime().getTime();
    }
    public static DateFormat htmlExpiresDateFormat() {
        DateFormat httpDateFormat = new SimpleDateFormat(DATEFORMAT_FORMAT, Locale.US);
        httpDateFormat.setTimeZone(TimeZone.getTimeZone(GMT));
        return httpDateFormat;
    }

    public static void fastChannelCopy(final InputStream in, final OutputStream out) throws IOException {

        final ReadableByteChannel src = Channels.newChannel(in);
        final WritableByteChannel dest = Channels.newChannel(out);

        try {
            final ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);
            while (src.read(buffer) != -1) {
                buffer.flip();
                dest.write(buffer);
                buffer.compact();
            }
            buffer.flip();

            while (buffer.hasRemaining()) {
                dest.write(buffer);
            }
        } finally {
            safeClose(src);
            safeClose(dest);
        }
    }

    private static void safeClose(Closeable close) {
        try {
            close.close();
        } catch (Throwable eat) {
        }
    }

    private String resolveContentType(String resource) {
        assert resource.indexOf(".")!=-1 : "Invalid resource";

        String contentType = null;
        for(String suffix : contentTypeMapping.keySet()) {
            if(resource.endsWith(suffix)) {
                contentType = contentTypeMapping.get(suffix);
                break;
            }
        }

        if(null==contentType) contentType = APPLICATION_OCTET_STREAM;

        return contentType;
    }

    private void respond404(HttpExchange http) throws IOException {

        final Headers responseHeaders = http.getResponseHeaders();
        responseHeaders.add(CONTENT_TYPE, TEXT_HTML);
        responseHeaders.add(ACCESS_CONTROL_ALLOW_ORIGIN, WILDCARD);
        http.sendResponseHeaders(NOT_FOUND, 0);
        OutputStream out = http.getResponseBody();
        out.flush();
        safeClose(out);
    }

    private ClassLoader getLoader() {
        if(loader!=null)
            return loader;
        else
            return ConsoleHandler.class.getClassLoader();
    }

    public void start(HttpServer httpServer, SecurityRealm securityRealm) {
        httpServer.createContext(CONTEXT, this);
    }

    public void stop(HttpServer httpServer) {
        httpServer.removeContext(CONTEXT);
    }
}
TOP

Related Classes of org.jboss.as.domain.http.server.ConsoleHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.