| Method from org.apache.jk.core.MsgContext Detail: |
public void action(ActionCode actionCode,
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 " );
Response res = (Response)param;
if(!res.isCommitted()) {
action(ActionCode.ACTION_COMMIT, res);
}
try {
source.flush( null, this );
} catch(IOException iex) {
// This is logged elsewhere, so debug only here
log.debug("Error during flush",iex);
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 int execute() throws IOException {
int status=next.invoke(msgs[0], this);
return status;
}
Invoke a java hook. The xEnv is the representation of the current execution
environment ( the jni_env_t * ) |
public byte[] getBuffer(int id) {
// We use a single buffer right now.
if( msgs[id]==null ) {
return null;
}
return msgs[id].getBuffer();
}
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. |
public Object getControl() {
return control;
}
|
public final C2BConverter getConverter() {
return c2b;
}
|
public JkInputStream getInputStream() {
return jkIS;
}
|
public long getJniContext() {
return jkEndpointP;
}
|
public long getJniEnv() {
return xEnvP;
}
|
public final long getLong(int i) {
return timers[i];
}
|
public final Msg getMsg(int i) {
return msgs[i];
}
The context may store a number of messages ( buffers + marshalling ) |
public final JkHandler getNext() {
return next;
}
|
public final Object getNote(int id) {
return notes[id];
}
|
public final Request getRequest() {
return req;
}
|
public final JkChannel getSource() {
return source;
}
|
public final int getStatus() {
return status;
}
|
public final int getType() {
return type;
}
|
public final WorkerEnv getWorkerEnv() {
return wEnv;
}
|
public final boolean isLogTimeEnabled() {
return logTime.isDebugEnabled();
}
|
public void recycle() {
jkIS.recycle();
}
|
public void setControl(Object control) {
this.control = control;
}
|
public final void setConverter(C2BConverter c2b) {
this.c2b = c2b;
}
|
public void setJniContext(long cContext) {
this.jkEndpointP=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. |
public void setJniEnv(long xEnvP) {
this.xEnvP=xEnvP;
}
Store native execution context data when this handler is called
from JNI. This will change on each call, represent temproary
call data. |
public final void setLong(int i,
long l) {
timers[i]=l;
}
|
public final void setMsg(int i,
Msg msg) {
this.msgs[i]=msg;
}
|
public final void setNext(JkHandler ch) {
this.next=ch;
}
|
public final void setNote(int id,
Object o) {
notes[id]=o;
}
|
public final void setRequest(Request req) {
this.req=req;
req.setInputBuffer(jkIS);
Response res = req.getResponse();
res.setOutputBuffer(jkIS);
res.setHook(this);
}
The high level request object associated with this context |
public final void setSource(JkChannel ch) {
this.source=ch;
}
|
public final void setStatus(int s) {
status=s;
}
|
public final void setType(int i) {
type=i;
}
|
public final void setWorkerEnv(WorkerEnv we) {
this.wEnv=we;
}
|