You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by jv...@apache.org on 2011/08/29 23:13:35 UTC

svn commit: r1163009 - in /mina/trunk/http: ./ src/main/java/org/apache/mina/ src/main/java/org/apache/mina/http/ src/main/java/org/apache/mina/http/api/ src/test/java/org/apache/mina/http/

Author: jvermillard
Date: Mon Aug 29 21:13:35 2011
New Revision: 1163009

URL: http://svn.apache.org/viewvc?rev=1163009&view=rev
Log:
some HTTP decoding 

Added:
    mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/
    mina/trunk/http/src/main/java/org/apache/mina/http/api/
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMessage.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMethod.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequest.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVersion.java   (with props)
Modified:
    mina/trunk/http/pom.xml
    mina/trunk/http/src/main/java/org/apache/mina/HttpProtocol.java
    mina/trunk/http/src/test/java/org/apache/mina/http/HttpTest.java

Modified: mina/trunk/http/pom.xml
URL: http://svn.apache.org/viewvc/mina/trunk/http/pom.xml?rev=1163009&r1=1163008&r2=1163009&view=diff
==============================================================================
--- mina/trunk/http/pom.xml (original)
+++ mina/trunk/http/pom.xml Mon Aug 29 21:13:35 2011
@@ -47,5 +47,6 @@
     	<version>r09</version>
     </dependency>
   </dependencies>
+  <description>Low level HTTP codec for building simple &amp; fast HTTP server and clients</description>
 </project>
 

Added: mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,182 @@
+package org.apache.mina;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.mina.api.IdleStatus;
+import org.apache.mina.api.IoFilter;
+import org.apache.mina.api.IoSession;
+import org.apache.mina.filterchain.ReadFilterChainController;
+import org.apache.mina.filterchain.WriteFilterChainController;
+import org.apache.mina.http.api.HttpEndOfContent;
+import org.apache.mina.http.api.HttpMethod;
+import org.apache.mina.http.api.HttpRequestImpl;
+import org.apache.mina.http.api.HttpVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+
+public class HttpServerCodec implements IoFilter {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpServerCodec.class);
+
+    /** Key for decoder current state */
+    private static final String DECODER_STATE_ATT = "http.ds";
+
+    /** Key for the partial HTTP requests head */
+    private static final String PARTIAL_HEAD_ATT = "http.ph";
+
+    /** Key for the number of bytes remaining to read for completing the body */
+    private static final String BODY_REMAINING_BYTES = "http.brb";
+
+    /** Regex to parse HttpRequest Request Line */
+    public static final Pattern REQUEST_LINE_PATTERN = Pattern.compile(" ");
+    /** Regex to parse out QueryString from HttpRequest */
+    public static final Pattern QUERY_STRING_PATTERN = Pattern.compile("\\?");
+    /** Regex to parse out parameters from query string */
+    public static final Pattern PARAM_STRING_PATTERN = Pattern.compile("\\&|;");
+    /** Regex to parse out key/value pairs */
+    public static final Pattern KEY_VALUE_PATTERN = Pattern.compile("=");
+    /** Regex to parse raw headers and body */
+    public static final Pattern RAW_VALUE_PATTERN = Pattern.compile("\\r\\n\\r\\n");
+    // TODO fix a better regexp for this
+    /** Regex to parse raw headers from body */
+    public static final Pattern HEADERS_BODY_PATTERN = Pattern.compile("\\r\\n");
+    /** Regex to parse header name and value */
+    public static final Pattern HEADER_VALUE_PATTERN = Pattern.compile(": ");
+    /** Regex to split cookie header following RFC6265 Section 5.4 */
+    public static final Pattern COOKIE_SEPARATOR_PATTERN = Pattern.compile(";");
+
+    @Override
+    public void sessionCreated(IoSession session) {
+        session.setAttribute(DECODER_STATE_ATT, DecoderState.NEW);
+    }
+
+    @Override
+    public void sessionOpened(IoSession session) {
+    }
+
+    @Override
+    public void sessionClosed(IoSession session) {
+        session.removeAttribute(DECODER_STATE_ATT);
+        session.removeAttribute(PARTIAL_HEAD_ATT);
+
+    }
+
+    @Override
+    public void sessionIdle(IoSession session, IdleStatus status) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void messageReceived(IoSession session, Object message, ReadFilterChainController controller) {
+        if (!(message instanceof ByteBuffer)) {
+            throw new RuntimeException("invalid message type : " + message.getClass());
+        }
+        ByteBuffer msg = (ByteBuffer) message;
+
+        DecoderState state = session.getAttribute(DECODER_STATE_ATT);
+        switch (state) {
+        case HEAD:
+            LOG.debug("decoding HEAD");
+            // grab the stored a partial HEAD request
+            ByteBuffer oldBuffer = session.getAttribute(PARTIAL_HEAD_ATT);
+            // concat the old buffer and the new incoming one
+            msg = ByteBuffer.allocate(oldBuffer.remaining() + msg.remaining()).put(oldBuffer).put(msg);
+            msg.flip();
+            // now let's decode like it was a new message
+        case NEW:
+            LOG.debug("decoding NEW");
+            HttpRequestImpl rq = parseHttpRequestHead(msg);
+            if (rq == null) {
+                // no request decoded, we accumulate
+                session.setAttribute(PARTIAL_HEAD_ATT, msg);
+                session.setAttribute(DECODER_STATE_ATT, DecoderState.HEAD);
+                return;
+            } else {
+                controller.callReadNextFilter(session, rq);
+                // is it a request with some body content ?
+                if (rq.getMethod() == HttpMethod.POST || rq.getMethod() == HttpMethod.PUT) {
+                    LOG.debug("request with content");
+                    session.setAttribute(DECODER_STATE_ATT, DecoderState.BODY);
+
+                    String contentLen = rq.getHeader("content-length");
+                    if (contentLen != null) {
+                        LOG.debug("found content len : {}", contentLen);
+                        session.setAttribute(BODY_REMAINING_BYTES, new Integer(contentLen));
+                    } else {
+                        throw new RuntimeException("no content length !");
+                    }
+                } else {
+                    LOG.debug("request without content");
+                    session.setAttribute(DECODER_STATE_ATT, DecoderState.NEW);
+                }
+            }
+            break;
+        case BODY:
+            LOG.debug("decoding BODY");
+            int chunkSize = msg.remaining();
+            // send the chunk of body
+            controller.callReadNextFilter(session, msg);
+            // do we have reach end of body ?
+            int remaining = session.getAttribute(BODY_REMAINING_BYTES);
+            remaining -= chunkSize;
+
+            if (remaining <= 0) {
+                LOG.debug("end of HTTP body");
+                controller.callReadNextFilter(session, new HttpEndOfContent());
+                session.setAttribute(DECODER_STATE_ATT, DecoderState.NEW);
+                session.removeAttribute(BODY_REMAINING_BYTES);
+            } else {
+                session.setAttribute(BODY_REMAINING_BYTES, new Integer(remaining));
+            }
+            break;
+
+        default:
+            throw new RuntimeException("Unknonwn decoder state : " + state);
+        }
+
+    }
+
+    @Override
+    public void messageWriting(IoSession session, Object message, WriteFilterChainController controller) {
+        // TODO encode HTTP response to ByteBuffer
+    }
+
+    private HttpRequestImpl parseHttpRequestHead(ByteBuffer buffer) {
+        String raw = new String(buffer.array(), 0, buffer.limit(), Charsets.ISO_8859_1);
+        String[] headersAndBody = RAW_VALUE_PATTERN.split(raw, -1);
+        if (headersAndBody.length <= 1) {
+            // we didn't receive the full HTTP head
+            return null;
+        }
+        String[] headerFields = HEADERS_BODY_PATTERN.split(headersAndBody[0]);
+        headerFields = ArrayUtil.dropFromEndWhile(headerFields, "");
+
+        String requestLine = headerFields[0];
+        Map<String, String> generalHeaders = new HashMap<String, String>();
+        for (int i = 1; i < headerFields.length; i++) {
+            String[] header = HEADER_VALUE_PATTERN.split(headerFields[i]);
+            generalHeaders.put(header[0].toLowerCase(), header[1]);
+        }
+
+        String[] elements = REQUEST_LINE_PATTERN.split(requestLine);
+        HttpMethod method = HttpMethod.valueOf(elements[0]);
+        HttpVersion version = HttpVersion.fromString(elements[2]);
+        String[] pathFrags = QUERY_STRING_PATTERN.split(elements[1]);
+        String requestedPath = pathFrags[0];
+
+        // we put the buffer position where we found the beginning of the HTTP body
+        buffer.position(headersAndBody[0].length());
+        return new HttpRequestImpl(version, method, requestedPath, generalHeaders);
+    }
+
+    private enum DecoderState {
+        NEW, // waiting for a new HTTP requests, the session is new of last request was completed
+        HEAD, // accumulating the HTTP request head (everything before the body)
+        BODY // receiving HTTP body slices
+    }
+}
\ No newline at end of file

Propchange: mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,28 @@
+/*
+ *  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.http.api;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+public interface HttpContentChunk {
+
+    List<ByteBuffer> getContent();
+}

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,24 @@
+/*
+ *  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.http.api;
+
+public class HttpEndOfContent {
+
+}

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMessage.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMessage.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMessage.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMessage.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,71 @@
+/*
+ *  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.http.api;
+
+import java.util.Map;
+
+/**
+ * An HTTP message, the ancestor of HTTP request & response.
+ * 
+ * @author jvermillar
+ * 
+ */
+public interface HttpMessage {
+
+    /**
+     * The HTTP version of the message
+     * 
+     * @return HTTP/1.0 or HTTP/1.1
+     */
+    HttpVersion getProtocolVersion();
+
+    /**
+     * Gets the <tt>Content-Type</tt> header of the message.
+     * 
+     * @return The content type.
+     */
+    String getContentType();
+
+    /**
+     * Returns <tt>true</tt> if this message enables keep-alive connection.
+     */
+    boolean isKeepAlive();
+
+    /**
+     * Returns the value of the HTTP header with the specified name. If more than one header with the given name is
+     * associated with this request, one is selected and returned.
+     * 
+     * @param name The name of the desired header
+     * @return The header value - or null if no header is found with the specified name
+     */
+    String getHeader(String name);
+
+    /**
+     * Returns <tt>true</tt> if the HTTP header with the specified name exists in this request.
+     */
+    boolean containsHeader(String name);
+
+    /**
+     * Returns a read-only {@link Map} of HTTP headers whose key is a {@link String} and whose value is a {@link String}
+     * s.
+     */
+    Map<String, String> getHeaders();
+}

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMessage.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMethod.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMethod.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMethod.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMethod.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,30 @@
+/*
+ *  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.http.api;
+
+/**
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * 
+ */
+public enum HttpMethod {
+
+    GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, CONNECT
+}

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpMethod.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequest.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequest.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequest.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequest.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,65 @@
+/*
+ *  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.http.api;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An HTTP request
+ * 
+ * @author jvermillar
+ * 
+ */
+public interface HttpRequest extends HttpMessage {
+
+    /**
+     * Determines whether this request contains at least one parameter with the specified name
+     * 
+     * @param name The parameter name
+     * @return <code>true</code> if this request contains at least one parameter with the specified name
+     */
+    boolean containsParameter(String name);
+
+    /**
+     * Returns the value of a request parameter as a String, or null if the parameter does not exist.
+     * 
+     * If the request contained multiple parameters with the same name, this method returns the first parameter
+     * encountered in the request with the specified name
+     * 
+     * @param name The parameter name
+     * @return The value
+     */
+    String getParameter(String name);
+
+    /**
+     * Returns a read only {@link Map} of query parameters whose key is a {@link String} and whose value is a
+     * {@link List} of {@link String}s.
+     */
+    Map<String, List<String>> getParameters();
+
+    /**
+     * Return the HTTP method used for this message {@link HttpMethod}
+     * 
+     * @return the method
+     */
+    HttpMethod getMethod();
+}

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,112 @@
+/*
+ *  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.http.api;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class HttpRequestImpl implements HttpRequest {
+
+    private final HttpVersion version;
+    private final HttpMethod method;
+    private final String requestedPath;
+    private final Map<String, String> headers;
+
+    public HttpRequestImpl(HttpVersion version, HttpMethod method, String requestedPath, Map<String, String> headers) {
+        this.version = version;
+        this.method = method;
+        this.requestedPath = requestedPath;
+        this.headers = Collections.unmodifiableMap(headers);
+    }
+
+    @Override
+    public HttpVersion getProtocolVersion() {
+        return version;
+    }
+
+    @Override
+    public String getContentType() {
+        return headers.get("content-type");
+    }
+
+    @Override
+    public boolean isKeepAlive() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getHeader(String name) {
+        return headers.get(name);
+    }
+
+    @Override
+    public boolean containsHeader(String name) {
+        return headers.containsKey(name);
+    }
+
+    @Override
+    public Map<String, String> getHeaders() {
+        return headers;
+    }
+
+    @Override
+    public boolean containsParameter(String name) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getParameter(String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<String, List<String>> getParameters() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public HttpMethod getMethod() {
+        return method;
+    }
+
+    @Override
+    public String toString() {
+        String result = "METHOD: " + method + "\n";
+        result += "VERSION: " + version + "\n";
+        result += "PATH: " + requestedPath + "\n";
+
+        result += "--- HEADER --- \n";
+        for (String key : headers.keySet()) {
+            String value = headers.get(key);
+            result += key + ":" + value + "\n";
+        }
+
+        /*
+         * result += "--- PARAMETERS --- \n"; for (String key : parameters.keySet()) { Collection<String> values =
+         * parameters.get(key); for (String value : values) { result += key + ":" + value + "\n"; } }
+         */
+        return result;
+    }
+}

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,30 @@
+/*
+ *  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.http.api;
+
+/**
+ * An HTTP response to an HTTP request
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * 
+ */
+public interface HttpResponse extends HttpMessage {
+
+}

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVersion.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVersion.java?rev=1163009&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVersion.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVersion.java Mon Aug 29 21:13:35 2011
@@ -0,0 +1,69 @@
+/*
+ *  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.http.api;
+
+/**
+ * Type safe enumeration representing HTTP protocol version
+ * 
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ */
+public enum HttpVersion {
+    /**
+     * HTTP 1/1
+     */
+    HTTP_1_1("HTTP/1.1"),
+
+    /**
+     * HTTP 1/0
+     */
+    HTTP_1_0("HTTP/1.0");
+
+    private final String value;
+
+    private HttpVersion(String value) {
+        this.value = value;
+    }
+
+    /**
+     * Returns the {@link HttpVersion} instance from the specified string.
+     * 
+     * @return The version, or <code>null</code> if no version is found
+     */
+    public static HttpVersion fromString(String string) {
+        if (HTTP_1_1.toString().equalsIgnoreCase(string)) {
+            return HTTP_1_1;
+        }
+
+        if (HTTP_1_0.toString().equalsIgnoreCase(string)) {
+            return HTTP_1_0;
+        }
+
+        return null;
+    }
+
+    /**
+     * @return A String representation of this version
+     */
+    @Override
+    public String toString() {
+        return value;
+    }
+
+}

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVersion.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: mina/trunk/http/src/test/java/org/apache/mina/http/HttpTest.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/test/java/org/apache/mina/http/HttpTest.java?rev=1163009&r1=1163008&r2=1163009&view=diff
==============================================================================
--- mina/trunk/http/src/test/java/org/apache/mina/http/HttpTest.java (original)
+++ mina/trunk/http/src/test/java/org/apache/mina/http/HttpTest.java Mon Aug 29 21:13:35 2011
@@ -2,10 +2,7 @@ package org.apache.mina.http;
 
 import java.net.InetSocketAddress;
 
-import org.apache.mina.HttpProtocol;
-import org.apache.mina.api.IoService;
-import org.apache.mina.api.IoServiceListener;
-import org.apache.mina.api.IoSession;
+import org.apache.mina.HttpServerCodec;
 import org.apache.mina.filter.logging.LoggingFilter;
 import org.apache.mina.service.OneThreadSelectorStrategy;
 import org.apache.mina.service.SelectorFactory;
@@ -21,27 +18,7 @@ public class HttpTest {
         OneThreadSelectorStrategy strategy = new OneThreadSelectorStrategy(new SelectorFactory(
                 NioSelectorProcessor.class));
         NioTcpServer acceptor = new NioTcpServer(strategy);
-
-        acceptor.addListener(new IoServiceListener() {
-
-            @Override
-            public void sessionDestroyed(IoSession session) {
-            }
-
-            @Override
-            public void sessionCreated(IoSession session) {
-                session.getFilterChain().getChain().add(new HttpProtocol());
-                session.getFilterChain().getChain().add(new LoggingFilter("Logging"));
-            }
-
-            @Override
-            public void serviceInactivated(IoService service) {
-            }
-
-            @Override
-            public void serviceActivated(IoService service) {
-            }
-        });
+        acceptor.setFilters(new LoggingFilter("INCOMING"), new HttpServerCodec(), new LoggingFilter("DECODED"));
 
         acceptor.bind(new InetSocketAddress(8080));
         Thread.sleep(20000);