costin 02/01/06 00:39:38 Added: jk/java/org/apache/catalina/jk JkRequest40.java JkResponse40.java Worker40.java Log: Initial ( not complete yet ) impl, mostly cut&paste from the existing connector. Revision Changes Path 1.1 jakarta-tomcat-connectors/jk/java/org/apache/catalina/jk/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 [EMAIL PROTECTED] * * 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.catalina.jk; import java.io.IOException; import java.io.UnsupportedEncodingException; 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.HttpRequestBase; import org.apache.catalina.Globals; 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; public JkRequest40() { super(); } public void recycle() { super.recycle(); } void setAjpRequest(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(); } } 1.1 jakarta-tomcat-connectors/jk/java/org/apache/catalina/jk/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 [EMAIL PROTECTED] * * 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.catalina.jk; import java.io.IOException; 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.Globals; 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() { super.recycle(); this.finished = false; this.headersSent = false; this.headers.recycle(); } protected void sendHeaders() throws IOException { 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 ); } MsgAjp msg=(MsgAjp)ep.getNote( headersMsgNote ); msg.reset(); msg.appendByte(HandlerRequest.JK_AJP13_SEND_HEADERS); msg.appendInt( getStatus() ); c2b.convert( getStatusMessage(getStatus())); msg.appendByteChunk(c2b.getByteChunk()); c2b.recycle(); msg.appendInt(numHeaders); // XXX do we need this ? If so, we need to adjust numHeaders // and avoid duplication // // send each header // if (getContentType() != null) { // ajp13.sendHeader("Content-Type", getContentType()); // } // if (getContentLength() >= 0) { // ajp13.sendHeader("Content-Length", String.valueOf(getContentLength())); // } for (i = 0; i < hnames.length; ++i) { String name = hnames[i]; String[] values = (String[])hvalues[i]; for (int j = 0; j < values.length; ++j) { c2b.convert( name ); msg.appendByteChunk(c2b.getByteChunk()); c2b.recycle(); c2b.convert( values[j] ); msg.appendByteChunk(c2b.getByteChunk()); c2b.recycle(); } } msg.send( ch, ep ); // The response is now committed committed = true; } public void finishResponse() throws IOException { 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 ); } } 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 ); } } } 1.1 jakarta-tomcat-connectors/jk/java/org/apache/catalina/jk/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 [EMAIL PROTECTED] * * 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.catalina.jk; 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 { public Worker40() { super(); } Container container; public void setContainer( Container ct40 ) { this.container=ct40; } public void service( BaseRequest req, Channel ch, Endpoint ep ) throws IOException { d("Incoming request " ); // container.invoke( req40, res40 ); } 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: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>