⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ajp13.java

📁 精通tomcat书籍原代码,希望大家共同学习
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.ajp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import org.apache.tomcat.util.http.BaseRequest;
import org.apache.tomcat.util.http.HttpMessages;
import org.apache.tomcat.util.http.MimeHeaders;

/**
 * Represents a single, persistent connection between the web server and
 * the servlet container.  Uses the Apache JServ Protocol version 1.3 for
 * communication.  Because this protocal does not multiplex requests, this
 * connection can only be associated with a single request-handling cycle
 * at a time.<P>
 *
 * This class contains knowledge about how an individual packet is laid out
 * (via the <CODE>Ajp13Packet</CODE> class), and also about the
 * stages of communicaton between the server and the servlet container.  It
 * translates from Tomcat's internal servlet support methods
 * (e.g. doWrite) to the correct packets to send to the web server.
 *
 * @author Dan Milstein [danmil@shore.net]
 * @author Keith Wannamaker [Keith@Wannamaker.org]
 * @author Kevin Seguin [seguin@apache.org]
 * @author Henri Gomez [hgomez@apache.org]
 * @author Costin Manolache
 */
public class Ajp13 {

    public static final int MAX_PACKET_SIZE=8192;
    public static final int H_SIZE=4;  // Size of basic packet header

    public static final int  MAX_READ_SIZE = MAX_PACKET_SIZE - H_SIZE - 2;
    public static final int  MAX_SEND_SIZE = MAX_PACKET_SIZE - H_SIZE - 4;

    // Error code for Ajp13
    public static final int  JK_AJP13_BAD_HEADER        = -100;
    public static final int  JK_AJP13_NO_HEADER         = -101;
    public static final int  JK_AJP13_COMM_CLOSED       = -102;
    public static final int  JK_AJP13_COMM_BROKEN       = -103;
    public static final int  JK_AJP13_BAD_BODY          = -104;
    public static final int  JK_AJP13_INCOMPLETE_BODY   = -105;

    // ============ Instance Properties ====================

    OutputStream out;
    InputStream in;

    // Buffer used of output body and headers
    public Ajp13Packet outBuf = new Ajp13Packet( MAX_PACKET_SIZE );
    // Buffer used for input body
    Ajp13Packet inBuf  = new Ajp13Packet( MAX_PACKET_SIZE );
    // Buffer used for request head ( and headers )
    Ajp13Packet hBuf=new Ajp13Packet( MAX_PACKET_SIZE );

    // Holds incoming reads of request body data (*not* header data)
    byte []bodyBuff = new byte[MAX_READ_SIZE];
    
    int blen;  // Length of current chunk of body data in buffer
    int pos;   // Current read position within that buffer

    boolean end_of_stream;  // true if we've received an empty packet
    
    // Required handler - essential request processing
    public RequestHandler reqHandler;
    // AJP14 - detect protocol,set communication parameters, login
    // If no password is set, use only Ajp13 messaging
    boolean backwardCompat=true;
    boolean logged=false;
    String secret=null;
    
    public Ajp13() {
	super();
	initBuf();
        reqHandler=new RequestHandler();
	reqHandler.init( this );
    }

    public Ajp13(RequestHandler reqHandler ) {
	super();
	initBuf();
        this.reqHandler=reqHandler;
	reqHandler.init( this );
    }

    /** Will be overriden
     */
    public void initBuf() {
	outBuf = new Ajp13Packet( MAX_PACKET_SIZE );
	inBuf  = new Ajp13Packet( MAX_PACKET_SIZE );
	hBuf=new Ajp13Packet( MAX_PACKET_SIZE );
    }
    
    public void recycle() {
        if (debug > 0) {
            logger.log("recycle()");
        }

        // This is a touch cargo-cultish, but I think wise.
        blen = 0; 
        pos = 0;
        end_of_stream = false;
        logged=false;
    }
    
    /**
     * Associate an open socket with this instance.
     */
    public void setSocket( Socket socket ) throws IOException {
        if (debug > 0) {
            logger.log("setSocket()");
        }
        
	socket.setSoLinger( true, 100);
	out = socket.getOutputStream();
	in  = socket.getInputStream();
	pos = 0;
    }

    /**
     * Backward compat mode, no login  needed
     */
    public void setBackward(boolean b) 
    {
        backwardCompat=b;
    }

    public boolean isLogged() {
	return logged;
    }

    void setLogged( boolean b ) {
        logged=b;
    }

    public void setSecret( String s ) {
        secret=s;
    }

    public String getSecret() {
        return secret;
    }
    
    // -------------------- Handlers registry --------------------

    static final int MAX_HANDLERS=32;
    static final int RESERVED=16;  // reserved names, backward compat

    // Note that we don't make distinction between in and out
    // messages ( i.e. one id is used only in one direction )
    AjpHandler handlers[]=new AjpHandler[MAX_HANDLERS];
    String handlerName[]=new String[MAX_HANDLERS];
    int currentId=RESERVED;

    public int registerMessageType( int id, String name, AjpHandler h,
				    String sig[] )
    {
	if( id < 0 ) {
	    // try to find it by name
	    for( int i=0; i< handlerName.length; i++ )
		if( name.equals( handlerName[i] ) ) return i;
	    handlerName[currentId]=name;
	    handlers[currentId]=h;
	    currentId++;
	    return currentId;
	}
	// fixed id
	handlerName[id]=name;
	handlers[id]=h;
	return id;
    }
    
    // -------------------- Main dispatch --------------------
    
    /**
     * Read a new packet from the web server and decode it.  If it's a
     * forwarded request, store its properties in the passed-in AjpRequest
     * object.
     *
     * @param req An empty (newly-recycled) request object.
     * 
     * @return 200 in case of a successful read of a forwarded request, 500
     * if there were errors in the reading of the request, and -2 if the
     * server is asking the container to shut itself down.  
     */
    public int receiveNextRequest(BaseRequest req) throws IOException {
        if (debug > 0) {
            logger.log("receiveNextRequest()");
        }
        
        // XXX The return values are awful.

        int err = 0;

        // if we receive an IOException here, it must be because
        // the remote just closed the ajp13 connection, and it's not
        // an error, we just need to close the AJP13 connection
        try {
            err = receive(hBuf);
        } catch (IOException ioe) {
            if(debug >0 ) logger.log( "IOException receiving message ");
            return -1;  // Indicate it's a disconnection from the remote end
        }
        
	if(err < 0) {
	    if(debug >0 ) logger.log( "Error receiving message ");
	    return 500;
	}
	
	int type = (int)hBuf.getByte();
        //        System.out.println("XXX " + this );
        return handleMessage( type, hBuf, req );
    }

    /** Override for ajp14, temporary
     */
    public int handleMessage( int type, Ajp13Packet hBuf, BaseRequest req )
        throws IOException
    {
        if( type > handlers.length ) {
	    logger.log( "Invalid handler " + type );
	    return 500;
	}

        if( debug > 0 )
            logger.log( "Received " + type + " " + handlerName[type]);
        
        // Ajp14, unlogged
	if( ! backwardCompat && ! isLogged() ) {
	    if( type != NegociationHandler.JK_AJP14_LOGINIT_CMD &&
		type != NegociationHandler.JK_AJP14_LOGCOMP_CMD ) {

                logger.log( "Ajp14 error: not logged " +
                            type + " " + handlerName[type]);

		return 300;
	    }
	    // else continue

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -