FileDocCategorySizeDatePackage
MsgContext.javaAPI DocApache Tomcat 6.0.1413023Fri Jul 20 04:20:34 BST 2007org.apache.jk.core

MsgContext

public class MsgContext extends Object implements org.apache.coyote.ActionHook
author
Henri Gomez [hgomez@apache.org]
author
Dan Milstein [danmil@shore.net]
author
Keith Wannamaker [Keith@Wannamaker.org]
author
Kevin Seguin
author
Costin Manolache

Fields Summary
private static org.apache.juli.logging.Log
log
private static org.apache.juli.logging.Log
logTime
private int
type
private Object[]
notes
private JkHandler
next
private JkChannel
source
private org.apache.jk.common.JkInputStream
jkIS
private org.apache.tomcat.util.buf.C2BConverter
c2b
private org.apache.coyote.Request
req
private WorkerEnv
wEnv
private Msg[]
msgs
private int
status
private Object
control
private long[]
timers
private long
jkEndpointP
private long
xEnvP
public static final int
TIMER_RECEIVED
public static final int
TIMER_PRE_REQUEST
public static final int
TIMER_POST_REQUEST
public static final int
JK_STATUS_NEW
public static final int
JK_STATUS_HEAD
public static final int
JK_STATUS_CLOSED
public static final int
JK_STATUS_ERROR
Constructors Summary
public MsgContext(int bsize)


       
        try {
            c2b = new C2BConverter("iso-8859-1");
        } catch(IOException iex) {
            log.warn("Can't happen", iex);
        }
        jkIS = new JkInputStream(this, bsize);
    
public MsgContext()

deprecated

        this(8*1024);
    
Methods Summary
public voidaction(org.apache.coyote.ActionCode actionCode, java.lang.Object param)

        if( actionCode==ActionCode.ACTION_COMMIT ) {
            if( log.isDebugEnabled() ) log.debug("COMMIT " );
            Response res=(Response)param;

            if(  res.isCommitted() ) {
                if( log.isDebugEnabled() )
                    log.debug("Response already committed " );
            } else {
                try {
                    jkIS.appendHead( res );
                } catch(IOException iex) {
                    log.warn("Unable to send headers",iex);
                    setStatus(JK_STATUS_ERROR);
                }
            }
        } else if( actionCode==ActionCode.ACTION_RESET ) {
            if( log.isDebugEnabled() )
                log.debug("RESET " );
            
        } else if( actionCode==ActionCode.ACTION_CLIENT_FLUSH ) {
            if( log.isDebugEnabled() ) log.debug("CLIENT_FLUSH " );
            try {
                source.flush( null, this );
            } catch(IOException iex) {
                // This is logged elsewhere, so debug only here
                log.debug("Error during flush",iex);
                Response res = (Response)param;
                res.setErrorException(iex);
                setStatus(JK_STATUS_ERROR);
            }
            
        } else if( actionCode==ActionCode.ACTION_CLOSE ) {
            if( log.isDebugEnabled() ) log.debug("CLOSE " );
            
            Response res=(Response)param;
            if( getStatus()== JK_STATUS_CLOSED || getStatus() == JK_STATUS_ERROR) {
                // Double close - it may happen with forward 
                if( log.isDebugEnabled() ) log.debug("Double CLOSE - forward ? " + res.getRequest().requestURI() );
                return;
            }
                 
            if( !res.isCommitted() )
                this.action( ActionCode.ACTION_COMMIT, param );
            try {            
                jkIS.endMessage();
            } catch(IOException iex) {
                log.warn("Error sending end packet",iex);
                setStatus(JK_STATUS_ERROR);
            }
            if(getStatus() != JK_STATUS_ERROR) {
                setStatus(JK_STATUS_CLOSED );
            }

            if( logTime.isDebugEnabled() ) 
                logTime(res.getRequest(), res);
        } else if( actionCode==ActionCode.ACTION_REQ_SSL_ATTRIBUTE ) {
            Request req=(Request)param;

            // Extract SSL certificate information (if requested)
            MessageBytes certString = (MessageBytes)req.getNote(WorkerEnv.SSL_CERT_NOTE);
            if( certString != null && !certString.isNull() ) {
                ByteChunk certData = certString.getByteChunk();
                ByteArrayInputStream bais = 
                    new ByteArrayInputStream(certData.getBytes(),
                                             certData.getStart(),
                                             certData.getLength());
 
                // Fill the first element.
                X509Certificate jsseCerts[] = null;
                try {
                    CertificateFactory cf =
                        CertificateFactory.getInstance("X.509");
                    X509Certificate cert = (X509Certificate)
                        cf.generateCertificate(bais);
                    jsseCerts =  new X509Certificate[1];
                    jsseCerts[0] = cert;
                } catch(java.security.cert.CertificateException e) {
                    log.error("Certificate convertion failed" , e );
                    return;
                }
 
                req.setAttribute(SSLSupport.CERTIFICATE_KEY, 
                                 jsseCerts);
            }
                
        } else if( actionCode==ActionCode.ACTION_REQ_HOST_ATTRIBUTE ) {
            Request req=(Request)param;

            // If remoteHost not set by JK, get it's name from it's remoteAddr
            if( req.remoteHost().isNull()) {
                try {
                    req.remoteHost().setString(InetAddress.getByName(
                                               req.remoteAddr().toString()).
                                               getHostName());
                } catch(IOException iex) {
                    if(log.isDebugEnabled())
                        log.debug("Unable to resolve "+req.remoteAddr());
                }
            }
        } else if( actionCode==ActionCode.ACTION_ACK ) {
            if( log.isTraceEnabled() )
                log.trace("ACK " );
        } else if ( actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY ) {
            if( log.isTraceEnabled() )
                log.trace("Replay ");
            ByteChunk bc = (ByteChunk)param;
            req.setContentLength(bc.getLength());
            jkIS.setReplay(bc);
        }
    
public intexecute()
Invoke a java hook. The xEnv is the representation of the current execution environment ( the jni_env_t * )

        int status=next.invoke(msgs[0], this);
        return status;
    
public byte[]getBuffer(int id)
Each context contains a number of byte[] buffers used for communication. The C side will contain a char * equivalent - both buffers are long-lived and recycled. This will be called at init time. A long-lived global reference to the byte[] will be stored in the C context.

        // We use a single buffer right now. 
        if( msgs[id]==null ) {
            return null;
        }
        return msgs[id].getBuffer();
    
public java.lang.ObjectgetControl()

        return control;
    
public final org.apache.tomcat.util.buf.C2BConvertergetConverter()

        return c2b;
    
public org.apache.jk.common.JkInputStreamgetInputStream()

        return jkIS;
    
public longgetJniContext()

        return jkEndpointP;
    
public longgetJniEnv()

        return xEnvP;
    
public final longgetLong(int i)

        return timers[i];
    
public final MsggetMsg(int i)
The context may store a number of messages ( buffers + marshalling )

        return msgs[i];
    
public final JkHandlergetNext()

        return next;
    
public final java.lang.ObjectgetNote(int id)

        return notes[id];
    
public final org.apache.coyote.RequestgetRequest()

        return req;
    
public final JkChannelgetSource()

        return source;
    
public final intgetStatus()

        return status;
    
public final intgetType()
The id of the chain

        return type;
    
public final WorkerEnvgetWorkerEnv()

        return wEnv;
    
public final booleanisLogTimeEnabled()

        return logTime.isDebugEnabled();
    
private voidlogTime(org.apache.coyote.Request req, org.apache.coyote.Response res)

        // called after the request
        //            org.apache.coyote.Request req=(org.apache.coyote.Request)param;
        //            Response res=req.getResponse();
        String uri=req.requestURI().toString();
        if( uri.indexOf( ".gif" ) >0 ) return;
        
        setLong( MsgContext.TIMER_POST_REQUEST, System.currentTimeMillis());
        long t1= getLong( MsgContext.TIMER_PRE_REQUEST ) -
            getLong( MsgContext.TIMER_RECEIVED );
        long t2= getLong( MsgContext.TIMER_POST_REQUEST ) -
            getLong( MsgContext.TIMER_PRE_REQUEST );
        
        logTime.debug("Time pre=" + t1 + "/ service=" + t2 + " " +
                      res.getContentLength() + " " + 
                      uri );
    
public voidrecycle()

        jkIS.recycle();
    
public voidsetControl(java.lang.Object control)

        this.control = control;
    
public final voidsetConverter(org.apache.tomcat.util.buf.C2BConverter c2b)

        this.c2b = c2b;
    
public voidsetJniContext(long cContext)
The long-lived JNI context associated with this java context. The 2 share pointers to buffers and cache data to avoid expensive jni calls.

        this.jkEndpointP=cContext;
    
public voidsetJniEnv(long xEnvP)
Store native execution context data when this handler is called from JNI. This will change on each call, represent temproary call data.

            this.xEnvP=xEnvP;
    
public final voidsetLong(int i, long l)

        timers[i]=l;
    
public final voidsetMsg(int i, Msg msg)

        this.msgs[i]=msg;
    
public final voidsetNext(JkHandler ch)

        this.next=ch;
    
public final voidsetNote(int id, java.lang.Object o)

        notes[id]=o;
    
public final voidsetRequest(org.apache.coyote.Request req)
The high level request object associated with this context

        this.req=req;
        req.setInputBuffer(jkIS);
        Response res = req.getResponse();
        res.setOutputBuffer(jkIS);
        res.setHook(this);
    
public final voidsetSource(JkChannel ch)

        this.source=ch;
    
public final voidsetStatus(int s)

        status=s;
    
public final voidsetType(int i)

        type=i;
    
public final voidsetWorkerEnv(WorkerEnv we)

        this.wEnv=we;