jicarilla-sandbox/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing KeepAliveStage.java,NONE,1.1 PlumbingUtil.java,NONE,1.1 ReallySimpleChannelFactory.java,NONE,1.1 RequestRewritingStage.java,NONE,1.1 ServerInformationHeadersStage.java,NONE,1.1 AbstractStage.java,1.2,1.3 BenchmarkStage.java,1.1,1.2 FilesystemStage.java,1.2,1.3 HTTPEvent.java,1.2,1.3 ParsingStage.java,1.2,1.3 ResponseCompletionStage.java,1.2,1.3 BeanshellHTTPChannelFactory.java,1.1,NONE GeneralAndResponseHeadersStage.java,1.2,NONE

Leo Simons <[email protected]> Thu, 15 Apr 2004 09:43:12 +0000
Newsgroups gmane.comp.java.jicarilla.cvs
Message-ID <[email protected]>
Update of /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4871/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing

Modified Files:
	AbstractStage.java BenchmarkStage.java FilesystemStage.java 
	HTTPEvent.java ParsingStage.java ResponseCompletionStage.java 
Added Files:
	KeepAliveStage.java PlumbingUtil.java 
	ReallySimpleChannelFactory.java RequestRewritingStage.java 
	ServerInformationHeadersStage.java 
Removed Files:
	BeanshellHTTPChannelFactory.java 
	GeneralAndResponseHeadersStage.java 
Log Message:
I forgot to commit some work the other day. Mostly plumbing work on the HTTP server.

Index: ResponseCompletionStage.java
===================================================================
RCS file: /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing/ResponseCompletionStage.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ResponseCompletionStage.java	9 Apr 2004 15:52:27 -0000	1.2
+++ ResponseCompletionStage.java	15 Apr 2004 09:43:10 -0000	1.3
@@ -29,6 +29,7 @@
 import org.jicarilla.http.Encoding;
 import org.jicarilla.http.Field;
 import org.jicarilla.http.Message;
+import org.jicarilla.http.MessageUtil;
 import org.jicarilla.http.util.NioUtil;
 import org.jicarilla.plumbing.Sink;
 
@@ -50,104 +51,7 @@
 
     protected void process( final HTTPEvent e )
     {
-        ensureStartLine( e );
-        ensureContentLengthHeader( e );
-    }
-
-    protected void ensureStartLine( final HTTPEvent e )
-    {
-        final Message res = e.getHTTPResponse();
-
-        if( res.getField1() == null )
-            res.setField1( Encoding.VERSION_10 );
-        if( res.getField2() == null )
-            res.setStatusCode( Encoding.STATUS_200_OK );
-        if( res.getField3() == null )
-            res.setField3( Encoding.STATUS_MSG[res.getStatusCode()] );
-    }
-
-    protected void ensureContentLengthHeader( final HTTPEvent e )
-    {
-        final Message req = e.getHTTPRequest();
-        final Message res = e.getHTTPResponse();
-
-        if( contentLengthNotSet( res ) )
-        {
-            if( noBodySoNoContentLengthHeader( req, res ) )
-                return;
-
-            if( nonIdentifyTransferCodingPresent( req, res ) )
-                return;
-
-            final ByteBuffer[] body = res.getBodyParts();
-            if( body.length == 0 )
-            {
-                res.addHeader(
-                        Encoding.HEADER_CONTENT_LENGTH_BUFFER,
-                        NioUtil.toByteBuffer( 0 )
-                );
-            }
-            else
-            {
-                int size = 0;
-                for( int i = 0; i < body.length; i++ )
-                {
-                    final ByteBuffer byteBuffer = body[i];
-                    size += byteBuffer.remaining();
-                }
-
-                res.addHeader(
-                        Encoding.HEADER_CONTENT_LENGTH_BUFFER,
-                        NioUtil.toByteBuffer( size )
-                );
-            }
-        }
-    }
-
-    private boolean noBodySoNoContentLengthHeader( final Message req,
-            final Message res )
-    {
-        if( Encoding.METHOD_HEAD.equals( req.getField1String() ) )
-            return true;
-
-        final int responseCode = res.getStatusCode();
-        if( (Encoding.STATUS_100_Continue <= responseCode && responseCode < Encoding.STATUS_200_OK) ||
-                responseCode == Encoding.STATUS_204_No_Content ||
-                responseCode == Encoding.STATUS_304_Not_Modified )
-            return true;
-
-        return false;
-    }
-
-    protected boolean nonIdentifyTransferCodingPresent( final Message req,
-            final Message res )
-    {
-        final Iterator it = res.getHeaders().iterator();
-        while( it.hasNext() )
-        {
-            final Field field = (Field)it.next();
-            if( Encoding.HEADER_TRANSFER_ENCODING.equals(
-                    field.getNameString() ) )
-            {
-                return !Encoding.CONTENT_CODING_IDENTITY.equals(
-                        field.getNameString() );
-            }
-        }
-        return false;
-    }
-
-    protected boolean contentLengthNotSet( final Message response )
-    {
-        final Iterator it = response.getHeaders().iterator();
-        while( it.hasNext() )
-        {
-            final Field field = (Field)it.next();
-            if( field.getName().equals(
-                    Encoding.HEADER_CONTENT_LENGTH_BUFFER ) )
-            {
-                return false;
-            }
-        }
-        return true;
+        MessageUtil.ensureStartLine( e );
+        MessageUtil.ensureContentLengthHeader( e );
     }
 }

Index: HTTPEvent.java
===================================================================
RCS file: /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing/HTTPEvent.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- HTTPEvent.java	9 Apr 2004 15:52:27 -0000	1.2
+++ HTTPEvent.java	15 Apr 2004 09:43:10 -0000	1.3
@@ -36,6 +36,7 @@
  */
 public class HTTPEvent extends Event
 {
+    // todo why synchronized? 
     public synchronized Message getHTTPRequest()
     {
         if( getRequest() == null )

--- NEW FILE: KeepAliveStage.java ---
/* ====================================================================
The Jicarilla Software License

Copyright (c) 2003 Leo Simons.
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.webserver.plumbing;


import org.jicarilla.plumbing.Sink;
import org.jicarilla.http.HTTPException;
import org.jicarilla.http.Encoding;
import org.jicarilla.net.SocketServerImpl;
import org.apache.commons.pool.ObjectPool;
import EDU.oswego.cs.dl.util.concurrent.Channel;
import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;

import java.util.Map;

import junit.framework.Assert;

/**
 * 
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: KeepAliveStage.java,v 1.1 2004/04/15 09:43:10 lsimons Exp $
 * @todo refactor the common functionality of SocketServImpl and this class out
 */
public class KeepAliveStage extends AbstractStage
{

    protected PooledExecutor m_threadPool;
    protected ObjectPool m_handlerPool;
    protected ObjectPool m_eventPool;

    public KeepAliveStage( Channel channel, Sink errorHandler,
            ObjectPool keepAliveHandlerObjectPool, ObjectPool
            eventPool, PooledExecutor threadPool )
    {
        super( channel, errorHandler );
        
        Assert.assertNotNull(
                "keepAliveHandlerObjectPool argument may not be null",
                keepAliveHandlerObjectPool );
        Assert.assertNotNull( "threadPool argument may not be null",
                threadPool );
        Assert.assertNotNull( "eventPool argument may not be null", eventPool );
        m_handlerPool = keepAliveHandlerObjectPool;
        m_threadPool = threadPool;
        m_eventPool = eventPool;
    }

    public void process( final HTTPEvent e ) throws HTTPException
    {
        if( PlumbingUtil.shouldDoKeepAlive( e ) )
        {
            try
            {
                handleKeepAlive( e );
            }
            catch( Exception ex )
            {
                throw new HTTPException(
                        Encoding.STATUS_500_Internal_Server_Error,
                        ex
                );
            }
        }
    }

    protected void handleKeepAlive( HTTPEvent e ) throws Exception
    {
        Channel handler =
                (Channel)m_handlerPool.borrowObject();
        
        HTTPEvent newEvent = (HTTPEvent)m_eventPool.borrowObject();
        newEvent.setChannel( e.getChannel() );
        
        // run the channel
        SocketServerImpl.setPoolReturningSink( m_threadPool, m_handlerPool,
                m_eventPool, handler, newEvent );
        handler.put( newEvent );
    }
}

Index: AbstractStage.java
===================================================================
RCS file: /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing/AbstractStage.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- AbstractStage.java	9 Apr 2004 15:52:12 -0000	1.2
+++ AbstractStage.java	15 Apr 2004 09:42:54 -0000	1.3
@@ -51,9 +51,6 @@
  */
 public abstract class AbstractStage extends DefaultStage
 {
-    public final static String EXCEPTION_CONTEXT_KEY = "urn:jicarilla:http:context-key:" +
-            AbstractStage.class.getPackage().getName() + "exception";
-
     protected AbstractStage( final Channel channel,
             final Sink errorHandler )
     {
@@ -74,9 +71,13 @@
         }
         catch( IOException ioe )
         {
-            handleException( e,
-                    new HTTPException( Encoding.STATUS_999_IO_Problem,
-                            ioe ) );
+            handleException(
+                    e,
+                    new HTTPException(
+                            Encoding.STATUS_999_IO_Problem,
+                            ioe
+                    )
+            );
         }
     }
 
@@ -95,9 +96,12 @@
         }
         catch( IOException ioe )
         {
-            handleException( e,
-                    new HTTPException( Encoding.STATUS_999_IO_Problem,
-                            ioe ) );
+            handleException(
+                    e,
+                    new HTTPException(
+                            Encoding.STATUS_999_IO_Problem,
+                            ioe )
+            );
         }
 
         return true;
@@ -111,11 +115,9 @@
     {
         Assert.assertNotNull( event );
 
-        ensureContext( event );
-        final Map m = event.getContext();
-        if( !m.containsKey( EXCEPTION_CONTEXT_KEY ) )
+        if( !PlumbingUtil.hasAnExceptionOccurred( event ) )
         {
-            m.put( EXCEPTION_CONTEXT_KEY, t );
+            PlumbingUtil.setException( event, t );
 
             if( t instanceof HTTPException )
             {
@@ -125,35 +127,4 @@
         }
         handleError( event );
     }
-    protected static void ensureContext( final Event event )
-    {
-        Assert.assertNotNull( event );
-
-        if( event.getContext() == null )
-            event.setContext( new HashMap() );
-    }
-
-    public static boolean checkExceptionOccured( final Event event )
-    {
-        Assert.assertNotNull( event );
-
-        //ensureContext( event );
-        final Map m = event.getContext();
-        if( m != null && m.containsKey( EXCEPTION_CONTEXT_KEY ) )
-            return true;
-
-        return false;
-    }
-
-    public static Throwable getThrowable( final Event event )
-    {
-        Assert.assertNotNull( event );
-        //ensureContext( event );
-
-        final Map m = event.getContext();
-        if( m != null && m.containsKey( EXCEPTION_CONTEXT_KEY ) )
-            return (Throwable)m.get( EXCEPTION_CONTEXT_KEY );
-
-        return null;
-    }
-}
+}
\ No newline at end of file

--- GeneralAndResponseHeadersStage.java DELETED ---

Index: FilesystemStage.java
===================================================================
RCS file: /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing/FilesystemStage.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- FilesystemStage.java	9 Apr 2004 15:52:26 -0000	1.2
+++ FilesystemStage.java	15 Apr 2004 09:43:09 -0000	1.3
@@ -44,11 +44,12 @@
 {
     protected FileReader m_fileReader;
 
-    public FilesystemStage( final Channel queue, final Sink errorHandler, final FileReader fr )
+    public FilesystemStage( final Channel queue, final Sink errorHandler,
+            final FileReader fr )
     {
         super( queue, errorHandler );
 
-        setFileReader( fr);
+        setFileReader( fr );
     }
 
     public FileReader getFileReader()

Index: BenchmarkStage.java
===================================================================
RCS file: /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing/BenchmarkStage.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- BenchmarkStage.java	31 Mar 2004 12:11:00 -0000	1.1
+++ BenchmarkStage.java	15 Apr 2004 09:43:09 -0000	1.2
@@ -59,21 +59,18 @@
         if( !e.getContext().containsKey( BENCHMARK_START_CONTEXT_KEY ) )
         {
             final long startTime = System.currentTimeMillis();
-            e.getContext().put( BENCHMARK_START_CONTEXT_KEY, new Long( startTime ) );
+            e.getContext().put(
+                    BENCHMARK_START_CONTEXT_KEY, new Long( startTime ) );
         }
         else
         {
-            final long startTime = ((Long)e.getContext().get( BENCHMARK_START_CONTEXT_KEY )).longValue();
+            final long startTime = ((Long)e.getContext()
+                    .get( BENCHMARK_START_CONTEXT_KEY )).longValue();
 
             e.getHTTPResponse().addHeader(
                     "Debug-Time-Taken",
                     ""+(System.currentTimeMillis() - startTime)/MILLISECONDS_IN_A_SECOND
             );
-
-            /*e.getHTTPResponse().addBodyPart(
-                    "Debugging....time taken: "
-                    +(System.currentTimeMillis() - startTime)/1000.0 + "\r\n\r\n"
-            );*/
         }
     }
 }

--- NEW FILE: ServerInformationHeadersStage.java ---
/* ====================================================================
The Jicarilla Software License

Copyright (c) 2003 Leo Simons.
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.webserver.plumbing;

import EDU.oswego.cs.dl.util.concurrent.Channel;
import org.jicarilla.http.Message;
import org.jicarilla.http.Encoding;
import org.jicarilla.lang.Assert;
import org.jicarilla.plumbing.Sink;

/**
 * 
 * @todo Connection header
 * @todo Date header
 * @todo put constants in Encoding
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: ServerInformationHeadersStage.java,v 1.1 2004/04/15 09:43:10 lsimons Exp $
 */
public class ServerInformationHeadersStage extends AbstractStage
{
    protected String m_serverIdentification;

    public ServerInformationHeadersStage( final Channel channel, final Sink errorHandler,
            final String serverIdentification )
    {
        super( channel, errorHandler );
        Assert.assertNotNull( "serverIdentification argument may not be null",
                serverIdentification );
        m_serverIdentification = serverIdentification;
    }

    protected void process( final HTTPEvent event )
    {
        final Message res = event.getHTTPResponse();

        res.addHeader( Encoding.HEADER_SERVER, m_serverIdentification );
        
        // todo remove
        res.addHeader( Encoding.HEADER_CONNECTION_BUFFER,
                Encoding.HEADER_CONNECTION_CLOSE_BUFFER );
    }
}

--- NEW FILE: PlumbingUtil.java ---
/* ====================================================================
The Jicarilla Software License

Copyright (c) 2003 Leo Simons.
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.webserver.plumbing;

import org.jicarilla.net.Event;
import junit.framework.Assert;

import java.util.HashMap;
import java.util.Map;

/**
 * 
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: PlumbingUtil.java,v 1.1 2004/04/15 09:43:10 lsimons Exp $
 */
public class PlumbingUtil
{
    public final static String EXCEPTION_CONTEXT_KEY = "urn:jicarilla:http:context-key:" +
            AbstractStage.class.getPackage().getName() + "exception";
    public final static String KEEPALIVE_CONTEXT_KEY = "urn:jicarilla:http:context-key:" +
           KeepAliveStage.class.getPackage().getName() + ":doKeepAlive";

    public static boolean hasAnExceptionOccurred( final Event event )
    {
        Assert.assertNotNull( event );

        return event.getContext().containsKey(
                EXCEPTION_CONTEXT_KEY );
    }

    public static Throwable getThrowable( final Event event )
    {
        Assert.assertNotNull( event );

        final Map m = event.getContext();
        if( m != null && m.containsKey( EXCEPTION_CONTEXT_KEY ) )
            return (Throwable)m.get( EXCEPTION_CONTEXT_KEY );

        return null;
    }

    public static void setException( final Event event, final Throwable t )
    {
        event.getContext().put( EXCEPTION_CONTEXT_KEY, t );
    }

    public static boolean isExceptionSet( final HTTPEvent event )
    {
        return event.getContext().containsKey(
                EXCEPTION_CONTEXT_KEY );
    }

    public static boolean shouldDoKeepAlive( HTTPEvent e )
    {
        if( e == null ) return false;
        
        Map context = e.getContext();
        Boolean keepAlive = (Boolean)context.get( KEEPALIVE_CONTEXT_KEY );
        if( keepAlive.booleanValue() )
            return true;
        else
            return false;
    }
}

Index: ParsingStage.java
===================================================================
RCS file: /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/impl/src/java/org/jicarilla/webserver/plumbing/ParsingStage.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ParsingStage.java	9 Apr 2004 15:52:27 -0000	1.2
+++ ParsingStage.java	15 Apr 2004 09:43:10 -0000	1.3
@@ -27,6 +27,7 @@
 
 import EDU.oswego.cs.dl.util.concurrent.Channel;
 import org.apache.commons.pool.impl.SoftReferenceObjectPool;
+import org.apache.commons.pool.ObjectPool;
 import org.jicarilla.http.Encoding;
 import org.jicarilla.http.HTTPException;
 import org.jicarilla.http.Message;
@@ -55,29 +56,26 @@
 {
     public final static int BUFFER_SIZE = 8096;
 
-    protected ParserImpl m_parser;
+    protected Parser m_parser;
     protected MessageGenerator m_generator;
     protected Listener m_listener;
-
-    public ParsingStage( final Channel queue, final Sink errorHandler )
+    
+    public ParsingStage( final Channel queue, final Sink errorHandler,
+            final ObjectPool messagePool )
     {
         super( queue, errorHandler );
 
-        // todo: remove hard-wiring
         setListener( new Listener() );
         setGenerator(
                 new MessageGenerator(
                         getListener(),
                         getListener(),
-                        new SoftReferenceObjectPool( new MessageFactory() )
-                )
-        );
-        setParser(
-                new ParserImpl(
-                        getGenerator(),
-                        getGenerator()
+                        messagePool
                 )
         );
+        
+        Parser parser = new ParserImpl( getGenerator(), getGenerator() );
+        m_parser = parser;
     }
 
     protected Listener getListener()
@@ -115,47 +113,18 @@
     {
         try
         {
-            // todo: robustness
             final SocketChannel c = e.getChannel();
-            HTTPException ex = null;
-            while( true )
-            {
-                if( getListener().message != null )
-                    break;
 
-                final ByteBuffer buf = ByteBuffer.allocate( BUFFER_SIZE );
-                final int read = c.read( buf );
-
-                if( read < 0 )
-                    break;
-                if( read == 0 )
-                {
-                    Thread.yield();
-                    continue;
-                }
+            runParser( c );
 
-                buf.rewind();
+            if( getListener().throwable != null )
+                throw new HTTPException( Encoding.STATUS_400_Bad_Request,
+                        getListener().throwable );
 
-                try
-                {
-                    getParser().parse( buf, read );
-                }
-                catch( HTTPException he )
-                {
-                    ex = he;
-                    break;
-                }
-            }
             if( getListener().message == null )
-            {
-                // note the listener will have heard of the exception
-                // if the message is not null :D
-                m_listener.exceptionOccurred( ex );
-            }
-            else
-            {
-                e.setRequest( getListener().message );
-            }
+                throw new HTTPException( Encoding.STATUS_400_Bad_Request );
+
+            e.setRequest( getListener().message );
         }
         finally
         {
@@ -165,10 +134,36 @@
         }
     }
 
-    protected static class Listener
+    protected void runParser( final SocketChannel c )
+            throws IOException, HTTPException
+    {
+        while( true )
+        {
+            if( getListener().message != null )
+                break;
+
+            final ByteBuffer buf = ByteBuffer.allocate( BUFFER_SIZE );
+            final int read = c.read( buf );
+
+            if( read < 0 )
+                break;
+            if( read == 0 )
+            {
+                Thread.yield();
+                continue;
+            }
+
+            buf.rewind();
+            
+            getParser().parse( buf, read );
+        }
+    }
+
+    protected class Listener
             implements MessageReceivedListener, ExceptionListener
     {
         public Message message = null;
+        public Throwable throwable;
 
         public void messageReceived( final Message m )
         {
@@ -177,24 +172,7 @@
 
         public void exceptionOccurred( final Throwable t )
         {
-            // todo improve
-            final Message exMessage = new Message();
-            exMessage.setMessageType( Message.TYPE_RESPONSE );
-            exMessage.setField1( Encoding.VERSION_10 );
-            exMessage.setStatusCode(
-                    Encoding.STATUS_500_Internal_Server_Error );
-            exMessage.setField3( "Internal Server Error" );
-
-            final StringWriter sw = new StringWriter();
-            final PrintWriter pw = new PrintWriter(sw);
-
-            t.printStackTrace(pw);
-            exMessage.addHeader( "Content-Type", "text/html");
-            exMessage.addBodyPart( "<html><head><title>Internal Server Error</title></head><body><h1>An unexpected exception occurred:</h1><pre>" );
-            exMessage.addBodyPart( sw.toString() );
-            exMessage.addBodyPart( "</pre></body><html>" );
-
-            message = exMessage;
+            throwable = t;
         }
     }
 }

--- BeanshellHTTPChannelFactory.java DELETED ---

--- NEW FILE: RequestRewritingStage.java ---
/* ====================================================================
The Jicarilla Software License

Copyright (c) 2003 Leo Simons.
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.webserver.plumbing;

import EDU.oswego.cs.dl.util.concurrent.Channel;
import org.jicarilla.plumbing.Sink;
import org.jicarilla.webserver.RequestRewriter;
import org.jicarilla.lang.Assert;
import org.jicarilla.http.Message;

/**
 * 
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: RequestRewritingStage.java,v 1.1 2004/04/15 09:43:10 lsimons Exp $
 */
public class RequestRewritingStage extends AbstractStage
{
    protected RequestRewriter m_rewriter;
    
    public RequestRewritingStage( Channel channel, Sink errorHandler,
            RequestRewriter rewriter )
    {
        super( channel, errorHandler );
        
        Assert.assertNotNull( "rewriter argument may not be null", rewriter );
        m_rewriter = rewriter;
    }

    public void process( HTTPEvent e )
    {
        Message m = e.getHTTPRequest();
        m_rewriter.rewrite( m );
    }
}

--- NEW FILE: ReallySimpleChannelFactory.java ---
/* ====================================================================
 The Jicarilla Software License

 Copyright (c) 2003 Leo Simons.
 All rights reserved.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.webserver.plumbing;

import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
import org.jicarilla.lang.Assert;
import org.jicarilla.lang.RecyclingObjectFactory;
import org.jicarilla.net.Event;
import org.jicarilla.plumbing.NoopSink;
import org.jicarilla.plumbing.PostProcessor;
import org.jicarilla.plumbing.Stage;
import org.jicarilla.http.MessageFactory;
import org.jicarilla.http.ParserImpl;
import org.apache.commons.pool.impl.SoftReferenceObjectPool;

/**
 *
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: ReallySimpleChannelFactory.java,v 1.1 2004/04/15 09:43:10 lsimons Exp $
 */
public class ReallySimpleChannelFactory extends RecyclingObjectFactory
{
    //private Stage m_stage;

    public synchronized Object makeObject() throws Exception
    {
        //if( m_stage == null )
        //{
            /*Interpreter i = new Interpreter();
            i.source( "create-pipeline.bsh" );

            m_stage = (Stage)i.get( "pipeline" );*/

        //    m_stage = createPipeline();
        //}
        //return m_stage;
        return createPipeline();
    }

    public Stage createPipeline()
    {
        final PostProcessor processor = new PostProcessor(
                new LinkedQueue(),
                new NoopSink()
                )
        {
            public void put( final Object o ) throws InterruptedException
            {
                final HTTPEvent e = getEvent( o );
                super.put( e );
            }

            public boolean offer( final Object o, final long l ) throws InterruptedException
            {
                final HTTPEvent e = getEvent( o );
                return super.offer( e, l );
            }

            protected HTTPEvent getEvent( final Object o )
            {
                Assert.assertTrue( o instanceof Event );

                if( o instanceof HTTPEvent )
                    return (HTTPEvent)o;

                final Event ev = (Event)o;
                final HTTPEvent e = new HTTPEvent();
                e.setChannel( ev.getChannel() );
                e.setContext( ev.getContext() );
                return e;
            }
        };

        processor.addStage(
                new BenchmarkStage( // start
                        new LinkedQueue(),
                        new NoopSink()
                )
        );
        processor.addStage(
                new ParsingStage(
                        new LinkedQueue(),
                        new NoopSink(),
                        new SoftReferenceObjectPool( new MessageFactory() )
                )
        );
        processor.addStage(
                new EchoStage(
                        new LinkedQueue(),
                        new NoopSink()
                )
        );
        /*processor.addStage(
                new FilesystemStage(
                        new LinkedQueue(),
                        new NoopSink(),
                        new FilesystemImpl(".")
                )
        );*/
        processor.addStage(
                new BenchmarkStage( // finish
                        new LinkedQueue(),
                        new NoopSink()
                )
        );
        processor.addStage(
                new WritingStage(
                        new LinkedQueue(),
                        new NoopSink()
                )
        );

        return processor;
    }
}



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click