You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2002/01/12 05:10:14 UTC
cvs commit: jakarta-tomcat-connectors/jk/java/org/apache/jk/server/tomcat40 JkConnector.java JkRequest40.java JkResponse40.java Worker40.java
costin 02/01/11 20:10:14
Added: jk/java/org/apache/jk/server/tomcat40 JkConnector.java
JkRequest40.java JkResponse40.java Worker40.java
Log:
Jk2-style connector for 4.0.
I couldn't find any way to make it work as a servlet ( class loader is a nightmare ),
so JkConnector must be added to server.xml and the jar files must be copied.
However we do use the JkServlet and web.xml for all the config - so configuration
will be identical and more importanly standard webapp tools ( and knowledge ) can be used.
Of course, there are other options as well - server.xml settings, workers.properties
( I'll try this later - it would be a nice idea to jave a single file for both C and java,
and set things like port only there ).
Webapp features like reloading ( or hot update, etc ) will probably not work with
4.0 ( probably not very usefull for most people anyway ).
Revision Changes Path
1.1 jakarta-tomcat-connectors/jk/java/org/apache/jk/server/tomcat40/JkConnector.java
Index: JkConnector.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.jk.server.tomcat40;
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import org.apache.catalina.*;
import org.apache.catalina.core.*;
import org.apache.catalina.net.DefaultServerSocketFactory;
import org.apache.catalina.net.ServerSocketFactory;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
import org.apache.jk.server.*;
import org.apache.catalina.jk.*;
/**
* Implementation of an Jk connector.
*
* @author Kevin Seguin
* @author Costin Manolache
*/
public final class JkConnector
implements Connector, Lifecycle {
/**
* The Container used for processing requests received by this Connector.
*/
protected Container container = null;
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
private boolean started = false;
private boolean stopped = false;
private Service service = null;
// ------------------------------------------------------------- Properties
/**
* Return the Container used for processing requests received by this
* Connector.
*/
public Container getContainer() {
return container;
}
/**
* Set the Container used for processing requests received by this
* Connector.
*
* @param container The new Container to use
*/
public void setContainer(Container container) {
this.container = container;
}
/**
* Return descriptive information about this Connector implementation.
*/
public String getInfo() {
return "JkConnector/2.0dev";
}
/**
* Returns the <code>Service</code> with which we are associated.
*/
public Service getService() {
return service;
}
/**
* Set the <code>Service</code> with which we are associated.
*/
public void setService(Service service) {
this.service = service;
}
// --------------------------------------------------------- Public Methods
/**
* Invoke a pre-startup initialization. This is used to allow connectors
* to bind to restricted ports under Unix operating environments.
* ServerSocket (we start as root and change user? or I miss something?).
*/
public void initialize() throws LifecycleException {
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Add a lifecycle event listener to this component.
*
* @param listener The listener to add
*/
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
/**
* Get the lifecycle listeners associated with this lifecycle. If this
* Lifecycle has no listeners registered, a zero-length array is returned.
*/
public LifecycleListener[] findLifecycleListeners() {
return null; // FIXME: lifecycle.findLifecycleListeners();
}
/**
* Remove a lifecycle event listener from this component.
*
* @param listener The listener to add
*/
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
Properties props=new Properties();
/**
* Begin processing requests via this Connector.
*
* @exception LifecycleException if a fatal startup error occurs
*/
public void start() throws LifecycleException {
JkConfig40 config=new JkConfig40();
lifecycle.fireLifecycleEvent(START_EVENT, null);
if( dL > 0 )
d( "Start " + container + " " + service );
Worker40 worker=new Worker40();
Container ct=service.getContainer();
worker.setContainer( ct );
((ContainerBase)ct).addLifecycleListener(config);
config.loadExisting( ct );
JkMain jkMain=new JkMain();
jkMain.setProperties( props );
jkMain.setDefaultWorker( worker );
String catalinaHome=System.getProperty("catalina.home");
File f=new File( catalinaHome );
File jkHomeF=new File( f, "webapps/jk" );
d("Setting jkHome " + jkHomeF );
jkMain.setJkHome( jkHomeF.getAbsolutePath() );
try {
jkMain.start();
} catch( Exception ex ) {
ex.printStackTrace();
}
}
/**
* Terminate processing requests via this Connector.
*
* @exception LifecycleException if a fatal shutdown error occurs
*/
public void stop() throws LifecycleException {
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
}
private static final int dL=10;
private static void d(String s ) {
System.err.println( "JkConnector: " + s );
}
// -------------------- Not used --------------------
public void setConnectionTimeout(int connectionTimeout) {}
public boolean getEnableLookups() { return false;}
public void setEnableLookups(boolean enableLookups) {}
public org.apache.catalina.net.ServerSocketFactory getFactory() { return null; }
public void setFactory(org.apache.catalina.net.ServerSocketFactory s) {}
public int getRedirectPort() { return -1; }
public void setRedirectPort(int i ) {}
public java.lang.String getScheme() { return null; }
public void setScheme(java.lang.String s ) {}
public boolean getSecure() { return false; }
public void setSecure(boolean b) {}
public org.apache.catalina.Request createRequest() { return null; }
public org.apache.catalina.Response createResponse() { return null; }
}
1.1 jakarta-tomcat-connectors/jk/java/org/apache/jk/server/tomcat40/JkRequest40.java
Index: JkRequest40.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.jk.server.tomcat40;
import java.io.*;
import java.util.List;
import java.util.Iterator;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Cookie;
import org.apache.catalina.connector.*;
import org.apache.catalina.*;
import org.apache.catalina.util.RequestUtil;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.Cookies;
import org.apache.tomcat.util.http.ServerCookie;
import org.apache.tomcat.util.http.BaseRequest;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.jk.core.*;
import org.apache.jk.common.*;
public class JkRequest40 extends HttpRequestBase {
private static final String match =
";" + Globals.SESSION_PARAMETER_NAME + "=";
private static int id = 1;
Channel ch;
Endpoint ep;
public JkRequest40() {
super();
}
public void recycle() {
// save response - we're a pair
Response res=response;
super.recycle();
response=res;
}
public void setEndpoint( Channel ch, Endpoint ep ) {
this.ch=ch;
this.ep=ep;
}
void setBaseRequest(BaseRequest ajp) throws UnsupportedEncodingException {
// XXX make this guy wrap AjpRequest so
// we're more efficient (that's the whole point of
// all of the MessageBytes in AjpRequest)
setMethod(ajp.method().toString());
setProtocol(ajp.protocol().toString());
setRequestURI(ajp.requestURI().toString());
setRemoteAddr(ajp.remoteAddr().toString());
setRemoteHost(ajp.remoteHost().toString());
setServerName(ajp.serverName().toString());
setServerPort(ajp.getServerPort());
String remoteUser = ajp.remoteUser().toString();
if (remoteUser != null) {
setUserPrincipal(new Ajp13Principal(remoteUser));
}
setAuthType(ajp.authType().toString());
setQueryString(ajp.queryString().toString());
setScheme(ajp.getScheme());
setSecure(ajp.getSecure());
setContentLength(ajp.getContentLength());
String contentType = ajp.contentType().toString();
if (contentType != null) {
setContentType(contentType);
}
MimeHeaders mheaders = ajp.headers();
int nheaders = mheaders.size();
for (int i = 0; i < nheaders; ++i) {
MessageBytes name = mheaders.getName(i);
MessageBytes value = mheaders.getValue(i);
addHeader(name.toString(), value.toString());
}
Iterator itr = ajp.getAttributeNames();
while (itr.hasNext()) {
String name = (String)itr.next();
setAttribute(name, ajp.getAttribute(name));
}
addCookies(ajp.cookies());
}
// public Object getAttribute(String name) {
// return ajp.getAttribute(name);
// }
// public Enumeration getAttributeNames() {
// return new Enumerator(ajp.getAttributeNames());
// }
public void setRequestURI(String uri) {
int semicolon = uri.indexOf(match);
if (semicolon >= 0) {
String rest = uri.substring(semicolon + match.length());
int semicolon2 = rest.indexOf(";");
if (semicolon2 >= 0) {
setRequestedSessionId(rest.substring(0, semicolon2));
rest = rest.substring(semicolon2);
} else {
setRequestedSessionId(rest);
rest = "";
}
setRequestedSessionURL(true);
uri = uri.substring(0, semicolon) + rest;
if (dL > 0)
d(" Requested URL session id is " +
((HttpServletRequest) getRequest())
.getRequestedSessionId());
} else {
setRequestedSessionId(null);
setRequestedSessionURL(false);
}
super.setRequestURI(uri);
}
private void addCookies(Cookies cookies) {
int ncookies = cookies.getCookieCount();
for (int j = 0; j < ncookies; j++) {
ServerCookie scookie = cookies.getCookie(j);
Cookie cookie = new Cookie(scookie.getName().toString(),
scookie.getValue().toString());
if (cookie.getName().equals(Globals.SESSION_COOKIE_NAME)) {
// Override anything requested in the URL
if (!isRequestedSessionIdFromCookie()) {
// Accept only the first session id cookie
setRequestedSessionId(cookie.getValue());
setRequestedSessionCookie(true);
setRequestedSessionURL(false);
if (dL > 0)
d(" Requested cookie session id is " +
((HttpServletRequest) getRequest())
.getRequestedSessionId());
}
}
if (dL > 0) {
d(" Adding cookie " + cookie.getName() + "=" +
cookie.getValue());
}
addCookie(cookie);
}
}
public ServletInputStream createInputStream() throws IOException {
return (ServletInputStream)getStream();
}
private static final int dL=0;
private static void d(String s ) {
System.err.println( "JkRequest40: " + s );
}
}
class Ajp13Principal implements java.security.Principal {
String user;
Ajp13Principal(String user) {
this.user = user;
}
public boolean equals(Object o) {
if (o == null) {
return false;
} else if (!(o instanceof Ajp13Principal)) {
return false;
} else if (o == this) {
return true;
} else if (this.user == null && ((Ajp13Principal)o).user == null) {
return true;
} else if (user != null) {
return user.equals( ((Ajp13Principal)o).user);
} else {
return false;
}
}
public String getName() {
return user;
}
public int hashCode() {
if (user == null) return 0;
else return user.hashCode();
}
public String toString() {
return getName();
}
}
class JkInputStream extends InputStream {
JkInputStream() {
}
public int available() throws IOException {
return 0;
}
public void close() throws IOException {
}
public void mark(int readLimit) {
}
public boolean markSupported() {
return false;
}
public void reset() throws IOException {
throw new IOException("reset() not supported");
}
byte singleRead[]=new byte[1];
public int read() throws IOException {
int rc=read( singleRead, 0, 1 );
if( rc== 1 )
return singleRead[0];
return -1;
}
public int read(byte[] b, int off, int len) throws IOException {
return -1;// ajp13.doRead(b, off, len);
}
public long skip(long n) throws IOException {
if (n > Integer.MAX_VALUE) {
throw new IOException("can't skip than many: " + n);
}
// XXX if n is big, split this in multiple reads
byte[] b = new byte[(int)n];
return read(b, 0, b.length);
}
}
1.1 jakarta-tomcat-connectors/jk/java/org/apache/jk/server/tomcat40/JkResponse40.java
Index: JkResponse40.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.jk.server.tomcat40;
import java.io.*;
import java.util.Iterator;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.catalina.connector.HttpResponseBase;
import org.apache.catalina.*;
import org.apache.catalina.util.CookieTools;
import org.apache.jk.core.*;
import org.apache.jk.common.*;
import org.apache.tomcat.util.http.MimeHeaders;
public class JkResponse40 extends HttpResponseBase {
private boolean finished = false;
private boolean headersSent = false;
private MimeHeaders headers = new MimeHeaders();
private StringBuffer cookieValue = new StringBuffer();
Channel ch;
Endpoint ep;
int headersMsgNote;
int utfC2bNote;
public JkResponse40(WorkerEnv we)
{
super();
headersMsgNote=we.getNoteId( WorkerEnv.ENDPOINT_NOTE, "headerMsg" );
utfC2bNote=we.getNoteId( WorkerEnv.ENDPOINT_NOTE, "utfC2B" );
}
String getStatusMessage() {
return getStatusMessage(getStatus());
}
public void recycle() {
// We're a pair - preserve
Request req=request;
super.recycle();
request=req;
this.finished = false;
this.headersSent = false;
this.stream=null;
this.headers.recycle();
}
protected void sendHeaders() throws IOException {
if( dL>0 ) d("sendHeaders " + headersSent);
if (headersSent) {
// don't send headers twice
return;
}
headersSent = true;
int numHeaders = 0;
if (getContentType() != null) {
numHeaders++;
}
if (getContentLength() >= 0) {
numHeaders++;
}
// Add the session ID cookie if necessary
HttpServletRequest hreq = (HttpServletRequest)request.getRequest();
HttpSession session = hreq.getSession(false);
if ((session != null) && session.isNew() && (getContext() != null)
&& getContext().getCookies()) {
Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,
session.getId());
cookie.setMaxAge(-1);
String contextPath = null;
if (context != null)
contextPath = context.getPath();
if ((contextPath != null) && (contextPath.length() > 0))
cookie.setPath(contextPath);
else
cookie.setPath("/");
if (hreq.isSecure())
cookie.setSecure(true);
addCookie(cookie);
}
// Send all specified cookies (if any)
synchronized (cookies) {
Iterator items = cookies.iterator();
while (items.hasNext()) {
Cookie cookie = (Cookie) items.next();
cookieValue.delete(0, cookieValue.length());
CookieTools.getCookieHeaderValue(cookie, cookieValue);
addHeader(CookieTools.getCookieHeaderName(cookie),
cookieValue.toString());
}
}
// figure out how many headers...
// can have multiple headers of the same name...
// need to loop through headers once to get total
// count, once to add header to outBuf
String[] hnames = getHeaderNames();
Object[] hvalues = new Object[hnames.length];
int i;
for (i = 0; i < hnames.length; ++i) {
String[] tmp = getHeaderValues(hnames[i]);
numHeaders += tmp.length;
hvalues[i] = tmp;
}
C2B c2b=(C2B)ep.getNote( utfC2bNote );
if( c2b==null ) {
c2b=new C2B( "UTF8" );
ep.setNote( utfC2bNote, c2b );
}
if( dL>0 ) d("sendHeaders " + numHeaders );
MsgAjp msg=(MsgAjp)ep.getNote( headersMsgNote );
msg.reset();
msg.appendByte(HandlerRequest.JK_AJP13_SEND_HEADERS);
msg.appendInt( getStatus() );
c2b.convert( getStatusMessage(getStatus()));
c2b.flushBuffer();
msg.appendByteChunk(c2b.getByteChunk());
c2b.recycle();
String contentType=getContentType();
int cl=getContentLength();
msg.appendInt(numHeaders);
if ( contentType != null) {
sendHeader(msg, c2b, "Content-Type", contentType );
}
if ( cl >= 0) {
sendHeader(msg, c2b, "Content-Length", String.valueOf(cl));
}
// XXX do we need this ? If so, we need to adjust numHeaders
// and avoid duplication
for (i = 0; i < hnames.length; ++i) {
String name = hnames[i];
String[] values = (String[])hvalues[i];
for (int j = 0; j < values.length; ++j) {
sendHeader( msg, c2b, name, values[j] );
}
}
msg.send( ch, ep );
// The response is now committed
committed = true;
}
private void sendHeader( Msg msg, C2B c2b, String n, String v )
throws IOException
{
if( dL > 0 ) d( "SendHeader " + n + " " + v );
c2b.convert( n );
c2b.flushBuffer();
msg.appendByteChunk(c2b.getByteChunk());
c2b.recycle();
c2b.convert( v );
c2b.flushBuffer();
msg.appendByteChunk(c2b.getByteChunk());
c2b.recycle();
}
public void finishResponse() throws IOException {
if( dL>0 ) d("finishResponse " + this.finished );
if(!this.finished) {
super.finishResponse();
this.finished = true; // Avoid END_OF_RESPONSE sent 2 times
MsgAjp msg=(MsgAjp)ep.getNote( headersMsgNote );
msg.reset();
msg.appendByte( HandlerRequest.JK_AJP13_END_RESPONSE );
msg.appendInt( 1 );
msg.send(ch, ep );
}
}
public void write(byte b[], int off, int len ) throws IOException {
if( dL>0 ) d("write " + len);
if( !headersSent ) sendHeaders();
MsgAjp msg=(MsgAjp)ep.getNote( headersMsgNote );
msg.reset();
msg.appendByte( HandlerRequest.JK_AJP13_SEND_BODY_CHUNK);
msg.appendBytes( b, off, len );
msg.send( ch, ep );
}
void setEndpoint(Channel ch, Endpoint ep) {
this.ch=ch;
this.ep=ep;
MsgAjp msg=(MsgAjp)ep.getNote( headersMsgNote );
if( msg==null ) {
msg=new MsgAjp();
ep.setNote( headersMsgNote, msg );
}
setStream( new JkOutputStream( this ));
}
private static final int dL=10;
private static void d(String s ) {
System.err.println( "JkResponse40: " + s );
}
}
class JkOutputStream extends OutputStream {
JkResponse40 resp;
JkOutputStream(JkResponse40 resp) {
this.resp=resp;
}
//XXX buffer
byte singeByteWrite[]=new byte[1];
public void write(int b) throws IOException {
singeByteWrite[0]=(byte)b;
write(singeByteWrite, 0, 1);
}
public void write(byte[] b, int off, int len) throws IOException {
resp.write( b, off, len );
}
public void close() throws IOException {
}
public void flush() throws IOException {
}
}
1.1 jakarta-tomcat-connectors/jk/java/org/apache/jk/server/tomcat40/Worker40.java
Index: Worker40.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.jk.server.tomcat40;
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.jk.*;
import org.apache.tomcat.modules.server.PoolTcpConnector;
import org.apache.tomcat.util.net.*;
import org.apache.tomcat.util.buf.*;
import org.apache.tomcat.util.log.*;
import org.apache.tomcat.util.http.*;
import org.apache.jk.core.*;
import org.apache.catalina.*;
/** Tomcat 40 worker
*
*/
public class Worker40 extends Worker
{
private int reqNote;
Container container;
public Worker40()
{
super();
}
public void setContainer( Container ct40 ) {
this.container=ct40;
}
public void init(WorkerEnv we) throws IOException {
reqNote=we.getNoteId( WorkerEnv.REQUEST_NOTE, "tomcat40Request" );
}
public void service( BaseRequest req, Channel ch, Endpoint ep )
throws IOException
{
d("Incoming request " );
JkRequest40 treq=(JkRequest40)req.getNote( reqNote );
JkResponse40 tres;
if( treq==null ) {
treq=new JkRequest40();
req.setNote( reqNote, treq );
tres=new JkResponse40(we);
treq.setResponse( tres );
tres.setRequest( treq );
}
tres=(JkResponse40)treq.getResponse();
treq.setEndpoint( ch, ep );
treq.setBaseRequest( req );
tres.setEndpoint( ch, ep );
try {
container.invoke( treq, tres );
} catch(Throwable ex ) {
ex.printStackTrace();
}
d("Finishing response");
tres.finishResponse();
treq.finishRequest();
treq.recycle();
tres.recycle();
}
private static final int dL=0;
private static void d(String s ) {
System.err.println( "Worker40: " + s );
}
// -------------------- Handler implementation --------------------
// /** Construct the request object, with probably unnecesary
// sanity tests ( should work without thread pool - but that is
// not supported in PoolTcpConnector, maybe in future )
// */
// private Ajp14Request initRequest(Object thData[] ) {
// if( ajp14_note < 0 ) throw new RuntimeException( "assert: ajp14_note>0" );
// Ajp14Request req=null;
// if( thData != null ) {
// req=(Ajp14Request)thData[0];
// }
// if( req != null ) {
// Response res=req.getResponse();
// req.recycle();
// res.recycle();
// // make the note available to other modules
// req.setNote( ajp14_note, req.ajp13);
// return req;
// }
// // either thData==null or broken ( req==null)
// Ajp13 ajp13=new Ajp13(reqHandler);
// negHandler.init( ajp13 );
// negHandler.setContainerSignature( ContextManager.TOMCAT_NAME +
// " v" + ContextManager.TOMCAT_VERSION);
// if( password!= null ) {
// negHandler.setPassword( password );
// ajp13.setBackward(false);
// }
// BaseRequest ajpreq=new BaseRequest();
// req=new Ajp14Request(ajp13, ajpreq);
// Ajp14Response res=new Ajp14Response(ajp13);
// cm.initRequest(req, res);
// return req;
// }
// /** Called whenever a new TCP connection is received. The connection
// is reused.
// */
// public void processConnection(TcpConnection connection, Object thData[])
// {
// try {
// if( debug>0)
// log( "Received ajp14 connection ");
// Socket socket = connection.getSocket();
// // assert: socket!=null, connection!=null ( checked by PoolTcpEndpoint )
// socket.setSoLinger( true, 100);
// Ajp14Request req=initRequest( thData );
// Ajp14Response res= (Ajp14Response)req.getResponse();
// Ajp13 ajp13=req.ajp13;
// BaseRequest ajpReq=req.ajpReq;
// ajp13.setSocket(socket);
// // first request should be the loginit.
// int status=ajp13.receiveNextRequest( ajpReq );
// if( status != 304 ) { // XXX use better codes
// log( "Failure in logInit ");
// return;
// }
// status=ajp13.receiveNextRequest( ajpReq );
// if( status != 304 ) { // XXX use better codes
// log( "Failure in login ");
// return;
// }
// boolean moreRequests = true;
// while(moreRequests) {
// status=ajp13.receiveNextRequest( ajpReq );
// 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) {
// log( "Invalid request received " + req );
// break;
// }
// req.recycle();
// res.recycle();
// }
// if( debug > 0 ) log("Closing ajp14 connection");
// ajp13.close();
// socket.close();
// } catch (Exception e) {
// log("Processing connection " + connection, e);
// }
// }
// // We don't need to check isSameAddress if we authenticate !!!
// 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 )
// // XXX It should work now - but will fail if servlets create
// // threads
// System.exit(0);
// }
// } catch(Exception ignored) {
// log("Ignored " + ignored);
// }
// log("Shutdown command ignored");
// return false;
// }
// // legacy, should be removed
// public void setServer(Object contextM)
// {
// this.cm=(ContextManager)contextM;
// }
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>