Package com.bbn.openmap.layer.util.http

Source Code of com.bbn.openmap.layer.util.http.HttpConnection

// **********************************************************************
//
// <copyright>
//
//  BBN Technologies
//  10 Moulton Street
//  Cambridge, MA 02138
//  (617) 873-8000
//
//  Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/layer/util/http/HttpConnection.java,v $
// $RCSfile: HttpConnection.java,v $
// $Revision: 1.3.2.5 $
// $Date: 2007/01/25 22:09:22 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.layer.util.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.util.StringTokenizer;

import com.bbn.openmap.util.Debug;

/**
* HttpConnection handles the communication with an HTTP client in its
* own thread. An instance of this class is created by the
* <code>HttpServer</code> each time a connection is made. The
* instance exists only long enough to fulfill the request, then dies.
*
* @author Tom Mitchell
* @version 1.1, 06/17/97
* @see HttpServer
*/
public class HttpConnection extends Thread {

    protected HttpServer server;
    protected Socket client;
    protected BufferedReader in;
    protected OutputStream out;
    protected boolean isConnectionOpen = true;

    public final static String CONTENT_JPEG = "image/jpeg";
    public final static String CONTENT_GIF = "image/gif";
    public final static String CONTENT_PPM = "image/ppm";
    public final static String CONTENT_PNG = "image/png";
    public final static String CONTENT_TIFF = "image/tiff";
    public final static String CONTENT_GEOTIFF = "image/geotiff";
    public final static String CONTENT_WBMP = "image/wbmp";
    public final static String CONTENT_SVG = "image/svg";
    public final static String CONTENT_HTML = "text/html";
    public final static String CONTENT_MOV = "video/quicktime";
    public final static String CONTENT_PLAIN = "text/plain";
    public final static String CONTENT_XML = "text/xml";

    /**
     * Initialize the input <code>Reader</code> and output
     * <code>Writer</code> and start the connection thread.
     *
     * @param client_socket the client's socket
     * @param server the server object
     */
    public HttpConnection(Socket client_socket, HttpServer server) {
        client = client_socket;
        this.server = server;
        InputStreamReader isr;
//        OutputStreamWriter osr;

        try {
            isr = new InputStreamReader(client.getInputStream());
            in = new BufferedReader(isr);
            out = client.getOutputStream();
//              osr = new OutputStreamWriter(client.getOutputStream());
//              out = new BufferedWriter(osr);
        } catch (IOException e) {
            try {
                close();
            } catch (IOException e2) {
                ;
            }
            System.err.println("Exception while getting socket streams: " + e);
            return;
        }
        this.start();
    }

    public static String[] getAllContentTypes() {
        return new String[] { CONTENT_JPEG, CONTENT_GIF, CONTENT_HTML,
                CONTENT_MOV, CONTENT_PLAIN, CONTENT_XML, CONTENT_PPM,
                CONTENT_PNG, CONTENT_SVG, CONTENT_GEOTIFF, CONTENT_TIFF,
                CONTENT_WBMP};
    }

    /**
     * The running thread simply reads all the lines of input and
     * hands each line off to be parsed.
     */
    public void run() {
        String line;

        try {
            while (isConnectionOpen) {
                // read in a line
                line = in.readLine();
                if (line == null)
                    break;
                processLine(line);
            }
        } catch (IOException e) {
        } finally {
            try {
                close();
            } catch (IOException e2) {
            }
        }
        Debug.message("httpconnection", "Connection closed. Exiting thread");
    }

    /**
     * Processes a line of an HTTP request. The only interesting line
     * we really look at is a GET command, which starts with "GET".
     *
     * @param line one line of an HTTP request
     */
    protected void processLine(String line) throws IOException {
        if (Debug.debugging("httpconnection")) {
            Debug.output("HttpConnection | processLine -- Processing command "
                    + line);
        }

        if (line.startsWith("GET")) {
            processGetCommand(line);
        } else if (line.startsWith("POST")) {
            Debug.message("httpconnection", "handling POST");
            handlePost();
        }
    }

    protected void handlePost() throws IOException {
        Debug.message("httpconnection", "HttpConnection | handlePost");
        String line;
        int contentLength = 0;
        try {
            while (isConnectionOpen) {
                // read in a line
                line = in.readLine();
                Debug.message("httpconnection", line);

                if (line == null)
                    break;

                String lineupp = line.toUpperCase();
                if (lineupp.startsWith("CONTENT-LENGTH")) {
                    contentLength = readContentLength(line);
                    Debug.message("httpconnection",
                            "HttpConnection -- Contentlength = "
                                    + contentLength);
                }

                if (line.equals("")) {
                    readContent(contentLength);
                }
            }
        } catch (IOException e) {
        } finally {
            try {
                close();
            } catch (IOException e2) {
            }
        }
    }

    protected int readContentLength(String line) {
        // Find the content length and read it
        StringTokenizer tokenizer = new StringTokenizer(line, ":");
        // this is first token "Content-length"
        tokenizer.nextToken();
        // Actual length after ':' "Content-length: xxx"
        String strLength = tokenizer.nextToken();
        int length = Integer.parseInt(strLength.trim());
        return length;
    }

    // check if it is an environment key - value pair
    // ASSUME actual content won't have ':'
    protected boolean isEnvarLine(String line) {
        if (line.indexOf(":") != -1) {
            return true;
        }
        return false;
    }

    protected void readContent(int length) throws IOException {

        char[] c_content = new char[length];
        int nread = 0;
        int remaining = length;
        try {
            while (nread < length) {
                //nread += in.read(c_content, nread, length);
                int tmp = in.read(c_content, nread, remaining);
                nread += tmp;
                remaining -= tmp;
                Debug.message("httpconnection", "Length of content read "
                        + nread + " length=" + length + " remaining="
                        + remaining);
            }

        } catch (java.io.IOException ioe) {
            Debug.error("HttpConnection | readContent -- Exception while reading content(key-values from POST) "
                    + ioe.getMessage());
        }

        String content = new String(c_content);
        content = content.trim();

        if (Debug.debugging("httpconnection")) {
            Debug.output("HttpConection showing Content :-- " + content);
        }

        //processGetCommand(content);

        HttpRequestEvent event = server.fireHttpRequestEvent(content, out);

        // Check to see if the Writer in the Event was used. If it
        // was, then the listeners contributed concatenated text, and
        // the result needs to be retrieved and sent back.
        if (event.isWriterUsed()) {
            Writer writer = event.getWriter();
            String result = writer.toString();
            writeHttpResponse(out, null, result);
        }

        // else - assume that the binary response listeners took care
        // of writing things back on their own,

        out.flush();
        close();
    }

    /**
     * Process a "GET" HTTP command. The leading "GET " and the
     * trailing HTTP version information are stripped off and a
     * HttpRequestEvent is fired via the HttpServer.
     *
     * @param cmd a "GET" HTTP command
     */
    protected void processGetCommand(String cmd) throws IOException {
        // Command looks like: "GET /thisURL HTTP/1.0"
        String location = cmd.substring(4); // remove the "GET "
        int locationEnd = location.indexOf(" "); // end at first space
        location = location.substring(0, locationEnd);

        // Figure out what type of file to figure Content-type
        // string contents
        String contentType;
        if (location.endsWith(".gif") || location.endsWith(".GIF")) {

            contentType = CONTENT_GIF;

        } else if (location.endsWith(".htm") || location.endsWith(".html")
                || location.endsWith(".HTM") || location.endsWith(".HTML")) {

            contentType = CONTENT_HTML;

        } else if (location.endsWith(".jpg") || location.endsWith(".JPG")
                || location.endsWith(".jpeg") || location.endsWith(".JPEG")) {

            contentType = CONTENT_JPEG;

        } else if (location.endsWith(".mov") || location.endsWith(".MOV")) {

            contentType = CONTENT_MOV;

        } else if (location.indexOf('?') != -1) {

            contentType = null;

        } else {
            contentType = CONTENT_PLAIN;
        }

        HttpRequestEvent event = server.fireHttpRequestEvent(location, out);

        // Check to see if the Writer in the Event was used. If it
        // was, then the listeners contributed concatenated text, and
        // the result needs to be retrieved and sent back.
        if (event.isWriterUsed()) {
            Writer writer = event.getWriter();
            String result = writer.toString();
            writeHttpResponse(out, contentType, result);
        }

        // else - assume that the binary response listeners took care
        // of writing things back on their own,

        out.flush();
        close();
    }

    /**
     * Can be used to write the header to an HttpResponse. You need to
     * create a Writer tied to the OutputStream in order to write this
     * text.
     *
     * @param out Writer to place text on the OutputStream.
     * @param contentType the mime type for your response.
     * @param contentLength the byte length of your response.
     */
    public static void writeHttpResponseHeader(Writer out, String contentType,
                                               int contentLength)
            throws IOException {

        out.write("HTTP/1.0 200 \n"); // return status
        out.write("Content-type: " + contentType + "\n"); // important!
        out.write("Content-Length: " + contentLength + "\n"); // important!
        out.write("\n");
    }

    /**
     * Write a String response to the OutputStream.
     *
     * @param out the OutputStream of the response.
     * @param contentType the content type of the response.
     * @param response the string containing the response.
     */
    public static void writeHttpResponse(OutputStream out, String contentType,
                                         String response) throws IOException {

        OutputStreamWriter osw = new OutputStreamWriter(out);
        writeHttpResponseHeader(osw, contentType, response.length());
        osw.write(response);
        osw.flush();
    }

    /**
     * Write a byte[] response to the OutputStream.
     *
     * @param out the OutputStream of the response.
     * @param contentType the content type of the response.
     * @param response the byte array containing the response.
     */
    public static void writeHttpResponse(OutputStream out, String contentType,
                                         byte[] response) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(out);
        writeHttpResponseHeader(osw, contentType, response.length);
        osw.flush();
        out.write(response, 0, response.length);
        osw.flush();
    }

    /**
     * Close the socket connection that we have opened
     */
    public void close() throws IOException {
        client.close();
        isConnectionOpen = false;
    }
}
TOP

Related Classes of com.bbn.openmap.layer.util.http.HttpConnection

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.