You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by hg...@apache.org on 2001/06/22 12:35:47 UTC
cvs commit: jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33 Ajp14.java Ajp14Interceptor.java Ajp14Packet.java
hgomez 01/06/22 03:35:46
Added: jk/java/org/apache/ajp/tomcat33 Ajp14.java
Ajp14Interceptor.java Ajp14Packet.java
Log:
The long awaited initial Ajp14 support.
Interceptor, Packet, Protocol (advanced login and SSL_KEY_SIZE)
Revision Changes Path
1.1 jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33/Ajp14.java
Index: Ajp14.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.ajp.tomcat33;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Enumeration;
import java.security.*;
import org.apache.tomcat.core.*;
import org.apache.tomcat.util.*;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.HttpMessages;
import org.apache.tomcat.util.buf.HexUtils;
/**
* 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 internal <CODE>Ajp14Packet</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.
*
* @see Ajp14Interceptor
*
* @author Henri Gomez [hgomez@slib.fr]
* @author Dan Milstein [danmil@shore.net]
* @author Keith Wannamaker [Keith@Wannamaker.org]
*/
public class Ajp14 extends Ajp13
{
// AJP14 commands
// Initial Login Phase (web server -> servlet engine)
public static final byte JK_AJP14_LOGINIT_CMD = 0x10;
// Second Login Phase (servlet engine -> web server), md5 seed is received
public static final byte JK_AJP14_LOGSEED_CMD = 0x11;
// Third Login Phase (web server -> servlet engine), md5 of seed + secret is sent
public static final byte JK_AJP14_LOGCOMP_CMD = 0x12;
// Login Accepted (servlet engine -> web server)
public static final byte JK_AJP14_LOGOK_CMD = 0x13;
// Login Rejected (servlet engine -> web server), will be logged
public static final byte JK_AJP14_LOGNOK_CMD = 0x14;
// Context Query (web server -> servlet engine), which URI are handled by servlet engine ?
public static final byte JK_AJP14_CONTEXT_QRY_CMD = 0x15;
// Context Info (servlet engine -> web server), URI handled response
public static final byte JK_AJP14_CONTEXT_INFO_CMD = 0x16;
// Context Update (servlet engine -> web server), status of context changed
public static final byte JK_AJP14_CONTEXT_UPDATE_CMD = 0x17;
// Servlet Engine Status (web server -> servlet engine), what's the status of the servlet engine ?
public static final byte JK_AJP14_STATUS_CMD = 0x18;
// Secure Shutdown command (web server -> servlet engine), please servlet stop yourself.
public static final byte JK_AJP14_SHUTDOWN_CMD = 0x19;
// Secure Shutdown command Accepted (servlet engine -> web server)
public static final byte JK_AJP14_SHUTOK_CMD = 0x1A;
// Secure Shutdown Rejected (servlet engine -> web server)
public static final byte JK_AJP14_SHUTNOK_CMD = 0x1B;
// Context Status (web server -> servlet engine), what's the status of the context ?
public static final byte JK_AJP14_CONTEXT_STATE_CMD = 0x1C;
// Context Status Reply (servlet engine -> web server), status of context
public static final byte JK_AJP14_CONTEXT_STATE_REP_CMD = 0x1D;
// Unknown Packet Reply (web server <-> servlet engine), when a packet couldn't be decoded
public static final byte JK_AJP14_UNKNOW_PACKET_CMD = 0x1E;
// Entropy Packet Size
public static final int AJP14_ENTROPY_SEED_LEN = 32;
public static final int AJP14_COMPUTED_KEY_LEN = 32;
// web-server want context info after login
public static final int AJP14_CONTEXT_INFO_NEG = 0x80000000;
// web-server want context updates
public static final int AJP14_CONTEXT_UPDATE_NEG = 0x40000000;
// web-server want compressed stream
public static final int AJP14_GZIP_STREAM_NEG = 0x20000000;
// web-server want crypted DES56 stream with secret key
public static final int AJP14_DES56_STREAM_NEG = 0x10000000;
// Extended info on server SSL vars
public static final int AJP14_SSL_VSERVER_NEG = 0x08000000;
// Extended info on client SSL vars
public static final int AJP14_SSL_VCLIENT_NEG = 0x04000000;
// Extended info on crypto SSL vars
public static final int AJP14_SSL_VCRYPTO_NEG = 0x02000000;
// Extended info on misc SSL vars
public static final int AJP14_SSL_VMISC_NEG = 0x01000000;
// mask of protocol supported
public static final int AJP14_PROTO_SUPPORT_AJPXX_NEG = 0x00FF0000;
// communication could use AJP14
public static final int AJP14_PROTO_SUPPORT_AJP14_NEG = 0x00010000;
// communication could use AJP15
public static final int AJP14_PROTO_SUPPORT_AJP15_NEG = 0x00020000;
// communication could use AJP16
public static final int AJP14_PROTO_SUPPORT_AJP16_NEG = 0x00040000;
// Some failure codes
public static final int AJP14_BAD_KEY_ERR = 0xFFFFFFFF;
public static final int AJP14_ENGINE_DOWN_ERR = 0xFFFFFFFE;
public static final int AJP14_RETRY_LATER_ERR = 0xFFFFFFFD;
public static final int AJP14_SHUT_AUTHOR_FAILED_ERR = 0xFFFFFFFC;
// Some status codes
public static final byte AJP14_CONTEXT_DOWN = 0x01;
public static final byte AJP14_CONTEXT_UP = 0x02;
public static final byte AJP14_CONTEXT_OK = 0x03;
// AJP14 new header
public static final byte SC_A_SSL_KEY_SIZE = 11;
// ============ Instance Properties ====================
// AJP14
boolean logged = false;
int webserverNegociation = 0;
String webserverName;
String seed;
String password;
public Ajp14()
{
super();
setSeed("myveryrandomentropy");
setPassword("myverysecretkey");
}
public void initBuf()
{
outBuf = new Ajp14Packet( headersWriter );
inBuf = new Ajp14Packet( MAX_PACKET_SIZE );
hBuf = new Ajp14Packet( MAX_PACKET_SIZE );
}
/**
* Set the original entropy seed
*/
public void setSeed(String pseed)
{
String[] credentials = new String[1];
credentials[0] = pseed;
seed = digest(credentials, "md5");
}
/**
* Get the original entropy seed
*/
public String getSeed()
{
return seed;
}
/**
* Set the secret password
*/
public void setPassword(String ppwd)
{
password = ppwd;
}
/**
* Get the secret password
*/
public String getPassword()
{
return password;
}
/**
* Compute a digest (MD5 in AJP14) for an array of String
*/
public final static String digest(String[] credentials, String algorithm) {
try {
// Obtain a new message digest with MD5 encryption
MessageDigest md = (MessageDigest)MessageDigest.getInstance(algorithm).clone();
// encode the credentials items
for (int i = 0; i < credentials.length; i++) {
// System.out.println("got : " + credentials[i]);
md.update(credentials[i].getBytes());
}
// obtain the byte array from the digest
byte[] dig = md.digest();
return HexUtils.convert(dig);
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
/**
* Read a new packet from the web server and decode it. If it's a
* forwarded request, store its properties in the passed-in Request
* 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(Request req) throws IOException
{
// XXX The return values are awful.
int err = receive(hBuf);
if(err < 0) {
return 500;
}
int type = (int)hBuf.getByte();
switch(type) {
case JK_AJP13_FORWARD_REQUEST:
if (logged)
return decodeRequest(req, hBuf);
else {
System.out.println("can't handle forward request until logged");
return 200;
}
case JK_AJP13_SHUTDOWN:
if (logged)
return -2;
else {
System.out.println("can't handle AJP13 shutdown command until logged");
return 200;
}
case JK_AJP14_LOGINIT_CMD :
if (! logged)
return handleLogInit(hBuf);
else {
System.out.println("shouldn't handle logint command when logged");
return 200;
}
case JK_AJP14_LOGCOMP_CMD :
if (! logged)
return handleLogComp(hBuf);
else {
System.out.println("shouldn't handle logcomp command when logged");
return 200;
}
case JK_AJP14_CONTEXT_QRY_CMD :
if (logged)
return handleContextQuery(hBuf);
else {
System.out.println("can't handle contextquery command until logged");
return 200;
}
case JK_AJP14_STATUS_CMD :
if (logged)
return handleStatus(hBuf);
else {
System.out.println("can't handle status command until logged");
return 200;
}
case JK_AJP14_SHUTDOWN_CMD :
if (logged)
return handleShutdown(hBuf);
else {
System.out.println("can't handle AJP14 shutdown command until logged");
return 200;
}
case JK_AJP14_CONTEXT_STATE_CMD :
if (logged)
return handleContextState(hBuf);
else {
System.out.println("can't handle contextstate command until logged");
return 200;
}
case JK_AJP14_UNKNOW_PACKET_CMD :
if (logged)
return handleUnknowPacket(hBuf);
else {
System.out.println("can't handle unknown packet command until logged");
return 200;
}
}
System.out.println("unknown command " + type + " received");
return 200; // XXX This is actually an error condition
}
/**
* Display Negociation field in human form
*/
private String decodeNegociation(int nego)
{
StringBuffer buf = new StringBuffer(128);
if ((nego & AJP14_CONTEXT_INFO_NEG) != 0)
buf.append(" CONTEXT-INFO");
if ((nego & AJP14_CONTEXT_UPDATE_NEG) != 0)
buf.append(" CONTEXT-UPDATE");
if ((nego & AJP14_GZIP_STREAM_NEG) != 0)
buf.append(" GZIP-STREAM");
if ((nego & AJP14_DES56_STREAM_NEG) != 0)
buf.append(" DES56-STREAM");
if ((nego & AJP14_SSL_VSERVER_NEG) != 0)
buf.append(" SSL-VSERVER");
if ((nego & AJP14_SSL_VCLIENT_NEG) != 0)
buf.append(" SSL-VCLIENT");
if ((nego & AJP14_SSL_VCRYPTO_NEG) != 0)
buf.append(" SSL-VCRYPTO");
if ((nego & AJP14_SSL_VMISC_NEG) != 0)
buf.append(" SSL-VMISC");
if ((nego & AJP14_PROTO_SUPPORT_AJP14_NEG) != 0)
buf.append(" AJP14");
if ((nego & AJP14_PROTO_SUPPORT_AJP15_NEG) != 0)
buf.append(" AJP15");
if ((nego & AJP14_PROTO_SUPPORT_AJP16_NEG) != 0)
buf.append(" AJP16");
return (new String(buf));
}
/**
* Handle the Initial Login Message from Web-Server
*
* Get the requested Negociation Flags
* Get also the Web-Server Name
*
* Send Login Seed (MD5 of seed)
*/
private int handleLogInit( AjpPacket msg ) throws IOException
{
webserverNegociation = msg.getLongInt();
webserverName = msg.getString();
System.out.println("in handleLogInit with nego " + decodeNegociation(webserverNegociation) + " from webserver " + webserverName);
outBuf.reset();
outBuf.appendByte(JK_AJP14_LOGSEED_CMD);
String[] credentials = new String[1];
credentials[0] = getSeed();
outBuf.appendXBytes(getSeed().getBytes(), 0, AJP14_ENTROPY_SEED_LEN);
System.out.println("in handleLogInit: sent entropy " + getSeed());
outBuf.end();
send(outBuf);
return 304;
}
/**
* Handle the Second Phase of Login (accreditation)
*
* Get the MD5 digest of entropy + secret password
* If the authentification is valid send back LogOk
* If the authentification failed send back LogNok
*/
private int handleLogComp( AjpPacket msg ) throws IOException
{
// System.out.println("in handleLogComp :");
byte [] rdigest = new byte[AJP14_ENTROPY_SEED_LEN];
if (msg.getXBytes(rdigest, AJP14_ENTROPY_SEED_LEN) < 0)
return 200;
String[] credentials = new String[2];
credentials[0] = getSeed();
credentials[1] = getPassword();
String computed = digest(credentials, "md5");
String received = new String(rdigest);
if (! computed.equalsIgnoreCase(received)) {
System.out.println("in handleLogComp : authentification failure received=" + received + " awaited=" + computed);
// we should have here a security mecanism which could maintain
// a list of remote IP which failed too many times
// so we could reject them quickly at next connect
outBuf.reset();
outBuf.appendByte(JK_AJP14_LOGNOK_CMD);
outBuf.appendLongInt(AJP14_BAD_KEY_ERR);
outBuf.end();
send(outBuf);
return 200;
} else {
logged = true; // logged we can go process requests
outBuf.reset();
outBuf.appendByte(JK_AJP14_LOGOK_CMD);
outBuf.appendLongInt(getProtocolFlags(webserverNegociation));
outBuf.appendString(ContextManager.TOMCAT_NAME + " v" + ContextManager.TOMCAT_VERSION);
outBuf.end();
send(outBuf);
}
return (304);
}
/**
* Compute the Protocol Negociation Flags
*
* Depending the protocol fatures implemented on servet-engine,
* we'll drop requested features which could be asked by web-server
*
* Hopefully this functions could be overrided by decendants (AJP15/AJP16...)
*/
private int getProtocolFlags(int wanted)
{
wanted &= ~(AJP14_CONTEXT_UPDATE_NEG | // no real-time context update yet
AJP14_GZIP_STREAM_NEG | // no gzip compression yet
AJP14_DES56_STREAM_NEG | // no DES56 cyphering yet
AJP14_SSL_VSERVER_NEG | // no Extended info on server SSL vars yet
AJP14_SSL_VCLIENT_NEG | // no Extended info on client SSL vars yet
AJP14_SSL_VCRYPTO_NEG | // no Extended info on crypto SSL vars yet
AJP14_SSL_VMISC_NEG | // no Extended info on misc SSL vars yet
AJP14_PROTO_SUPPORT_AJPXX_NEG); // Reset AJP protocol mask
return (wanted | AJP14_PROTO_SUPPORT_AJP14_NEG); // Only strict AJP14 supported
}
private int handleContextQuery( AjpPacket msg ) throws IOException
{
System.out.println("in handleContextQuery :");
return (304);
}
private int handleStatus( AjpPacket msg ) throws IOException
{
System.out.println("in handleStatus :");
return (304);
}
private int handleShutdown( AjpPacket msg ) throws IOException
{
System.out.println("in handleShutdown :");
return (304);
}
private int handleContextState( AjpPacket msg ) throws IOException
{
System.out.println("in handleContextState :");
return (304);
}
private int handleUnknowPacket( AjpPacket msg ) throws IOException
{
System.out.println("in handleUnknowPacket :");
return (304);
}
int decodeMoreHeaders(Request req, byte attribute, AjpPacket msg)
{
if (attribute == SC_A_SSL_KEY_SIZE) {
req.setAttribute("javax.servlet.request.key_size", Integer.toString(msg.getInt()));
return 200;
}
return 500; // Error
}
/**
* Close the socket connection to the web server. In general, sockets
* are maintained across many requests, so this will not be called
* after finish().
*
* @see Ajp14Interceptor#processConnection
*/
public void close() throws IOException {
if(null != out) {
out.close();
}
if(null !=in) {
in.close();
}
logged = false; // no more logged now
}
}
1.1 jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33/Ajp14Interceptor.java
Index: Ajp14Interceptor.java
===================================================================
/*
* $Header: /home/cvs/jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33/Ajp14Interceptor.java,v 1.1 2001/06/22 10:35:45 hgomez Exp $
* $Revision: 1.1 $
* $Date: 2001/06/22 10:35:45 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.ajp.tomcat33;
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.tomcat.core.*;
import org.apache.tomcat.util.net.*;
import org.apache.tomcat.util.*;
import org.apache.tomcat.util.log.*;
public class Ajp14Interceptor extends PoolTcpConnector
implements TcpConnectionHandler
{
public Ajp14Interceptor()
{
super();
}
// -------------------- PoolTcpConnector --------------------
protected void localInit() throws Exception {
ep.setConnectionHandler( this );
}
// -------------------- Handler implementation --------------------
public Object[] init()
{
Object thData[]=new Object[3];
Ajp14Request req=new Ajp14Request();
Ajp14Response res=new Ajp14Response();
cm.initRequest(req, res);
thData[0]=req;
thData[1]=res;
thData[2]=new Ajp14();
return thData;
}
// XXX
// Nothing overriden, right now AJPRequest implment AJP and read
// everything.
// "Shortcuts" to be added here ( Vhost and context set by Apache, etc)
// XXX handleEndpoint( Endpoint x )
public void processConnection(TcpConnection connection, Object thData[])
{
try {
if(connection == null) {
return;
}
Socket socket = connection.getSocket();
if(socket == null) {
return;
}
socket.setSoLinger( true, 100);
Ajp14 con=null;
Ajp14Request req=null;
Ajp14Response res=null;
if(thData != null) {
req = (Ajp14Request)thData[0];
res = (Ajp14Response)thData[1];
con = (Ajp14)thData[2];
if(req != null) req.recycle();
if(res != null) res.recycle();
if(con != null) con.recycle();
}
if(req == null || res == null || con == null) {
req = new Ajp14Request();
res = new Ajp14Response();
con = new Ajp14();
cm.initRequest( req, res );
}
// XXX
req.ajp14=con;
res.ajp14=con;
con.setSocket(socket);
boolean moreRequests = true;
while(moreRequests) {
int status=req.receiveNextRequest();
if( status==-2) {
// special case - shutdown
// XXX need better communication, refactor it
if( !doShutdown(socket.getLocalAddress(),
socket.getInetAddress())) {
moreRequests = false;
continue;
}
}
if( status == 200)
cm.service(req, res);
else if (status == 500)
break;
req.recycle();
res.recycle();
}
log("Closing connection", Log.DEBUG);
con.close();
socket.close();
} catch (Exception e) {
log("Processing connection " + connection, e);
}
}
public void setServer(Object contextM)
{
this.cm=(ContextManager)contextM;
}
protected boolean doShutdown(InetAddress serverAddr,
InetAddress clientAddr)
{
try {
// close the socket connection before handling any signal
// but get the addresses first so they are not corrupted
if(isSameAddress(serverAddr, clientAddr)) {
cm.stop();
// same behavior as in past, because it seems that
// stopping everything doesn't work - need to figure
// out what happens with the threads ( XXX )
System.exit(0);
}
} catch(Exception ignored) {
log("Ignored " + ignored);
}
log("Shutdown command ignored");
return false;
}
}
class Ajp14Request extends Request
{
Ajp14 ajp14=new Ajp14();
public Ajp14Request()
{
super();
}
protected int receiveNextRequest() throws IOException
{
return ajp14.receiveNextRequest( this );
}
public int doRead() throws IOException
{
if( available <= 0 )
return -1;
available--;
return ajp14.doRead();
}
public int doRead(byte[] b, int off, int len) throws IOException
{
if( available <= 0 )
return -1;
int rd=ajp14.doRead( b,off, len );
available -= rd;
return rd;
}
public void recycle()
{
super.recycle();
if( ajp14!=null) ajp14.recycle();
}
}
class Ajp14Response extends Response
{
Ajp14 ajp14;
boolean finished=false;
public Ajp14Response()
{
super();
}
public void recycle() {
super.recycle();
finished=false;
}
public void setSocket( Socket s ) {
ajp14=((Ajp14Request)request).ajp14;
}
// XXX if more headers that MAX_SIZE, send 2 packets!
public void endHeaders() throws IOException
{
super.endHeaders();
if (request.protocol().isNull()) {
return;
}
ajp14.sendHeaders(getStatus(), getMimeHeaders());
}
public void finish() throws IOException
{
if(!finished) {
super.finish();
finished = true; // Avoid END_OF_RESPONSE sent 2 times
ajp14.finish();
}
}
public void doWrite( byte b[], int off, int len) throws IOException
{
ajp14.doWrite(b, off, len );
}
}
1.1 jakarta-tomcat-connectors/jk/java/org/apache/ajp/tomcat33/Ajp14Packet.java
Index: Ajp14Packet.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.ajp.tomcat33;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Enumeration;
import java.security.*;
import org.apache.tomcat.core.*;
import org.apache.tomcat.util.*;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.HttpMessages;
import org.apache.tomcat.util.buf.HexUtils;
/**
* A single packet for communication between the web server and the
* container. Designed to be reused many times with no creation of
* garbage. Understands the format of data types for these packets.
* Can be used (somewhat confusingly) for both incoming and outgoing
* packets.
*
* @see Ajp14/Ajp13Packet
*
* @author Henri Gomez [hgomez@slib.fr]
* @author Dan Milstein [danmil@shore.net]
* @author Keith Wannamaker [Keith@Wannamaker.org]
*/
public class Ajp14Packet extends Ajp13Packet {
/**
* Create a new packet with an internal buffer of given size.
*/
public Ajp14Packet( int size ) {
super(size);
}
public Ajp14Packet( byte b[] ) {
super(b);
}
public Ajp14Packet( OutputBuffer ob ) {
super(ob);
}
/**
* Parse the packet header for a packet sent from the web server to
* the container. Set the read position to immediately after
* the header.
*
* @return The length of the packet payload, as encoded in the
* header, or -1 if the packet doesn't have a valid header.
*/
public int checkIn() {
pos = 0;
int mark = getInt();
len = getInt();
if( mark != 0x1235 ) {
// XXX Logging
System.out.println("BAD packet " + mark);
dump( "In: " );
return -1;
}
return len;
}
/**
* Prepare this packet for accumulating a message from the container to
* the web server. Set the write position to just after the header
* (but leave the length unwritten, because it is as yet unknown).
*/
public void reset() {
len = 4;
pos = 4;
buff[0] = (byte)0x12;
buff[1] = (byte)0x35;
}
}