Package winstone.ajp13

Source Code of winstone.ajp13.Ajp13IncomingPacket

/*
* Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
* Distributed under the terms of either:
* - the common development and distribution license (CDDL), v1.0; or
* - the GNU Lesser General Public License, v2.1 or later
*/
package winstone.ajp13;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
import java.util.Map;

import winstone.Logger;
import winstone.RequestHandlerThread;
import winstone.WinstoneException;

/**
* Models a single incoming ajp13 packet.
*
* Fixes by Cory Osborn 2007/4/3 - IIS related. Thanks
*
* @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a>
* @version $Id: Ajp13IncomingPacket.java,v 1.6 2007/04/03 01:23:19 rickknowles Exp $
*/
public class Ajp13IncomingPacket {
    // Server originated packet types
    byte SERVER_FORWARD_REQUEST = 0x02;

    // public static byte SERVER_SHUTDOWN = 0x07; //not implemented
    // public static byte SERVER_PING = 0x08; //not implemented
    // public static byte SERVER_CPING = 0x10; //not implemented

    private int packetLength;
    private byte packetBytes[];
    private byte packetType;
    private String method;
    private String protocol;
    private String uri;
    private String remoteAddr;
    private String remoteHost;
    private String serverName;
    private int serverPort;
    private boolean isSSL;
    private String headers[];
    private Map attributes;

    /**
     * Constructor
     */
    public Ajp13IncomingPacket(InputStream in,
            RequestHandlerThread handler) throws IOException {
        // Get the incoming packet flag
        byte headerBuffer[] = new byte[4];
        int headerBytesRead = in.read(headerBuffer);
        handler.setRequestStartTime();
        if (headerBytesRead != 4)
            throw new WinstoneException(Ajp13Listener.AJP_RESOURCES
                    .getString("Ajp13IncomingPacket.InvalidHeader"));
        else if ((headerBuffer[0] != 0x12) || (headerBuffer[1] != 0x34))
            throw new WinstoneException(Ajp13Listener.AJP_RESOURCES
                    .getString("Ajp13IncomingPacket.InvalidHeader"));

        // Read in the whole packet
        packetLength = ((headerBuffer[2] & 0xFF) << 8)
                + (headerBuffer[3] & 0xFF);
        packetBytes = new byte[packetLength];
        int packetBytesRead = in.read(packetBytes);

        if (packetBytesRead < packetLength)
            throw new WinstoneException(Ajp13Listener.AJP_RESOURCES
                    .getString("Ajp13IncomingPacket.ShortPacket"));
        // Ajp13Listener.packetDump(packetBytes, packetBytesRead);
    }

    public byte parsePacket(String encoding) throws IOException {
        int position = 0;
        this.packetType = packetBytes[position++];

        if (this.packetType != SERVER_FORWARD_REQUEST)
            throw new WinstoneException(Ajp13Listener.AJP_RESOURCES.getString(
                    "Ajp13IncomingPacket.UnknownPacketType", this.packetType
                            + ""));

        // Check for terminator
        if (packetBytes[packetLength - 1] != (byte) 255)
            throw new WinstoneException(Ajp13Listener.AJP_RESOURCES
                    .getString("Ajp13IncomingPacket.InvalidTerminator"));

        this.method = decodeMethodType(packetBytes[position++]);
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.Method", method);

        // Protocol
        int protocolLength = readInteger(position, packetBytes, true);
        position += 2;
        this.protocol = (protocolLength > -1)
                ? readString(position, packetBytes, encoding, protocolLength)
                        : null;
        position += protocolLength + 1;
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.Protocol", protocol);

        // URI
        int uriLength = readInteger(position, packetBytes, true);
        position += 2;
        this.uri = (uriLength > -1)
                ? readString(position, packetBytes, encoding, uriLength)
                : null;
        position += uriLength + 1;
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.URI", uri);

        // Remote addr
        int remoteAddrLength = readInteger(position, packetBytes, true);
        position += 2;
        this.remoteAddr = (remoteAddrLength > -1)
                ? readString(position, packetBytes, encoding, remoteAddrLength)
                : null;
        position += remoteAddrLength + 1;
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.RemoteAddress", remoteAddr);

        // Remote host
        int remoteHostLength = readInteger(position, packetBytes, true);
        position += 2;
        this.remoteHost = (remoteHostLength > -1)
                ? readString(position, packetBytes, encoding, remoteHostLength)
                : null;   
        position += remoteHostLength + 1;
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.RemoteHost", remoteHost);

        // Server name
        int serverNameLength = readInteger(position, packetBytes, true);
        position += 2;
        this.serverName = (serverNameLength > -1)
                ? readString(position, packetBytes, encoding, serverNameLength)
                : null;
        position += serverNameLength + 1;
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.ServerName", serverName);

        this.serverPort = readInteger(position, packetBytes, false);
        position += 2;
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.ServerPort", "" + serverPort);

        this.isSSL = readBoolean(position++, packetBytes);
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.SSL", "" + isSSL);

        // Read headers
        int headerCount = readInteger(position, packetBytes, false);
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.HeaderCount", "" + headerCount);
        position += 2;
        this.headers = new String[headerCount];
        for (int n = 0; n < headerCount; n++) {
            // Header name
            int headerTypeOrLength = readInteger(position, packetBytes, false);
            position += 2;
            String headerName = null;
            if (packetBytes[position - 2] == (byte) 0xA0)
                headerName = decodeHeaderType(headerTypeOrLength);
            else {
                headerName = readString(position, packetBytes, encoding,
                        headerTypeOrLength);
                position += headerTypeOrLength + 1;
            }

            // Header value
            int headerValueLength = readInteger(position, packetBytes, true);
            position += 2;
            this.headers[n] = headerName
                    + ": "
                    + ((headerValueLength > -1)
                        ? readString(position, packetBytes, encoding, headerValueLength)
                        : "");
            position += headerValueLength + 1;
            Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                    "Ajp13IncomingPacket.Header", this.headers[n]);
        }

        // Attribute parsing
        this.attributes = new Hashtable();
        while (position < packetLength - 2) {
            String attName = decodeAttributeType(packetBytes[position++]);
            int attValueLength = readInteger(position, packetBytes, true);
            position += 2;
            String attValue = (attValueLength > -1)
                      ? readString(position, packetBytes, encoding, attValueLength)
                      : null;
            position += attValueLength + 1;

            this.attributes.put(attName, attValue);
            Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                    "Ajp13IncomingPacket.Attribute", new String[] { attName,
                            attValue });
        }
        Logger.log(Logger.FULL_DEBUG, Ajp13Listener.AJP_RESOURCES,
                "Ajp13IncomingPacket.SuccessfullyReadRequest", ""
                        + packetLength);
        return this.packetType;
    }

    public int getPacketLength() {
        return this.packetLength;
    }

    public String getMethod() {
        return this.method;
    }

    public String getProtocol() {
        return this.protocol;
    }

    public String getURI() {
        return this.uri;
    }

    public String getRemoteAddress() {
        return this.remoteAddr;
    }

    public String getRemoteHost() {
        return this.remoteHost;
    }

    public String getServerName() {
        return this.serverName;
    }

    public int getServerPort() {
        return this.serverPort;
    }

    public boolean isSSL() {
        return this.isSSL;
    }

    public String[] getHeaders() {
        return this.headers;
    }

    public Map getAttributes() {
        return this.attributes;
    }

    /**
     * Read a single integer from the stream
     */
    private int readInteger(int position, byte packet[], boolean forStringLength) {
        if (forStringLength && (packet[position] == (byte) 0xFF)
                && (packet[position + 1] == (byte) 0xFF))
            return -1;
        else
            return ((packet[position] & 0xFF) << 8)
                    + (packet[position + 1] & 0xFF);
    }

    /**
     * Read a single boolean from the stream
     */
    private boolean readBoolean(int position, byte packet[]) {
        return (packet[position] == (byte) 1);
    }

    /**
     * Read a single string from the stream
     */
    private String readString(int position, byte packet[], String encoding,
            int length) throws UnsupportedEncodingException {
//        System.out.println("Reading string length: " + length +
//                " position=" + position + " packetLength=" + packet.length);
        return length == 0 ? ""
                : new String(packet, position, length, encoding);
    }

    /**
     * Decodes the method types into Winstone HTTP method strings
     */
    private String decodeMethodType(byte methodType) {
        switch (methodType) {
        case 1:
            return "OPTIONS";
        case 2:
            return "GET";
        case 3:
            return "HEAD";
        case 4:
            return "POST";
        case 5:
            return "PUT";
        case 6:
            return "DELETE";
        case 7:
            return "TRACE";
        case 8:
            return "PROPFIND";
        case 9:
            return "PROPPATCH";
        case 10:
            return "MKCOL";
        case 11:
            return "COPY";
        case 12:
            return "MOVE";
        case 13:
            return "LOCK";
        case 14:
            return "UNLOCK";
        case 15:
            return "ACL";
        case 16:
            return "REPORT";
        case 17:
            return "VERSION-CONTROL";
        case 18:
            return "CHECKIN";
        case 19:
            return "CHECKOUT";
        case 20:
            return "UNCHECKOUT";
        case 21:
            return "SEARCH";
        case 22:
            return "MKWORKSPACE";
        case 23:
            return "UPDATE";
        case 24:
            return "LABEL";
        case 25:
            return "MERGE";
        case 26:
            return "BASELINE_CONTROL";
        case 27:
            return "MKACTIVITY";
        default:
            return "UNKNOWN";
        }
    }

    /**
     * Decodes the header types into Winstone HTTP header strings
     */
    private String decodeHeaderType(int headerType) {
        switch (headerType) {
        case 0xA001:
            return "Accept";
        case 0xA002:
            return "Accept-Charset";
        case 0xA003:
            return "Accept-Encoding";
        case 0xA004:
            return "Accept-Language";
        case 0xA005:
            return "Authorization";
        case 0xA006:
            return "Connection";
        case 0xA007:
            return "Content-Type";
        case 0xA008:
            return "Content-Length";
        case 0xA009:
            return "Cookie";
        case 0xA00A:
            return "Cookie2";
        case 0xA00B:
            return "Host";
        case 0xA00C:
            return "Pragma";
        case 0xA00D:
            return "Referer";
        case 0xA00E:
            return "User-Agent";
        default:
            return null;
        }
    }

    /**
     * Decodes the header types into Winstone HTTP header strings
     */
    private String decodeAttributeType(byte attributeType) {
        switch (attributeType) {
        case 0x01:
            return "context";
        case 0x02:
            return "servlet_path";
        case 0x03:
            return "remote_user";
        case 0x04:
            return "auth_type";
        case 0x05:
            return "query_string";
        case 0x06:
            return "jvm_route";
        case 0x07:
            return "ssl_cert";
        case 0x08:
            return "ssl_cipher";
        case 0x09:
            return "ssl_session";
        case 0x0A:
            return "req_attribute";
        default:
            return null;
        }
    }
}
TOP

Related Classes of winstone.ajp13.Ajp13IncomingPacket

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.