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/09/03 08:51:17 UTC

svn commit: r1164808 - in /mina/trunk: core/src/main/java/org/apache/mina/filterchain/ http/src/main/java/org/apache/mina/ http/src/main/java/org/apache/mina/http/ http/src/main/java/org/apache/mina/http/api/ http/src/test/java/org/apache/mina/http/

Author: jvermillard
Date: Sat Sep  3 06:51:17 2011
New Revision: 1164808

URL: http://svn.apache.org/viewvc?rev=1164808&view=rev
Log:
Basicly working low level HTTP encode & decode, to be completed and tested

Added:
    mina/trunk/http/src/main/java/org/apache/mina/http/ArrayUtil.java   (contents, props changed)
      - copied, changed from r1163102, mina/trunk/http/src/main/java/org/apache/mina/ArrayUtil.java
    mina/trunk/http/src/main/java/org/apache/mina/http/DateUtil.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/HttpException.java   (contents, props changed)
      - copied, changed from r1163102, mina/trunk/http/src/main/java/org/apache/mina/HttpException.java
    mina/trunk/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java   (contents, props changed)
      - copied, changed from r1163102, mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java
    mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerCodec.java   (contents, props changed)
      - copied, changed from r1163102, mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java
    mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerDescriptor.java   (contents, props changed)
      - copied, changed from r1163102, mina/trunk/http/src/main/java/org/apache/mina/HttpServerDescriptor.java
    mina/trunk/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpStatus.java   (with props)
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVerb.java   (contents, props changed)
      - copied, changed from r1163102, mina/trunk/http/src/main/java/org/apache/mina/HttpVerb.java
Modified:
    mina/trunk/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterController.java
    mina/trunk/http/src/main/java/org/apache/mina/ArrayUtil.java
    mina/trunk/http/src/main/java/org/apache/mina/HttpException.java
    mina/trunk/http/src/main/java/org/apache/mina/HttpRequest.java
    mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java
    mina/trunk/http/src/main/java/org/apache/mina/HttpServerDescriptor.java
    mina/trunk/http/src/main/java/org/apache/mina/HttpVerb.java
    mina/trunk/http/src/main/java/org/apache/mina/MalFormedHttpRequest.java
    mina/trunk/http/src/main/java/org/apache/mina/PartialHttpRequest.java
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java
    mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java
    mina/trunk/http/src/test/java/org/apache/mina/http/HttpTest.java

Modified: mina/trunk/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterController.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterController.java?rev=1164808&r1=1164807&r2=1164808&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterController.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/filterchain/DefaultIoFilterController.java Sat Sep  3 06:51:17 2011
@@ -86,7 +86,8 @@ public class DefaultIoFilterController i
     public void processMessageWriting(IoSession session, Object message) {
         LOG.debug("processing message '{}' writing event ", message);
         if (chain.length < 1) {
-            LOG.debug("Nothing to do, the chain is empty");
+            LOG.debug("Nothing to do, the chain is empty, we just enqueue the message");
+            session.enqueueWriteRequest(message);
         } else {
             writeChainPosition = chain.length - 1;
             // we call the first filter, it's supposed to call the next ones using the filter chain controller
@@ -96,9 +97,11 @@ public class DefaultIoFilterController i
 
     @Override
     public void callWriteNextFilter(IoSession session, Object message) {
+        LOG.debug("calling next filter for writing for message '{}' position : {}", message, writeChainPosition);
         writeChainPosition--;
         if (writeChainPosition < 0 || chain.length == 0) {
             // end of chain processing
+            LOG.debug("end of write chan we enque the message in the session : {}", message);
             session.enqueueWriteRequest(message);
         } else {
             chain[writeChainPosition].messageWriting(session, message, this);

Copied: mina/trunk/http/src/main/java/org/apache/mina/http/ArrayUtil.java (from r1163102, mina/trunk/http/src/main/java/org/apache/mina/ArrayUtil.java)
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/ArrayUtil.java?p2=mina/trunk/http/src/main/java/org/apache/mina/http/ArrayUtil.java&p1=mina/trunk/http/src/main/java/org/apache/mina/ArrayUtil.java&r1=1163102&r2=1164808&rev=1164808&view=diff
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/ArrayUtil.java (original)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/ArrayUtil.java Sat Sep  3 06:51:17 2011
@@ -17,7 +17,7 @@
  *  under the License. 
  *  
  */
-package org.apache.mina;
+package org.apache.mina.http;
 
 public class ArrayUtil {
 

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

Added: mina/trunk/http/src/main/java/org/apache/mina/http/DateUtil.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/DateUtil.java?rev=1164808&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/DateUtil.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/DateUtil.java Sat Sep  3 06:51:17 2011
@@ -0,0 +1,118 @@
+/*
+ *  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;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.regex.Pattern;
+
+public class DateUtil {
+
+    private final static Locale LOCALE = Locale.US;
+    private final static TimeZone GMT_ZONE;
+    private final static String RFC_1123_PATTERN = "EEE, dd MMM yyyy HH:mm:ss zzz";
+    private final static DateFormat RFC_1123_FORMAT;
+
+    /** Pattern to find digits only. */
+    private final static Pattern DIGIT_PATTERN = Pattern.compile("^\\d+$");
+
+    static {
+        RFC_1123_FORMAT = new SimpleDateFormat(DateUtil.RFC_1123_PATTERN, DateUtil.LOCALE);
+        GMT_ZONE = TimeZone.getTimeZone("GMT");
+        DateUtil.RFC_1123_FORMAT.setTimeZone(DateUtil.GMT_ZONE);
+    }
+
+    public static String getCurrentAsString() {
+        return DateUtil.RFC_1123_FORMAT.format(new Date());
+    }
+
+    /**
+     * Translate a given date <code>String</code> in the <em>RFC 1123</em>
+     * format to a <code>long</code> representing the number of milliseconds
+     * since epoch.
+     * 
+     * @param dateString a date <code>String</code> in the <em>RFC 1123</em>
+     *            format.
+     * @return the parsed <code>Date</code> in milliseconds.
+     */
+    private static long parseDateStringToMilliseconds(final String dateString) {
+
+        try {
+            return DateUtil.RFC_1123_FORMAT.parse(dateString).getTime();
+        } catch (final ParseException e) {
+            return 0;
+        }
+    }
+
+    /**
+     * Parse a given date <code>String</code> to a <code>long</code>
+     * representation of the time. Where the provided value is all digits the
+     * value is returned as a <code>long</code>, otherwise attempt is made to
+     * parse the <code>String</code> as a <em>RFC 1123</em> date.
+     * 
+     * @param dateValue the value to parse.
+     * @return the <code>long</code> value following parse, or zero where not
+     *         successful.
+     */
+    public static long parseToMilliseconds(final String dateValue) {
+
+        long ms = 0;
+
+        if (DateUtil.DIGIT_PATTERN.matcher(dateValue).matches()) {
+            ms = Long.parseLong(dateValue);
+        } else {
+            ms = parseDateStringToMilliseconds(dateValue);
+        }
+
+        return ms;
+    }
+
+    /**
+     * Converts a millisecond representation of a date to a
+     * <code>RFC 1123</code> formatted <code>String</code>.
+     * 
+     * @param dateValue the <code>Date</code> represented as milliseconds.
+     * @return a <code>String</code> representation of the date.
+     */
+    public static String parseToRFC1123(final long dateValue) {
+
+        final Calendar calendar = Calendar.getInstance();
+        calendar.setTimeInMillis(dateValue);
+
+        return DateUtil.RFC_1123_FORMAT.format(calendar.getTime());
+    }
+
+    /**
+     * Convert a given <code>Date</code> object to a <code>RFC 1123</code>
+     * formatted <code>String</code>.
+     * 
+     * @param date the <code>Date</code> object to convert
+     * @return a <code>String</code> representation of the date.
+     */
+    public static String getDateAsString(Date date) {
+        return RFC_1123_FORMAT.format(date);
+    }
+
+}

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

Copied: mina/trunk/http/src/main/java/org/apache/mina/http/HttpException.java (from r1163102, mina/trunk/http/src/main/java/org/apache/mina/HttpException.java)
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/HttpException.java?p2=mina/trunk/http/src/main/java/org/apache/mina/http/HttpException.java&p1=mina/trunk/http/src/main/java/org/apache/mina/HttpException.java&r1=1163102&r2=1164808&rev=1164808&view=diff
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/HttpException.java (original)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/HttpException.java Sat Sep  3 06:51:17 2011
@@ -17,7 +17,7 @@
  *  under the License. 
  *  
  */
-package org.apache.mina;
+package org.apache.mina.http;
 
 @SuppressWarnings("serial")
 public class HttpException extends RuntimeException {

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

Copied: mina/trunk/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java (from r1163102, 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/HttpRequestImpl.java?p2=mina/trunk/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java&p1=mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java&r1=1163102&r2=1164808&rev=1164808&view=diff
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpRequestImpl.java (original)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java Sat Sep  3 06:51:17 2011
@@ -17,17 +17,24 @@
  *  under the License. 
  *  
  */
-package org.apache.mina.http.api;
+package org.apache.mina.http;
 
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.mina.http.api.HttpMethod;
+import org.apache.mina.http.api.HttpRequest;
+import org.apache.mina.http.api.HttpVersion;
+
 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) {
@@ -93,7 +100,7 @@ public class HttpRequestImpl implements 
 
     @Override
     public String toString() {
-        String result = "METHOD: " + method + "\n";
+        String result = "HTTP REQUEST METHOD: " + method + "\n";
         result += "VERSION: " + version + "\n";
         result += "PATH: " + requestedPath + "\n";
 

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

Copied: mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerCodec.java (from r1163102, 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/http/HttpServerCodec.java?p2=mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerCodec.java&p1=mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java&r1=1163102&r2=1164808&rev=1164808&view=diff
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/HttpServerCodec.java (original)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerCodec.java Sat Sep  3 06:51:17 2011
@@ -1,4 +1,4 @@
-package org.apache.mina;
+package org.apache.mina.http;
 
 import java.nio.ByteBuffer;
 import java.util.HashMap;
@@ -12,7 +12,7 @@ import org.apache.mina.filterchain.ReadF
 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.HttpResponse;
 import org.apache.mina.http.api.HttpVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,19 +34,25 @@ public class HttpServerCodec implements 
 
     /** 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(";");
 
@@ -143,7 +149,25 @@ public class HttpServerCodec implements 
 
     @Override
     public void messageWriting(IoSession session, Object message, WriteFilterChainController controller) {
-        // TODO encode HTTP response to ByteBuffer
+        if (message instanceof HttpResponse) {
+            HttpResponse msg = (HttpResponse) message;
+            StringBuilder sb = new StringBuilder(msg.getStatus().line());
+            for (Map.Entry<String, String> header : msg.getHeaders().entrySet()) {
+                sb.append(header.getKey());
+                sb.append(": ");
+                sb.append(header.getValue());
+                sb.append("\r\n");
+            }
+            sb.append("\r\n");
+            byte[] bytes = sb.toString().getBytes(Charsets.UTF_8);
+            controller.callWriteNextFilter(session, ByteBuffer.wrap(bytes));
+        } else if (message instanceof ByteBuffer) {
+            controller.callWriteNextFilter(session, message);
+        } else if (message instanceof HttpEndOfContent) {
+            // end of HTTP content
+            // keep alive ?
+            session.close(false);
+        }
     }
 
     private HttpRequestImpl parseHttpRequestHead(ByteBuffer buffer) {

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

Copied: mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerDescriptor.java (from r1163102, mina/trunk/http/src/main/java/org/apache/mina/HttpServerDescriptor.java)
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerDescriptor.java?p2=mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerDescriptor.java&p1=mina/trunk/http/src/main/java/org/apache/mina/HttpServerDescriptor.java&r1=1163102&r2=1164808&rev=1164808&view=diff
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/HttpServerDescriptor.java (original)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/HttpServerDescriptor.java Sat Sep  3 06:51:17 2011
@@ -17,7 +17,7 @@
  *  under the License. 
  *  
  */
-package org.apache.mina;
+package org.apache.mina.http;
 
 /**
  * This class provides a possiblity to change the tunables used by Deft for the http server configuration.
@@ -25,20 +25,20 @@ package org.apache.mina;
  */
 public class HttpServerDescriptor {
 
-	/** The number of seconds Deft will wait for subsequent socket activity before closing the connection */
-	public static int KEEP_ALIVE_TIMEOUT = 30 * 1000;	// 30s
-	
-	/**
-	 * Size of the read (receive) buffer.
-	 * "Ideally, an HTTP request should not go beyond 1 packet. 
-	 * The most widely used networks limit packets to approximately 1500 bytes, so if you can constrain each request 
-	 * to fewer than 1500 bytes, you can reduce the overhead of the request stream." (from: http://bit.ly/bkksUu)
-	 */
-	public static int READ_BUFFER_SIZE = 1024;	// 1024 bytes
-	
-	/**
-	 * Size of the write (send) buffer.
-	 */
-	public static int WRITE_BUFFER_SIZE = 1024;	// 1024 bytes
+    /** The number of seconds Deft will wait for subsequent socket activity before closing the connection */
+    public static int KEEP_ALIVE_TIMEOUT = 30 * 1000; // 30s
+
+    /**
+     * Size of the read (receive) buffer.
+     * "Ideally, an HTTP request should not go beyond 1 packet. 
+     * The most widely used networks limit packets to approximately 1500 bytes, so if you can constrain each request 
+     * to fewer than 1500 bytes, you can reduce the overhead of the request stream." (from: http://bit.ly/bkksUu)
+     */
+    public static int READ_BUFFER_SIZE = 1024; // 1024 bytes
+
+    /**
+     * Size of the write (send) buffer.
+     */
+    public static int WRITE_BUFFER_SIZE = 1024; // 1024 bytes
 
 }

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

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java?rev=1164808&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java Sat Sep  3 06:51:17 2011
@@ -0,0 +1,87 @@
+/*
+ *  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;
+
+public class DefaultHttpResponse implements HttpResponse {
+
+    private final HttpVersion version;
+
+    private final HttpStatus status;
+
+    private final Map<String, String> headers;
+
+    public DefaultHttpResponse(HttpVersion version, HttpStatus status, Map<String, String> headers) {
+        this.version = version;
+        this.status = status;
+        this.headers = headers;
+    }
+
+    @Override
+    public HttpVersion getProtocolVersion() {
+        return version;
+    }
+
+    @Override
+    public String getContentType() {
+        return headers.get("content-type");
+    }
+
+    @Override
+    public boolean isKeepAlive() {
+        // TODO check header and version for keep alive
+        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 HttpStatus getStatus() {
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        String result = "HTTP RESPONSE STATUS: " + status + "\n";
+        result += "VERSION: " + version + "\n";
+
+        result += "--- HEADER --- \n";
+        for (String key : headers.keySet()) {
+            String value = headers.get(key);
+            result += key + ":" + value + "\n";
+        }
+
+        return result;
+    }
+}

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

Modified: 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=1164808&r1=1164807&r2=1164808&view=diff
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java (original)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpResponse.java Sat Sep  3 06:51:17 2011
@@ -26,5 +26,11 @@ package org.apache.mina.http.api;
  * 
  */
 public interface HttpResponse extends HttpMessage {
+    /**
+     * The HTTP status code for the HTTP response (e.g. 200 for OK, 404 for not found, etc..)
+     * 
+     * @return the status of the HTTP response
+     */
+    HttpStatus getStatus();
 
 }

Added: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpStatus.java
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpStatus.java?rev=1164808&view=auto
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpStatus.java (added)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpStatus.java Sat Sep  3 06:51:17 2011
@@ -0,0 +1,215 @@
+/*
+ *  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 <code>Enumeration</code> of all known HTTP status codes.
+ */
+public enum HttpStatus {
+
+    /**
+     * 200 - OK
+     */
+    SUCCESS_OK(200, "HTTP/1.1 200 OK"),
+    /**
+     * 201 - Created
+     */
+    SUCCESS_CREATED(201, "HTTP/1.1 201 Created"),
+    /**
+     * 202 - Accepted
+     */
+    SUCCESS_ACCEPTED(202, "HTTP/1.1 202 Accepted"),
+    /**
+     * 203 - Non-Authoritative Information
+     */
+    SUCCESS_NON_AUTHORATIVE_INFORMATION(203, "HTTP/1.1 203 Non-Authoritative Information"),
+    /**
+     * 204 - No Content
+     */
+    SUCCESS_NO_CONTENT(204, "HTTP/1.1 204 No Content"),
+    /**
+     * 205 - Reset Content
+     */
+    SUCCESS_RESET_CONTENT(205, "HTTP/1.1 205 Reset Content"),
+    /**
+     * 206 - Created
+     */
+    SUCCESS_PARTIAL_CONTENT(206, "HTTP/1.1 206 Partial Content"),
+
+    /**
+     * 300 - Multiple Choices
+     */
+    REDIRECTION_MULTIPLE_CHOICES(300, "HTTP/1.1 300 Multiple Choices"),
+    /**
+     * 301 - Moved Permanently
+     */
+    REDIRECTION_MOVED_PERMANENTLY(301, "HTTP/1.1 301 Moved Permanently"),
+    /**
+     * 302 - Found / Moved Temporarily
+     */
+    REDIRECTION_FOUND(302, "HTTP/1.1 302 Found"),
+    /**
+     * 303 - See Others
+     */
+    REDIRECTION_SEE_OTHER(303, "HTTP/1.1 303 See Other"),
+    /**
+     * 304 - Not Modified
+     */
+    REDIRECTION_NOT_MODIFIED(304, "HTTP/1.1 304 Not Modified"),
+    /**
+     * 305 - Use Proxy
+     */
+    REDIRECTION_USE_PROXY(305, "HTTP/1.1 305 Use Proxy"),
+    /**
+     * 307 - Temporary Redirect
+     */
+    REDIRECTION_TEMPORARILY_REDIRECT(307, "HTTP/1.1 307 Temporary Redirect"),
+
+    /**
+     * 400 - Bad Request
+     */
+    CLIENT_ERROR_BAD_REQUEST(400, "HTTP/1.1 400 Bad Request"),
+    /**
+     * 401 - Unauthorized
+     */
+    CLIENT_ERROR_UNAUTHORIZED(401, "HTTP/1.1 401 Unauthorized"),
+    /**
+     * 403 - Forbidden
+     */
+    CLIENT_ERROR_FORBIDDEN(403, "HTTP/1.1 403 Forbidden"),
+    /**
+     * 404 - Not Found
+     */
+    CLIENT_ERROR_NOT_FOUND(404, "HTTP/1.1 404 Not Found"),
+    /**
+     * 405 - Method Not Allowed
+     */
+    CLIENT_ERROR_METHOD_NOT_ALLOWED(405, "HTTP/1.1 405 Method Not Allowed"),
+    /**
+     * 406 - Not Acceptable
+     */
+    CLIENT_ERROR_NOT_ACCEPTABLE(406, "HTTP/1.1 406 Not Acceptable"),
+    /**
+     * 407 - Proxy Authentication Required
+     */
+    CLIENT_ERROR_PROXY_AUTHENTICATION_REQUIRED(407, "HTTP/1.1 407 Proxy Authentication Required"),
+    /**
+     * 408 - Request Timeout
+     */
+    CLIENT_ERROR_REQUEST_TIMEOUT(408, "HTTP/1.1 408 Request Timeout"),
+    /**
+     * 409 - Conflict
+     */
+    CLIENT_ERROR_CONFLICT(409, "HTTP/1.1 409 Conflict"),
+    /**
+     * 410 - Gone
+     */
+    CLIENT_ERROR_GONE(410, "HTTP/1.1 410 Gone"),
+    /**
+     * 411 - Length Required
+     */
+    CLIENT_ERROR_LENGTH_REQUIRED(411, "HTTP/1.1 411 Length Required"),
+    /**
+     * 412 - Precondition Failed
+     */
+    CLIENT_ERROR_PRECONDITION_FAILED(412, "HTTP/1.1 412 Precondition Failed"),
+    /**
+     * 413 - Request Entity Too Large
+     */
+    CLIENT_ERROR_REQUEST_ENTITY_TOO_LARGE(413, "HTTP/1.1 413 Request Entity Too Large"),
+    /**
+     * 414 - Bad Request
+     */
+    CLIENT_ERROR_REQUEST_URI_TOO_LONG(414, "HTTP/1.1 414 Request-URI Too Long"),
+    /**
+     * 415 - Unsupported Media Type
+     */
+    CLIENT_ERROR_UNSUPPORTED_MEDIA_TYPE(415, "HTTP/1.1 415 Unsupported Media Type"),
+    /**
+     * 416 - Requested Range Not Satisfiable
+     */
+    CLIENT_ERROR_REQUESTED_RANGE_NOT_SATISFIABLE(416, "HTTP/1.1 416 Requested Range Not Satisfiable"),
+    /**
+     * 417 - Expectation Failed
+     */
+    CLIENT_ERROR_EXPECTATION_FAILED(417, "HTTP/1.1 417 Expectation Failed"),
+
+    /**
+     * 500 - Internal Server Error
+     */
+    SERVER_ERROR_INTERNAL_SERVER_ERROR(500, "HTTP/1.1 500 Internal Server Error"),
+    /**
+     * 501 - Not Implemented
+     */
+    SERVER_ERROR_NOT_IMPLEMENTED(501, "HTTP/1.1 501 Not Implemented"),
+    /**
+     * 502 - Bad Gateway
+     */
+    SERVER_ERROR_BAD_GATEWAY(502, "HTTP/1.1 502 Bad Gateway"),
+    /**
+     * 503 - Service Unavailable
+     */
+    SERVER_ERROR_SERVICE_UNAVAILABLE(503, "HTTP/1.1 503 Service Unavailable"),
+    /**
+     * 504 - Gateway Timeout
+     */
+    SERVER_ERROR_GATEWAY_TIMEOUT(504, "HTTP/1.1 504 Gateway Timeout"),
+    /**
+     * 505 - HTTP Version Not Supported
+     */
+    SERVER_ERROR_HTTP_VERSION_NOT_SUPPORTED(505, "HTTP/1.1 505 HTTP Version Not Supported");
+
+    /** The code associated with this status, for example "404" for "Not Found". */
+    private int code;
+
+    /**
+     * The line associated with this status, "HTTP/1.1 501 Not Implemented".
+     */
+    private String line;
+
+    /**
+     * Create an instance of this type.
+     * 
+     * @param code the status code.
+     * @param phrase the associated phrase.
+     */
+    private HttpStatus(int code, String phrase) {
+        this.code = code;
+        line = phrase;
+    }
+
+    /**
+     * Retrieve the status code for this instance.
+     * 
+     * @return the status code.
+     */
+    public int code() {
+        return code;
+    }
+
+    /**
+     * Retrieve the status line for this instance.
+     * 
+     * @return the status line.
+     */
+    public String line() {
+        return line + "\r\n";
+    }
+}

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

Copied: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVerb.java (from r1163102, mina/trunk/http/src/main/java/org/apache/mina/HttpVerb.java)
URL: http://svn.apache.org/viewvc/mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVerb.java?p2=mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVerb.java&p1=mina/trunk/http/src/main/java/org/apache/mina/HttpVerb.java&r1=1163102&r2=1164808&rev=1164808&view=diff
==============================================================================
--- mina/trunk/http/src/main/java/org/apache/mina/HttpVerb.java (original)
+++ mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVerb.java Sat Sep  3 06:51:17 2011
@@ -17,16 +17,9 @@
  *  under the License. 
  *  
  */
-package org.apache.mina;
+package org.apache.mina.http.api;
 
 public enum HttpVerb {
-	
-	GET,
-	HEAD,
-	POST,
-	PUT,
-	DELETE,
-	OPTIONS,
-	TRACE,
-	CONNECT
+
+    GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, CONNECT
 }

Propchange: mina/trunk/http/src/main/java/org/apache/mina/http/api/HttpVerb.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=1164808&r1=1164807&r2=1164808&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 Sat Sep  3 06:51:17 2011
@@ -1,28 +1,141 @@
+/*
+ *  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;
 
 import java.net.InetSocketAddress;
-
-import org.apache.mina.HttpServerCodec;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.mina.api.IdleStatus;
+import org.apache.mina.api.IoFilter;
+import org.apache.mina.api.IoSession;
 import org.apache.mina.filter.logging.LoggingFilter;
+import org.apache.mina.filterchain.ReadFilterChainController;
+import org.apache.mina.filterchain.WriteFilterChainController;
+import org.apache.mina.http.api.DefaultHttpResponse;
+import org.apache.mina.http.api.HttpEndOfContent;
+import org.apache.mina.http.api.HttpMethod;
+import org.apache.mina.http.api.HttpRequest;
+import org.apache.mina.http.api.HttpStatus;
+import org.apache.mina.http.api.HttpVersion;
 import org.apache.mina.service.OneThreadSelectorStrategy;
 import org.apache.mina.service.SelectorFactory;
 import org.apache.mina.transport.tcp.NioSelectorProcessor;
 import org.apache.mina.transport.tcp.nio.NioTcpServer;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class HttpTest {
 
+    private static final Logger LOG = LoggerFactory.getLogger(HttpTest.class);
+
     @Test
     public void simpleServer() throws Exception {
 
         OneThreadSelectorStrategy strategy = new OneThreadSelectorStrategy(new SelectorFactory(
                 NioSelectorProcessor.class));
         NioTcpServer acceptor = new NioTcpServer(strategy);
-        acceptor.setFilters(new LoggingFilter("INCOMING"), new HttpServerCodec(), new LoggingFilter("DECODED"));
+        acceptor.setFilters(new LoggingFilter("INCOMING"), new HttpServerCodec(), new LoggingFilter("DECODED"),
+                new DummyHttpSever());
 
         acceptor.bind(new InetSocketAddress(8080));
         Thread.sleep(20000);
         acceptor.unbindAll();
 
     }
+
+    private class DummyHttpSever implements IoFilter {
+
+        @Override
+        public void sessionCreated(IoSession session) {
+
+        }
+
+        @Override
+        public void sessionOpened(IoSession session) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void sessionClosed(IoSession session) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public void sessionIdle(IoSession session, IdleStatus status) {
+            // TODO Auto-generated method stub
+
+        }
+
+        private HttpRequest incomingRequest;
+
+        private List<ByteBuffer> body;
+
+        @Override
+        public void messageReceived(IoSession session, Object message, ReadFilterChainController controller) {
+            if (message instanceof HttpRequest) {
+                incomingRequest = (HttpRequest) message;
+                body = new ArrayList<ByteBuffer>();
+
+                // check if this request is going to be followed by and HTTP body or not
+                if (incomingRequest.getMethod() != HttpMethod.POST && incomingRequest.getMethod() != HttpMethod.PUT) {
+                    sendResponse(session, incomingRequest);
+                } else {
+
+                }
+            } else if (message instanceof ByteBuffer) {
+                body.add((ByteBuffer) message);
+            } else if (message instanceof HttpEndOfContent) {
+                // we received all the post content, send the crap back
+                sendResponse(session, incomingRequest);
+            }
+
+        }
+
+        public void sendResponse(IoSession session, HttpRequest request) {
+            Map<String, String> headers = new HashMap<String, String>();
+            headers.put("Server", "Apache MINA Dummy test server/0.0.");
+            headers.put("Date", DateUtil.getCurrentAsString());
+            headers.put("Connection", "Close");
+            String strContent = "Hello ! we reply to request !";
+            ByteBuffer content = ByteBuffer.wrap(strContent.getBytes());
+
+            // compute content len
+            headers.put("Content-Length", String.valueOf(content.remaining()));
+            session.write(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SUCCESS_OK, headers));
+            session.write(content);
+            session.write(new HttpEndOfContent());
+
+        }
+
+        @Override
+        public void messageWriting(IoSession session, Object message, WriteFilterChainController controller) {
+            // we just push the message in the chain
+            controller.callWriteNextFilter(session, message);
+        }
+
+    }
 }