You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by tr...@apache.org on 2007/11/19 04:41:35 UTC

svn commit: r596187 [2/3] - in /mina: sandbox/asyncweb/ sandbox/asyncweb/core/ sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/ sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/ sandbox/asyncweb/core/src/main/java/org/sa...

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpCodecUtils.java (from r596084, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/HttpCodecUtils.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpCodecUtils.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpCodecUtils.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/HttpCodecUtils.java&r1=596084&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/HttpCodecUtils.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpCodecUtils.java Sun Nov 18 19:41:14 2007
@@ -17,25 +17,29 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.codec;
+package org.apache.mina.filter.codec.http;
 
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.mina.common.IoBuffer;
 import org.apache.mina.filter.codec.ProtocolDecoderException;
-import org.safehaus.asyncweb.codec.decoder.HttpDecoderException;
-import org.safehaus.asyncweb.common.HttpResponseStatus;
-import org.safehaus.asyncweb.common.HttpResponseStatus.Category;
+import org.apache.mina.filter.codec.http.HttpResponseStatus.Category;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class HttpCodecUtils {
+class HttpCodecUtils {
 
     /**
      * The default charset we employ
      */
     public static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
 
+    public static final String US_ASCII_CHARSET_NAME = "US-ASCII";
+
     /**
      * Ampersand character
      */
@@ -111,8 +115,6 @@
      */
     private static final byte[] CRLF_BYTES = new byte[] { CR, LF };
 
-    private static final String US_ASCII_CHARSET_NAME = "US-ASCII";
-
     /**
      * A lookup table for HTPP separator characters
      */
@@ -236,7 +238,7 @@
     }
 
     /**
-     * Throws a {@link HttpDecoderException} with a specified cause.
+     * Throws a {@link HttpRequestDecoderException} with a specified cause.
      * This method should be used when the request is badly formed.
      *
      * @param cause  The cause
@@ -247,7 +249,7 @@
     }
 
     /**
-     * Throws a {@link HttpDecoderException} with a specified response
+     * Throws a {@link HttpRequestDecoderException} with a specified response
      * status
      *
      * @param message   The cause
@@ -263,7 +265,7 @@
         if (LOG.isInfoEnabled()) {
             LOG.info("Decode failure. Cause: " + message);
         }
-        throw new HttpDecoderException(message, status);
+        throw new HttpRequestDecoderException(message, status);
     }
 
     /**
@@ -300,6 +302,47 @@
      */
     public static void appendCRLF(IoBuffer buffer) {
         buffer.put(CRLF_BYTES);
+    }
+    
+    /**
+     * Encodes the headers of a <code>Response</code> to a specified buffer.
+     * This encoder does not make smart decisions about which headers to write -
+     * the response is expected to already contain self-consistent headers.
+     *
+     * @param message  The response whose headers are to be encoded
+     * @param buffer   The buffer
+     */
+    public static void encodeHeaders(
+            HttpMessage message, IoBuffer buffer, CharsetEncoder encoder) throws CharacterCodingException {
+        
+        try {
+            for (Map.Entry<String, List<String>> header : message.getHeaders()
+                    .entrySet()) {
+                byte[] key = header.getKey().getBytes("US-ASCII");
+                for (String value : header.getValue()) {
+                    buffer.put(key);
+                    buffer.put((byte) ':');
+                    buffer.put((byte) ' ');
+                    buffer.putString(value, encoder);
+                    HttpCodecUtils.appendCRLF(buffer);
+                }
+            }
+        } catch (UnsupportedEncodingException e) {
+            throw new InternalError("US-ASCII should be available.");
+        }
+
+        HttpCodecUtils.appendCRLF(buffer);
+    }
+
+    /**
+     * Writes the response body bytes, if any, to the specified buffer
+     *
+     * @param message  The response
+     * @param buffer   The buffer to write to
+     */
+    public static void encodeBody(HttpMessage message, IoBuffer buffer) {
+        IoBuffer content = (IoBuffer) message.getContent();
+        buffer.put(content);
     }
 
     static {

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpDateFormat.java (from r596084, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/util/HttpDateFormat.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpDateFormat.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpDateFormat.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/util/HttpDateFormat.java&r1=596084&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/util/HttpDateFormat.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpDateFormat.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.util;
+package org.apache.mina.filter.codec.http;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderConstants.java (from r596084, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/util/HttpHeaderConstants.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderConstants.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderConstants.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/util/HttpHeaderConstants.java&r1=596084&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/util/HttpHeaderConstants.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderConstants.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.util;
+package org.apache.mina.filter.codec.http;
 
 /**
  * HTTP Header Constants.
@@ -47,6 +47,18 @@
      * The header value to indicate connection keep-alive (http 1.0)
      */
     public static final String VALUE_KEEP_ALIVE = "Keep-Alive";
+    
+    /**
+     * The "content-type" header name.
+     */
+    public static final String KEY_CONTENT_TYPE = "Content-Type";
+    
+    /**
+     * The value of "content-type" header that indicates the content contains a
+     * URL-encoded form.
+     */
+    public static final String VALUE_URLENCODED_FORM =
+        "application/x-www-form-urlencoded";
 
     /**
      * The "content-length" header name

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderDecodingState.java (from r596084, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpHeaderDecodingState.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderDecodingState.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderDecodingState.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpHeaderDecodingState.java&r1=596084&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpHeaderDecodingState.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderDecodingState.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.codec.decoder;
+package org.apache.mina.filter.codec.http;
 
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;

Added: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderNameComparator.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderNameComparator.java?rev=596187&view=auto
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderNameComparator.java (added)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderNameComparator.java Sun Nov 18 19:41:14 2007
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.filter.codec.http;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+public class HttpHeaderNameComparator implements Comparator<String>, Serializable {
+    private static final long serialVersionUID = -3781572057321507963L;
+
+    public static final HttpHeaderNameComparator INSTANCE = new HttpHeaderNameComparator();
+
+    public int compare(String o1, String o2) {
+        return o1.compareToIgnoreCase(o2);
+    }
+
+    private Object readResolve() {
+        return INSTANCE;
+    }
+}

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderNameComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpHeaderNameComparator.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpMessage.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpMessage.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpMessage.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpMessage.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpMessage.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpMessage.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpMessage.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 import java.io.Serializable;
 import java.util.List;
@@ -27,7 +27,7 @@
 /**
  * Base message type of {@link HttpRequest} and {@link HttpResponse}.
  *
- * @author trustin
+ * @author The Apache MINA Project (dev@mina.apache.org)
  * @version $Rev$, $Date$
  */
 public interface HttpMessage extends Serializable {
@@ -79,5 +79,5 @@
     /**
      * Returns the content of the request body.
      */
-    Content getContent();
+    Object getContent();
 }

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpMethod.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpMethod.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpMethod.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpMethod.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpMethod.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpMethod.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpMethod.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 /**
  * Type-safe enumeration of standard HTTP Methods

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequest.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpRequest.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequest.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequest.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpRequest.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpRequest.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequest.java Sun Nov 18 19:41:14 2007
@@ -17,22 +17,17 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 import java.net.URI;
 import java.util.List;
 import java.util.Map;
 
 /**
- * Represents a HTTP request made by a client.
- * <code>HttpRequest</code>s may be responded to asyncronously at any
- * time. <code>createHttpResponse</code> should be used to create a
- * response to be populated - and when ready should be committed to the
- * client using <code>commitResponse</code>
- *
- * @author irvingd
- * @author trustin
- *
+ * A HTTP request.
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
  */
 public interface HttpRequest extends HttpMessage {
 
@@ -42,7 +37,7 @@
      *
      * @param name  The parameter name
      * @return      <code>true</code> if this request contains at least one parameter
-     *              with the specfied name
+     *              with the specified name
      */
     boolean containsParameter(String name);
 
@@ -90,7 +85,7 @@
     boolean isKeepAlive();
 
     /**
-     * Determines whether ths request requires a "100-continue" response.
+     * Determines whether this request requires a "100-continue" response.
      * A client may set a continuation expectation when sending a request
      * before continuing to send the body of a request (e.g. because it
      * would be inefficient to send the whole body if the server will

Added: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoder.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoder.java?rev=596187&view=auto
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoder.java (added)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoder.java Sun Nov 18 19:41:14 2007
@@ -0,0 +1,43 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.filter.codec.http;
+
+import java.util.List;
+
+import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.apache.mina.filter.codec.statemachine.DecodingState;
+import org.apache.mina.filter.codec.statemachine.StateMachineProtocolDecoder;
+
+/**
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class HttpRequestDecoder extends StateMachineProtocolDecoder {
+    public HttpRequestDecoder() {
+        super(new HttpResponseDecodingState() {
+            @Override
+            protected DecodingState finishDecode(List<Object> childProducts,
+                    ProtocolDecoderOutput out) throws Exception {
+                // Never be executed.
+                return null;
+            }
+        });
+    }
+}

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoder.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoderException.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoderException.java?rev=596187&view=auto
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoderException.java (added)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoderException.java Sun Nov 18 19:41:14 2007
@@ -0,0 +1,68 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.filter.codec.http;
+
+import org.apache.mina.filter.codec.ProtocolDecoderException;
+
+/**
+ * An exception thrown by HTTP decoders.
+ *
+ * This exception enables decoders which are capable of determining the type of
+ * failure to specify the response which is ultimately returned to the client.
+ *
+ * @author irvingd
+ * @author trustin
+ * @version $Rev$, $Date$
+ */
+public class HttpRequestDecoderException extends ProtocolDecoderException {
+
+    private static final long serialVersionUID = 3256999969109063480L;
+
+    private HttpResponseStatus responseStatus;
+
+    /**
+     * Creates a new instance with the default response status code
+     * ({@link HttpResponseStatus#BAD_REQUEST}).
+     *
+     * @param message The description of the failure
+     */
+    public HttpRequestDecoderException(String message) {
+        this(message, HttpResponseStatus.BAD_REQUEST);
+    }
+
+    /**
+     * Creates a new instance.
+     *
+     * @param message         A description of the failure
+     * @param responseStatus  The associated response status
+     */
+    public HttpRequestDecoderException(String message,
+            HttpResponseStatus responseStatus) {
+        super(message);
+        this.responseStatus = responseStatus;
+    }
+
+    /**
+     * Returns the response status associated with this exception.
+     */
+    public HttpResponseStatus getResponseStatus() {
+        return responseStatus;
+    }
+}

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoderException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecoderException.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecodingState.java (from r596084, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpRequestDecodingState.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecodingState.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecodingState.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpRequestDecodingState.java&r1=596084&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpRequestDecodingState.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestDecodingState.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.codec.decoder;
+package org.apache.mina.filter.codec.http;
 
 import java.net.URI;
 import java.util.List;
@@ -30,14 +30,6 @@
 import org.apache.mina.filter.codec.statemachine.DecodingState;
 import org.apache.mina.filter.codec.statemachine.DecodingStateMachine;
 import org.apache.mina.filter.codec.statemachine.FixedLengthDecodingState;
-import org.safehaus.asyncweb.codec.HttpCodecUtils;
-import org.safehaus.asyncweb.common.DefaultHttpRequest;
-import org.safehaus.asyncweb.common.HttpMethod;
-import org.safehaus.asyncweb.common.HttpRequest;
-import org.safehaus.asyncweb.common.HttpResponseStatus;
-import org.safehaus.asyncweb.common.HttpVersion;
-import org.safehaus.asyncweb.common.MutableHttpRequest;
-import org.safehaus.asyncweb.common.content.ByteBufferContent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -134,7 +126,7 @@
             request.setMethod((HttpMethod) childProducts.get(0));
             request.setRequestUri(requestUri);
             request.setProtocolVersion((HttpVersion) childProducts.get(2));
-            request.setParameters(requestUri.getQuery());
+            request.setParameters(requestUri.getRawQuery());
             return READ_HEADERS;
         }
     };
@@ -193,10 +185,9 @@
                                 body.put(chunk);
                             }
                             body.flip();
-                            request.setContent(new ByteBufferContent(body));
+                            request.setContent(body);
                         } else {
-                            request.setContent(new ByteBufferContent(
-                                    (IoBuffer) childProducts.get(0)));
+                            request.setContent((IoBuffer) childProducts.get(0));
                         }
 
                         out.write(request);
@@ -215,7 +206,7 @@
                         @Override
                         protected DecodingState finishDecode(IoBuffer readData,
                                 ProtocolDecoderOutput out) throws Exception {
-                            request.setContent(new ByteBufferContent(readData));
+                            request.setContent(readData);
                             out.write(request);
                             return null;
                         }

Modified: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestEncoder.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestEncoder.java?rev=596187&r1=596186&r2=596187&view=diff
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestEncoder.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestEncoder.java Sun Nov 18 19:41:14 2007
@@ -19,13 +19,9 @@
  */
 package org.apache.mina.filter.codec.http;
 
-import java.net.URL;
-import java.nio.charset.CharacterCodingException;
+import java.net.URI;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetEncoder;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 import org.apache.mina.common.IoBuffer;
 import org.apache.mina.common.IoSession;
@@ -39,133 +35,39 @@
  * @version $Rev$, $Date$
  */
 public class HttpRequestEncoder extends ProtocolEncoderAdapter {
-    private static final byte[] CRLF = new byte[] { 0x0D, 0x0A };
 
-    private static final String POST_CONTENT_TYPE = "application/x-www-form-urlencoded";
+    private static final Charset US_ASCII = Charset.forName("US-ASCII");
+    private final CharsetEncoder asciiEncoder = US_ASCII.newEncoder();
 
-    private URL url;
-
-    public HttpRequestEncoder(URL url) {
-        this.url = url;
+    public HttpRequestEncoder() {
     }
 
-    public void encode(IoSession ioSession, Object message,
+    public void encode(
+            IoSession session, Object message,
             ProtocolEncoderOutput out) throws Exception {
-        HttpRequestMessage msg = (HttpRequestMessage) message;
-
-        IoBuffer buf = IoBuffer.allocate(256);
-
-        // Enable auto-expand for easier encoding
-        buf.setAutoExpand(true);
-
-        try {
-            //If we have content, lets create the query string
-            int attrCount = msg.getParameters().size();
-            String urlAttrs = "";
-            if (attrCount > 0) {
-                NameValuePair attrs[] = new NameValuePair[attrCount];
-                Set<Map.Entry<String, String>> set = msg.getParameters()
-                        .entrySet();
-                int i = 0;
-                for (Map.Entry<String, String> entry : set) {
-                    attrs[i++] = new NameValuePair(entry.getKey(), entry
-                            .getValue());
-                }
-                urlAttrs = EncodingUtil.formUrlEncode(attrs, Charset
-                        .defaultCharset().toString());
-            }
-
-            CharsetEncoder encoder = Charset.defaultCharset().newEncoder();
-            buf.putString(msg.getRequestMethod(), encoder);
-            buf.putString(" ", encoder);
-            buf.putString(msg.getPath(), encoder);
-            //If its a GET, append the attributes
-            if (msg.getRequestMethod().equals(HttpRequestMessage.REQUEST_GET)
-                    && attrCount > 0) {
-                //If there is not already a ? in the query, append one, otherwise append a &
-                if (!msg.getPath().contains("?")) {
-                    buf.putString("?", encoder);
-                } else {
-                    buf.putString("&", encoder);
-                }
-                buf.putString(urlAttrs, encoder);
-            }
-            buf.putString(" HTTP/1.1", encoder);
-            buf.put(CRLF);
-
-            //This header is required for HTTP/1.1
-            buf.putString("Host: ", encoder);
-            buf.putString(url.getHost(), encoder);
-            if ((url.getProtocol().equals("http") && url.getPort() != 80 && url
-                    .getPort() != -1)
-                    && (url.getProtocol().equals("https")
-                            && url.getPort() != 443 && url.getPort() != -1)) {
-                buf.putString(":", encoder);
-                buf.putString(url.getPort() + "", encoder);
-            }
-            buf.put(CRLF);
-
-            //Process any headers we have
-            List<NameValuePair> headers = msg.getHeaders();
-            for (NameValuePair header : headers) {
-                String name = header.getName();
-                String value = header.getValue();
-
-                buf.putString(name, encoder);
-                buf.putString(": ", encoder);
-                buf.putString(value, encoder);
-                buf.put(CRLF);
-            }
-
-            //Process cookies
-            //NOTE: I am just passing the name value pairs and not doing management of the expiration or path
-            //As that will be left up to the user.  A possible enhancement is to make use of a CookieManager
-            //to handle these issues for the request
-            List<Cookie> cookies = msg.getCookies();
-            if (cookies.size() > 0) {
-                buf.putString("Cookie: ", encoder);
-                for (Cookie cookie : cookies) {
-                    String name = cookie.getName();
-                    String value = cookie.getValue();
-
-                    buf.putString(name, encoder);
-                    buf.putString("=", encoder);
-                    buf.putString(value, encoder);
-                    buf.putString("; ", encoder);
-                }
-                buf.put(CRLF);
-            }
-
-            //If this is a POST, then we need a content length and type
-            if (msg.getRequestMethod().equals(HttpRequestMessage.REQUEST_POST)) {
-                byte content[] = urlAttrs.getBytes();
-
-                //Type
-                buf.putString(HttpMessage.CONTENT_TYPE, encoder);
-                buf.putString(": ", encoder);
-                buf.putString(POST_CONTENT_TYPE, encoder);
-                buf.put(CRLF);
-
-                //Length
-                buf.putString(HttpMessage.CONTENT_LENGTH, encoder);
-                buf.putString(": ", encoder);
-                buf.putString(content.length + "", encoder);
-                buf.put(CRLF);
-                //Blank line
-                buf.put(CRLF);
-                buf.put(content);
-            } else {
-                //Blank line
-                buf.put(CRLF);
-            }
-
-        } catch (CharacterCodingException ex) {
-            ex.printStackTrace();
+        
+        asciiEncoder.reset();
+        HttpRequest req = (HttpRequest) message;
+        IoBuffer buf = IoBuffer.allocate(256).setAutoExpand(true);
+
+        // Write request line.
+        buf.putString(req.getMethod().toString(), asciiEncoder);
+        buf.put((byte) ' ');
+        
+        URI uri = req.getRequestUri();
+        buf.putString(uri.getPath(), asciiEncoder);
+        String query = uri.getQuery();
+        if (query != null && query.length() > 0) {
+            buf.put((byte) '?');
+            buf.putString(query, asciiEncoder);
         }
+        buf.putString(" HTTP/1.1", asciiEncoder);
+        HttpCodecUtils.appendCRLF(buf);
+
+        HttpCodecUtils.encodeHeaders(req, buf, asciiEncoder);
+        HttpCodecUtils.encodeBody(req, buf);
 
         buf.flip();
         out.write(buf);
-
     }
-
 }

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestLineDecodingState.java (from r596084, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpRequestLineDecodingState.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestLineDecodingState.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestLineDecodingState.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpRequestLineDecodingState.java&r1=596084&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/codec/decoder/HttpRequestLineDecodingState.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpRequestLineDecodingState.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.codec.decoder;
+package org.apache.mina.filter.codec.http;
 
 import java.net.URI;
 import java.nio.charset.Charset;
@@ -25,16 +25,11 @@
 
 import org.apache.mina.common.IoBuffer;
 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
-import org.apache.mina.filter.codec.statemachine.ConsumeToDynamicTerminatorDecodingState;
 import org.apache.mina.filter.codec.statemachine.ConsumeToLinearWhitespaceDecodingState;
 import org.apache.mina.filter.codec.statemachine.CrLfDecodingState;
 import org.apache.mina.filter.codec.statemachine.DecodingState;
 import org.apache.mina.filter.codec.statemachine.DecodingStateMachine;
 import org.apache.mina.filter.codec.statemachine.LinearWhitespaceSkippingState;
-import org.safehaus.asyncweb.codec.HttpCodecUtils;
-import org.safehaus.asyncweb.common.HttpMethod;
-import org.safehaus.asyncweb.common.HttpResponseStatus;
-import org.safehaus.asyncweb.common.HttpVersion;
 
 /**
  * Decodes an HTTP request line - populating an associated <code>Request</code>
@@ -106,24 +101,12 @@
         }
     };
 
-    private final DecodingState READ_PROTOCOL_VERSION = new ConsumeToDynamicTerminatorDecodingState() {
+    private final DecodingState READ_PROTOCOL_VERSION = new HttpVersionDecodingState() {
         @Override
-        protected DecodingState finishDecode(IoBuffer product,
-                ProtocolDecoderOutput out) throws Exception {
-            String versionStr = product.getString(asciiDecoder);
-            HttpVersion version = HttpVersion.valueOf(versionStr);
-            if (version == null) {
-                HttpCodecUtils.throwDecoderException(
-                        "Unsupported HTTP version: " + versionStr,
-                        HttpResponseStatus.HTTP_VERSION_NOT_SUPPORTED);
-            }
+        protected DecodingState finishDecode(
+                HttpVersion version, ProtocolDecoderOutput out) throws Exception {
             out.write(version);
             return AFTER_READ_PROTOCOL_VERSION;
-        }
-
-        @Override
-        protected boolean isTerminator(byte b) {
-            return Character.isWhitespace(b);
         }
     };
 

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponse.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpResponse.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponse.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponse.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpResponse.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpResponse.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponse.java Sun Nov 18 19:41:14 2007
@@ -17,16 +17,18 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 import java.util.List;
 import java.util.Map;
 
+import org.apache.mina.common.IoBuffer;
+
 /**
  * Represents a response to an <code>HttpRequest</code>.
  *
- * @author irvingd
- *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
  */
 public interface HttpResponse extends HttpMessage {
 
@@ -70,5 +72,5 @@
     /**
      * Returns the content of the response body.
      */
-    Content getContent();
+    IoBuffer getContent();
 }

Modified: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecoder.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecoder.java?rev=596187&r1=596186&r2=596187&view=diff
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecoder.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecoder.java Sun Nov 18 19:41:14 2007
@@ -19,207 +19,25 @@
  */
 package org.apache.mina.filter.codec.http;
 
-import org.apache.mina.common.IoBuffer;
-import org.apache.mina.common.AttributeKey;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
+import java.util.List;
+
 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.apache.mina.filter.codec.statemachine.DecodingState;
+import org.apache.mina.filter.codec.statemachine.StateMachineProtocolDecoder;
 
 /**
- * TODO HttpResponseDecoder.
- *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-public class HttpResponseDecoder extends CumulativeProtocolDecoder {
-
-    private final AttributeKey CURRENT_RESPONSE =
-        new AttributeKey(getClass(), "currentResponse");
-
-    private HttpDecoder httpDecoder = new HttpDecoder();
-    
-    protected boolean doDecode(IoSession ioSession, IoBuffer in,
-            ProtocolDecoderOutput out) throws Exception {
-
-        HttpResponseMessage response = (HttpResponseMessage) ioSession.getAttribute(CURRENT_RESPONSE);
-        if (response == null) {
-            response = new HttpResponseMessage();
-            ioSession.setAttribute(CURRENT_RESPONSE, response);
-        }
-
-        try {
-            // Test if we need the response...
-            if (response.getState() == HttpResponseMessage.STATE_START) {
-    
-                if (!processStatus(response, in)) {
-                    return false;
-                }
-    
-                //Handle HTTP/1.1 100 Continue
-                if (response.getStatusCode() == 100) {
-                    response.setState(HttpResponseMessage.STATE_STATUS_CONTINUE);
-                } else {
-                    response.setState(HttpResponseMessage.STATE_STATUS_READ);
-                }
-            }
-    
-            //If we are in a 100 Continue, read until we get the real header
-            if (response.getState() == HttpResponseMessage.STATE_STATUS_CONTINUE) {
-                //Continue reading until we get a blank line
-                while (true) {
-                    String line = httpDecoder.decodeLine(in);
-    
-                    //Check if the entire response has been read
-                    if (line == null)
-                        return false;
-    
-                    //Check if the entire response headers have been read
-                    if (line.length() == 0) {
-                        response.setState(HttpResponseMessage.STATE_STATUS_READ);
-    
-                        //The next line should be a header
-                        if (!processStatus(response, in)) {
-                            return false;
-                        }
-                        break;
-                    }
-                }
-            }
-    
-            //Are we reading headers?
-            if (response.getState() == HttpResponseMessage.STATE_STATUS_READ) {
-                if (processHeaders(response, in) == false)
-                    return false;
-            }
-    
-            //Are we reading content?
-            if (response.getState() == HttpResponseMessage.STATE_HEADERS_READ) {
-                if (processContent(response, in) == false)
-                    return false;
-            }
-    
-            //If we are chunked and we have read all the content, then read the footers if there are any
-            if (response.isChunked()
-                    && response.getState() == HttpResponseMessage.STATE_CONTENT_READ) {
-                if (processFooters(response, in) == false)
-                    return false;
+public class HttpResponseDecoder extends StateMachineProtocolDecoder {
+    public HttpResponseDecoder() {
+        super(new HttpResponseDecodingState() {
+            @Override
+            protected DecodingState finishDecode(List<Object> childProducts,
+                    ProtocolDecoderOutput out) throws Exception {
+                // Never be executed.
+                return null;
             }
-    
-            response.setState(HttpResponseMessage.STATE_FINISHED);
-    
-            out.write(response);
-    
-            ioSession.removeAttribute(CURRENT_RESPONSE);
-            return true;
-        } catch (Exception e) {
-            ioSession.removeAttribute(CURRENT_RESPONSE);
-            throw e;
-        }
-    }
-
-    private boolean processHeaders(HttpResponseMessage response, IoBuffer in)
-            throws Exception {
-        if (!findHeaders(response, in))
-            return false;
-
-        response.setState(HttpResponseMessage.STATE_HEADERS_READ);
-        return true;
-    }
-
-    private boolean processFooters(HttpResponseMessage response, IoBuffer in)
-            throws Exception {
-        if (!findHeaders(response, in))
-            return false;
-
-        response.setState(HttpResponseMessage.STATE_FOOTERS_READ);
-        return true;
-    }
-
-    private boolean findHeaders(HttpResponseMessage response, IoBuffer in)
-            throws Exception {
-        //Read the headers and process them
-        while (true) {
-            String line = httpDecoder.decodeLine(in);
-
-            //Check if the entire response has been read
-            if (line == null)
-                return false;
-
-            //Check if the entire response headers have been read
-            if (line.length() == 0) {
-                break;
-            }
-
-            httpDecoder.decodeHeader(line, response);
-        }
-        return true;
-    }
-
-    private boolean processContent(HttpResponseMessage response, IoBuffer in)
-            throws Exception {
-        if (response.isChunked()) {
-            while (true) {
-                //Check what kind of record we are reading (content or size)
-                if (response.getExpectedToRead() == HttpResponseMessage.EXPECTED_NOT_READ) {
-                    //We haven't read the size, so we are expecting a size
-                    String line = httpDecoder.decodeLine(in);
-
-                    //Check if the entire line has been read
-                    if (line == null)
-                        return false;
-
-                    response.setExpectedToRead(httpDecoder.decodeSize(line));
-
-                    //Are we done reading the chunked content? (A zero means we are done)
-                    if (response.getExpectedToRead() == 0) {
-                        break;
-                    }
-                }
-
-                //Now read the content chunk
-
-                //Be sure all of the data is there for us to retrieve + the CRLF...
-                if (response.getExpectedToRead() + 2 > in.remaining()) {
-                    //Need more data
-                    return false;
-                }
-
-                //Read the content
-                httpDecoder.decodeChunkedContent(in, response);
-
-                //Flag that it's time to read a size record
-                response
-                        .setExpectedToRead(HttpResponseMessage.EXPECTED_NOT_READ);
-
-            }
-
-        } else if (response.getContentLength() > 0) {
-            //Do we have enough data?
-            if ((response.getContentLength()) > in.remaining())
-                return false;
-            httpDecoder.decodeContent(in, response);
-        }
-
-        response.setState(HttpResponseMessage.STATE_CONTENT_READ);
-
-        return true;
-    }
-
-    @Override
-    public void finishDecode(IoSession session, ProtocolDecoderOutput out)
-            throws Exception {
-        session.removeAttribute(CURRENT_RESPONSE);
-    }
-
-    private boolean processStatus(HttpResponseMessage response, IoBuffer in)
-            throws Exception {
-        //Read the status header
-        String header = httpDecoder.decodeLine(in);
-        if (header == null)
-            return false;
-
-        httpDecoder.decodeStatus(header, response);
-
-        return true;
+        });
     }
 }

Added: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecodingState.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecodingState.java?rev=596187&view=auto
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecodingState.java (added)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecodingState.java Sun Nov 18 19:41:14 2007
@@ -0,0 +1,279 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.filter.codec.http;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.mina.common.IoBuffer;
+import org.apache.mina.filter.codec.ProtocolDecoderException;
+import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.apache.mina.filter.codec.statemachine.CrLfDecodingState;
+import org.apache.mina.filter.codec.statemachine.DecodingState;
+import org.apache.mina.filter.codec.statemachine.DecodingStateMachine;
+import org.apache.mina.filter.codec.statemachine.FixedLengthDecodingState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Parses HTTP requests.
+ * Clients should register a <code>HttpRequestParserListener</code>
+ * in order to receive notifications at important stages of request
+ * building.<br/>
+ *
+ * <code>HttpRequestParser</code>s should not be built for each request
+ * as each parser constructs an underlying state machine which is
+ * relatively costly to build.<br/> Instead, parsers should be pooled.<br/>
+ *
+ * Note, however, that a parser <i>must</i> be <code>prepare</code>d before
+ * each new parse.
+ *
+ * @author irvingd
+ * @author trustin
+ * @version $Rev$, $Date$
+ */
+public abstract class HttpResponseDecodingState extends DecodingStateMachine {
+
+    private static final Logger LOG = LoggerFactory
+            .getLogger(HttpResponseDecodingState.class);
+
+    private static final String HEADER_COOKIE = "Cookie";
+
+    /**
+     * The header which provides a requests transfer coding
+     */
+    private static final String TRANSFER_CODING = "transfer-encoding";
+
+    /**
+     * The chunked coding
+     */
+    private static final String CHUNKED = "chunked";
+
+    /**
+     * The header which provides a requests content length
+     */
+    private static final String CONTENT_LENGTH = "content-length";
+
+    /**
+     * Indicates the start of a coding extension
+     */
+    private static final char EXTENSION_CHAR = ';';
+
+    /**
+     * The request we are building
+     */
+    private MutableHttpResponse response;
+
+    private boolean parseCookies = true;
+
+    public HttpResponseDecodingState() {
+    }
+
+    public boolean isParseCookies() {
+        return parseCookies;
+    }
+
+    public void setParseCookies(boolean parseCookies) {
+        this.parseCookies = parseCookies;
+    }
+
+    @Override
+    protected DecodingState init() throws Exception {
+        response = new DefaultHttpResponse();
+        return SKIP_EMPTY_LINES;
+    }
+
+    @Override
+    protected void destroy() throws Exception {
+    }
+
+    private final DecodingState SKIP_EMPTY_LINES = new CrLfDecodingState() {
+
+        @Override
+        protected DecodingState finishDecode(boolean foundCRLF,
+                ProtocolDecoderOutput out) throws Exception {
+            if (foundCRLF) {
+                return this;
+            } else {
+                return READ_RESPONSE_LINE;
+            }
+        }
+    };
+
+    private final DecodingState READ_RESPONSE_LINE = new HttpResponseLineDecodingState() {
+        @Override
+        protected DecodingState finishDecode(List<Object> childProducts,
+                ProtocolDecoderOutput out) throws Exception {
+            response.setProtocolVersion((HttpVersion) childProducts.get(0));
+            response.setStatus(HttpResponseStatus.forId((Integer) childProducts.get(1)));
+            String reasonPhrase = (String) childProducts.get(2);
+            if (reasonPhrase.length() > 0) {
+                response.setStatusReasonPhrase(reasonPhrase);
+            }
+            return READ_HEADERS;
+        }
+    };
+
+    private final DecodingState READ_HEADERS = new HttpHeaderDecodingState() {
+        @Override
+        @SuppressWarnings("unchecked")
+        protected DecodingState finishDecode(List<Object> childProducts,
+                ProtocolDecoderOutput out) throws Exception {
+            Map<String, List<String>> headers = (Map<String, List<String>>) childProducts
+                    .get(0);
+            if (parseCookies) {
+                List<String> cookies = headers.remove(HEADER_COOKIE);
+                if (cookies != null && !cookies.isEmpty()) {
+                    if (cookies.size() > 1) {
+                        if (LOG.isWarnEnabled()) {
+                            LOG.warn("Ignoring extra cookie headers: "
+                                    + cookies.subList(1, cookies.size()));
+                        }
+                    }
+                    // FIXME Parse cookies.
+                    //response.setCookies(cookies.get(0));
+                }
+            }
+            response.setHeaders(headers);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Decoded header: " + response.getHeaders());
+            }
+
+            // Select appropriate body decoding state.
+            boolean isChunked = false;
+            if (response.getProtocolVersion() == HttpVersion.HTTP_1_1) {
+                LOG.debug("Request is HTTP 1/1. Checking for transfer coding");
+                isChunked = isChunked(response);
+            } else {
+                LOG.debug("Request is not HTTP 1/1. Using content length");
+            }
+            DecodingState nextState;
+            if (isChunked) {
+                LOG.debug("Using chunked decoder for request");
+                nextState = new ChunkedBodyDecodingState() {
+                    @Override
+                    protected DecodingState finishDecode(
+                            List<Object> childProducts,
+                            ProtocolDecoderOutput out) throws Exception {
+                        if (childProducts.size() != 1) {
+                            int chunkSize = 0;
+                            for (Object product : childProducts) {
+                                IoBuffer chunk = (IoBuffer) product;
+                                chunkSize += chunk.remaining();
+                            }
+
+                            IoBuffer body = IoBuffer.allocate(chunkSize);
+                            for (Object product : childProducts) {
+                                IoBuffer chunk = (IoBuffer) product;
+                                body.put(chunk);
+                            }
+                            body.flip();
+                            response.setContent(body);
+                        } else {
+                            response.setContent((IoBuffer) childProducts.get(0));
+                        }
+
+                        out.write(response);
+                        return null;
+                    }
+                };
+            } else {
+                int length = getContentLength(response);
+                if (length > 0) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG
+                                .debug("Using fixed length decoder for request with length "
+                                        + length);
+                    }
+                    nextState = new FixedLengthDecodingState(length) {
+                        @Override
+                        protected DecodingState finishDecode(IoBuffer readData,
+                                ProtocolDecoderOutput out) throws Exception {
+                            response.setContent(readData);
+                            out.write(response);
+                            return null;
+                        }
+                    };
+                } else {
+                    LOG.debug("No entity body for this request");
+                    out.write(response);
+                    nextState = null;
+                }
+            }
+            return nextState;
+        }
+
+        /**
+         * Obtains the content length from the specified request
+         *
+         * @param response  The request
+         * @return         The content length, or 0 if not specified
+         * @throws HttpDecoderException If an invalid content length is specified
+         */
+        private int getContentLength(HttpResponse response)
+                throws ProtocolDecoderException {
+            int length = 0;
+            String lengthValue = response.getHeader(CONTENT_LENGTH);
+            if (lengthValue != null) {
+                try {
+                    length = Integer.parseInt(lengthValue);
+                } catch (NumberFormatException e) {
+                    HttpCodecUtils.throwDecoderException(
+                            "Invalid content length: " + length,
+                            HttpResponseStatus.BAD_REQUEST);
+                }
+            }
+            return length;
+        }
+
+        /**
+         * Determines whether a specified request employs a chunked
+         * transfer coding
+         *
+         * @param response  The request
+         * @return         <code>true</code> iff the request employs a
+         *                 chunked transfer coding
+         * @throws HttpDecoderException
+         *                 If the request employs an unsupported coding
+         */
+        private boolean isChunked(HttpResponse response)
+                throws ProtocolDecoderException {
+            boolean isChunked = false;
+            String coding = response.getHeader(TRANSFER_CODING);
+            if (coding != null) {
+                int extensionIndex = coding.indexOf(EXTENSION_CHAR);
+                if (extensionIndex != -1) {
+                    coding = coding.substring(0, extensionIndex);
+                }
+                if (CHUNKED.equalsIgnoreCase(coding)) {
+                    isChunked = true;
+                } else {
+                    // As we only support chunked encoding, any other encoding
+                    // is unsupported
+                    HttpCodecUtils.throwDecoderException(
+                            "Unknown transfer coding " + coding,
+                            HttpResponseStatus.NOT_IMPLEMENTED);
+                }
+            }
+            return isChunked;
+        }
+    };
+}

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecodingState.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseDecodingState.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseEncoder.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseEncoder.java?rev=596187&view=auto
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseEncoder.java (added)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseEncoder.java Sun Nov 18 19:41:14 2007
@@ -0,0 +1,83 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.filter.codec.http;
+
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+
+import org.apache.mina.common.IoBuffer;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.codec.ProtocolEncoder;
+import org.apache.mina.filter.codec.ProtocolEncoderOutput;
+
+public class HttpResponseEncoder implements ProtocolEncoder {
+
+    private static final Charset US_ASCII = Charset.forName("US-ASCII");
+    private final CharsetEncoder asciiEncoder = US_ASCII.newEncoder();
+
+    public void encode(IoSession session, Object message,
+            ProtocolEncoderOutput out) throws Exception {
+        asciiEncoder.reset();
+        HttpResponse response = (HttpResponse) message;
+        IoBuffer buffer = IoBuffer.allocate(512);
+        buffer.setAutoExpand(true);
+
+        encodeStatusLine(response, buffer);
+        HttpCodecUtils.encodeHeaders(response, buffer, asciiEncoder);
+        HttpCodecUtils.encodeBody(response, buffer);
+
+        buffer.flip();
+        out.write(buffer);
+    }
+
+    public void dispose(IoSession session) throws Exception {
+    }
+
+    /**
+     * Encodes the status line of a <code>Response</code> to a specified
+     * buffer.
+     * The status line takes the form:<br/>
+     * <pre>
+     *   HTTP-Version SP Status-Code SP Reason-Phrase CRLF
+     * </pre>
+     *
+     * @param response  The response
+     * @param buffer    The buffer
+     * @throws CharacterCodingException
+     */
+    private void encodeStatusLine(HttpResponse response, IoBuffer buffer)
+            throws CharacterCodingException {
+        // Write protocol version.
+        buffer.putString(
+                response.getProtocolVersion().toString(), asciiEncoder);
+        buffer.put(HttpCodecUtils.SP);
+
+        // Write status code.
+        HttpResponseStatus status = response.getStatus();
+        // TODO: Cached buffers for response codes / descriptions?
+        HttpCodecUtils.appendString(buffer, String.valueOf(status.getCode()));
+        buffer.put(HttpCodecUtils.SP);
+
+        // Write reason phrase.
+        HttpCodecUtils.appendString(buffer, response.getStatusReasonPhrase());
+        HttpCodecUtils.appendCRLF(buffer);
+    }
+}

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseEncoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseEncoder.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseLineDecodingState.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseLineDecodingState.java?rev=596187&view=auto
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseLineDecodingState.java (added)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseLineDecodingState.java Sun Nov 18 19:41:14 2007
@@ -0,0 +1,101 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.filter.codec.http;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+
+import org.apache.mina.common.IoBuffer;
+import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.apache.mina.filter.codec.statemachine.ConsumeToCrLfDecodingState;
+import org.apache.mina.filter.codec.statemachine.ConsumeToLinearWhitespaceDecodingState;
+import org.apache.mina.filter.codec.statemachine.DecodingState;
+import org.apache.mina.filter.codec.statemachine.DecodingStateMachine;
+import org.apache.mina.filter.codec.statemachine.LinearWhitespaceSkippingState;
+
+/**
+ * Decodes a HTTP response line.
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ */
+abstract class HttpResponseLineDecodingState extends DecodingStateMachine {
+
+    private static final Charset US_ASCII = Charset.forName("US-ASCII");
+    private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+    private final CharsetDecoder asciiDecoder = US_ASCII.newDecoder();
+    private final CharsetDecoder utf8Decoder = UTF_8.newDecoder();
+
+    @Override
+    protected DecodingState init() throws Exception {
+        return READ_PROTOCOL_VERSION;
+    }
+
+    @Override
+    protected void destroy() throws Exception {
+    }
+
+    private final DecodingState READ_PROTOCOL_VERSION = new HttpVersionDecodingState() {
+        @Override
+        protected DecodingState finishDecode(HttpVersion version,
+                ProtocolDecoderOutput out) throws Exception {
+            out.write(version);
+            return AFTER_READ_PROTOCOL_VERSION;
+        }
+    };
+    
+    private final DecodingState AFTER_READ_PROTOCOL_VERSION = new LinearWhitespaceSkippingState() {
+        @Override
+        protected DecodingState finishDecode(int skippedBytes) throws Exception {
+            return READ_STATUS_CODE;
+        }
+    };
+    
+    private final DecodingState READ_STATUS_CODE = new ConsumeToLinearWhitespaceDecodingState() {
+        @Override
+        protected DecodingState finishDecode(IoBuffer product,
+                ProtocolDecoderOutput out) throws Exception {
+            String statusCode = product.getString(asciiDecoder);
+            try {
+                out.write(Integer.parseInt(statusCode));
+            } catch (NumberFormatException e) {
+                HttpCodecUtils.throwDecoderException("Bad status code");
+            }
+            return AFTER_READ_STATUS_CODE;
+        }
+    };
+
+    private final DecodingState AFTER_READ_STATUS_CODE = new LinearWhitespaceSkippingState() {
+        @Override
+        protected DecodingState finishDecode(int skippedBytes) throws Exception {
+            return READ_REASON_PHRASE;
+        }
+    };
+
+    private final DecodingState READ_REASON_PHRASE = new ConsumeToCrLfDecodingState() {
+        @Override
+        protected DecodingState finishDecode(IoBuffer product,
+                ProtocolDecoderOutput out) throws Exception {
+            out.write(product.getString(utf8Decoder).trim());
+            return null;
+        }
+    };
+}

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseLineDecodingState.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseLineDecodingState.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseStatus.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpResponseStatus.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseStatus.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseStatus.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpResponseStatus.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpResponseStatus.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpResponseStatus.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 import java.io.Serializable;
 

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersion.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpVersion.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersion.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersion.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpVersion.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/HttpVersion.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersion.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 import java.io.InvalidObjectException;
 import java.io.ObjectStreamException;

Added: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersionDecodingState.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersionDecodingState.java?rev=596187&view=auto
==============================================================================
--- mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersionDecodingState.java (added)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersionDecodingState.java Sun Nov 18 19:41:14 2007
@@ -0,0 +1,70 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.mina.filter.codec.http;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+
+import org.apache.mina.common.IoBuffer;
+import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.apache.mina.filter.codec.statemachine.ConsumeToDynamicTerminatorDecodingState;
+import org.apache.mina.filter.codec.statemachine.DecodingState;
+
+/**
+ * Decodes HTTP version.
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev$, $Date$
+ */
+abstract class HttpVersionDecodingState implements DecodingState {
+
+    private static final Charset US_ASCII = Charset.forName("US-ASCII");
+    private final CharsetDecoder asciiDecoder = US_ASCII.newDecoder();
+    
+    private final DecodingState READ_PROTOCOL_VERSION = new ConsumeToDynamicTerminatorDecodingState() {
+        @Override
+        protected DecodingState finishDecode(IoBuffer product,
+                ProtocolDecoderOutput out) throws Exception {
+            String versionStr = product.getString(asciiDecoder);
+            HttpVersion version = HttpVersion.valueOf(versionStr);
+            if (version == null) {
+                HttpCodecUtils.throwDecoderException(
+                        "Unsupported HTTP version: " + versionStr,
+                        HttpResponseStatus.HTTP_VERSION_NOT_SUPPORTED);
+            }
+            
+            return HttpVersionDecodingState.this.finishDecode(version, out);
+        }
+
+        @Override
+        protected boolean isTerminator(byte b) {
+            return Character.isWhitespace(b);
+        }
+    };
+    
+    public DecodingState decode(IoBuffer in, ProtocolDecoderOutput out)
+            throws Exception {
+        return READ_PROTOCOL_VERSION.decode(in, out);
+    }
+
+
+    protected abstract DecodingState finishDecode(
+            HttpVersion version, ProtocolDecoderOutput out) throws Exception;
+}

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersionDecodingState.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/HttpVersionDecodingState.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableCookie.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableCookie.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableCookie.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableCookie.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableCookie.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableCookie.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableCookie.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 /**
  * A mutable {@link Cookie}.

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpMessage.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpMessage.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpMessage.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpMessage.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpMessage.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpMessage.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpMessage.java Sun Nov 18 19:41:14 2007
@@ -17,12 +17,14 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.mina.common.IoBuffer;
+
 /**
  * A mutable {@link HttpMessage}.
  * @author trustin
@@ -108,5 +110,5 @@
      *
      * @param content <tt>null</tt> to clear the body content
      */
-    void setContent(Content content);
+    void setContent(IoBuffer content);
 }

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpRequest.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpRequest.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpRequest.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpRequest.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpRequest.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpRequest.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpRequest.java Sun Nov 18 19:41:14 2007
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
@@ -26,7 +26,8 @@
 
 /**
  * A mutable {@link HttpRequest}.
- * @author trustin
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
  * @version $Rev$, $Date$
  */
 public interface MutableHttpRequest extends MutableHttpMessage, HttpRequest {
@@ -90,4 +91,23 @@
      * Sets the URI of the request.
      */
     void setRequestUri(URI requestUri);
+    
+    /**
+     * Normalizes this request to fix possible protocol violations.  The
+     * following is the normalization step:
+     * <ol>
+     * <li>Sets the query part of the <tt>requestUri</tt> with the current
+     *     <tt>parameters</tt> if the <tt>method</tt> of this request is
+     *     not {@link HttpMethod#POST}.</li>
+     * <li>Sets the body content if there's any parameter entry in this
+     *     requests and if <tt>method</tt> of this request is 
+     *     {@link HttpMethod#POST}.
+     * <li>Adds proper header entries for the current <tt>cookies</tt>.</li>
+     * <li>Adds '<tt>Host</tt>' header if necessary.</li>
+     * <li>Adds '<tt>Content-length</tt>' header if possible.</li>
+     * </ol>
+     *
+     * @param request the request that pairs with this response
+     */
+    void normalize();
 }

Copied: mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpResponse.java (from r596083, mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpResponse.java)
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpResponse.java?p2=mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpResponse.java&p1=mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpResponse.java&r1=596083&r2=596187&rev=596187&view=diff
==============================================================================
--- mina/sandbox/asyncweb/core/src/main/java/org/safehaus/asyncweb/common/MutableHttpResponse.java (original)
+++ mina/trunk/filter-codec-http/src/main/java/org/apache/mina/filter/codec/http/MutableHttpResponse.java Sun Nov 18 19:41:14 2007
@@ -17,17 +17,19 @@
  *  under the License.
  *
  */
-package org.safehaus.asyncweb.common;
+package org.apache.mina.filter.codec.http;
 
 /**
  * A mutable {@link HttpResponse}
- * @author trustin
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
  * @version $Rev$, $Date$
  */
 public interface MutableHttpResponse extends MutableHttpMessage, HttpResponse {
 
     /**
-     * Adds the cookie of this message by parsing the specified <tt>headerValue</tt>.
+     * Adds the cookie of this message by parsing the specified
+     * <tt>headerValue</tt>.
      */
     void addCookie(String headerValue);
 
@@ -39,20 +41,24 @@
     void setStatus(HttpResponseStatus status);
 
     /**
-     * Sets the reason phrase which is associated with the current status of this response.
+     * Sets the reason phrase which is associated with the current status of
+     * this response.
      */
     void setStatusReasonPhrase(String reasonPhrase);
 
     /**
-     * Normalizes this response to fix possible protocol violations.  The following is the
-     * normalization step:
+     * Normalizes this response to fix possible protocol violations.  The
+     * following is the normalization step:
      * <ol>
-     * <li>Adds '<tt>Connection</tt>' header with an appropriate value determined from the specified
-     *     <tt>request</tt> and the status of this response.</li>
-     * <li>Adds '<tt>Data</tt>' header with current time.</li>
-     * <li>Remove body content if the {@link HttpMethod} of the specified <tt>request</tt> doesn't
-     *     allow body or the satus of this response doesn't allow body.</li>
-     * <li>Adds '<tt>Content-length</tt>' header if '<tt>Transfer-coding</tt>' header presents.</li>
+     * <li>Adds '<tt>Connection</tt>' header with an appropriate value
+     *     determined from the specified <tt>request</tt> and the status of
+     *     this response.</li>
+     * <li>Adds '<tt>Date</tt>' header with current time.</li>
+     * <li>Removes body content if the {@link HttpMethod} of the specified
+     *     <tt>request</tt> doesn't allow body or the status of this response
+     *     doesn't allow body.</li>
+     * <li>Adds '<tt>Content-length</tt>' header if '<tt>Transfer-coding</tt>'
+     *     header doesn't exist.</li>
      * </ol>
      *
      * @param request the request that pairs with this response

Modified: mina/trunk/filter-codec-netty/src/main/java/org/apache/mina/filter/codec/netty/NettyCodecFactory.java
URL: http://svn.apache.org/viewvc/mina/trunk/filter-codec-netty/src/main/java/org/apache/mina/filter/codec/netty/NettyCodecFactory.java?rev=596187&r1=596186&r2=596187&view=diff
==============================================================================
--- mina/trunk/filter-codec-netty/src/main/java/org/apache/mina/filter/codec/netty/NettyCodecFactory.java (original)
+++ mina/trunk/filter-codec-netty/src/main/java/org/apache/mina/filter/codec/netty/NettyCodecFactory.java Sun Nov 18 19:41:14 2007
@@ -22,6 +22,7 @@
 import net.gleamynode.netty2.Message;
 import net.gleamynode.netty2.MessageRecognizer;
 
+import org.apache.mina.common.IoSession;
 import org.apache.mina.filter.codec.ProtocolCodecFactory;
 
 /**
@@ -44,11 +45,11 @@
         this.recognizer = recognizer;
     }
 
-    public org.apache.mina.filter.codec.ProtocolEncoder getEncoder() {
+    public org.apache.mina.filter.codec.ProtocolEncoder getEncoder(IoSession session) {
         return ENCODER;
     }
 
-    public org.apache.mina.filter.codec.ProtocolDecoder getDecoder() {
+    public org.apache.mina.filter.codec.ProtocolDecoder getDecoder(IoSession session) {
         return new NettyDecoder(recognizer);
     }
 }

Modified: mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/AsyncHttpClient.java
URL: http://svn.apache.org/viewvc/mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/AsyncHttpClient.java?rev=596187&r1=596186&r2=596187&view=diff
==============================================================================
--- mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/AsyncHttpClient.java (original)
+++ mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/AsyncHttpClient.java Sun Nov 18 19:41:14 2007
@@ -29,8 +29,9 @@
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IoSession;
 import org.apache.mina.filter.codec.ProtocolCodecFilter;
-import org.apache.mina.filter.codec.http.HttpProtocolCodecFactory;
-import org.apache.mina.filter.codec.http.HttpRequestMessage;
+import org.apache.mina.filter.codec.http.HttpCodecFactory;
+import org.apache.mina.filter.codec.http.HttpRequest;
+import org.apache.mina.filter.codec.http.MutableHttpRequest;
 import org.apache.mina.filter.ssl.SslFilter;
 import org.apache.mina.transport.socket.nio.NioSocketConnector;
 
@@ -77,7 +78,7 @@
         }
 
         connector.getFilterChain().addLast("protocolFilter",
-                new ProtocolCodecFilter(new HttpProtocolCodecFactory(url)));
+                new ProtocolCodecFilter(new HttpCodecFactory()));
         connector.setHandler(new HttpIoHandler(callback));
         ConnectFuture future = connector.connect(new InetSocketAddress(url
                 .getHost(), port));
@@ -95,7 +96,10 @@
         session = null;
     }
 
-    public void sendRequest(HttpRequestMessage message) {
+    public void sendRequest(HttpRequest message) {
+        if (message instanceof MutableHttpRequest) {
+            ((MutableHttpRequest) message).normalize();
+        }
         session.write(message);
     }
 

Modified: mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/AsyncHttpClientCallback.java
URL: http://svn.apache.org/viewvc/mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/AsyncHttpClientCallback.java?rev=596187&r1=596186&r2=596187&view=diff
==============================================================================
--- mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/AsyncHttpClientCallback.java (original)
+++ mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/AsyncHttpClientCallback.java Sun Nov 18 19:41:14 2007
@@ -19,12 +19,10 @@
  */
 package org.apache.mina.protocol.http.client;
 
-import org.apache.mina.filter.codec.http.HttpResponseMessage;
+import org.apache.mina.filter.codec.http.HttpResponse;
 
 public interface AsyncHttpClientCallback {
-    public void onResponse(HttpResponseMessage message);
-
+    public void onResponse(HttpResponse message);
     public void onException(Throwable cause);
-
     public void onClosed();
 }

Modified: mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/HttpIoHandler.java
URL: http://svn.apache.org/viewvc/mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/HttpIoHandler.java?rev=596187&r1=596186&r2=596187&view=diff
==============================================================================
--- mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/HttpIoHandler.java (original)
+++ mina/trunk/protocol-http-client/src/main/java/org/apache/mina/protocol/http/client/HttpIoHandler.java Sun Nov 18 19:41:14 2007
@@ -21,9 +21,7 @@
 
 import org.apache.mina.common.IoHandlerAdapter;
 import org.apache.mina.common.IoSession;
-import org.apache.mina.filter.codec.ProtocolCodecFilter;
-import org.apache.mina.filter.codec.http.HttpResponseDecoder;
-import org.apache.mina.filter.codec.http.HttpResponseMessage;
+import org.apache.mina.filter.codec.http.HttpResponse;
 
 public class HttpIoHandler extends IoHandlerAdapter {
     private AsyncHttpClientCallback callback;
@@ -40,26 +38,18 @@
     @Override
     public void messageReceived(IoSession ioSession, Object object)
             throws Exception {
-        HttpResponseMessage message = (HttpResponseMessage) object;
+        HttpResponse message = (HttpResponse) object;
         callback.onResponse(message);
     }
 
     @Override
     public void exceptionCaught(IoSession ioSession, Throwable throwable)
             throws Exception {
-        cleanup(ioSession);
         callback.onException(throwable);
     }
 
     @Override
     public void sessionClosed(IoSession ioSession) throws Exception {
-        cleanup(ioSession);
         callback.onClosed();
-    }
-
-    private void cleanup(IoSession ioSession) throws Exception {
-        // Clean up if any in-proccess decoding was occurring
-        ProtocolCodecFilter codecFilter = (ProtocolCodecFilter) ioSession.getFilterChain().get("protocolFilter");
-        ((HttpResponseDecoder) codecFilter.getDecoder(ioSession)).finishDecode(ioSession, null);
     }
 }