dev@grizzly.java.net

[FYI] New higher level HTTP classes, new modules for better Grizzly HTTP extensions

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Tue, 29 Jan 2008 14:05:35 -0500

Hi,

based on the feedback I've got recently when people extend Grizzly Http
WebServer, I've reworked a little the HTTP Web Server can came with the
following new classes (under
http-utils/src/main/java/com/sun/grizzly/tcp/http11)

GrizzlyAdapter.java
GrizzlyInputBuffer.java
GrizzlyInputStream.java
GrizzlyOutputBuffer.java
GrizzlyOutputStream.java
GrizzlyReader.java
GrizzlyRequest.java
GrizzlyResponse.java
GrizzlyWriter.java

Those classes are build on top of the
http-utils/src/main/java/com/sun/grizzly/tcp classes
(Request/Response/Adapter) and makes much more easy the task of
extending the Grizzly HTTP WebServer. To see and example of how you can
use those new classes, I recommend you take a look at the new Servlet
module I've added under:

modules/http-servlet

This module allow you to load a Servlet and execute it outside a Servlet
Container (but with a limited set of features). This modules is
extremely useful when a Servlet is used as a proxy. As an example, and
PHPServlet or CGIServlet can be bootstraped using that module,
significantly improving the performance as they don't need all the
features a Servlet Container offer.

If you are planning to extend the Grizzly HTTP WebServer, I strongly
recommend you take a look at the new Grizzly* classes. Of course they
introduce a small performance hit if you compare with the current
Request/Response object, but they greatly reduce the complexity of
extending Grizzly HTTP.

Feedback appreciated :-)

A+

-- Jeanfrancois

P.S Documentation is coming, as usual.




-------- Original Message --------
Subject: svn commit: r742 - trunk/modules:
comet/src/main/java/com/sun/grizzly/container
cometd/src/main/java/com/sun/grizzly/cometd cometd/src/main/java/co...
Date: Tue, 29 Jan 2008 18:48:18 +0000
From: jfarcand_at_dev.java.net
Reply-To: commits_at_grizzly.dev.java.net
To: commits_at_grizzly.dev.java.net

Author: jfarcand
Date: 2008-01-29 18:48:15+0000
New Revision: 742

Added:
    trunk/modules/http-servlet/
    trunk/modules/http-servlet/pom.xml (contents, props changed)
    trunk/modules/http-servlet/src/
    trunk/modules/http-servlet/src/main/
    trunk/modules/http-servlet/src/main/java/
    trunk/modules/http-servlet/src/main/java/com/
    trunk/modules/http-servlet/src/main/java/com/sun/
    trunk/modules/http-servlet/src/main/java/com/sun/grizzly/
    trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/
    trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/
 
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/CookieWrapper.java
   (contents, props changed)
 
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/HttpServletRequestImpl.java
   (contents, props changed)
 
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/HttpServletResponseImpl.java
   (contents, props changed)
 
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletAdapter.java
   (contents, props changed)
 
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletConfigImpl.java
   (contents, props changed)
 
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletContextImpl.java
   (contents, props changed)
 
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletInputStreamImpl.java
   (contents, props changed)
 
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletOutputStreamImpl.java
   (contents, props changed)
    trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/
       - copied from r713,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/ActionCode.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/ActionCode.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/ActionHook.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/ActionHook.java
    trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/Adapter.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/Adapter.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/Constants.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/Constants.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/DynamicContentAdapter.java
       - copied, changed from r713,
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/InputBuffer.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/InputBuffer.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/NotesManager.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/NotesManager.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/NotesManagerImpl.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/NotesManagerImpl.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/OutputBuffer.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/OutputBuffer.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/Processor.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/Processor.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/ProtocolHandler.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/ProtocolHandler.java
    trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/Request.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/Request.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/RequestGroupInfo.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/RequestGroupInfo.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/RequestInfo.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/RequestInfo.java
    trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/Response.java
       - copied unchanged from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/Response.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/StaticResourcesAdapter.java
       - copied, changed from r713,
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java
    trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/
       - copied from r741,
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/http11/
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/ClientAbortException.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyAdapter.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyInputBuffer.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyInputStream.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyOutputBuffer.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyOutputStream.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyReader.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyRequest.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyResponse.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyWriter.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Cookie.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Enumerator.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/FastDateFormat.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Globals.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings.properties
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_es.properties
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_fr.properties
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_ja.properties
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/MimeType.java
       - copied, changed from r713,
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/ParameterMap.java
   (contents, props changed)
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/StringParser.java
   (contents, props changed)
Modified:
 
trunk/modules/comet/src/main/java/com/sun/grizzly/container/GrizzletAdapter.java
 
trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/CometdNotificationHandler.java
 
trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/standalone/CometdAdapter.java
 
trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/Constants.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/InternalInputBuffer.java
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/LocalStrings.properties
 
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/buf/DateTool.java
 
trunk/modules/http/src/main/java/com/sun/grizzly/http/DefaultProcessorTask.java
 
trunk/modules/http/src/main/java/com/sun/grizzly/http/KeepAliveCountManager.java
 
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java
    trunk/modules/http/src/main/java/com/sun/grizzly/standalone/Main.java
 
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java
 
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java
 
trunk/modules/jruby/src/main/java/com/sun/grizzly/jruby/RailsAdapter.java
    trunk/modules/jruby/src/main/java/com/sun/grizzly/standalone/JRuby.java

Log:
Refactorize the http implementation by adding new high level objects,
which are build on top of the current Request/Response objects, but with
a API similar to the Servlet API where
InputStream/OutputStream/Reader/Writer can get used instead of
manipulating bytes. Add a new module called http-servlet which can be
used to bootstrap a Servlet class and execute it outside a Servlet
Container (there is limited support of the Servlet API, with no support
for Filters/Dispacher). This new module will be used to launch the Comet
and Cometd Servlet (who doesn't require any Servlet API), avoiding to
have to support CometdAdapter/CometAdapter/GrizzletAdapter and instead
launch their respective Servlet.

The refactoring consist of:

+ move http/src/main/java/com/sun/grizzly/tcp/*
   under
   http-utils/src/main/java/com/sun/grizzly/tcp
+ Add new Grizzly* http classes
(GrizzlyRequest,GrizzlyResponse,GrizzlyAdapter, etc.) that can be used
wheb extending the http runtime.
+ Added a new http-servlet module, which use the new Grizzly classes.
+ Deprecated classes under
http/src/main/java/com/sun/grizzly/standalone, and moved the
implementation under http-utils/src/main/java/com/sun/grizzly/tcp/.

Hopefully nothing is broken. The new classes will eventually be used by
Netbeans (Phobos), Jersey and any http extensions.




Modified:
trunk/modules/comet/src/main/java/com/sun/grizzly/container/GrizzletAdapter.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/comet/src/main/java/com/sun/grizzly/container/GrizzletAdapter.java?view=diff&rev=742&p1=trunk/modules/comet/src/main/java/com/sun/grizzly/container/GrizzletAdapter.java&p2=trunk/modules/comet/src/main/java/com/sun/grizzly/container/GrizzletAdapter.java&r1=741&r2=742
==============================================================================
---
trunk/modules/comet/src/main/java/com/sun/grizzly/container/GrizzletAdapter.java
(original)
+++
trunk/modules/comet/src/main/java/com/sun/grizzly/container/GrizzletAdapter.java
2008-01-29 18:48:15+0000
@@ -29,15 +29,13 @@

  import com.sun.grizzly.comet.CometContext;
  import com.sun.grizzly.comet.CometEngine;
-import com.sun.grizzly.comet.CometEvent;
  import com.sun.grizzly.grizzlet.Grizzlet;
-import com.sun.grizzly.grizzlet.AsyncConnection;
-import com.sun.grizzly.standalone.StaticResourcesAdapter;
  import java.io.File;

  import com.sun.grizzly.tcp.Adapter;
  import com.sun.grizzly.tcp.Request;
  import com.sun.grizzly.tcp.Response;
+import com.sun.grizzly.tcp.StaticResourcesAdapter;
  import com.sun.grizzly.util.buf.ByteChunk;
  import com.sun.grizzly.util.buf.MessageBytes;


Modified:
trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/CometdNotificationHandler.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/CometdNotificationHandler.java?view=diff&rev=742&p1=trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/CometdNotificationHandler.java&p2=trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/CometdNotificationHandler.java&r1=741&r2=742
==============================================================================
---
trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/CometdNotificationHandler.java
(original)
+++
trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/CometdNotificationHandler.java
2008-01-29 18:48:15+0000
@@ -56,6 +56,7 @@
      /**
       * Notify only client subscribed to the active channel.
       */
+ @Override
      protected void notify0(CometEvent
cometEvent,Iterator<CometHandler> iteratorHandlers)
              throws IOException{
          ArrayList<Throwable> exceptions = null;

Modified:
trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/standalone/CometdAdapter.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/standalone/CometdAdapter.java?view=diff&rev=742&p1=trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/standalone/CometdAdapter.java&p2=trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/standalone/CometdAdapter.java&r1=741&r2=742
==============================================================================
---
trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/standalone/CometdAdapter.java
(original)
+++
trunk/modules/cometd/src/main/java/com/sun/grizzly/cometd/standalone/CometdAdapter.java
2008-01-29 18:48:15+0000
@@ -40,7 +40,6 @@
  import com.sun.grizzly.http.SelectorThread;
  import com.sun.grizzly.comet.CometContext;
  import com.sun.grizzly.comet.CometEngine;
-import com.sun.grizzly.standalone.StaticResourcesAdapter;
  import com.sun.grizzly.cometd.BayeuxCometHandler;
  import com.sun.grizzly.cometd.CometdNotificationHandler;
  import com.sun.grizzly.cometd.CometdRequest;
@@ -53,6 +52,7 @@
  import com.sun.grizzly.tcp.Adapter;
  import com.sun.grizzly.tcp.Request;
  import com.sun.grizzly.tcp.Response;
+import com.sun.grizzly.tcp.StaticResourcesAdapter;
  import com.sun.grizzly.util.buf.ByteChunk;
  import com.sun.grizzly.util.buf.MessageBytes;
  import com.sun.grizzly.util.http.Parameters;

Modified:
trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java?view=diff&rev=742&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java&r1=741&r2=742
==============================================================================
---
trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java
(original)
+++
trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPSelectorHandler.java
2008-01-29 18:48:15+0000
@@ -697,8 +697,13 @@
          try {
              CallbackHandlerContextTask task =
CallbackHandlerContextTask.poll();
              task.setCallBackHandler(callbackHandler);
- context.execute(task);
- } catch (PipelineFullException ex){
+ if (context.getCurrentOpType() != Context.OpType.OP_CONNECT){
+ context.execute(task);
+ } else {
+ task.setContext(context);
+ task.call();
+ }
+ } catch (Exception ex){
              throw new IOException(ex.getMessage());
          }
      }

Added: trunk/modules/http-servlet/pom.xml
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/pom.xml?view=auto&rev=742
==============================================================================
--- (empty file)
+++ trunk/modules/http-servlet/pom.xml 2008-01-29 18:48:15+0000
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>com.sun.grizzly</groupId>
+ <artifactId>grizzly-project</artifactId>
+ <version>1.7-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.sun.grizzly</groupId>
+ <artifactId>grizzly-http-servlet</artifactId>
+ <packaging>jar</packaging>
+ <version>${grizzly-version}</version>
+ <name>grizzly-http-servlet</name>
+ <url>https://grizzly.dev.java.net</url>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <repositories>
+ <repository>
+ <id>java.net</id>
+
<url>https://maven-repository.dev.java.net/nonav/repository</url>
+ <layout>legacy</layout>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>com.sun.grizzly</groupId>
+ <artifactId>grizzly-http-utils</artifactId>
+ <version>${grizzly-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit-version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>

Added:
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/CookieWrapper.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/CookieWrapper.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/CookieWrapper.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,453 @@
+
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
obtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.grizzly.http.servlet;
+
+import com.sun.grizzly.util.http.Cookie;
+
+/**
+ *
+ * @author jfarcand
+ */
+public class CookieWrapper extends Cookie {
+ /**
+ * Constructs a cookie with a specified name and value.
+ *
+ * <p>The name must conform to RFC 2109. That means it can contain
+ * only ASCII alphanumeric characters and cannot contain commas,
+ * semicolons, or white space or begin with a $ character. The cookie's
+ * name cannot be changed after creation.
+ *
+ * <p>The value can be anything the server chooses to send. Its
+ * value is probably of interest only to the server. The cookie's
+ * value can be changed after creation with the
+ * <code>setValue</code> method.
+ *
+ * <p>By default, cookies are created according to the Netscape
+ * cookie specification. The version can be changed with the
+ * <code>setVersion</code> method.
+ *
+ *
+ * @param name a <code>String</code> specifying the name of the
cookie
+ *
+ * @param value a <code>String</code> specifying the value of the
cookie
+ *
+ * @throws IllegalArgumentException if the cookie name contains
illegal characters
+ * (for example, a comma, space, or semicolon)
+ * or it is one of the tokens reserved for use
+ * by the cookie protocol
+ * @see #setValue
+ * @see #setVersion
+ *
+ */
+ public CookieWrapper(String name, String value) {
+ super(name,value);
+ }
+
+ private javax.servlet.http.Cookie wrappedCookie = null;
+
+ /**
+ *
+ * Specifies a comment that describes a cookie's purpose.
+ * The comment is useful if the browser presents the cookie
+ * to the user. Comments
+ * are not supported by Netscape Version 0 cookies.
+ *
+ * @param purpose a <code>String</code> specifying the comment
+ * to display to the user
+ *
+ * @see #getComment
+ *
+ */
+
+ @Override
+ public void setComment(String purpose) {
+ wrappedCookie.setComment(purpose);
+ }
+
+
+
+
+ /**
+ * Returns the comment describing the purpose of this cookie, or
+ * <code>null</code> if the cookie has no comment.
+ *
+ * @return a <code>String</code> containing the comment,
+ * or <code>null</code> if none
+ *
+ * @see #setComment
+ *
+ */
+
+ @Override
+ public String getComment() {
+ return wrappedCookie.getComment();
+ }
+
+
+
+
+
+ /**
+ *
+ * Specifies the domain within which this cookie should be presented.
+ *
+ * <p>The form of the domain name is specified by RFC 2109. A domain
+ * name begins with a dot (<code>.foo.com</code>) and means that
+ * the cookie is visible to servers in a specified Domain Name System
+ * (DNS) zone (for example, <code>www.foo.com</code>, but not
+ * <code>a.b.foo.com</code>). By default, cookies are only returned
+ * to the server that sent them.
+ *
+ *
+ * @param pattern a <code>String</code> containing the domain name
+ * within which this cookie is visible;
+ * form is according to RFC 2109
+ *
+ * @see #getDomain
+ *
+ */
+
+ @Override
+ public void setDomain(String pattern) {
+ wrappedCookie.setDomain(pattern);
+ }
+
+
+
+
+
+ /**
+ * Returns the domain name set for this cookie. The form of
+ * the domain name is set by RFC 2109.
+ *
+ * @return a <code>String</code> containing the domain name
+ *
+ * @see #setDomain
+ *
+ */
+
+ @Override
+ public String getDomain() {
+ return wrappedCookie.getDomain();
+ }
+
+
+
+
+ /**
+ * Sets the maximum age of the cookie in seconds.
+ *
+ * <p>A positive value indicates that the cookie will expire
+ * after that many seconds have passed. Note that the value is
+ * the <i>maximum</i> age when the cookie will expire, not the cookie's
+ * current age.
+ *
+ * <p>A negative value means
+ * that the cookie is not stored persistently and will be deleted
+ * when the Web browser exits. A zero value causes the cookie
+ * to be deleted.
+ *
+ * @param expiry an integer specifying the maximum age of the
+ * cookie in seconds; if negative, means
+ * the cookie is not stored; if zero, deletes
+ * the cookie
+ *
+ *
+ * @see #getMaxAge
+ *
+ */
+
+ @Override
+ public void setMaxAge(int expiry) {
+ wrappedCookie.setMaxAge(expiry);
+ }
+
+
+
+
+ /**
+ * Returns the maximum age of the cookie, specified in seconds,
+ * By default, <code>-1</code> indicating the cookie will persist
+ * until browser shutdown.
+ *
+ *
+ * @return an integer specifying the maximum age of the
+ * cookie in seconds; if negative, means
+ * the cookie persists until browser shutdown
+ *
+ *
+ * @see #setMaxAge
+ *
+ */
+
+ @Override
+ public int getMaxAge() {
+ return wrappedCookie.getMaxAge();
+ }
+
+
+
+
+ /**
+ * Specifies a path for the cookie
+ * to which the client should return the cookie.
+ *
+ * <p>The cookie is visible to all the pages in the directory
+ * you specify, and all the pages in that directory's subdirectories.
+ * A cookie's path must include the servlet that set the cookie,
+ * for example, <i>/catalog</i>, which makes the cookie
+ * visible to all directories on the server under <i>/catalog</i>.
+ *
+ * <p>Consult RFC 2109 (available on the Internet) for more
+ * information on setting path names for cookies.
+ *
+ *
+ * @param uri a <code>String</code> specifying a path
+ *
+ *
+ * @see #getPath
+ *
+ */
+
+ @Override
+ public void setPath(String uri) {
+ wrappedCookie.setPath(uri);
+ }
+
+
+
+
+ /**
+ * Returns the path on the server
+ * to which the browser returns this cookie. The
+ * cookie is visible to all subpaths on the server.
+ *
+ *
+ * @return a <code>String</code> specifying a path that contains
+ * a servlet name, for example, <i>/catalog</i>
+ *
+ * @see #setPath
+ *
+ */
+
+ @Override
+ public String getPath() {
+ return wrappedCookie.getPath();
+ }
+
+
+
+
+
+ /**
+ * Indicates to the browser whether the cookie should only be sent
+ * using a secure protocol, such as HTTPS or SSL.
+ *
+ * <p>The default value is <code>false</code>.
+ *
+ * @param flag if <code>true</code>, sends the cookie from the browser
+ * to the server only when using a secure protocol;
+ * if <code>false</code>, sent on any protocol
+ *
+ * @see #getSecure
+ *
+ */
+
+ @Override
+ public void setSecure(boolean flag) {
+ wrappedCookie.setSecure(flag);
+ }
+
+
+
+
+ /**
+ * Returns <code>true</code> if the browser is sending cookies
+ * only over a secure protocol, or <code>false</code> if the
+ * browser can send cookies using any protocol.
+ *
+ * @return <code>true</code> if the browser uses a secure protocol;
+ * otherwise, <code>true</code>
+ *
+ * @see #setSecure
+ *
+ */
+
+ @Override
+ public boolean getSecure() {
+ return wrappedCookie.getSecure();
+ }
+
+
+
+
+
+ /**
+ * Returns the name of the cookie. The name cannot be changed after
+ * creation.
+ *
+ * @return a <code>String</code> specifying the cookie's name
+ *
+ */
+
+ @Override
+ public String getName() {
+ return wrappedCookie.getName();
+ }
+
+
+
+
+
+ /**
+ *
+ * Assigns a new value to a cookie after the cookie is created.
+ * If you use a binary value, you may want to use BASE64 encoding.
+ *
+ * <p>With Version 0 cookies, values should not contain white
+ * space, brackets, parentheses, equals signs, commas,
+ * double quotes, slashes, question marks, at signs, colons,
+ * and semicolons. Empty values may not behave the same way
+ * on all browsers.
+ *
+ * @param newValue a <code>String</code> specifying the new value
+ *
+ *
+ * @see #getValue
+ * @see Cookie
+ *
+ */
+
+ @Override
+ public void setValue(String newValue) {
+ wrappedCookie.setValue(newValue);
+ }
+
+
+
+
+ /**
+ * Returns the value of the cookie.
+ *
+ * @return a <code>String</code> containing the cookie's
+ * present value
+ *
+ * @see #setValue
+ * @see Cookie
+ *
+ */
+
+ @Override
+ public String getValue() {
+ return wrappedCookie.getValue();
+ }
+
+
+
+
+ /**
+ * Returns the version of the protocol this cookie complies
+ * with. Version 1 complies with RFC 2109,
+ * and version 0 complies with the original
+ * cookie specification drafted by Netscape. Cookies provided
+ * by a browser use and identify the browser's cookie version.
+ *
+ *
+ * @return 0 if the cookie complies with the
+ * original Netscape specification; 1
+ * if the cookie complies with RFC 2109
+ *
+ * @see #setVersion
+ *
+ */
+
+ @Override
+ public int getVersion() {
+ return wrappedCookie.getVersion();
+ }
+
+
+
+
+ /**
+ * Sets the version of the cookie protocol this cookie complies
+ * with. Version 0 complies with the original Netscape cookie
+ * specification. Version 1 complies with RFC 2109.
+ *
+ * <p>Since RFC 2109 is still somewhat new, consider
+ * version 1 as experimental; do not use it yet on production sites.
+ *
+ *
+ * @param v 0 if the cookie should comply with
+ * the original Netscape specification;
+ * 1 if the cookie should comply with RFC 2109
+ *
+ * @see #getVersion
+ *
+ */
+
+ @Override
+ public void setVersion(int v) {
+ wrappedCookie.setVersion(v);
+ }
+
+ /**
+ *
+ * Overrides the standard <code>java.lang.Object.clone</code>
+ * method to return a copy of this cookie.
+ *
+ *
+ */
+
+ @Override
+ public Object clone() {
+ return wrappedCookie.clone();
+ }
+
+ public javax.servlet.http.Cookie getWrappedCookie() {
+ return wrappedCookie;
+ }
+
+
+ public void setWrappedCookie(javax.servlet.http.Cookie wrappedCookie) {
+ this.wrappedCookie = wrappedCookie;
+ }
+}

Added:
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/HttpServletRequestImpl.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/HttpServletRequestImpl.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/HttpServletRequestImpl.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,901 @@
+
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
obtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+
+package com.sun.grizzly.http.servlet;
+
+import com.sun.grizzly.tcp.http11.Constants;
+import com.sun.grizzly.tcp.http11.GrizzlyRequest;
+import com.sun.grizzly.util.http.Cookie;
+import com.sun.grizzly.util.res.StringManager;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Locale;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.ServletInputStream;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Facade class that wraps a Coyote request object.
+ * All methods are delegated to the wrapped request.
+ *
+ * @author Craig R. McClanahan
+ * @author Remy Maucherat
+ * @author Jean-Francois Arcand
+ * @version $Revision: 1.7 $ $Date: 2007/08/01 19:04:28 $
+ */
+public class HttpServletRequestImpl implements HttpServletRequest {
+
+ private ServletInputStream inputStream = null;
+
+ // -----------------------------------------------------------
DoPrivileged
+
+ private final class GetAttributePrivilegedAction
+ implements PrivilegedAction {
+
+ public Object run() {
+ return request.getAttributeNames();
+ }
+ }
+
+
+ private final class GetParameterMapPrivilegedAction
+ implements PrivilegedAction {
+
+ public Object run() {
+ return request.getParameterMap();
+ }
+ }
+
+
+ private final class GetRequestDispatcherPrivilegedAction
+ implements PrivilegedAction {
+
+ private String path;
+
+ public GetRequestDispatcherPrivilegedAction(String path){
+ this.path = path;
+ }
+
+ public Object run() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+
+
+ private final class GetParameterPrivilegedAction
+ implements PrivilegedAction {
+
+ public String name;
+
+ public GetParameterPrivilegedAction(String name){
+ this.name = name;
+ }
+
+ public Object run() {
+ return request.getParameter(name);
+ }
+ }
+
+
+ private final class GetParameterNamesPrivilegedAction
+ implements PrivilegedAction {
+
+ public Object run() {
+ return request.getParameterNames();
+ }
+ }
+
+
+ private final class GetParameterValuePrivilegedAction
+ implements PrivilegedAction {
+
+ public String name;
+
+ public GetParameterValuePrivilegedAction(String name){
+ this.name = name;
+ }
+
+ public Object run() {
+ return request.getParameterValues(name);
+ }
+ }
+
+
+ private final class GetCookiesPrivilegedAction
+ implements PrivilegedAction {
+
+ public Object run() {
+ return request.getCookies();
+ }
+ }
+
+
+ private final class GetCharacterEncodingPrivilegedAction
+ implements PrivilegedAction {
+
+ public Object run() {
+ return request.getCharacterEncoding();
+ }
+ }
+
+
+ private final class GetHeadersPrivilegedAction
+ implements PrivilegedAction {
+
+ private String name;
+
+ public GetHeadersPrivilegedAction(String name){
+ this.name = name;
+ }
+
+ public Object run() {
+ return request.getHeaders(name);
+ }
+ }
+
+
+ private final class GetHeaderNamesPrivilegedAction
+ implements PrivilegedAction {
+
+ public Object run() {
+ return request.getHeaderNames();
+ }
+ }
+
+
+ private final class GetLocalePrivilegedAction
+ implements PrivilegedAction {
+
+ public Object run() {
+ return request.getLocale();
+ }
+ }
+
+
+ private final class GetLocalesPrivilegedAction
+ implements PrivilegedAction {
+
+ public Object run() {
+ return request.getLocales();
+ }
+ }
+
+ private final class GetSessionPrivilegedAction
+ implements PrivilegedAction {
+
+ private boolean create;
+
+ public GetSessionPrivilegedAction(boolean create){
+ this.create = create;
+ }
+
+ public Object run() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ /**
+ * Construct a wrapper for the specified request.
+ *
+ * @param request The request to be wrapped
+ */
+ public HttpServletRequestImpl(GrizzlyRequest request) throws
IOException {
+ this.request = request;
+ this.inputStream = new
ServletInputStreamImpl(request.createInputStream());
+ }
+
+
+ // ----------------------------------------------- Class/Instance
Variables
+
+ /**
+ * The string manager for this package.
+ */
+ protected static final StringManager sm =
+ StringManager.getManager(Constants.Package);
+
+
+ /**
+ * The wrapped request.
+ */
+ protected GrizzlyRequest request = null;
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Prevent cloning the facade.
+ */
+ @Override
+ protected Object clone()
+ throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+
+ /**
+ * Clear facade.
+ */
+ public void clear() {
+ request = null;
+ }
+
+
+ // ------------------------------------------------- ServletRequest
Methods
+
+
+ public Object getAttribute(String name) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getAttribute(name);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Enumeration getAttributeNames() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (Enumeration)AccessController.doPrivileged(
+ new GetAttributePrivilegedAction());
+ } else {
+ return request.getAttributeNames();
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public String getCharacterEncoding() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (String)AccessController.doPrivileged(
+ new GetCharacterEncodingPrivilegedAction());
+ } else {
+ return request.getCharacterEncoding();
+ }
+ }
+
+
+ public void setCharacterEncoding(String env)
+ throws java.io.UnsupportedEncodingException {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ request.setCharacterEncoding(env);
+ }
+
+
+ public int getContentLength() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getContentLength();
+ }
+
+
+ public String getContentType() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getContentType();
+ }
+
+
+ public ServletInputStream getInputStream() throws IOException {
+
+ if (inputStream == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return inputStream;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public String getParameter(String name) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (String)AccessController.doPrivileged(
+ new GetParameterPrivilegedAction(name));
+ } else {
+ return request.getParameter(name);
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Enumeration getParameterNames() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (Enumeration)AccessController.doPrivileged(
+ new GetParameterNamesPrivilegedAction());
+ } else {
+ return request.getParameterNames();
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public String[] getParameterValues(String name) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ String[] ret = null;
+
+ /*
+ * Clone the returned array only if there is a security manager
+ * in place, so that performance won't suffer in the nonsecure case
+ */
+ if (System.getSecurityManager() != null){
+ ret = (String[]) AccessController.doPrivileged(
+ new GetParameterValuePrivilegedAction(name));
+ if (ret != null) {
+ ret = (String[]) ret.clone();
+ }
+ } else {
+ ret = request.getParameterValues(name);
+ }
+
+ return ret;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Map getParameterMap() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (Map)AccessController.doPrivileged(
+ new GetParameterMapPrivilegedAction());
+ } else {
+ return request.getParameterMap();
+ }
+ }
+
+
+ public String getProtocol() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getProtocol();
+ }
+
+
+ public String getScheme() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getScheme();
+ }
+
+
+ public String getServerName() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getServerName();
+ }
+
+
+ public int getServerPort() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getServerPort();
+ }
+
+
+ public BufferedReader getReader() throws IOException {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getReader();
+ }
+
+
+ public String getRemoteAddr() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getRemoteAddr();
+ }
+
+
+ public String getRemoteHost() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getRemoteHost();
+ }
+
+
+ public void setAttribute(String name, Object o) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ request.setAttribute(name, o);
+ }
+
+
+ public void removeAttribute(String name) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ request.removeAttribute(name);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Locale getLocale() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (Locale)AccessController.doPrivileged(
+ new GetLocalePrivilegedAction());
+ } else {
+ return request.getLocale();
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Enumeration getLocales() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (Enumeration)AccessController.doPrivileged(
+ new GetLocalesPrivilegedAction());
+ } else {
+ return request.getLocales();
+ }
+ }
+
+
+ public boolean isSecure() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.isSecure();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public RequestDispatcher getRequestDispatcher(String path) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ @SuppressWarnings("deprecation")
+ public String getRealPath(String path) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ public String getAuthType() {
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getAuthType();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Cookie[] getGrizzlyCookies() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ Cookie[] ret = null;
+
+ /*
+ * Clone the returned array only if there is a security manager
+ * in place, so that performance won't suffer in the nonsecure case
+ */
+ if (System.getSecurityManager() != null){
+ ret = (Cookie[])AccessController.doPrivileged(
+ new GetCookiesPrivilegedAction());
+ if (ret != null) {
+ ret = (Cookie[]) ret.clone();
+ }
+ } else {
+ ret = request.getCookies();
+ }
+
+ return ret;
+ }
+
+
+ public long getDateHeader(String name) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getDateHeader(name);
+ }
+
+
+ public String getHeader(String name) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getHeader(name);
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Enumeration getHeaders(String name) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (Enumeration)AccessController.doPrivileged(
+ new GetHeadersPrivilegedAction(name));
+ } else {
+ return request.getHeaders(name);
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Enumeration getHeaderNames() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ if (System.getSecurityManager() != null){
+ return (Enumeration)AccessController.doPrivileged(
+ new GetHeaderNamesPrivilegedAction());
+ } else {
+ return request.getHeaderNames();
+ }
+ }
+
+
+ public int getIntHeader(String name) {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getIntHeader(name);
+ }
+
+
+ public String getMethod() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getMethod();
+ }
+
+
+ public String getPathInfo() {
+ throw new IllegalStateException("Not yet implemented");
+
+ }
+
+
+ public String getPathTranslated() {
+ throw new IllegalStateException("Not yet implemented");
+
+ }
+
+
+ public String getContextPath() {
+ return "/";
+ }
+
+
+ public String getQueryString() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getQueryString();
+ }
+
+
+ public String getRemoteUser() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getRemoteUser();
+ }
+
+
+ public boolean isUserInRole(String role) {
+ throw new IllegalStateException("Not yet implemented");
+
+ }
+
+
+ public java.security.Principal getUserPrincipal() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getUserPrincipal();
+ }
+
+
+ public String getRequestedSessionId() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getRequestedSessionId();
+ }
+
+
+ public String getRequestURI() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getRequestURI();
+ }
+
+
+ public StringBuffer getRequestURL() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getRequestURL();
+ }
+
+
+ public String getServletPath() {
+ throw new IllegalStateException("Not yet implemented");
+
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public HttpSession getSession(boolean create) {
+ throw new IllegalStateException("Not yet implemented");
+
+ }
+
+ public HttpSession getSession() {
+
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return getSession(true);
+ }
+
+
+ public boolean isRequestedSessionIdValid() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ public boolean isRequestedSessionIdFromCookie() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ public boolean isRequestedSessionIdFromURL() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ @SuppressWarnings({"deprecation", "deprecation"})
+ public boolean isRequestedSessionIdFromUrl() {
+ return isRequestedSessionIdFromURL();
+ }
+
+ public javax.servlet.http.Cookie[] getCookies() {
+ Cookie[] internalCookies = request.getCookies();
+ javax.servlet.http.Cookie[] cookies
+ = new javax.servlet.http.Cookie[internalCookies.length];
+ for (int i = 0; i < internalCookies.length; i++){
+ cookies[i] =
((CookieWrapper)internalCookies[i]).getWrappedCookie();
+ }
+ return cookies;
+ }
+
+
+ public int getRemotePort() {
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getRemotePort();
+ }
+
+ public String getLocalName() {
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getLocalName();
+ }
+
+ public String getLocalAddr() {
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getLocalAddr();
+ }
+
+ public int getLocalPort() {
+ if (request == null) {
+ throw new IllegalStateException(
+ sm.getString("requestFacade.nullRequest"));
+ }
+
+ return request.getLocalPort();
+ }
+
+ public void recycle(){
+ request.recycle();
+ }
+
+}

Added:
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/HttpServletResponseImpl.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/HttpServletResponseImpl.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/HttpServletResponseImpl.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,573 @@
+
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
obtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+
+package com.sun.grizzly.http.servlet;
+
+import com.sun.grizzly.tcp.http11.Constants;
+import com.sun.grizzly.tcp.http11.GrizzlyResponse;
+import com.sun.grizzly.util.http.Globals;
+import com.sun.grizzly.util.res.StringManager;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecurityPermission;
+import java.util.Locale;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+
+
+/**
+ * Facade class that wraps a Coyote response object.
+ * All methods are delegated to the wrapped response.
+ *
+ * @author Remy Maucherat
+ * @author Jean-Francois Arcand
+ * @version $Revision: 1.9 $ $Date: 2007/05/05 05:32:43 $
+ */
+
+
+public class HttpServletResponseImpl implements HttpServletResponse {
+
+ private ServletOutputStream outputStream = null;
+
+ // -----------------------------------------------------------
DoPrivileged
+
+ private final class SetContentTypePrivilegedAction
+ implements PrivilegedAction {
+
+ private String contentType;
+
+ public SetContentTypePrivilegedAction(String contentType){
+ this.contentType = contentType;
+ }
+
+ public Object run() {
+ response.setContentType(contentType);
+ return null;
+ }
+ }
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ /**
+ * Construct a wrapper for the specified response.
+ *
+ * @param response The response to be wrapped
+ */
+ public HttpServletResponseImpl(GrizzlyResponse response) throws
IOException {
+ this.response = response;
+ this.outputStream = new
ServletOutputStreamImpl(response.createOutputStream());
+ }
+
+
+ // ----------------------------------------------- Class/Instance
Variables
+
+
+ /**
+ * The string manager for this package.
+ */
+ protected static final StringManager sm =
+ StringManager.getManager(Constants.Package);
+
+
+ /**
+ * The wrapped response.
+ */
+ protected GrizzlyResponse response = null;
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Prevent cloning the facade.
+ */
+ @Override
+ protected Object clone()
+ throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+
+ /**
+ * Clear facade.
+ */
+ public void clear() {
+ response = null;
+ }
+
+
+ public void finish() {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ response.setSuspended(true);
+
+ }
+
+
+ public boolean isFinished() {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ return response.isSuspended();
+
+ }
+
+
+ // ------------------------------------------------ ServletResponse
Methods
+
+
+ public String getCharacterEncoding() {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ return response.getCharacterEncoding();
+ }
+
+
+ public ServletOutputStream getOutputStream()
+ throws IOException {
+
+ // if (isFinished())
+ // throw new IllegalStateException
+ //
(/*sm.getString("HttpServletResponseImpl.finished")*/);
+
+ if (isFinished())
+ response.setSuspended(true);
+ return outputStream;
+
+ }
+
+
+ public PrintWriter getWriter()
+ throws IOException {
+
+ // if (isFinished())
+ // throw new IllegalStateException
+ //
(/*sm.getString("HttpServletResponseImpl.finished")*/);
+
+ PrintWriter writer = response.getWriter();
+ if (isFinished())
+ response.setSuspended(true);
+ return (writer);
+
+ }
+
+
+ public void setContentLength(int len) {
+
+ if (isCommitted())
+ return;
+
+ response.setContentLength(len);
+
+ }
+
+
+ public void setContentType(String type) {
+
+ if (isCommitted())
+ return;
+
+ if (System.getSecurityManager() != null){
+ AccessController.doPrivileged(new
SetContentTypePrivilegedAction(type));
+ } else {
+ response.setContentType(type);
+ }
+ }
+
+
+ public void setBufferSize(int size) {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (/*sm.getString("responseBase.reset.ise")*/);
+
+ response.setBufferSize(size);
+
+ }
+
+
+ public int getBufferSize() {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ return response.getBufferSize();
+ }
+
+
+ public void flushBuffer()
+ throws IOException {
+
+ if (isFinished())
+ // throw new IllegalStateException
+ //
(/*sm.getString("HttpServletResponseImpl.finished")*/);
+ return;
+
+ if (System.getSecurityManager() != null){
+ try{
+ AccessController.doPrivileged(new
PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ response.setAppCommitted(true);
+
+ response.flushBuffer();
+ return null;
+ }
+ });
+ } catch(PrivilegedActionException e){
+ Exception ex = e.getException();
+ if (ex instanceof IOException){
+ throw (IOException)ex;
+ }
+ }
+ } else {
+ response.setAppCommitted(true);
+
+ response.flushBuffer();
+ }
+
+ }
+
+
+ public void resetBuffer() {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (/*sm.getString("responseBase.reset.ise")*/);
+
+ response.resetBuffer();
+
+ }
+
+
+ public boolean isCommitted() {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ return (response.isAppCommitted());
+ }
+
+
+ public void reset() {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (/*sm.getString("responseBase.reset.ise")*/);
+
+ response.reset();
+
+ }
+
+
+ public void setLocale(Locale loc) {
+
+ if (isCommitted())
+ return;
+
+ response.setLocale(loc);
+ }
+
+
+ public Locale getLocale() {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ return response.getLocale();
+ }
+
+
+ public void addCookie(Cookie cookie) {
+
+ if (isCommitted())
+ return;
+ CookieWrapper wrapper = new
CookieWrapper(cookie.getName(),cookie.getValue());
+ wrapper.setWrappedCookie(cookie);
+ response.addCookie(wrapper);
+
+ }
+
+
+ public boolean containsHeader(String name) {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ return response.containsHeader(name);
+ }
+
+
+ public String encodeURL(String url) {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ public String encodeRedirectURL(String url) {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ public String encodeUrl(String url) {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ public String encodeRedirectUrl(String url) {
+
+ if (response == null) {
+ throw new IllegalStateException(
+
sm.getString("HttpServletResponseImpl.nullResponse"));
+ }
+
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ public void sendError(int sc, String msg)
+ throws IOException {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (/*sm.getString("responseBase.reset.ise")*/);
+
+ response.setAppCommitted(true);
+
+ response.sendError(sc, msg);
+
+ }
+
+
+ public void sendError(int sc)
+ throws IOException {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (/*sm.getString("responseBase.reset.ise")*/);
+
+ response.setAppCommitted(true);
+
+ response.sendError(sc);
+
+ }
+
+
+ public void sendRedirect(String location)
+ throws IOException {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (/*sm.getString("responseBase.reset.ise")*/);
+
+ response.setAppCommitted(true);
+
+ response.sendRedirect(location);
+
+ }
+
+
+ public void setDateHeader(String name, long date) {
+
+ if (isCommitted())
+ return;
+
+ response.setDateHeader(name, date);
+
+ }
+
+
+ public void addDateHeader(String name, long date) {
+
+ if (isCommitted())
+ return;
+
+ response.addDateHeader(name, date);
+
+ }
+
+
+ public void setHeader(String name, String value) {
+
+ if (isCommitted())
+ return;
+
+ response.setHeader(name, value);
+
+ }
+
+
+ public void addHeader(String name, String value) {
+
+ if (isCommitted())
+ return;
+
+ response.addHeader(name, value);
+
+ }
+
+
+ public void setIntHeader(String name, int value) {
+
+ if (isCommitted())
+ return;
+
+ response.setIntHeader(name, value);
+
+ }
+
+
+ public void addIntHeader(String name, int value) {
+
+ if (isCommitted())
+ return;
+
+ response.addIntHeader(name, value);
+
+ }
+
+
+ public void setStatus(int sc) {
+
+ if (isCommitted())
+ return;
+
+ response.setStatus(sc);
+
+ }
+
+
+ public void setStatus(int sc, String sm) {
+
+ if (isCommitted())
+ return;
+
+ response.setStatus(sc, sm);
+
+ }
+
+
+ // START SJSAS 6374990
+ public int getStatus() {
+ return response.getStatus();
+ }
+
+ public String getMessage() {
+ return response.getMessage();
+ }
+
+ public void setSuspended(boolean suspended) {
+ response.setSuspended(suspended);
+ }
+
+ public void setAppCommitted(boolean appCommitted) {
+ response.setAppCommitted(appCommitted);
+ }
+
+ public int getContentCount() {
+ return response.getContentCount();
+ }
+
+ public boolean isError() {
+ return response.isError();
+ }
+ // END SJSAS 6374990
+
+
+ public String getContentType() {
+ return response.getContentType();
+ }
+
+
+ public void setCharacterEncoding(String charEnc) {
+ response.setCharacterEncoding(charEnc);
+ }
+
+ public void recycle(){
+ response.recycle();
+ }
+}

Added:
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletAdapter.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletAdapter.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletAdapter.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,166 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
obtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):& 0
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.grizzly.http.servlet;
+
+import com.sun.grizzly.tcp.http11.GrizzlyAdapter;
+import com.sun.grizzly.tcp.Request;
+import com.sun.grizzly.tcp.Response;
+import com.sun.grizzly.tcp.http11.GrizzlyRequest;
+import com.sun.grizzly.tcp.http11.GrizzlyResponse;
+import java.util.HashMap;
+import java.util.logging.Level;
+import javax.servlet.Servlet;
+
+/**
+ * Adapter class that can initiate a Servlet and execute it.
+ *
+ * @author Jeanfrancois Arcand
+ */
+public class ServletAdapter extends GrizzlyAdapter {
+ public static final int REQUEST_RESPONSE_NOTES = 12;
+ public static final int SERVLETCONFIG_NOTES = 13;
+ private Servlet servletInstance = null;
+
+ /**
+ * The merged context initialization parameters for this Context.
+ */
+ private HashMap<String,String> parameters = new
HashMap<String,String>();
+
+
+ public ServletAdapter() {
+ super();
+ }
+
+
+ public ServletAdapter(String publicDirectory) {
+ super(publicDirectory);
+ }
+
+
+ @Override
+ public void service(GrizzlyRequest request, GrizzlyResponse response) {
+ try {
+ Request req = request.getRequest();
+ Response res = response.getResponse();
+
+ HttpServletRequestImpl httpRequest =
(HttpServletRequestImpl) req.getNote(REQUEST_RESPONSE_NOTES);
+ HttpServletResponseImpl httpResponse =
(HttpServletResponseImpl) res.getNote(REQUEST_RESPONSE_NOTES);
+ ServletConfigImpl servletConfig = (ServletConfigImpl)
req.getNote(SERVLETCONFIG_NOTES);
+
+ if (httpRequest == null) {
+ httpRequest = new HttpServletRequestImpl(request);
+ httpResponse = new HttpServletResponseImpl(response);
+ ServletContextImpl servletCtx = new ServletContextImpl();
+ servletCtx.setInitParameter(parameters);
+ servletConfig = new ServletConfigImpl(servletCtx);
+
+ req.setNote(REQUEST_RESPONSE_NOTES, httpRequest);
+ req.setNote(SERVLETCONFIG_NOTES, servletConfig);
+ res.setNote(REQUEST_RESPONSE_NOTES, httpResponse);
+ }
+
+ // TRy to load the instance using the System.getProperties();
+ if (servletInstance == null) {
+ String servletClassName =
System.getProperty("com.sun.grizzly.servletClass");
+ if (servletClassName != null) {
+ servletInstance =
loadServletInstance(servletClassName);
+ }
+
+ if (servletInstance == null) {
+ throw new RuntimeException("No Servlet defined");
+ }
+ }
+
+ httpResponse.addHeader("server", "grizzly/1.7");
+ servletInstance.init(servletConfig);
+ //System.out.println("Executing PHP script");
+ servletInstance.service(httpRequest, httpResponse);
+ //System.out.println("Execution completed");
+ } catch (Throwable ex) {
+ logger.log(Level.SEVERE, "service exception:", ex);
+ }
+ //System.out.println("Execution completed");
+ }
+
+
+ @Override
+ public void afterService(GrizzlyRequest request, GrizzlyResponse
response) throws Exception {
+ Request req = request.getRequest();
+ Response res = response.getResponse();
+ HttpServletRequestImpl httpRequest = (HttpServletRequestImpl)
req.getNote(REQUEST_RESPONSE_NOTES);
+ HttpServletResponseImpl httpResponse =
(HttpServletResponseImpl) req.getNote(REQUEST_RESPONSE_NOTES);
+
+ httpRequest.recycle();
+ httpResponse.recycle();
+ }
+
+
+ /**
+ * Add a new servlet initialization parameter for this servlet.
+ *
+ * @param name Name of this initialization parameter to add
+ * @param value Value of this initialization parameter to add
+ */
+ public void addInitParameter(String name, String value){
+ parameters.put(name, value);
+ }
+
+
+ private static Servlet loadServletInstance(String servletClass) {
+ Class className = null;
+ try {
+ className = Class.forName(servletClass, true,
Thread.currentThread().getContextClassLoader());
+ return (Servlet) className.newInstance();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ // Log me
+ }
+ return null;
+ }
+
+
+ public Servlet getServletInstance() {
+ return servletInstance;
+ }
+
+
+ public void setServletInstance(Servlet servletInstance) {
+ this.servletInstance = servletInstance;
+ }
+}

Added:
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletConfigImpl.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletConfigImpl.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletConfigImpl.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,141 @@
+
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
obtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+
+
+
+package com.sun.grizzly.http.servlet;
+
+import com.sun.grizzly.util.http.Enumerator;
+import java.util.Enumeration;
+import java.util.HashMap;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+/**
+ *
+ * @author Jeanfrancois Arcand
+ */
+public class ServletConfigImpl implements ServletConfig{
+
+ /**
+ * The initialization parameters for this servlet, keyed by
+ * parameter name.
+ */
+ private HashMap<String,String> parameters = new
HashMap<String,String>();
+
+
+ private String name;
+
+
+ private ServletContextImpl servletContextImpl;
+
+
+ public ServletConfigImpl(ServletContextImpl servletContextImpl){
+ this.servletContextImpl = servletContextImpl;
+ }
+
+
+ public String getServletName() {
+ return name;
+ }
+
+
+ public ServletContext getServletContext() {
+ return servletContextImpl;
+ }
+
+
+ public String getInitParameter(String name) {
+ return findInitParameter(name);
+ }
+
+
+ /**
+ * Set the name of this servlet.
+ *
+ * @param name The new name of this servlet
+ */
+ protected void setServletName(String name) {
+ this.name = name;
+ }
+
+
+ /**
+ * Add a new servlet initialization parameter for this servlet.
+ *
+ * @param name Name of this initialization parameter to add
+ * @param value Value of this initialization parameter to add
+ */
+ public void addInitParameter(String name, String value) {
+
+ synchronized (parameters) {
+ parameters.put(name, value);
+ }
+
+ //TODO: Not yet supported
+ /* if (notifyContainerListeners) {
+ fireContainerEvent("addInitParameter", name);
+ }*/
+ }
+
+ /**
+ * Return the value for the specified initialization parameter name,
+ * if any; otherwise return <code>null</code>.
+ *
+ * @param name Name of the requested initialization parameter
+ */
+ protected String findInitParameter(String name) {
+ synchronized (parameters) {
+ return parameters.get(name);
+ }
+ }
+
+
+ /**
+ * Return the set of initialization parameter names defined for this
+ * servlet. If none are defined, an empty Enumeration is returned.
+ */
+ public Enumeration getInitParameterNames() {
+ synchronized (parameters) {
+ return (new Enumerator(parameters.keySet()));
+ }
+ }
+}

Added:
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletContextImpl.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletContextImpl.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletContextImpl.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,458 @@
+
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
obtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+
+
+
+package com.sun.grizzly.http.servlet;
+
+import com.sun.grizzly.util.http.Enumerator;
+import com.sun.grizzly.util.http.MimeType;
+import java.io.File;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+
+/**
+ *
+ * @author Jeanfrancois Arcand
+ */
+public class ServletContextImpl implements ServletContext {
+ /**
+ * Empty collection to serve as the basis for empty enumerations.
+ * <strong>DO NOT ADD ANY ELEMENTS TO THIS COLLECTION!</strong>
+ */
+ private static final ArrayList empty = new ArrayList();
+
+
+ /**
+ * The merged context initialization parameters for this Context.
+ */
+ private HashMap<String,String> parameters;
+
+
+ /**
+ * The context attributes for this context.
+ */
+ private HashMap attributes = new HashMap();
+
+
+ /**
+ * Base path.
+ */
+ private String basePath = "/";
+
+
+ private Logger logger = Logger.getLogger("Grizzly");
+
+
+ /**
+ * Returns the context path of the web application.
+ *
+ * <p>The context path is the portion of the request URI that is used
+ * to select the context of the request. The context path always comes
+ * first in a request URI. The path starts with a "/" character but
does
+ * not end with a "/" character. For servlets in the default (root)
+ * context, this method returns "".
+ *
+ * <p>It is possible that a servlet container may match a context by
+ * more than one context path. In such cases the
+ * {_at_link javax.servlet.http.HttpServletRequest#getContextPath()}
+ * will return the actual context path used by the request and it may
+ * differ from the path returned by this method.
+ * The context path returned by this method should be considered as the
+ * prime or preferred context path of the application.
+ *
+ * @see javax.servlet.http.HttpServletRequest#getContextPath()
+ */
+ public String getContextPath() {
+ return basePath;
+ }
+
+
+ /**
+ * Return a <code>ServletContext</code> object that corresponds to a
+ * specified URI on the server. This method allows servlets to gain
+ * access to the context for various parts of the server, and as needed
+ * obtain <code>RequestDispatcher</code> objects or resources from the
+ * context. The given path must be absolute (beginning with a "/"),
+ * and is interpreted based on our virtual host's document root.
+ *
+ * @param uri Absolute URI of a resource on the server
+ * TODO: Not yet supported
+ */
+ public ServletContext getContext(String uri) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ /**
+ * Return the major version of the Java Servlet API that we implement.
+ */
+ public int getMajorVersion() {
+
+ return 2;
+
+ }
+
+
+ /**
+ * Return the minor version of the Java Servlet API that we implement.
+ */
+ public int getMinorVersion() {
+ return 6;
+ }
+
+
+ /**
+ * Return the MIME type of the specified file, or <code>null</code> if
+ * the MIME type cannot be determined.
+ *
+ * @param file Filename for which to identify a MIME type
+ */
+ public String getMimeType(String file) {
+
+ if (file == null)
+ return (null);
+ int period = file.lastIndexOf(".");
+ if (period < 0)
+ return (null);
+ String extension = file.substring(period + 1);
+ if (extension.length() < 1)
+ return (null);
+ return MimeType.get(extension);
+ }
+
+
+ /**
+ * Return a Set containing the resource paths of resources member
of the
+ * specified collection. Each path will be a String starting with
+ * a "/" character. The returned set is immutable.
+ *
+ * @param path Collection path
+ * TODO: Not yet supported
+ */
+ public Set getResourcePaths(String path) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ /**
+ * Return the URL to the resource that is mapped to a specified path.
+ * The path must begin with a "/" and is interpreted as relative to the
+ * current context root.
+ *
+ * @param path The path to the desired resource
+ *
+ * @exception MalformedURLException if the path is not given
+ * in the correct form
+ */
+ public URL getResource(String path) throws MalformedURLException {
+
+ if (path == null || !path.startsWith("/")) {
+ throw new MalformedURLException(path);
+ }
+
+ path = normalize(path);
+ if (path == null)
+ return (null);
+
+ return Thread.currentThread().getContextClassLoader()
+ .getResource(path);
+ }
+
+
+ /**
+ * Return the requested resource as an <code>InputStream</code>. The
+ * path must be specified according to the rules described under
+ * <code>getResource</code>. If no such resource can be identified,
+ * return <code>null</code>.
+ *
+ * @param path The path to the desired resource.
+ */
+ public InputStream getResourceAsStream(String path) {
+
+ path = normalize(path);
+ if (path == null)
+ return (null);
+
+ return Thread.currentThread().getContextClassLoader()
+ .getResourceAsStream(path);
+ }
+
+
+ //TODO.
+ public RequestDispatcher getRequestDispatcher(String arg0) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ //TODO.
+ public RequestDispatcher getNamedDispatcher(String arg0) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ /**
+ * @deprecated As of Java Servlet API 2.1, with no direct replacement.
+ */
+ public Servlet getServlet(String name) {
+
+ return (null);
+
+ }
+
+
+ /**
+ * @deprecated As of Java Servlet API 2.1, with no direct replacement.
+ */
+ public Enumeration getServlets() {
+ return (new Enumerator(empty));
+ }
+
+
+ /**
+ * @deprecated As of Java Servlet API 2.1, with no direct replacement.
+ */
+ public Enumeration getServletNames() {
+ return (new Enumerator(empty));
+ }
+
+
+ public void log(String arg0) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+
+ @SuppressWarnings("deprecation")
+ public void log(Exception e, String msg) {
+ logger.log(Level.INFO,msg,e);
+ }
+
+
+ public void log(String msg, Throwable t) {
+ logger.log(Level.INFO,msg,t);
+ }
+
+
+ /**
+ * Return the real path for a given virtual path, if possible;
otherwise
+ * return <code>null</code>.
+ *
+ * @param path The path to the desired resource
+ */
+ public String getRealPath(String path) {
+
+ if (path == null) {
+ return null;
+ }
+
+ File file = new File(basePath, path);
+ return (file.getAbsolutePath());
+
+ }
+
+
+ //TODO: Make it configurable via System.getProperty();
+ public String getServerInfo() {
+ return "Grizzly";
+ }
+
+
+ /**
+ * Return the value of the specified initialization parameter, or
+ * <code>null</code> if this parameter does not exist.
+ *
+ * @param name Name of the initialization parameter to retrieve
+ */
+ public String getInitParameter(final String name) {
+ synchronized (parameters) {
+ return parameters.get(name);
+ }
+ }
+
+
+ /**
+ * Return the names of the context's initialization parameters, or an
+ * empty enumeration if the context has no initialization parameters.
+ */
+ public Enumeration getInitParameterNames() {
+ synchronized (parameters) {
+ return (new Enumerator(parameters.keySet()));
+ }
+
+ }
+
+
+ protected void setInitParameter(HashMap<String,String> parameters){
+ this.parameters = parameters;
+ }
+
+
+ /**
+ * Return the value of the specified context attribute, if any;
+ * otherwise return <code>null</code>.
+ *
+ * @param name Name of the context attribute to return
+ */
+ public Object getAttribute(String name) {
+ synchronized (attributes) {
+ return (attributes.get(name));
+ }
+ }
+
+
+ /**
+ * Return an enumeration of the names of the context attributes
+ * associated with this context.
+ */
+ public Enumeration getAttributeNames() {
+ synchronized (attributes) {
+ return new Enumerator(attributes.keySet(), true);
+ }
+ }
+
+
+ /**
+ * Bind the specified value with the specified context attribute name,
+ * replacing any existing value for that name.
+ *
+ * @param name Attribute name to be bound
+ * @param value New attribute value to be bound
+ */
+ @SuppressWarnings("unchecked")
+ public void setAttribute(String name, Object value) {
+
+ // Name cannot be null
+ if (name == null)
+ throw new IllegalArgumentException
+ ("Cannot be null");
+
+ // Null value is the same as removeAttribute()
+ if (value == null) {
+ removeAttribute(name);
+ return;
+ }
+
+ Object oldValue = null;
+ boolean replaced = false;
+
+ // Add or replace the specified attribute
+ synchronized (attributes) {
+ oldValue = attributes.get(name);
+ if (oldValue != null)
+ replaced = true;
+ attributes.put(name, value);
+ }
+ }
+
+
+ /**
+ * Remove the context attribute with the specified name, if any.
+ *
+ * @param name Name of the context attribute to be removed
+ */
+ public void removeAttribute(String name) {
+ Object value = null;
+ boolean found = false;
+
+ // Remove the specified attribute
+ synchronized (attributes) {
+ found = attributes.containsKey(name);
+ if (found) {
+ value = attributes.get(name);
+ attributes.remove(name);
+ } else {
+ return;
+ }
+ }
+ }
+
+ public String getServletContextName() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ /**
+ * Return a context-relative path, beginning with a "/", that
represents
+ * the canonical version of the specified path after ".." and "."
elements
+ * are resolved out. If the specified path attempts to go outside the
+ * boundaries of the current context (i.e. too many ".." path elements
+ * are present), return <code>null</code> instead.
+ *
+ * @param path Path to be normalized
+ */
+ private String normalize(String path) {
+
+ if (path == null) {
+ return null;
+ }
+
+ String normalized = path;
+
+ // Normalize the slashes and add leading slash if necessary
+ if (normalized.indexOf('\\') >= 0)
+ normalized = normalized.replace('\\', '/');
+
+ // Resolve occurrences of "/../" in the normalized path
+ while (true) {
+ int index = normalized.indexOf("/../");
+ if (index < 0)
+ break;
+ if (index == 0)
+ return (null); // Trying to go outside our context
+ int index2 = normalized.lastIndexOf('/', index - 1);
+ normalized = normalized.substring(0, index2) +
+ normalized.substring(index + 3);
+ }
+
+ // Return the normalized path that we have completed
+ return (normalized);
+
+ }
+}

Added:
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletInputStreamImpl.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletInputStreamImpl.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletInputStreamImpl.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,90 @@
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
obtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.grizzly.http.servlet;
+
+import com.sun.grizzly.tcp.http11.GrizzlyInputStream;
+import java.io.IOException;
+import javax.servlet.ServletInputStream;
+
+/**
+ *
+ * @author Jeanfrancois Arcand
+ */
+public class ServletInputStreamImpl extends ServletInputStream{
+
+ private GrizzlyInputStream inputStream;
+
+ protected ServletInputStreamImpl(GrizzlyInputStream inputStream){
+ this.inputStream = inputStream;
+ }
+
+ public int read() throws IOException {
+ return inputStream.read();
+ }
+
+ @Override
+ public int available() throws IOException {
+ return inputStream.available();
+ }
+
+ @Override
+ public int read(final byte[] b) throws IOException {
+ return inputStream.read(b, 0, b.length);
+ }
+
+
+ @Override
+ public int read(final byte[] b, final int off, final int len)
+ throws IOException {
+ return inputStream.read(b, off, len);
+ }
+
+
+ /**
+ * Close the stream
+ * Since we re-cycle, we can't allow the call to super.close()
+ * which would permantely disable us.
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public void close() throws IOException {
+ inputStream.close();
+ }
+}
\ No newline at end of file

Added:
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletOutputStreamImpl.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletOutputStreamImpl.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-servlet/src/main/java/com/sun/grizzly/http/servlet/ServletOutputStreamImpl.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,88 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
outputStreamtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.grizzly.http.servlet;
+
+import com.sun.grizzly.tcp.http11.GrizzlyOutputStream;
+import java.io.IOException;
+import javax.servlet.ServletOutputStream;
+
+/**
+ *
+ * @author Jeanfrancois Arcand
+ */
+public class ServletOutputStreamImpl extends ServletOutputStream {
+
+ private GrizzlyOutputStream outputStream;
+
+ protected ServletOutputStreamImpl(GrizzlyOutputStream outputStream) {
+ this.outputStream = outputStream;
+ }
+
+ public void write(int i) throws IOException {
+ outputStream.write(i);
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ outputStream.write(b, off, len);
+ }
+
+ /**
+ * Will send the buffer to the client.
+ */
+ @Override
+ public void flush() throws IOException {
+ outputStream.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ outputStream.close();
+ }
+ // -------------------------------------------- ServletOutputStream
Methods
+
+ public void print(String s) throws IOException {
+ outputStream.print(s);
+ }
+}
\ No newline at end of file

Copied:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/DynamicContentAdapter.java
(from r713,
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java)
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/DynamicContentAdapter.java?view=diff&rev=742&p1=/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java&p2=trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/DynamicContentAdapter.java&r1=713&r2=742
==============================================================================
---
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java
(original)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/DynamicContentAdapter.java
2008-01-29 18:48:15+0000
@@ -21,10 +21,9 @@
   * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
   */

-package com.sun.grizzly.standalone;
+package com.sun.grizzly.tcp;
+

-import com.sun.grizzly.tcp.Request;
-import com.sun.grizzly.tcp.Response;
  import com.sun.grizzly.util.buf.MessageBytes;
  import com.sun.grizzly.util.buf.ByteChunk;

@@ -37,8 +36,6 @@
  import java.text.SimpleDateFormat;
  import java.text.ParseException;

-import com.sun.grizzly.http.SelectorThread;
-
  /**
   * Abstract Adapter that contains all the common behaviour of the
Adapter implmentation
   * for standalone usage as well as embedded use.
@@ -56,6 +53,10 @@
      protected String contextRoot = null;


+ public DynamicContentAdapter() {
+ super();
+ }
+
      public DynamicContentAdapter(String publicDirectory) {
          super(publicDirectory);
      }
@@ -67,13 +68,15 @@
      abstract protected void serviceDynamicContent(Request req,
Response res) throws IOException;


+ @Override
      public void afterService(Request req, Response res) throws Exception {
- ; // Let the GrizzlyAdapter handle the life cycle of the
request/response.
+ ; // Let the Adapter handle the life cycle of the request/response.
      }


+ @Override
      public void fireAdapterEvent(String type, Object data) {
- ; // Let the GrizzlyAdapter handle the life cycle of the
request/response.
+ ; // Let the Adapter handle the life cycle of the request/response.
      }


@@ -118,15 +121,14 @@
                  serviceDynamicContent(req, res);
              }
          } catch (Exception e) {
- if (SelectorThread.logger().isLoggable(Level.SEVERE)) {
- SelectorThread.logger().log(Level.SEVERE, e.getMessage());
+ if (logger.isLoggable(Level.SEVERE)) {
+ logger.log(Level.SEVERE, e.getMessage());
              }

              throw e;
          }
      }
-
-
+
      /**
       * Simple InputStream that wrap the Grizzly internal object.
       */
@@ -180,7 +182,6 @@

      }

-
      public void setContextRoot(String contextRoot) {
          this.contextRoot = contextRoot;
      }

Copied:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/StaticResourcesAdapter.java
(from r713,
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java)
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/StaticResourcesAdapter.java?view=diff&rev=742&p1=/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java&p2=trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/StaticResourcesAdapter.java&r1=713&r2=742
==============================================================================
---
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java
(original)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/StaticResourcesAdapter.java
2008-01-29 18:48:15+0000
@@ -24,31 +24,18 @@
   * Portions Copyright Apache Software Foundation.
   */

-package com.sun.grizzly.standalone;
+package com.sun.grizzly.tcp;

-import com.sun.grizzly.http.Constants;
-import com.sun.grizzly.http.FileCache;
-import com.sun.grizzly.http.FileCacheFactory;
-import com.sun.grizzly.http.SelectorThread;
-import com.sun.grizzly.http.SocketChannelOutputBuffer;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SocketChannel;
-import java.util.Properties;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.logging.Level;
-import com.sun.grizzly.tcp.ActionCode;

-import com.sun.grizzly.tcp.Adapter;
-import com.sun.grizzly.tcp.Request;
-import com.sun.grizzly.tcp.Response;
-import com.sun.grizzly.tcp.http11.InternalOutputBuffer;
-import com.sun.grizzly.util.buf.Ascii;
  import com.sun.grizzly.util.buf.ByteChunk;
  import com.sun.grizzly.util.buf.MessageBytes;
-import com.sun.grizzly.util.http.MimeHeaders;
+import com.sun.grizzly.util.http.MimeType;
+import java.util.logging.Logger;

  /**
   * Simple HTTP based Web Server. Part of this class is from Tomcat
sandbox code
@@ -60,28 +47,20 @@

      private String rootFolder = ".";

- private File rootFolderF;
+ private File rootFolderF = null;

      private ConcurrentHashMap<String,File> cache
              = new ConcurrentHashMap<String,File>();
+
+ protected Logger logger = Logger.getLogger("Grizzly");


      public StaticResourcesAdapter() {
- this(SelectorThread.getWebAppRootPath());
+ this(".");
      }

      public StaticResourcesAdapter(String rootFolder) {
-
-
          this.rootFolder = rootFolder;
- rootFolderF = new File(rootFolder);
- try {
- rootFolder = rootFolderF.getCanonicalPath();
- SelectorThread.logger().log(Level.INFO, "New Servicing page
from: "
- + rootFolder);
-
- } catch (IOException e) {
- }
      }


@@ -91,7 +70,7 @@
          String uri = req.requestURI().toString();
          if (uri.indexOf("..") >= 0) {
              res.setStatus(404);
- return;
+ return;
          }
          service(uri, req, res);
      }
@@ -99,6 +78,16 @@

      protected void service(String uri, Request req, final Response res)
          throws Exception {
+ if (rootFolderF == null){
+ rootFolderF = new File(rootFolder);
+ try {
+ rootFolder = rootFolderF.getCanonicalPath();
+ logger.log(Level.INFO, "New Servicing Static Pages from: "
+ + rootFolderF.getAbsolutePath());
+
+ } catch (IOException e) {
+ }
+ }

          // local file
          File resource = cache.get(uri);
@@ -113,7 +102,7 @@
          }

          if (!resource.exists()) {
- SelectorThread.logger().log(Level.INFO,"File not found " +
resource);
+ logger.log(Level.INFO,"File not found " + resource);
              res.setStatus(404);
              return;
          }

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/ClientAbortException.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/ClientAbortException.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/ClientAbortException.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed 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 com.sun.grizzly.tcp.http11;
+
+import java.io.IOException;
+
+/**
+ * Wrap an IOException identifying it as being caused by an abort
+ * of a request by a remote client.
+ *
+ * @author Glenn L. Nielsen
+ * @version $Revision: 1.1 $ $Date: 2006/09/21 22:02:28 $
+ */
+
+public final class ClientAbortException extends IOException {
+
+
+ //------------------------------------------------------------
Constructors
+
+
+ /**
+ * Construct a new ClientAbortException with no other information.
+ */
+ public ClientAbortException() {
+
+ this(null, null);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified message.
+ *
+ * @param message Message describing this exception
+ */
+ public ClientAbortException(String message) {
+
+ this(message, null);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified throwable.
+ *
+ * @param throwable Throwable that caused this exception
+ */
+ public ClientAbortException(Throwable throwable) {
+
+ this(null, throwable);
+
+ }
+
+
+ /**
+ * Construct a new ClientAbortException for the specified message
+ * and throwable.
+ *
+ * @param message Message describing this exception
+ * @param throwable Throwable that caused this exception
+ */
+ public ClientAbortException(String message, Throwable throwable) {
+
+ super();
+ this.message = message;
+ this.throwable = throwable;
+
+ }
+
+
+ //------------------------------------------------------ Instance
Variables
+
+
+ /**
+ * The error message passed to our constructor (if any)
+ */
+ protected String message = null;
+
+
+ /**
+ * The underlying exception or error passed to our constructor (if any)
+ */
+ protected Throwable throwable = null;
+
+
+ //---------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Returns the message associated with this exception, if any.
+ */
+ public String getMessage() {
+
+ return (message);
+
+ }
+
+
+ /**
+ * Returns the cause that caused this exception, if any.
+ */
+ public Throwable getCause() {
+
+ return (throwable);
+
+ }
+
+
+ /**
+ * Return a formatted string that describes this exception.
+ */
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer("ClientAbortException: ");
+ if (message != null) {
+ sb.append(message);
+ if (throwable != null) {
+ sb.append(": ");
+ }
+ }
+ if (throwable != null) {
+ sb.append(throwable.toString());
+ }
+ return (sb.toString());
+
+ }
+
+
+}

Modified:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/Constants.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/Constants.java?view=diff&rev=742&p1=/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/http11/Constants.java&p2=trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/Constants.java&r1=741&r2=742
==============================================================================
---
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/http11/Constants.java
(original)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/Constants.java
2008-01-29 18:48:15+0000
@@ -268,5 +268,51 @@
          (byte) '\n'
      };

+ public static final int PROCESSOR_IDLE = 0;
+ public static final int PROCESSOR_ACTIVE = 1;

+ /**
+ * Default header names.
+ */
+ public static final String AUTHORIZATION_HEADER = "authorization";
+
+ /**
+ * SSL Certificate Request Attributite.
+ */
+ public static final String SSL_CERTIFICATE_ATTR =
"org.apache.coyote.request.X509Certificate";
+
+ /**
+ * Security flag.
+ */
+ public static final boolean SECURITY =
+ (System.getSecurityManager() != null);
+
+
+ // S1AS 4703023
+ public static final int DEFAULT_MAX_DISPATCH_DEPTH = 20;
+
+
+ // START SJSAS 6328909
+ /**
+ * The default response-type
+ */
+ public final static String DEFAULT_RESPONSE_TYPE =
+ "text/html; charset=iso-8859-1";
+
+
+ /**
+ * The forced response-type
+ */
+ public final static String FORCED_RESPONSE_TYPE =
+ "text/html; charset=iso-8859-1";
+ // END SJSAS 6328909
+
+
+ // START SJSAS 6337561
+ public final static String PROXY_JROUTE = "proxy-jroute";
+ // END SJSAS 6337561
+
+ // START SJSAS 6346226
+ public final static String JROUTE_COOKIE = "JROUTE";
+ // END SJSAS 6346226
  }

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyAdapter.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyAdapter.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyAdapter.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,483 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
obtain
+ * a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the
specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice
in each
+ * file and include the License file at
glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath"
exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):& 0
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL
or GPL
+ * Version 2] license." If you don't indicate a single choice of
license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option
applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.grizzly.tcp.http11;
+
+import com.sun.grizzly.tcp.*;
+import com.sun.grizzly.tcp.http11.GrizzlyRequest;
+import com.sun.grizzly.tcp.http11.GrizzlyResponse;
+import com.sun.grizzly.util.buf.B2CConverter;
+import com.sun.grizzly.util.buf.ByteChunk;
+import com.sun.grizzly.util.buf.CharChunk;
+import com.sun.grizzly.util.buf.MessageBytes;
+import java.io.IOException;
+import java.util.logging.Level;
+
+/**
+ * Base class to use when GrizzlyRequest/Response/InputStream/OutputStream
+ * are needed to implement a customized HTTP container/extendion to the
+ * http module.
+ *
+ * @author Jeanfrancois Arcand
+ */
+abstract public class GrizzlyAdapter extends StaticResourcesAdapter {
+
+ public static final int ADAPTER_NOTES = 1;
+ protected static final boolean ALLOW_BACKSLASH = false;
+ private static final boolean COLLAPSE_ADJACENT_SLASHES = true;
+
+ public GrizzlyAdapter() {
+ super();
+ }
+
+ public GrizzlyAdapter(String publicDirectory) {
+ super(publicDirectory);
+ }
+
+ @Override
+ public void service(Request req, Response res) {
+ GrizzlyRequest request = (GrizzlyRequest)
req.getNote(ADAPTER_NOTES);
+ GrizzlyResponse response = (GrizzlyResponse)
res.getNote(ADAPTER_NOTES);
+
+ if (request == null) {
+ // Create objects
+ request = new GrizzlyRequest();
+ request.setRequest(req);
+ response = new GrizzlyResponse();
+ response.setResponse(res);
+
+ // Link objects
+ request.setResponse(response);
+ response.setRequest(request);
+
+ // Set as notes
+ req.setNote(ADAPTER_NOTES, request);
+ res.setNote(ADAPTER_NOTES, response);
+ }
+
+ try {
+ // URI decoding
+ MessageBytes decodedURI = req.decodedURI();
+ decodedURI.duplicate(req.requestURI());
+ try {
+ req.getURLDecoder().convert(decodedURI, false);
+ } catch (IOException ioe) {
+ res.setStatus(400);
+ res.setMessage("Invalid URI: " + ioe.getMessage());
+ return;
+ }
+
+ convertURI(decodedURI, request);
+
+ // Normalize decoded URI
+ if (!normalize(decodedURI)) {
+ res.setStatus(400);
+ res.setMessage("Invalid URI");
+ return;
+ }
+ service(request,response);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ res.setStatus(500);
+ res.setMessage("Internal Error");
+ return;
+ }
+ }
+
+
+ /**
+ * This method should contains the logic for any http extension to the
+ * Grizzly HTTP Webserver.
+ */
+ abstract public void service(GrizzlyRequest request,GrizzlyResponse
response);
+
+
+ /**
+ * This method should contains the logic for any http extension to the
+ * Grizzly HTTP Webserver.
+ */
+ abstract public void afterService(GrizzlyRequest request,
+ GrizzlyResponse response) throws Exception;
+
+
+ @Override
+ public void afterService(Request req, Response res) throws Exception {
+ GrizzlyRequest request = (GrizzlyRequest)
req.getNote(ADAPTER_NOTES);
+ GrizzlyResponse response = (GrizzlyResponse)
res.getNote(ADAPTER_NOTES);
+
+ if (request == null || response == null) {
+ return;
+ }
+ try {
+ response.finishResponse();
+ req.action(ActionCode.ACTION_POST_REQUEST, null);
+ } catch (Throwable t) {
+ logger.log(Level.SEVERE,"afterService exception",t);
+ } finally {
+ // Recycle the wrapper request and response
+ request.recycle();
+ response.recycle();
+ req.recycle();
+ res.recycle();
+ }
+ afterService(request,response);
+ }
+
+
+ protected void convertURI(MessageBytes uri, GrizzlyRequest request)
throws Exception {
+ ByteChunk bc = uri.getByteChunk();
+ CharChunk cc = uri.getCharChunk();
+ cc.allocate(bc.getLength(), -1);
+
+ B2CConverter conv = request.getURIConverter();
+ try {
+ if (conv == null) {
+ conv = new B2CConverter("utf-8");
+ request.setURIConverter(conv);
+ } else {
+ conv.recycle();
+ }
+ } catch (IOException e) {
+ // Ignore
+ }
+ if (conv != null) {
+ try {
+ conv.convert(bc, cc);
+ uri.setChars(cc.getBuffer(), cc.getStart(),
cc.getLength());
+ return;
+ } catch (IOException e) {
+ cc.recycle();
+ }
+ }
+
+ // Default encoding: fast conversion
+ byte[] bbuf = bc.getBuffer();
+ char[] cbuf = cc.getBuffer();
+ int start = bc.getStart();
+ for (int i = 0; i < bc.getLength(); i++) {
+ cbuf[i] = (char) (bbuf[i + start] & 0xff);
+ }
+ uri.setChars(cbuf, 0, bc.getLength());
+ }
+
+
+ /**
+ * Normalize URI.
+ * <p>
+ * This method normalizes "\", "//", "/./" and "/../". This method will
+ * return false when trying to go above the root, or if the URI
contains
+ * a null byte.
+ *
+ * @param uriMB URI to be normalized
+ */
+ public static boolean normalize(MessageBytes uriMB) {
+
+ int type = uriMB.getType();
+ if (type == MessageBytes.T_CHARS) {
+ return normalizeChars(uriMB);
+ } else {
+ return normalizeBytes(uriMB);
+ }
+ }
+
+
+ private static boolean normalizeBytes(MessageBytes uriMB) {
+ ByteChunk uriBC = uriMB.getByteChunk();
+ byte[] b = uriBC.getBytes();
+ int start = uriBC.getStart();
+ int end = uriBC.getEnd();
+
+ // URL * is acceptable
+ if ((end - start == 1) && b[start] == (byte) '*') {
+ return true;
+ }
+ int pos = 0;
+ int index = 0;
+
+ // Replace '\' with '/'
+ // Check for null byte
+ for (pos = start; pos < end; pos++) {
+ if (b[pos] == (byte) '\\') {
+ if (ALLOW_BACKSLASH) {
+ b[pos] = (byte) '/';
+ } else {
+ return false;
+ }
+ }
+ if (b[pos] == (byte) 0) {
+ return false;
+ }
+ }
+
+ // The URL must start with '/'
+ if (b[start] != (byte) '/') {
+ return false;
+ }
+
+ // Replace "//" with "/"
+ if (COLLAPSE_ADJACENT_SLASHES) {
+ for (pos = start; pos < (end - 1); pos++) {
+ if (b[pos] == (byte) '/') {
+ while ((pos + 1 < end) && (b[pos + 1] == (byte) '/')) {
+ copyBytes(b, pos, pos + 1, end - pos - 1);
+ end--;
+ }
+ }
+ }
+ }
+
+ // If the URI ends with "/." or "/..", then we append an extra "/"
+ // Note: It is possible to extend requestthe URI by 1 without
any side effect
+ // as the next character is a non-significant WS.
+ if (((end - start) > 2) && (b[end - 1] == (byte) '.')) {
+ if ((b[end - 2] == (byte) '/') || ((b[end - 2] == (byte)
'.') && (b[end - 3] == (byte) '/'))) {
+ b[end] = (byte) '/';
+ end++;
+ }
+ }
+
+ uriBC.setEnd(end);
+
+ index = 0;
+
+ // Resolve occurrences of "/./" in the normalized path
+ while (true) {
+ index = uriBC.indexOf("/./", 0, 3, index);
+ if (index < 0) {
+ break;
+ }
+ copyBytes(b, start + index, start + index + 2, end - start
- index - 2);
+ end = end - 2;
+ uriBC.setEnd(end);
+ }
+
+ index = 0;
+
+ // Resolve occurrences of "/../" in the normalized path
+ while (true) {
+ index = uriBC.indexOf("/../", 0, 4, index);
+ if (index < 0) {
+ break;
+ }
+ // Prevent from going outside our context
+ if (index == 0) {
+ return false;
+ }
+ int index2 = -1;
+ for (pos = start + index - 1; (pos >= 0) && (index2 < 0);
pos--) {
+ if (b[pos] == (byte) '/') {
+ index2 = pos;
+ }
+ }
+ copyBytes(b, start + index2, start + index + 3, end - start
- index - 3);
+ end = end + index2 - index - 3;
+ uriBC.setEnd(end);
+ index = index2;
+ }
+
+ uriBC.setBytes(b, start, end);
+
+ return true;
+ }
+
+
+ private static boolean normalizeChars(MessageBytes uriMB) {
+ CharChunk uriCC = uriMB.getCharChunk();
+ char[] c = uriCC.getChars();
+ int start = uriCC.getStart();
+ int end = uriCC.getEnd();
+
+ // URL * is acceptable
+ if ((end - start == 1) && c[start] == (char) '*') {
+ return true;
+ }
+ int pos = 0;
+ int index = 0;
+
+ // Replace '\' with '/'
+ // Check for null char
+ for (pos = start; pos < end; pos++) {
+ if (c[pos] == (char) '\\') {
+ if (ALLOW_BACKSLASH) {
+ c[pos] = (char) '/';
+ } else {
+ return false;
+ }
+ }
+ if (c[pos] == (char) 0) {
+ return false;
+ }
+ }
+
+ // The URL must start with '/'
+ if (c[start] != (char) '/') {
+ return false;
+ }
+
+ // Replace "//" with "/"
+ if (COLLAPSE_ADJACENT_SLASHES) {
+ for (pos = start; pos < (end - 1); pos++) {
+ if (c[pos] == (char) '/') {
+ while ((pos + 1 < end) && (c[pos + 1] == (char) '/')) {
+ copyChars(c, pos, pos + 1, end - pos - 1);
+ end--;
+ }
+ }
+ }
+ }
+
+ // If the URI ends with "/." or "/..", then we append an extra "/"
+ // Note: It is possible to extend the URI by 1 without any side
effect
+ // as the next character is a non-significant WS.
+ if (((end - start) > 2) && (c[end - 1] == (char) '.')) {
+ if ((c[end - 2] == (char) '/') || ((c[end - 2] == (char)
'.') && (c[end - 3] == (char) '/'))) {
+ c[end] = (char) '/';
+ end++;
+ }
+ }
+
+ uriCC.setEnd(end);
+
+ index = 0;
+
+ // Resolve occurrences of "/./" in the normalized path
+ while (true) {
+ index = uriCC.indexOf("/./", 0, 3, index);
+ if (index < 0) {
+ break;
+ }
+ copyChars(c, start + index, start + index + 2, end - start
- index - 2);
+ end = end - 2;
+ uriCC.setEnd(end);
+ }
+
+ index = 0;
+
+ // Resolve occurrences of "/../" in the normalized path
+ while (true) {
+ index = uriCC.indexOf("/../", 0, 4, index);
+ if (index < 0) {
+ break;
+ }
+ // Prevent from going outside our context
+ if (index == 0) {
+ return false;
+ }
+ int index2 = -1;
+ for (pos = start + index - 1; (pos >= 0) && (index2 < 0);
pos--) {
+ if (c[pos] == (char) '/') {
+ index2 = pos;
+ }
+ }
+ copyChars(c, start + index2, start + index + 3, end - start
- index - 3);
+ end = end + index2 - index - 3;
+ uriCC.setEnd(end);
+ index = index2;
+ }
+
+ uriCC.setChars(c, start, end);
+
+ return true;
+ }
+
+ /**
+ * Copy an array of bytes to a different position. Used during
+ * normalization.
+ */
+ protected static void copyBytes(byte[] b, int dest, int src, int len) {
+ for (int pos = 0; pos < len; pos++) {
+ b[pos + dest] = b[pos + src];
+ }
+ }
+
+ /**
+ * Copy an array of chars to a different position. Used during
+ * normalization.
+ */
+ private static void copyChars(char[] c, int dest, int src, int len) {
+ for (int pos = 0; pos < len; pos++) {
+ c[pos + dest] = c[pos + src];
+ }
+ }
+
+ /**
+ * Log a message on the Logger associated with our Container (if any)
+ *
+ * @param message Message to be logged
+ */
+ protected void log(String message) {
+ if(logger.isLoggable(Level.FINE)){
+ logger.fine(message);
+ }
+ }
+
+ /**
+ * Log a message on the Logger associated with our Container (if any)
+ *
+ * @param message Message to be logged
+ * @param throwable Associated exception
+ */
+ protected void log(String message, Throwable throwable) {
+ if(logger.isLoggable(Level.FINE)){
+ logger.log(Level.FINE,message,throwable);
+ }
+ }
+
+
+ /**
+ * Character conversion of the a US-ASCII MessageBytes.
+ */
+ protected void convertMB(MessageBytes mb) {
+ // This is of course only meaningful for bytes
+ if (mb.getType() != MessageBytes.T_BYTES) {
+ return;
+ }
+ ByteChunk bc = mb.getByteChunk();
+ CharChunk cc = mb.getCharChunk();
+ cc.allocate(bc.getLength(), -1);
+
+ // Default encoding: fast conversion
+ byte[] bbuf = bc.getBuffer();
+ char[] cbuf = cc.getBuffer();
+ int start = bc.getStart();
+ for (int i = 0; i < bc.getLength(); i++) {
+ cbuf[i] = (char) (bbuf[i + start] & 0xff);
+ }
+ mb.setChars(cbuf, 0, bc.getLength());
+ }
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyInputBuffer.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyInputBuffer.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyInputBuffer.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,540 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+package com.sun.grizzly.tcp.http11;
+
+import com.sun.grizzly.tcp.InputBuffer;
+import com.sun.grizzly.tcp.Request;
+import com.sun.grizzly.util.buf.B2CConverter;
+import com.sun.grizzly.util.buf.ByteChunk;
+import com.sun.grizzly.util.buf.CharChunk;
+import java.io.IOException;
+import java.io.Reader;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+
+
+/**
+ * The buffer used by Tomcat request. This is a derivative of the
Tomcat 3.3
+ * OutputBuffer, adapted to handle input instead of output. This allows
+ * complete recycling of the facade objects (the ServletInputStream and the
+ * BufferedReader).
+ *
+ * @author Remy Maucherat
+ * @author Jean-Francois Arcand
+ */
+public class GrizzlyInputBuffer extends Reader
+ implements ByteChunk.ByteInputChannel, CharChunk.CharInputChannel,
+ CharChunk.CharOutputChannel {
+
+ // --------------------------------------------------------------
Constants
+
+
+ public static final String DEFAULT_ENCODING =
+ com.sun.grizzly.tcp.Constants.DEFAULT_CHARACTER_ENCODING;
+ public static final int DEFAULT_BUFFER_SIZE = 8*1024;
+ static final int debug = 0;
+
+
+ // The buffer can be used for byte[] and char[] reading
+ // ( this is needed to support ServletInputStream and BufferedReader )
+ public final int INITIAL_STATE = 0;
+ public final int CHAR_STATE = 1;
+ public final int BYTE_STATE = 2;
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ /**
+ * The byte buffer.
+ */
+ private ByteChunk bb;
+
+
+ /**
+ * The chunk buffer.
+ */
+ private CharChunk cb;
+
+
+ /**
+ * State of the output buffer.
+ */
+ private int state = 0;
+
+
+ /**
+ * Number of bytes read.
+ */
+ private int bytesRead = 0;
+
+
+ /**
+ * Number of chars read.
+ */
+ private int charsRead = 0;
+
+
+ /**
+ * Flag which indicates if the input buffer is closed.
+ */
+ private boolean closed = false;
+
+
+ /**
+ * Byte chunk used to input bytes.
+ */
+ private ByteChunk inputChunk = new ByteChunk();
+
+
+ /**
+ * Encoding to use.
+ */
+ private String enc;
+
+
+ /**
+ * Encoder is set.
+ */
+ private boolean gotEnc = false;
+
+
+ /**
+ * List of encoders.
+ */
+ protected HashMap encoders = new HashMap();
+
+
+ /**
+ * Current byte to char converter.
+ */
+ protected B2CConverter conv;
+
+
+ /**
+ * Associated Coyote request.
+ */
+ private Request coyoteRequest;
+
+
+ /**
+ * Buffer position.
+ */
+ private int markPos = -1;
+
+
+ /**
+ * Buffer size.
+ */
+ private int size = -1;
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ /**
+ * Default constructor. Allocate the buffer with the default buffer
size.
+ */
+ public GrizzlyInputBuffer() {
+
+ this(DEFAULT_BUFFER_SIZE);
+
+ }
+
+
+ /**
+ * Alternate constructor which allows specifying the initial buffer
size.
+ *
+ * @param size Buffer size to use
+ */
+ public GrizzlyInputBuffer(int size) {
+
+ this.size = size;
+ bb = new ByteChunk(size);
+ bb.setLimit(size);
+ bb.setByteInputChannel(this);
+ }
+
+
+ // START OF SJSAS 6231069
+ private void initChar() {
+ if (cb != null)
+ return;
+ cb = new CharChunk(size);
+ cb.setLimit(size);
+ cb.setOptimizedWrite(false);
+ cb.setCharInputChannel(this);
+ cb.setCharOutputChannel(this);
+ }
+ // END OF SJSAS 6231069
+ // -------------------------------------------------------------
Properties
+
+
+ /**
+ * Associated Coyote request.
+ *
+ * @param coyoteRequest Associated Coyote request
+ */
+ public void setRequest(Request coyoteRequest) {
+ this.coyoteRequest = coyoteRequest;
+ }
+
+
+ /**
+ * Get associated Coyote request.
+ *
+ * @return the associated Coyote request
+ */
+ public Request getRequest() {
+ return this.coyoteRequest;
+ }
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Recycle the output buffer.
+ */
+ public void recycle() {
+
+ state = INITIAL_STATE;
+ bytesRead = 0;
+ charsRead = 0;
+
+ // START OF SJSAS 6231069
+ /*
+ // If usage of mark made the buffer too big, reallocate it
+ if (cb.getChars().length > size) {
+ cb = new CharChunk(size);
+ cb.setLimit(size);
+ cb.setCharInputChannel(this);
+ cb.setCharOutputChannel(this);
+ } else {
+ cb.recycle();
+ }
+ */
+ cb = null;
+ // END OF SJSAS 6231069
+
+ bb.recycle();
+ markPos = -1;
+ closed = false;
+
+ if (conv != null) {
+ conv.recycle();
+ }
+
+ gotEnc = false;
+ enc = null;
+
+ }
+
+
+ /**
+ * Close the input buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void close()
+ throws IOException {
+ closed = true;
+ }
+
+
+ public int available()
+ throws IOException {
+ if (state == BYTE_STATE) {
+ return bb.getLength();
+ } else if (state == CHAR_STATE) {
+ return cb.getLength();
+ } else {
+ return 0;
+ }
+ }
+
+
+ // ------------------------------------------------- Bytes Handling
Methods
+
+
+ /**
+ * Reads new bytes in the byte chunk.
+ *
+ * @param buf Byte buffer to be written to the response
+ * @param off Offset
+ * @param cnt Length
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public int realReadBytes(byte cbuf[], int off, int len)
+ throws IOException {
+
+ if (closed)
+ return -1;
+ if (coyoteRequest == null)
+ return -1;
+
+ state = BYTE_STATE;
+
+ int result = coyoteRequest.doRead(bb);
+
+ return result;
+
+ }
+
+
+ public int readByte()
+ throws IOException {
+ return bb.substract();
+ }
+
+
+ public int read(byte[] b, int off, int len)
+ throws IOException {
+ return bb.substract(b, off, len);
+ }
+
+
+ // ------------------------------------------------- Chars Handling
Methods
+
+
+ /**
+ * Since the converter will use append, it is possible to get chars to
+ * be removed from the buffer for "writing". Since the chars have
already
+ * been read before, they are ignored. If a mark was set, then the
+ * mark is lost.
+ */
+ public void realWriteChars(char c[], int off, int len)
+ throws IOException {
+ // START OF SJSAS 6231069
+ initChar();
+ // END OF SJSAS 6231069
+ markPos = -1;
+ }
+
+
+ public void setEncoding(String s) {
+ enc = s;
+ }
+
+
+ public int realReadChars(char cbuf[], int off, int len)
+ throws IOException {
+
+ initChar();
+
+ if (!gotEnc)
+ setConverter();
+
+ if (bb.getLength() <= 0) {
+ int nRead = realReadBytes(bb.getBytes(), 0,
bb.getBytes().length);
+ if (nRead < 0) {
+ return -1;
+ }
+ }
+
+ if (markPos == -1) {
+ cb.setOffset(0);
+ cb.setEnd(0);
+ }
+
+ conv.convert(bb, cb);
+ bb.setOffset(bb.getEnd());
+ state = CHAR_STATE;
+
+ return cb.getLength();
+
+ }
+
+
+ @Override
+ public int read()
+ throws IOException {
+ // START OF SJSAS 6231069
+ initChar();
+ // END OF SJSAS 6231069
+ return cb.substract();
+ }
+
+
+ @Override
+ public int read(char[] cbuf)
+ throws IOException {
+ // START OF SJSAS 6231069
+ initChar();
+ // END OF SJSAS 6231069
+ return read(cbuf, 0, cbuf.length);
+ }
+
+
+ public int read(char[] cbuf, int off, int len)
+ throws IOException {
+ // START OF SJSAS 6231069
+ initChar();
+ // END OF SJSAS 6231069
+ return cb.substract(cbuf, off, len);
+ }
+
+
+ @Override
+ public long skip(long n)
+ throws IOException {
+
+ if (n < 0) {
+ throw new IllegalArgumentException();
+ }
+
+ // START OF SJSAS 6231069
+ initChar();
+ // END OF SJSAS 6231069
+ long nRead = 0;
+ while (nRead < n) {
+ if (cb.getLength() >= n) {
+ cb.setOffset(cb.getStart() + (int) n);
+ nRead = n;
+ } else {
+ nRead += cb.getLength();
+ cb.setOffset(cb.getEnd());
+ int toRead = 0;
+ if (cb.getChars().length < (n - nRead)) {
+ toRead = cb.getChars().length;
+ } else {
+ toRead = (int) (n - nRead);
+ }
+ int nb = realReadChars(cb.getChars(), 0, toRead);
+ if (nb < 0)
+ break;
+ }
+ }
+
+ return nRead;
+
+ }
+
+
+ public boolean ready()
+ throws IOException {
+ // START OF SJSAS 6231069
+ initChar();
+ // END OF SJSAS 6231069
+ return (cb.getLength() > 0);
+ }
+
+
+ public boolean markSupported() {
+ return true;
+ }
+
+
+ public void mark(int readAheadLimit)
+ throws IOException {
+ // START OF SJSAS 6231069
+ initChar();
+ // END OF SJSAS 6231069
+ if (cb.getLength() <= 0) {
+ cb.setOffset(0);
+ cb.setEnd(0);
+ } else {
+ if ((cb.getBuffer().length > (2 * size))
+ && (cb.getLength()) < (cb.getStart())) {
+ System.arraycopy(cb.getBuffer(), cb.getStart(),
+ cb.getBuffer(), 0, cb.getLength());
+ cb.setEnd(cb.getLength());
+ cb.setOffset(0);
+ }
+ }
+ int offset = readAheadLimit;
+ if (offset < size) {
+ offset = size;
+ }
+ cb.setLimit(cb.getStart() + offset);
+ markPos = cb.getStart();
+ }
+
+
+ public void reset()
+ throws IOException {
+ if (state == CHAR_STATE) {
+ if (markPos < 0) {
+ cb.recycle();
+ markPos = -1;
+ throw new IOException();
+ } else {
+ cb.setOffset(markPos);
+ }
+ } else {
+ bb.recycle();
+ }
+ }
+
+
+ public void checkConverter()
+ throws IOException {
+
+ if (!gotEnc)
+ setConverter();
+
+ }
+
+
+ protected void setConverter()
+ throws IOException {
+
+ if (coyoteRequest != null)
+ enc = coyoteRequest.getCharacterEncoding();
+
+ gotEnc = true;
+ if (enc == null)
+ enc = DEFAULT_ENCODING;
+ conv = (B2CConverter) encoders.get(enc);
+ if (conv == null) {
+ if (System.getSecurityManager() != null){
+ try{
+ conv = (B2CConverter)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ return new B2CConverter(enc);
+ }
+
+ }
+ );
+ }catch(PrivilegedActionException ex){
+ Exception e = ex.getException();
+ if (e instanceof IOException)
+ throw (IOException)e;
+
+ }
+ } else {
+ conv = new B2CConverter(enc);
+ }
+ encoders.put(enc, conv);
+ }
+
+ }
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyInputStream.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyInputStream.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyInputStream.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,241 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+
+package com.sun.grizzly.tcp.http11;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+
+/**
+ * This class handles reading bytes.
+ *
+ * @author Remy Maucherat
+ * @author Jean-Francois Arcand
+ */
+public class GrizzlyInputStream extends InputStream {
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ protected GrizzlyInputBuffer ib;
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ public GrizzlyInputStream(GrizzlyInputBuffer ib) {
+ this.ib = ib;
+ }
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Prevent cloning the facade.
+ */
+ @Override
+ protected Object clone()
+ throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+
+ // -------------------------------------------------------- Package
Methods
+
+
+ /**
+ * Clear facade.
+ */
+ void clear() {
+ ib = null;
+ }
+
+
+ // --------------------------------------------- ServletInputStream
Methods
+
+
+ public int read()
+ throws IOException {
+
+ if (System.getSecurityManager() != null){
+
+ try{
+ @SuppressWarnings("unchecked")
+ Integer result =
+ (Integer)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ Integer integer = new
Integer(ib.readByte());
+ return integer;
+ }
+
+ });
+ return result.intValue();
+ } catch(PrivilegedActionException pae){
+ Exception e = pae.getException();
+ if (e instanceof IOException){
+ throw (IOException)e;
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ } else {
+ return ib.readByte();
+ }
+ }
+
+ @Override
+ public int available() throws IOException {
+ if (System.getSecurityManager() != null){
+ try{
+ @SuppressWarnings("unchecked")
+ Integer result =
+ (Integer)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ Integer integer = new
Integer(ib.available());
+ return integer;
+ }
+
+ });
+ return result.intValue();
+ } catch(PrivilegedActionException pae){
+ Exception e = pae.getException();
+ if (e instanceof IOException){
+ throw (IOException)e;
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ } else {
+ return ib.available();
+ }
+ }
+
+ @Override
+ public int read(final byte[] b) throws IOException {
+ if (System.getSecurityManager() != null){
+ try{
+ @SuppressWarnings("unchecked")
+ Integer result =
+ (Integer)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ Integer integer =
+ new Integer(ib.read(b, 0, b.length));
+ return integer;
+ }
+
+ });
+ return result.intValue();
+ } catch(PrivilegedActionException pae){
+ Exception e = pae.getException();
+ if (e instanceof IOException){
+ throw (IOException)e;
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ } else {
+ return ib.read(b, 0, b.length);
+ }
+ }
+
+
+ @Override
+ public int read(final byte[] b, final int off, final int len)
+ throws IOException {
+
+ if (System.getSecurityManager() != null){
+ try{
+ @SuppressWarnings("unchecked")
+ Integer result =
+ (Integer)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ Integer integer =
+ new Integer(ib.read(b, off, len));
+ return integer;
+ }
+
+ });
+ return result.intValue();
+ } catch(PrivilegedActionException pae){
+ Exception e = pae.getException();
+ if (e instanceof IOException){
+ throw (IOException)e;
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ } else {
+ return ib.read(b, off, len);
+ }
+ }
+
+
+ /**
+ * Close the stream
+ * Since we re-cycle, we can't allow the call to super.close()
+ * which would permantely disable us.
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ public void close() throws IOException {
+ if (System.getSecurityManager() != null){
+ try{
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ ib.close();
+ return null;
+ }
+
+ });
+ } catch(PrivilegedActionException pae){
+ Exception e = pae.getException();
+ if (e instanceof IOException){
+ throw (IOException)e;
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ } else {
+ ib.close();
+ }
+ }
+
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyOutputBuffer.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyOutputBuffer.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyOutputBuffer.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,756 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+package com.sun.grizzly.tcp.http11;
+
+import com.sun.grizzly.tcp.ActionCode;
+import com.sun.grizzly.tcp.OutputBuffer;
+import com.sun.grizzly.tcp.Response;
+import com.sun.grizzly.util.buf.ByteChunk;
+import com.sun.grizzly.util.buf.C2BConverter;
+import com.sun.grizzly.util.buf.CharChunk;
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+
+/**
+ * The buffer used by Tomcat response. This is a derivative of the
Tomcat 3.3
+ * OutputBuffer, with the removal of some of the state handling (which in
+ * Coyote is mostly the Processor's responsability).
+ *
+ * @author Costin Manolache
+ * @author Remy Maucherat
+ */
+public class GrizzlyOutputBuffer extends Writer
+ implements ByteChunk.ByteOutputChannel, CharChunk.CharOutputChannel {
+
+ // --------------------------------------------------------------
Constants
+
+
+ public static final String DEFAULT_ENCODING =
+ com.sun.grizzly.tcp.Constants.DEFAULT_CHARACTER_ENCODING;
+ public static final int DEFAULT_BUFFER_SIZE = 8*1024;
+ static final int debug = 0;
+
+
+ // The buffer can be used for byte[] and char[] writing
+ // ( this is needed to support ServletOutputStream and for
+ // efficient implementations of templating systems )
+ public final int INITIAL_STATE = 0;
+ public final int CHAR_STATE = 1;
+ public final int BYTE_STATE = 2;
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ /**
+ * The byte buffer.
+ */
+ private ByteChunk bb;
+
+
+ /**
+ * The chunk buffer.
+ */
+ private CharChunk cb;
+
+
+ /**
+ * State of the output buffer.
+ */
+ private int state = 0;
+
+
+ /**
+ * Number of bytes written.
+ */
+ private int bytesWritten = 0;
+
+
+ /**
+ * Number of chars written.
+ */
+ private int charsWritten = 0;
+
+
+ /**
+ * Flag which indicates if the output buffer is closed.
+ */
+ private boolean closed = false;
+
+
+ /**
+ * Do a flush on the next operation.
+ */
+ private boolean doFlush = false;
+
+
+ /**
+ * Byte chunk used to output bytes.
+ */
+ private ByteChunk outputChunk = new ByteChunk();
+
+
+ /**
+ * Encoding to use.
+ */
+ private String enc;
+
+
+ /**
+ * Encoder is set.
+ */
+ private boolean gotEnc = false;
+
+
+ /**
+ * List of encoders.
+ */
+ protected HashMap encoders = new HashMap();
+
+
+ /**
+ * Current char to byte converter.
+ */
+ protected C2BConverter conv;
+
+
+ /**
+ * Associated Coyote response.
+ */
+ private Response coyoteResponse;
+
+
+ /**
+ * Suspended flag. All output bytes will be swallowed if this is true.
+ */
+ private boolean suspended = false;
+
+
+ /**
+ * The <code>ByteBuffer</code> used to cache the request.
+ */
+ private ByteBuffer byteBuffer;
+
+ /**
+ * Is the File Cache enabled
+ */
+ private boolean enableCache = false;
+ // -----------------------------------------------------------
Constructors
+
+
+ /**
+ * Default constructor. Allocate the buffer with the default buffer
size.
+ */
+ public GrizzlyOutputBuffer() {
+
+ this(DEFAULT_BUFFER_SIZE);
+
+ }
+
+
+ // START S1AS8 4861933
+ public GrizzlyOutputBuffer(boolean chunkingDisabled) {
+ this(DEFAULT_BUFFER_SIZE, chunkingDisabled);
+ }
+ // END S1AS8 4861933
+
+
+ /**
+ * Alternate constructor which allows specifying the initial buffer
size.
+ *
+ * @param size Buffer size to use
+ */
+ public GrizzlyOutputBuffer(int size) {
+ // START S1AS8 4861933
+ /*
+ bb = new ByteChunk(size);
+ bb.setLimit(size);
+ bb.setByteOutputChannel(this);
+ cb = new CharChunk(size);
+ cb.setCharOutputChannel(this);
+ cb.setLimit(size);
+ */
+ this(size, false);
+ // END S1AS8 4861933
+ }
+
+
+ // START S1AS8 4861933
+ public GrizzlyOutputBuffer(int size, boolean chunkingDisabled) {
+ bb = new ByteChunk(size);
+ if (!chunkingDisabled) {
+ bb.setLimit(size);
+ }
+ bb.setByteOutputChannel(this);
+ cb = new CharChunk(size);
+ cb.setCharOutputChannel(this);
+ if (!chunkingDisabled) {
+ cb.setLimit(size);
+ }
+ }
+ // END S1AS8 4861933
+
+
+ // -------------------------------------------------------------
Properties
+
+
+ /**
+ * Associated Coyote response.
+ *
+ * @param coyoteResponse Associated Coyote response
+ */
+ public void setResponse(Response coyoteResponse) {
+ this.coyoteResponse = coyoteResponse;
+ }
+
+
+ /**
+ * Get associated Coyote response.
+ *
+ * @return the associated Coyote response
+ */
+ public Response getResponse() {
+ return this.coyoteResponse;
+ }
+
+
+ /**
+ * Is the response output suspended ?
+ *
+ * @return suspended flag value
+ */
+ public boolean isSuspended() {
+ return this.suspended;
+ }
+
+
+ /**
+ * Set the suspended flag.
+ *
+ * @param suspended New suspended flag value
+ */
+ public void setSuspended(boolean suspended) {
+ this.suspended = suspended;
+ }
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Recycle the output buffer.
+ */
+ public void recycle() {
+ state = INITIAL_STATE;
+ bytesWritten = 0;
+ charsWritten = 0;
+
+ cb.recycle();
+ bb.recycle();
+ closed = false;
+ suspended = false;
+
+ if (conv!= null) {
+ conv.recycle();
+ }
+
+ gotEnc = false;
+ enc = null;
+
+ if ( enableCache)
+ byteBuffer.clear();
+
+ enableCache = false;
+ }
+
+
+ /**
+ * Close the output buffer. This tries to calculate the response
size if
+ * the response has not been committed yet.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void close()
+ throws IOException {
+
+ if (closed)
+ return;
+ if (suspended)
+ return;
+
+ if ((!coyoteResponse.isCommitted())
+ && (coyoteResponse.getContentLength() == -1)) {
+ // Flushing the char buffer
+ if (state == CHAR_STATE) {
+ cb.flushBuffer();
+ state = BYTE_STATE;
+ }
+ // If this didn't cause a commit of the response, the final
content
+ // length can be calculated
+ if (!coyoteResponse.isCommitted()) {
+ coyoteResponse.setContentLength(bb.getLength());
+ }
+ }
+
+ doFlush(false);
+ closed = true;
+
+ coyoteResponse.finish();
+
+ }
+
+
+ /**
+ * Flush bytes or chars contained in the buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void flush()
+ throws IOException {
+ doFlush(true);
+ }
+
+
+ /**
+ * Flush bytes or chars contained in the buffer.
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ protected void doFlush(boolean realFlush)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ doFlush = true;
+ if (state == CHAR_STATE) {
+ cb.flushBuffer();
+ bb.flushBuffer();
+ state = BYTE_STATE;
+ } else if (state == BYTE_STATE) {
+ bb.flushBuffer();
+ } else if (state == INITIAL_STATE) {
+ // If the buffers are empty, commit the response header
+ coyoteResponse.sendHeaders();
+ }
+ doFlush = false;
+
+ if (realFlush) {
+ coyoteResponse.action(ActionCode.ACTION_CLIENT_FLUSH,
+ coyoteResponse);
+ // If some exception occurred earlier, or if some IOE occurred
+ // here, notify the servlet with an IOE
+ if (coyoteResponse.isExceptionPresent()) {
+ throw new ClientAbortException
+ (coyoteResponse.getErrorException());
+ }
+ }
+
+ }
+
+
+ // ------------------------------------------------- Bytes Handling
Methods
+
+
+ /**
+ * Sends the buffer data to the client output, checking the
+ * state of Response and calling the right interceptors.
+ *
+ * @param buf Byte buffer to be written to the response
+ * @param off Offset
+ * @param cnt Length
+ *
+ * @throws IOException An underlying IOException occurred
+ */
+ public void realWriteBytes(byte buf[], int off, int cnt)
+ throws IOException {
+ if (closed)
+ return;
+ if (coyoteResponse == null)
+ return;
+
+ // If we really have something to write
+ if (cnt > 0) {
+ // real write to the adapter
+ outputChunk.setBytes(buf, off, cnt);
+ try {
+ coyoteResponse.doWrite(outputChunk);
+ } catch (IOException e) {
+ // An IOException on a write is almost always due to
+ // the remote client aborting the request. Wrap this
+ // so that it can be handled better by the error
dispatcher.
+ throw new ClientAbortException(e);
+ }
+ }
+
+ }
+
+
+ public void write(byte b[], int off, int len) throws IOException {
+
+ if (suspended)
+ return;
+
+ if (state == CHAR_STATE)
+ cb.flushBuffer();
+ state = BYTE_STATE;
+ writeBytes(b, off, len);
+
+ }
+
+
+ private void writeBytes(byte b[], int off, int len)
+ throws IOException {
+
+ if (closed)
+ return;
+
+ if ( enableCache){
+ makeSpace(len);
+ byteBuffer.put(b, off, len);
+ }
+ bb.append(b, off, len);
+ bytesWritten += len;
+
+ // if called from within flush(), then immediately flush
+ // remaining bytes
+ if (doFlush) {
+ bb.flushBuffer();
+ }
+
+ }
+
+
+ // XXX Char or byte ?
+ public void writeByte(int b)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ if (state == CHAR_STATE)
+ cb.flushBuffer();
+ state = BYTE_STATE;
+
+ if ( enableCache){
+ makeSpace(1);
+ byteBuffer.put( (byte)b );
+ }
+
+ bb.append( (byte)b );
+ bytesWritten++;
+
+ }
+
+
+ // ------------------------------------------------- Chars Handling
Methods
+
+
+ public void write(int c)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ if ( enableCache){
+ makeSpace(1);
+ byteBuffer.putChar((char)c);
+ }
+ cb.append((char) c);
+ charsWritten++;
+
+ }
+
+
+ public void write(char c[])
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ write(c, 0, c.length);
+
+ }
+
+
+ public void write(char c[], int off, int len)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ if ( enableCache){
+ makeSpace(len);
+ byteBuffer.put(new String(c).getBytes(),off,len);
+ }
+ cb.append(c, off, len);
+ charsWritten += len;
+
+ }
+
+
+ public void write(StringBuffer sb)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+
+ int len = sb.length();
+ charsWritten += len;
+ if ( enableCache){
+ byte[] bytes = sb.toString().getBytes();
+ makeSpace(bytes.length);
+ byteBuffer.put(bytes);
+ }
+ cb.append(sb);
+
+ }
+
+
+ /**
+ * Append a string to the buffer
+ */
+ public void write(String s, int off, int len)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state=CHAR_STATE;
+
+ charsWritten += len;
+ if (s==null)
+ s="null";
+ if ( enableCache){
+ makeSpace(len);
+ byteBuffer.put(s.getBytes(),off,len);
+ }
+ cb.append( s, off, len );
+
+ }
+
+
+ public void write(String s)
+ throws IOException {
+
+ if (suspended)
+ return;
+
+ state = CHAR_STATE;
+ if (s==null)
+ s="null";
+ write(s, 0, s.length());
+
+ }
+
+
+ public void flushChars()
+ throws IOException {
+ cb.flushBuffer();
+ state = BYTE_STATE;
+
+ }
+
+
+ public boolean flushCharsNeeded() {
+ return state == CHAR_STATE;
+ }
+
+
+ public void setEncoding(String s) {
+ enc = s;
+ }
+
+
+ public void realWriteChars(char c[], int off, int len)
+ throws IOException {
+ if (!gotEnc)
+ setConverter();
+ conv.convert(c, off, len);
+ conv.flushBuffer(); // ???
+
+ }
+
+
+ public void checkConverter()
+ throws IOException {
+
+ if (!gotEnc)
+ setConverter();
+
+ }
+
+
+ protected void setConverter()
+ throws IOException {
+
+ if (coyoteResponse != null)
+ enc = coyoteResponse.getCharacterEncoding();
+
+ gotEnc = true;
+ if (enc == null)
+ enc = DEFAULT_ENCODING;
+ conv = (C2BConverter) encoders.get(enc);
+ if (conv == null) {
+ if (System.getSecurityManager() != null){
+ try{
+ conv = (C2BConverter)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){
+
+ public Object run() throws IOException{
+ return new C2BConverter(bb, enc);
+ }
+
+ }
+ );
+ }catch(PrivilegedActionException ex){
+ Exception e = ex.getException();
+ if (e instanceof IOException)
+ throw (IOException)e;
+
+ }
+ } else {
+ conv = new C2BConverter(bb, enc);
+ }
+ encoders.put(enc, conv);
+
+ }
+ }
+
+
+ // -------------------- BufferedOutputStream compatibility
+
+
+ /**
+ * Real write - this buffer will be sent to the client
+ */
+ public void flushBytes()
+ throws IOException {
+
+ bb.flushBuffer();
+
+ }
+
+
+ public int getBytesWritten() {
+ return bytesWritten;
+ }
+
+
+ public int getCharsWritten() {
+ return charsWritten;
+ }
+
+
+ public int getContentWritten() {
+ return bytesWritten + charsWritten;
+ }
+
+
+ /**
+ * True if this buffer hasn't been used ( since recycle() ) -
+ * i.e. no chars or bytes have been added to the buffer.
+ */
+ public boolean isNew() {
+ return (bytesWritten == 0) && (charsWritten == 0);
+ }
+
+
+ public void setBufferSize(int size) {
+ if (size > bb.getLimit()) {// ??????
+ bb.setLimit(size);
+ }
+ }
+
+
+ public void reset() {
+
+ //count=0;
+ bb.recycle();
+ bytesWritten = 0;
+ cb.recycle();
+ charsWritten = 0;
+ gotEnc = false;
+ enc = null;
+
+ if ( enableCache)
+ byteBuffer.clear();
+
+ enableCache = false;
+ }
+
+
+ public int getBufferSize() {
+ return bb.getLimit();
+ }
+
+
+ /**
+ * Enable resource caching.
+ */
+ public void enableCache(boolean enableCache){
+ this.enableCache = enableCache;
+ if ( enableCache && byteBuffer == null){
+ byteBuffer = ByteBuffer.allocate(bb.getLimit());
+ }
+ }
+
+
+ /**
+ * Return a copy of the cached resources.
+ */
+ public ByteBuffer getCachedByteBuffer(){
+ ByteBuffer cache = ByteBuffer.allocate(byteBuffer.position());
+ byteBuffer.flip();
+ cache.put(byteBuffer);
+ return cache;
+ }
+
+
+ /**
+ * Meke sure we have enough space to store bytes.
+ */
+ private void makeSpace(int size){
+ int capacity = byteBuffer.capacity();
+ if ( byteBuffer.position() + size > capacity) {
+ ByteBuffer tmp = ByteBuffer.allocate(capacity * 2);
+ byteBuffer.flip();
+ tmp.put(byteBuffer);
+ byteBuffer = tmp;
+ }
+ }
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyOutputStream.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyOutputStream.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyOutputStream.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,126 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+
+package com.sun.grizzly.tcp.http11;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Coyote implementation of the servlet output stream.
+ *
+ * @author Costin Manolache
+ * @author Remy Maucherat
+ */
+public class GrizzlyOutputStream extends OutputStream{
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ protected GrizzlyOutputBuffer ob;
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ public GrizzlyOutputStream(GrizzlyOutputBuffer ob) {
+ this.ob = ob;
+ }
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Prevent cloning the facade.
+ */
+ @Override
+ protected Object clone()
+ throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+
+ // -------------------------------------------------------- Package
Methods
+
+
+ /**
+ * Clear facade.
+ */
+ void clear() {
+ ob = null;
+ }
+
+
+ // --------------------------------------------------- OutputStream
Methods
+
+
+ public void write(int i)
+ throws IOException {
+ ob.writeByte(i);
+ }
+
+
+ @Override
+ public void write(byte[] b)
+ throws IOException {
+ write(b, 0, b.length);
+ }
+
+
+ @Override
+ public void write(byte[] b, int off, int len)
+ throws IOException {
+ ob.write(b, off, len);
+ }
+
+
+ /**
+ * Will send the buffer to the client.
+ */
+ @Override
+ public void flush()
+ throws IOException {
+ ob.flush();
+ }
+
+
+ @Override
+ public void close()
+ throws IOException {
+ ob.close();
+ }
+
+
+ public void print(String s)
+ throws IOException {
+ ob.write(s);
+ }
+
+
+}
+

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyReader.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyReader.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyReader.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,227 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+
+package com.sun.grizzly.tcp.http11;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+
+/**
+ * Coyote implementation of the buffred reader.
+ *
+ * @author Remy Maucherat
+ */
+public class GrizzlyReader
+ extends BufferedReader {
+
+
+ // --------------------------------------------------------------
Constants
+
+
+ private static final char[] LINE_SEP = { '\r', '\n' };
+ private static final int MAX_LINE_LENGTH = 4096;
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ protected GrizzlyInputBuffer ib;
+
+ protected char[] lineBuffer = null;
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ public GrizzlyReader(GrizzlyInputBuffer ib) {
+ super(ib, 1);
+ this.ib = ib;
+ }
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Prevent cloning the facade.
+ */
+ @Override
+ protected Object clone()
+ throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+
+ // -------------------------------------------------------- Package
Methods
+
+
+ /**
+ * Clear facade.
+ */
+ void clear() {
+ ib = null;
+ }
+
+
+ // --------------------------------------------------------- Reader
Methods
+
+
+ @Override
+ public void close()
+ throws IOException {
+ ib.close();
+ }
+
+
+ @Override
+ public int read()
+ throws IOException {
+ return ib.read();
+ }
+
+
+ @Override
+ public int read(char[] cbuf)
+ throws IOException {
+ return ib.read(cbuf, 0, cbuf.length);
+ }
+
+
+ @Override
+ public int read(char[] cbuf, int off, int len)
+ throws IOException {
+ return ib.read(cbuf, off, len);
+ }
+
+
+ @Override
+ public long skip(long n)
+ throws IOException {
+ return ib.skip(n);
+ }
+
+
+ @Override
+ public boolean ready()
+ throws IOException {
+ return ib.ready();
+ }
+
+
+ @Override
+ public boolean markSupported() {
+ return true;
+ }
+
+
+ @Override
+ public void mark(int readAheadLimit)
+ throws IOException {
+ ib.mark(readAheadLimit);
+ }
+
+
+ @Override
+ public void reset()
+ throws IOException {
+ ib.reset();
+ }
+
+
+ @Override
+ public String readLine()
+ throws IOException {
+
+ if (lineBuffer == null) {
+ lineBuffer = new char[MAX_LINE_LENGTH];
+ }
+
+ String result = null;
+
+ int pos = 0;
+ int end = -1;
+ int skip = -1;
+ StringBuffer aggregator = null;
+ while (end < 0) {
+ mark(MAX_LINE_LENGTH);
+ while ((pos < MAX_LINE_LENGTH) && (end < 0)) {
+ int nRead = read(lineBuffer, pos, MAX_LINE_LENGTH - pos);
+ if (nRead < 0) {
+ if (pos == 0) {
+ return null;
+ }
+ end = pos;
+ skip = pos;
+ }
+ for (int i = pos; (i < (pos + nRead)) && (end < 0); i++) {
+ if (lineBuffer[i] == LINE_SEP[0]) {
+ end = i;
+ skip = i + 1;
+ char nextchar;
+ if (i == (pos + nRead - 1)) {
+ nextchar = (char) read();
+ } else {
+ nextchar = lineBuffer[i+1];
+ }
+ if (nextchar == LINE_SEP[1]) {
+ skip++;
+ }
+ } else if (lineBuffer[i] == LINE_SEP[1]) {
+ end = i;
+ skip = i + 1;
+ }
+ }
+ if (nRead > 0) {
+ pos += nRead;
+ }
+ }
+ if (end < 0) {
+ if (aggregator == null) {
+ aggregator = new StringBuffer();
+ }
+ aggregator.append(lineBuffer);
+ pos = 0;
+ } else {
+ reset();
+ skip(skip);
+ }
+ }
+
+ if (aggregator == null) {
+ result = new String(lineBuffer, 0, end);
+ } else {
+ aggregator.append(lineBuffer, 0, end);
+ result = aggregator.toString();
+ }
+
+ return result;
+
+ }
+
+ public GrizzlyInputBuffer getInputBuffer(){
+ return ib;
+ }
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyRequest.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyRequest.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyRequest.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,2004 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+
+package com.sun.grizzly.tcp.http11;
+
+import com.sun.grizzly.tcp.ActionCode;
+import com.sun.grizzly.tcp.Request;
+import com.sun.grizzly.util.buf.B2CConverter;
+import com.sun.grizzly.util.buf.MessageBytes;
+import com.sun.grizzly.util.http.Cookie;
+import com.sun.grizzly.util.http.Cookies;
+import com.sun.grizzly.util.http.Enumerator;
+import com.sun.grizzly.util.http.FastHttpDateFormat;
+import com.sun.grizzly.util.http.Globals;
+import com.sun.grizzly.util.http.ParameterMap;
+import com.sun.grizzly.util.http.Parameters;
+import com.sun.grizzly.util.http.ServerCookie;
+import com.sun.grizzly.util.http.StringParser;
+import com.sun.grizzly.util.res.StringManager;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.TreeMap;
+import javax.security.auth.Subject;
+
+/**
+ * Wrapper object for the Coyote request.
+ *
+ * @author Remy Maucherat
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.2 $ $Date: 2007/03/14 02:15:42 $
+ */
+
+public class GrizzlyRequest{
+
+ // -----------------------------------------------------------
Constructors
+
+
+ public GrizzlyRequest() {
+ // START OF SJSAS 6231069
+ formats = (SimpleDateFormat[]) staticDateFormats.get();
+ formats[0].setTimeZone(TimeZone.getTimeZone("GMT"));
+ formats[1].setTimeZone(TimeZone.getTimeZone("GMT"));
+ formats[2].setTimeZone(TimeZone.getTimeZone("GMT"));
+ // END OF SJSAS 6231069
+ }
+
+
+ // -------------------------------------------------------------
Properties
+
+
+ /**
+ * Coyote request.
+ */
+ protected Request request;
+
+ /**
+ * Set the Coyote request.
+ *
+ * @param request The Coyote request
+ */
+ public void setRequest(Request request) {
+ this.request = request;
+ inputBuffer.setRequest(request);
+ }
+
+ /**
+ * Get the Coyote request.
+ */
+ public Request getRequest() {
+ return (this.request);
+ }
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ /**
+ * The string manager for this package.
+ */
+ protected static StringManager sm =
+ StringManager.getManager(Constants.Package);
+
+
+ /**
+ * The set of cookies associated with this Request.
+ */
+ protected Cookie[] cookies = null;
+
+ // START OF SJSAS 6231069
+ /*
+ protected SimpleDateFormat formats[] = {
+ new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
+ new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
+ new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
+ }*/
+
+ /**
+ * The set of SimpleDateFormat formats to use in getDateHeader().
+ */
+ private static ThreadLocal staticDateFormats = new ThreadLocal() {
+ protected Object initialValue() {
+ SimpleDateFormat[] f = new SimpleDateFormat[3];
+ f[0] = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz",
+ Locale.US);
+ f[1] = new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz",
+ Locale.US);
+ f[2] = new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy",
Locale.US);
+ return f;
+ }
+ };
+ protected SimpleDateFormat formats[];
+ // END OF SJSAS 6231069
+
+ /**
+ * The default Locale if none are specified.
+ */
+ protected static Locale defaultLocale = Locale.getDefault();
+
+
+ /**
+ * The attributes associated with this Request, keyed by attribute
name.
+ */
+ protected HashMap attributes = new HashMap();
+
+
+ /**
+ * List of read only attributes for this Request.
+ */
+ private HashMap readOnlyAttributes = new HashMap();
+
+
+ /**
+ * The preferred Locales assocaited with this Request.
+ */
+ protected ArrayList locales = new ArrayList();
+
+
+ /**
+ * Internal notes associated with this request by Catalina components
+ * and event listeners.
+ */
+ private transient HashMap notes = new HashMap();
+
+
+ /**
+ * Authentication type.
+ */
+ protected String authType = null;
+
+
+ /**
+ * The current dispatcher type.
+ */
+ protected Object dispatcherType = null;
+
+
+ /**
+ * The associated input buffer.
+ */
+ protected GrizzlyInputBuffer inputBuffer = new GrizzlyInputBuffer();
+
+
+ /**
+ * GrizzlyInputStream.
+ */
+ protected GrizzlyInputStream inputStream =
+ new GrizzlyInputStream(inputBuffer);
+
+
+ /**
+ * Reader.
+ */
+ protected GrizzlyReader reader = new GrizzlyReader(inputBuffer);
+
+
+ /**
+ * Using stream flag.
+ */
+ protected boolean usingInputStream = false;
+
+
+ /**
+ * Using writer flag.
+ */
+ protected boolean usingReader = false;
+
+
+ /**
+ * User principal.
+ */
+ protected Principal userPrincipal = null;
+
+
+ /**
+ * Session parsed flag.
+ */
+ protected boolean sessionParsed = false;
+
+
+ /**
+ * Request parameters parsed flag.
+ */
+ protected boolean requestParametersParsed = false;
+
+
+ /**
+ * Cookies parsed flag.
+ */
+ protected boolean cookiesParsed = false;
+
+
+ /**
+ * Secure flag.
+ */
+ protected boolean secure = false;
+
+
+ /**
+ * The Subject associated with the current AccessControllerContext
+ */
+ protected Subject subject = null;
+
+
+ /**
+ * Post data buffer.
+ */
+ protected static int CACHED_POST_LEN = 8192;
+ protected byte[] postData = null;
+
+
+ /**
+ * Hash map used in the getParametersMap method.
+ */
+ protected ParameterMap parameterMap = new ParameterMap();
+
+
+ /**
+ * The current request dispatcher path.
+ */
+ protected Object requestDispatcherPath = null;
+
+
+ /**
+ * Was the requested session ID received in a cookie?
+ */
+ protected boolean requestedSessionCookie = false;
+
+
+ /**
+ * The requested session ID (if any) for this request.
+ */
+ protected String requestedSessionId = null;
+
+
+ /**
+ * Was the requested session ID received in a URL?
+ */
+ protected boolean requestedSessionURL = false;
+
+
+ /**
+ * The socket through which this Request was received.
+ */
+ protected Socket socket = null;
+
+
+ /**
+ * Parse locales.
+ */
+ protected boolean localesParsed = false;
+
+
+ /**
+ * The string parser we will use for parsing request lines.
+ */
+ private StringParser parser = new StringParser();
+
+ /**
+ * Local port
+ */
+ protected int localPort = -1;
+
+ /**
+ * Remote address.
+ */
+ protected String remoteAddr = null;
+
+
+ /**
+ * Remote host.
+ */
+ protected String remoteHost = null;
+
+
+ /**
+ * Remote port
+ */
+ protected int remotePort = -1;
+
+ /**
+ * Local address
+ */
+ protected String localName = null;
+
+
+ /**
+ * Local address
+ */
+ protected String localAddr = null;
+
+
+ // START S1AS 4703023
+ /**
+ * The current application dispatch depth.
+ */
+ private int dispatchDepth = 0;
+
+ /**
+ * The maximum allowed application dispatch depth.
+ */
+ private static int maxDispatchDepth =
Constants.DEFAULT_MAX_DISPATCH_DEPTH;
+ // END S1AS 4703023
+
+
+ // START SJSAS 6346226
+ private String jrouteId;
+ // END SJSAS 6346226
+
+
+ /**
+ * The response with which this request is associated.
+ */
+ protected GrizzlyResponse response = null;
+
+ /**
+ * Return the Response with which this Request is associated.
+ */
+ public GrizzlyResponse getResponse() {
+ return response;
+ }
+
+ /**
+ * Set the Response with which this Request is associated.
+ *
+ * @param response The new associated response
+ */
+ public void setResponse(GrizzlyResponse response) {
+ this.response = response;
+ }
+
+ // --------------------------------------------------------- Public
Methods
+
+ /**
+ * Release all object references, and initialize instance variables, in
+ * preparation for reuse of this object.
+ */
+ public void recycle() {
+
+ dispatcherType = null;
+ requestDispatcherPath = null;
+
+ authType = null;
+ inputBuffer.recycle();
+ usingInputStream = false;
+ usingReader = false;
+ userPrincipal = null;
+ subject = null;
+ sessionParsed = false;
+ requestParametersParsed = false;
+ cookiesParsed = false;
+ locales.clear();
+ localesParsed = false;
+ secure = false;
+ remoteAddr = null;
+ remoteHost = null;
+ remotePort = -1;
+ localPort = -1;
+ localAddr = null;
+ localName = null;
+
+ attributes.clear();
+ notes.clear();
+ cookies = null;
+
+
+ dispatchDepth = 0; // S1AS 4703023
+
+ parameterMap.setLocked(false);
+ parameterMap.clear();
+
+ if (System.getSecurityManager() != null) {
+ if (inputStream != null) {
+ inputStream.clear();
+ inputStream = null;
+ }
+ if (reader != null) {
+ reader.clear();
+ reader = null;
+ }
+ }
+
+ }
+
+
+ // -------------------------------------------------------- Request
Methods
+
+
+ /**
+ * Return the authorization credentials sent with this request.
+ */
+ public String getAuthorization() {
+ return (request.getHeader(Constants.AUTHORIZATION_HEADER));
+ }
+
+ /**
+ * Set the authorization credentials sent with this request.
+ *
+ * @param authorization The new authorization credentials
+ */
+ public void setAuthorization(String authorization) {
+ // Not used
+ }
+
+
+ /**
+ * Return the Socket (if any) through which this Request was received.
+ * This should <strong>only</strong> be used to access underlying state
+ * information about this Socket, such as the SSLSession associated
with
+ * an SSLSocket.
+ */
+ public Socket getSocket() {
+ return (socket);
+ }
+
+ /**
+ * Set the Socket (if any) through which this Request was received.
+ *
+ * @param socket The socket through which this request was received
+ */
+ public void setSocket(Socket socket) {
+ this.socket = socket;
+ remoteHost = null;
+ remoteAddr = null;
+ remotePort = -1;
+ localPort = -1;
+ localAddr = null;
+ localName = null;
+ }
+
+
+ /**
+ * Return the input stream associated with this Request.
+ */
+ public InputStream getStream() {
+ if (inputStream == null) {
+ inputStream = new GrizzlyInputStream(inputBuffer);
+ }
+ return inputStream;
+ }
+
+ /**
+ * Set the input stream associated with this Request.
+ *
+ * @param stream The new input stream
+ */
+ public void setStream(InputStream stream) {
+ // Ignore
+ }
+
+
+ /**
+ * URI byte to char converter (not recycled).
+ */
+ protected B2CConverter URIConverter = null;
+
+ /**
+ * Return the URI converter.
+ */
+ public B2CConverter getURIConverter() {
+ return URIConverter;
+ }
+
+ /**
+ * Set the URI converter.
+ *
+ * @param URIConverter the new URI connverter
+ */
+ public void setURIConverter(B2CConverter URIConverter) {
+ this.URIConverter = URIConverter;
+ }
+
+
+ // ------------------------------------------------- Request Public
Methods
+
+
+ /**
+ * Create and return a GrizzlyInputStream to read the content
+ * associated with this Request.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ public GrizzlyInputStream createInputStream()
+ throws IOException {
+ if (inputStream == null) {
+ inputStream = new GrizzlyInputStream(inputBuffer);
+ }
+ return inputStream;
+ }
+
+
+ /**
+ * Perform whatever actions are required to flush and close the input
+ * stream or reader, in a single operation.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ public void finishRequest() throws IOException {
+ // The reader and input stream don't need to be closed
+ }
+
+
+ /**
+ * Return the object bound with the specified name to the internal
notes
+ * for this request, or <code>null</code> if no such binding exists.
+ *
+ * @param name Name of the note to be returned
+ */
+ public Object getNote(String name) {
+ return (notes.get(name));
+ }
+
+
+ /**
+ * Return an Iterator containing the String names of all notes bindings
+ * that exist for this request.
+ */
+ public Iterator getNoteNames() {
+ return (notes.keySet().iterator());
+ }
+
+
+ /**
+ * Remove any object bound to the specified name in the internal notes
+ * for this request.
+ *
+ * @param name Name of the note to be removed
+ */
+ public void removeNote(String name) {
+ notes.remove(name);
+ }
+
+
+ /**
+ * Bind an object to a specified name in the internal notes associated
+ * with this request, replacing any existing binding for this name.
+ *
+ * @param name Name to which the object should be bound
+ * @param value Object to be bound to the specified name
+ */
+ public void setNote(String name, Object value) {
+ notes.put(name, value);
+ }
+
+
+ /**
+ * Set the content length associated with this Request.
+ *
+ * @param length The new content length
+ */
+ public void setContentLength(int length) {
+ // Not used
+ }
+
+
+ /**
+ * Set the content type (and optionally the character encoding)
+ * associated with this Request. For example,
+ * <code>text/html; charset=ISO-8859-4</code>.
+ *
+ * @param type The new content type
+ */
+ public void setContentType(String type) {
+ // Not used
+ }
+
+
+ /**
+ * Set the protocol name and version associated with this Request.
+ *
+ * @param protocol Protocol name and version
+ */
+ public void setProtocol(String protocol) {
+ // Not used
+ }
+
+
+ /**
+ * Set the IP address of the remote client associated with this
Request.
+ *
+ * @param remoteAddr The remote IP address
+ */
+ public void setRemoteAddr(String remoteAddr) {
+ // Not used
+ }
+
+
+ /**
+ * Set the fully qualified name of the remote client associated
with this
+ * Request.
+ *
+ * @param remoteHost The remote host name
+ */
+ public void setRemoteHost(String remoteHost) {
+ // Not used
+ }
+
+
+ /**
+ * Set the name of the scheme associated with this request.
Typical values
+ * are <code>http</code>, <code>https</code>, and <code>ftp</code>.
+ *
+ * @param scheme The scheme
+ */
+ public void setScheme(String scheme) {
+ // Not used
+ }
+
+
+ /**
+ * Set the value to be returned by <code>isSecure()</code>
+ * for this Request.
+ *
+ * @param secure The new isSecure value
+ */
+ public void setSecure(boolean secure) {
+ this.secure = secure;
+ }
+
+
+ /**
+ * Set the name of the server (virtual host) to process this request.
+ *
+ * @param name The server name
+ */
+ public void setServerName(String name) {
+ request.serverName().setString(name);
+ }
+
+
+ /**
+ * Set the port number of the server to process this request.
+ *
+ * @param port The server port
+ */
+ public void setServerPort(int port) {
+ request.setServerPort(port);
+ }
+
+
+ // ------------------------------------------------- ServletRequest
Methods
+
+
+ /**
+ * Return the specified request attribute if it exists; otherwise,
return
+ * <code>null</code>.
+ *
+ * @param name Name of the request attribute to return
+ */
+ public Object getAttribute(String name) {
+ Object attr=attributes.get(name);
+
+ if(attr!=null)
+ return(attr);
+
+ attr = request.getAttribute(name);
+ if(attr != null)
+ return attr;
+ // XXX Should move to Globals
+ if(Constants.SSL_CERTIFICATE_ATTR.equals(name)) {
+ request.action(ActionCode.ACTION_REQ_SSL_CERTIFICATE, null);
+ attr = getAttribute(Globals.CERTIFICATES_ATTR);
+ if(attr != null)
+ attributes.put(name, attr);
+ } else if( isSSLAttribute(name) ) {
+ request.action(ActionCode.ACTION_REQ_SSL_ATTRIBUTE,
+ request);
+ attr = request.getAttribute(Globals.CERTIFICATES_ATTR);
+ if( attr != null) {
+ attributes.put(Globals.CERTIFICATES_ATTR, attr);
+ }
+ attr = request.getAttribute(Globals.CIPHER_SUITE_ATTR);
+ if(attr != null) {
+ attributes.put(Globals.CIPHER_SUITE_ATTR, attr);
+ }
+ attr = request.getAttribute(Globals.KEY_SIZE_ATTR);
+ if(attr != null) {
+ attributes.put(Globals.KEY_SIZE_ATTR, attr);
+ }
+ attr = attributes.get(name);
+ }
+ return attr;
+ }
+
+
+ /**
+ * Test if a given name is one of the special Servlet-spec SSL
attributes.
+ */
+ static boolean isSSLAttribute(String name) {
+ return Globals.CERTIFICATES_ATTR.equals(name) ||
+ Globals.CIPHER_SUITE_ATTR.equals(name) ||
+ Globals.KEY_SIZE_ATTR.equals(name);
+ }
+
+ /**
+ * Return the names of all request attributes for this Request, or an
+ * empty <code>Enumeration</code> if there are none.
+ */
+ public Enumeration getAttributeNames() {
+ return new Enumerator(attributes.keySet(), true);
+ }
+
+
+ /**
+ * Return the character encoding for this Request.
+ */
+ public String getCharacterEncoding() {
+ return (request.getCharacterEncoding());
+ }
+
+
+ /**
+ * Return the content length for this Request.
+ */
+ public int getContentLength() {
+ return (request.getContentLength());
+ }
+
+
+ /**
+ * Return the content type for this Request.
+ */
+ public String getContentType() {
+ return (request.getContentType());
+ }
+
+
+ /**
+ * Return the servlet input stream for this Request. The default
+ * implementation returns a servlet input stream created by
+ * <code>createInputStream()</code>.
+ *
+ * @exception IllegalStateException if <code>getReader()</code> has
+ * already been called for this request
+ * @exception IOException if an input/output error occurs
+ */
+ public GrizzlyInputStream getInputStream() throws IOException {
+
+ if (usingReader)
+ throw new IllegalStateException
+ (sm.getString("request.getInputStream.ise"));
+
+ usingInputStream = true;
+ if (inputStream == null) {
+ inputStream = new GrizzlyInputStream(inputBuffer);
+ }
+ return inputStream;
+
+ }
+
+
+ /**
+ * Return the preferred Locale that the client will accept content in,
+ * based on the value for the first <code>Accept-Language</code> header
+ * that was encountered. If the request did not specify a preferred
+ * language, the server's default Locale is returned.
+ */
+ public Locale getLocale() {
+
+ if (!localesParsed)
+ parseLocales();
+
+ if (locales.size() > 0) {
+ return ((Locale) locales.get(0));
+ } else {
+ return (defaultLocale);
+ }
+
+ }
+
+
+ /**
+ * Return the set of preferred Locales that the client will accept
+ * content in, based on the values for any <code>Accept-Language</code>
+ * headers that were encountered. If the request did not specify a
+ * preferred language, the server's default Locale is returned.
+ */
+ public Enumeration getLocales() {
+
+ if (!localesParsed)
+ parseLocales();
+
+ if (locales.size() > 0)
+ return (new Enumerator(locales));
+ ArrayList results = new ArrayList();
+ results.add(defaultLocale);
+ return (new Enumerator(results));
+
+ }
+
+
+ /**
+ * Return the value of the specified request parameter, if any;
otherwise,
+ * return <code>null</code>. If there is more than one value defined,
+ * return only the first one.
+ *
+ * @param name Name of the desired request parameter
+ */
+ public String getParameter(String name) {
+
+ if (!requestParametersParsed)
+ parseRequestParameters();
+
+ return request.getParameters().getParameter(name);
+
+ }
+
+
+
+ /**
+ * Returns a <code>Map</code> of the parameters of this request.
+ * Request parameters are extra information sent with the request.
+ * For HTTP servlets, parameters are contained in the query string
+ * or posted form data.
+ *
+ * @return A <code>Map</code> containing parameter names as keys
+ * and parameter values as map values.
+ */
+ public Map getParameterMap() {
+
+ if (parameterMap.isLocked())
+ return parameterMap;
+
+ Enumeration e = getParameterNames();
+ while (e.hasMoreElements()) {
+ String name = e.nextElement().toString();
+ String[] values = getParameterValues(name);
+ parameterMap.put(name, values);
+ }
+
+ parameterMap.setLocked(true);
+
+ return parameterMap;
+
+ }
+
+
+ /**
+ * Return the names of all defined request parameters for this request.
+ */
+ public Enumeration getParameterNames() {
+
+ if (!requestParametersParsed)
+ parseRequestParameters();
+
+ return request.getParameters().getParameterNames();
+
+ }
+
+
+ /**
+ * Return the defined values for the specified request parameter,
if any;
+ * otherwise, return <code>null</code>.
+ *
+ * @param name Name of the desired request parameter
+ */
+ public String[] getParameterValues(String name) {
+
+ if (!requestParametersParsed)
+ parseRequestParameters();
+
+ return request.getParameters().getParameterValues(name);
+
+ }
+
+
+ /**
+ * Return the protocol and version used to make this Request.
+ */
+ public String getProtocol() {
+ return request.protocol().toString();
+ }
+
+
+ /**
+ * Read the Reader wrapping the input stream for this Request. The
+ * default implementation wraps a <code>BufferedReader</code>
around the
+ * servlet input stream returned by <code>createInputStream()</code>.
+ *
+ * @exception IllegalStateException if <code>getInputStream()</code>
+ * has already been called for this request
+ * @exception IOException if an input/output error occurs
+ */
+ public BufferedReader getReader() throws IOException {
+
+ if (usingInputStream)
+ throw new IllegalStateException
+ (sm.getString("request.getReader.ise"));
+
+ usingReader = true;
+ inputBuffer.checkConverter();
+ if (reader == null) {
+ reader = new GrizzlyReader(inputBuffer);
+ }
+ return reader;
+
+ }
+
+
+ /**
+ * Return the remote IP address making this Request.
+ */
+ public String getRemoteAddr() {
+ if (remoteAddr == null) {
+
+ if (socket != null) {
+ InetAddress inet = socket.getInetAddress();
+ remoteAddr = inet.getHostAddress();
+ } else {
+ request.action
+ (ActionCode.ACTION_REQ_HOST_ADDR_ATTRIBUTE, request);
+ remoteAddr = request.remoteAddr().toString();
+ }
+ }
+ return remoteAddr;
+ }
+
+
+ /**
+ * Return the remote host name making this Request.
+ */
+ public String getRemoteHost() {
+ if (remoteHost == null) {
+ if (socket != null) {
+ InetAddress inet = socket.getInetAddress();
+ remoteHost = inet.getHostName();
+ } else {
+ request.action
+ (ActionCode.ACTION_REQ_HOST_ATTRIBUTE, request);
+ remoteHost = request.remoteHost().toString();
+ }
+ }
+ return remoteHost;
+ }
+
+ /**
+ * Returns the Internet Protocol (IP) source port of the client
+ * or last proxy that sent the request.
+ */
+ public int getRemotePort(){
+ if (remotePort == -1) {
+ if (socket != null) {
+ remotePort = socket.getPort();
+ } else {
+ request.action
+ (ActionCode.ACTION_REQ_REMOTEPORT_ATTRIBUTE, request);
+ remotePort = request.getRemotePort();
+ }
+ }
+ return remotePort;
+ }
+
+ /**
+ * Returns the host name of the Internet Protocol (IP) interface on
+ * which the request was received.
+ */
+ public String getLocalName(){
+ if (localName == null) {
+ if (socket != null) {
+ InetAddress inet = socket.getLocalAddress();
+ localName = inet.getHostName();
+ } else {
+ request.action
+ (ActionCode.ACTION_REQ_LOCAL_NAME_ATTRIBUTE,
request);
+ localName = request.localName().toString();
+ }
+ }
+ return localName;
+ }
+
+ /**
+ * Returns the Internet Protocol (IP) address of the interface on
+ * which the request was received.
+ */
+ public String getLocalAddr(){
+ if (localAddr == null) {
+ if (socket != null) {
+ InetAddress inet = socket.getLocalAddress();
+ localAddr = inet.getHostAddress();
+ } else {
+ request.action
+ (ActionCode.ACTION_REQ_LOCAL_ADDR_ATTRIBUTE, request);
+ localAddr = request.localAddr().toString();
+ }
+ }
+ return localAddr;
+ }
+
+
+ /**
+ * Returns the Internet Protocol (IP) port number of the interface
+ * on which the request was received.
+ */
+ public int getLocalPort(){
+ if (localPort == -1){
+ if (socket != null) {
+ localPort = socket.getLocalPort();
+ } else {
+ request.action
+ (ActionCode.ACTION_REQ_LOCALPORT_ATTRIBUTE, request);
+ localPort = request.getLocalPort();
+ }
+ }
+ return localPort;
+ }
+
+
+ /**
+ * Return the scheme used to make this Request.
+ */
+ public String getScheme() {
+ return (request.scheme().toString());
+ }
+
+
+ /**
+ * Return the server name responding to this Request.
+ */
+ public String getServerName() {
+ return (request.serverName().toString());
+ }
+
+
+ /**
+ * Return the server port responding to this Request.
+ */
+ public int getServerPort() {
+ return (request.getServerPort());
+ }
+
+
+ /**
+ * Was this request received on a secure connection?
+ */
+ public boolean isSecure() {
+ return (secure);
+ }
+
+
+ /**
+ * Remove the specified request attribute if it exists.
+ *
+ * @param name Name of the request attribute to remove
+ */
+ public void removeAttribute(String name) {
+ Object value = null;
+ boolean found = false;
+
+ // Remove the specified attribute
+ // Check for read only attribute
+ // requests are per thread so synchronization unnecessary
+ if (readOnlyAttributes.containsKey(name)) {
+ return;
+ }
+ found = attributes.containsKey(name);
+ if (found) {
+ value = attributes.get(name);
+ attributes.remove(name);
+ } else {
+ return;
+ }
+ }
+
+
+ /**
+ * Set the specified request attribute to the specified value.
+ *
+ * @param name Name of the request attribute to set
+ * @param value The associated value
+ */
+ public void setAttribute(String name, Object value) {
+
+ // Name cannot be null
+ if (name == null)
+ throw new IllegalArgumentException
+ (sm.getString("request.setAttribute.namenull"));
+
+ // Null value is the same as removeAttribute()
+ if (value == null) {
+ removeAttribute(name);
+ return;
+ }
+
+ if (name.equals(Globals.DISPATCHER_TYPE_ATTR)) {
+ dispatcherType = value;
+ return;
+ } else if (name.equals(Globals.DISPATCHER_REQUEST_PATH_ATTR)) {
+ requestDispatcherPath = value;
+ return;
+ }
+
+ Object oldValue = null;
+ boolean replaced = false;
+
+ // Add or replace the specified attribute
+ // Check for read only attribute
+ // requests are per thread so synchronization unnecessary
+ if (readOnlyAttributes.containsKey(name)) {
+ return;
+ }
+
+ oldValue = attributes.put(name, value);
+ if (oldValue != null) {
+ replaced = true;
+ }
+
+ // START SJSAS 6231069
+ // Pass special attributes to the ngrizzly layer
+ if (name.startsWith("grizzly.")) {
+ request.setAttribute(name, value);
+ }
+ // END SJSAS 6231069
+ }
+
+
+ /**
+ * Overrides the name of the character encoding used in the body of
this
+ * request.
+ *
+ * This method must be called prior to reading request parameters or
+ * reading input using <code>getReader()</code>. Otherwise, it has no
+ * effect.
+ *
+ * @param env <code>String</code> containing the name of
+ * the character encoding.
+ * @throws java.io.UnsupportedEncodingException if this
+ * ServletRequest is still in a state where a
+ * character encoding may be set, but the specified
+ * encoding is invalid
+ *
+ * @since Servlet 2.3
+ */
+ public void setCharacterEncoding(String enc)
+ throws UnsupportedEncodingException {
+
+ // START SJSAS 4936855
+ if (requestParametersParsed || usingReader) {
+ return;
+ }
+ // END SJSAS 4936855
+
+ // Ensure that the specified encoding is valid
+ byte buffer[] = new byte[1];
+ buffer[0] = (byte) 'a';
+
+ // START S1AS 6179607: Workaround for 6181598. Workaround should be
+ // removed once the underlying issue in J2SE has been fixed.
+ /*
+ * String dummy = new String(buffer, enc);
+ */
+ // END S1AS 6179607
+ // START S1AS 6179607
+ final byte[] finalBuffer = buffer;
+ final String finalEnc = enc;
+ String dummy = null;
+ if (System.getSecurityManager() != null) {
+ try {
+ dummy = (String) AccessController.doPrivileged(
+ new PrivilegedExceptionAction() {
+ public Object run() throws
UnsupportedEncodingException {
+ return new String(finalBuffer, finalEnc);
+ }
+ });
+ } catch (PrivilegedActionException pae) {
+ throw (UnsupportedEncodingException) pae.getCause();
+ }
+ } else {
+ dummy = new String(buffer, enc);
+ }
+ // END S1AS 6179607
+
+ // Save the validated encoding
+ request.setCharacterEncoding(enc);
+
+ }
+
+
+ // START S1AS 4703023
+ /**
+ * Static setter method for the maximum dispatch depth
+ */
+ public static void setMaxDispatchDepth(int depth) {
+ maxDispatchDepth = depth;
+ }
+
+
+ public static int getMaxDispatchDepth(){
+ return maxDispatchDepth;
+ }
+
+ /**
+ * Increment the depth of application dispatch
+ */
+ public int incrementDispatchDepth() {
+ return ++dispatchDepth;
+ }
+
+
+ /**
+ * Decrement the depth of application dispatch
+ */
+ public int decrementDispatchDepth() {
+ return --dispatchDepth;
+ }
+
+
+ /**
+ * Check if the application dispatching has reached the maximum
+ */
+ public boolean isMaxDispatchDepthReached() {
+ return dispatchDepth > maxDispatchDepth;
+ }
+ // END S1AS 4703023
+
+
+ // ---------------------------------------------------- HttpRequest
Methods
+
+
+ /**
+ * Add a Cookie to the set of Cookies associated with this Request.
+ *
+ * @param cookie The new cookie
+ */
+ public void addCookie(Cookie cookie) {
+
+ // For compatibility only
+ if (!cookiesParsed)
+ parseCookies();
+
+ int size = 0;
+ if (cookie != null) {
+ size = cookies.length;
+ }
+
+ Cookie[] newCookies = new Cookie[size + 1];
+ for (int i = 0; i < size; i++) {
+ newCookies[i] = cookies[i];
+ }
+ newCookies[size] = cookie;
+
+ cookies = newCookies;
+
+ }
+
+
+ /**
+ * Add a Header to the set of Headers associated with this Request.
+ *
+ * @param name The new header name
+ * @param value The new header value
+ */
+ public void addHeader(String name, String value) {
+ // Not used
+ }
+
+
+ /**
+ * Add a Locale to the set of preferred Locales for this Request. The
+ * first added Locale will be the first one returned by getLocales().
+ *
+ * @param locale The new preferred Locale
+ */
+ public void addLocale(Locale locale) {
+ locales.add(locale);
+ }
+
+
+ /**
+ * Add a parameter name and corresponding set of values to this
Request.
+ * (This is used when restoring the original request on a form based
+ * login).
+ *
+ * @param name Name of this request parameter
+ * @param values Corresponding values for this request parameter
+ */
+ public void addParameter(String name, String values[]) {
+ request.getParameters().addParameterValues(name, values);
+ }
+
+
+ /**
+ * Clear the collection of Cookies associated with this Request.
+ */
+ public void clearCookies() {
+ cookiesParsed = true;
+ cookies = null;
+ }
+
+
+ /**
+ * Clear the collection of Headers associated with this Request.
+ */
+ public void clearHeaders() {
+ // Not used
+ }
+
+
+ /**
+ * Clear the collection of Locales associated with this Request.
+ */
+ public void clearLocales() {
+ locales.clear();
+ }
+
+
+ /**
+ * Clear the collection of parameters associated with this Request.
+ */
+ public void clearParameters() {
+ // Not used
+ }
+
+
+ /**
+ * Set the authentication type used for this request, if any; otherwise
+ * set the type to <code>null</code>. Typical values are "BASIC",
+ * "DIGEST", or "SSL".
+ *
+ * @param type The authentication type used
+ */
+ public void setAuthType(String type) {
+ this.authType = type;
+ }
+
+
+ /**
+ * Set the HTTP request method used for this Request.
+ *
+ * @param method The request method
+ */
+ public void setMethod(String method) {
+ // Not used
+ }
+
+
+ /**
+ * Set the query string for this Request. This will normally be called
+ * by the HTTP Connector, when it parses the request headers.
+ *
+ * @param query The query string
+ */
+ public void setQueryString(String query) {
+ // Not used
+ }
+
+
+ /**
+ * Set the unparsed request URI for this Request. This will
normally be
+ * called by the HTTP Connector, when it parses the request headers.
+ *
+ * @param uri The request URI
+ */
+ public void setRequestURI(String uri) {
+ // Not used
+ }
+
+
+ /**
+ * Set the decoded request URI.
+ *
+ * @param uri The decoded request URI
+ */
+ public void setDecodedRequestURI(String uri) {
+ // Not used
+ }
+
+
+ /**
+ * Get the decoded request URI.
+ *
+ * @return the URL decoded request URI
+ */
+ public String getDecodedRequestURI() {
+ return (request.decodedURI().toString());
+ }
+
+
+ /**
+ * Get the decoded request URI.
+ *
+ * @return the URL decoded request URI
+ */
+ public MessageBytes getDecodedRequestURIMB() {
+ return (request.decodedURI());
+ }
+
+
+ /**
+ * Set the Principal who has been authenticated for this Request. This
+ * value is also used to calculate the value to be returned by the
+ * <code>getRemoteUser()</code> method.
+ *
+ * @param principal The user Principal
+ */
+ public void setUserPrincipal(Principal principal) {
+ this.userPrincipal = principal;
+ }
+
+
+ // --------------------------------------------- HttpServletRequest
Methods
+
+
+ /**
+ * Return the authentication type used for this Request.
+ */
+ public String getAuthType() {
+ return (authType);
+ }
+
+
+ /**
+ * Return the set of Cookies received with this Request.
+ */
+ public Cookie[] getCookies() {
+
+ if (!cookiesParsed)
+ parseCookies();
+
+ return cookies;
+
+ }
+
+
+ /**
+ * Set the set of cookies recieved with this Request.
+ */
+ public void setCookies(Cookie[] cookies) {
+
+ this.cookies = cookies;
+
+ }
+
+
+ /**
+ * Return the value of the specified date header, if any; otherwise
+ * return -1.
+ *
+ * @param name Name of the requested date header
+ *
+ * @exception IllegalArgumentException if the specified header value
+ * cannot be converted to a date
+ */
+ public long getDateHeader(String name) {
+
+ String value = getHeader(name);
+ if (value == null)
+ return (-1L);
+
+ // Attempt to convert the date header in a variety of formats
+ long result = FastHttpDateFormat.parseDate(value, formats);
+ if (result != (-1L)) {
+ return result;
+ }
+ throw new IllegalArgumentException(value);
+
+ }
+
+
+ /**
+ * Return the first value of the specified header, if any; otherwise,
+ * return <code>null</code>
+ *
+ * @param name Name of the requested header
+ */
+ public String getHeader(String name) {
+ return request.getHeader(name);
+ }
+
+
+ /**
+ * Return all of the values of the specified header, if any; otherwise,
+ * return an empty enumeration.
+ *
+ * @param name Name of the requested header
+ */
+ public Enumeration getHeaders(String name) {
+ return request.getMimeHeaders().values(name);
+ }
+
+
+ /**
+ * Return the names of all headers received with this request.
+ */
+ public Enumeration getHeaderNames() {
+ return request.getMimeHeaders().names();
+ }
+
+
+ /**
+ * Return the value of the specified header as an integer, or -1 if
there
+ * is no such header for this request.
+ *
+ * @param name Name of the requested header
+ *
+ * @exception IllegalArgumentException if the specified header value
+ * cannot be converted to an integer
+ */
+ public int getIntHeader(String name) {
+
+ String value = getHeader(name);
+ if (value == null) {
+ return (-1);
+ } else {
+ return (Integer.parseInt(value));
+ }
+
+ }
+
+
+ /**
+ * Return the HTTP request method used in this Request.
+ */
+ public String getMethod() {
+ return request.method().toString();
+ }
+
+
+ /**
+ * Return the query string associated with this request.
+ */
+ public String getQueryString() {
+ String queryString = request.queryString().toString();
+
+ if (queryString == null || queryString.equals("")) {
+ return (null);
+ } else {
+ return queryString;
+ }
+ }
+
+
+ /**
+ * Return the name of the remote user that has been authenticated
+ * for this Request.
+ */
+ public String getRemoteUser() {
+
+ if (userPrincipal != null) {
+ return (userPrincipal.getName());
+ } else {
+ return (null);
+ }
+
+ }
+
+
+ /**
+ * Return the session identifier included in this request, if any.
+ */
+ public String getRequestedSessionId() {
+ return (requestedSessionId);
+ }
+
+
+ /**
+ * Return the request URI for this request.
+ */
+ public String getRequestURI() {
+ return request.requestURI().toString();
+ }
+
+
+ /**
+ * Reconstructs the URL the client used to make the request.
+ * The returned URL contains a protocol, server name, port
+ * number, and server path, but it does not include query
+ * string parameters.
+ * <p>
+ * Because this method returns a <code>StringBuffer</code>,
+ * not a <code>String</code>, you can modify the URL easily,
+ * for example, to append query parameters.
+ * <p>
+ * This method is useful for creating redirect messages and
+ * for reporting errors.
+ *
+ * @return A <code>StringBuffer</code> object containing the
+ * reconstructed URL
+ */
+ public StringBuffer getRequestURL() {
+
+ StringBuffer url = new StringBuffer();
+ String scheme = getScheme();
+ int port = getServerPort();
+ if (port < 0)
+ port = 80; // Work around java.net.URL bug
+
+ url.append(scheme);
+ url.append("://");
+ url.append(getServerName());
+ if ((scheme.equals("http") && (port != 80))
+ || (scheme.equals("https") && (port != 443))) {
+ url.append(':');
+ url.append(port);
+ }
+ url.append(getRequestURI());
+
+ return (url);
+
+ }
+
+ /**
+ * Return the principal that has been authenticated for this Request.
+ */
+ public Principal getUserPrincipal() {
+ return (userPrincipal);
+ }
+
+
+ /**
+ * Parse cookies.
+ */
+ protected void parseCookies() {
+
+ cookiesParsed = true;
+
+ Cookies serverCookies = request.getCookies();
+ int count = serverCookies.getCookieCount();
+ if (count <= 0)
+ return;
+
+ cookies = new Cookie[count];
+
+ int idx=0;
+ for (int i = 0; i < count; i++) {
+ ServerCookie scookie = serverCookies.getCookie(i);
+ try {
+ Cookie cookie = new Cookie(scookie.getName().toString(),
+ scookie.getValue().toString());
+ cookie.setPath(scookie.getPath().toString());
+ cookie.setVersion(scookie.getVersion());
+ String domain = scookie.getDomain().toString();
+ if (domain != null) {
+ cookie.setDomain(scookie.getDomain().toString());
+ }
+ cookies[idx++] = cookie;
+ } catch(IllegalArgumentException e) {
+ ; // Ignore bad cookie.
+ }
+ }
+ if( idx < count ) {
+ Cookie [] ncookies = new Cookie[idx];
+ System.arraycopy(cookies, 0, ncookies, 0, idx);
+ cookies = ncookies;
+ }
+
+ }
+
+
+ /**
+ * Parse request parameters.
+ */
+ protected void parseRequestParameters() {
+
+ /* SJSAS 4936855
+ requestParametersParsed = true;
+ */
+
+ Parameters parameters = request.getParameters();
+
+ // getCharacterEncoding() may have been overridden to search for
+ // hidden form field containing request encoding
+ String enc = getCharacterEncoding();
+ // START SJSAS 4936855
+ // Delay updating requestParametersParsed to TRUE until
+ // after getCharacterEncoding() has been called, because
+ // getCharacterEncoding() may cause setCharacterEncoding() to be
+ // called, and the latter will ignore the specified encoding if
+ // requestParametersParsed is TRUE
+ requestParametersParsed = true;
+ // END SJSAS 4936855
+ if (enc != null) {
+ parameters.setEncoding(enc);
+ parameters.setQueryStringEncoding(enc);
+ } else {
+ parameters.setEncoding
+ (com.sun.grizzly.tcp.Constants.DEFAULT_CHARACTER_ENCODING);
+ parameters.setQueryStringEncoding
+ (com.sun.grizzly.tcp.Constants.DEFAULT_CHARACTER_ENCODING);
+ }
+
+ parameters.handleQueryParameters();
+
+ if (usingInputStream || usingReader)
+ return;
+
+ if (!getMethod().equalsIgnoreCase("POST"))
+ return;
+
+ String contentType = getContentType();
+ if (contentType == null)
+ contentType = "";
+ int semicolon = contentType.indexOf(';');
+ if (semicolon >= 0) {
+ contentType = contentType.substring(0, semicolon).trim();
+ } else {
+ contentType = contentType.trim();
+ }
+ if (!("application/x-www-form-urlencoded".equals(contentType)))
+ return;
+
+ int len = getContentLength();
+
+ if (len > 0) {
+ try {
+ /* SJSAS 6346738
+ byte[] formData = null;
+ if (len < CACHED_POST_LEN) {
+ if (postData == null)
+ postData = new byte[CACHED_POST_LEN];
+ formData = postData;
+ } else {
+ formData = new byte[len];
+ }
+ int actualLen = readPostBody(formData, len);
+ if (actualLen == len) {
+ parameters.processParameters(formData, 0, len);
+ }
+ */
+ // START SJSAS 6346738
+ byte[] formData = getPostBody();
+ if (formData != null) {
+ parameters.processParameters(formData, 0, len);
+ }
+ // END SJSAS 6346738
+ } catch (Throwable t) {
+ ; // Ignore
+ }
+ }
+
+ }
+
+
+ // START SJSAS 6346738
+ /**
+ * Gets the POST body of this request.
+ *
+ * @return The POST body of this request
+ */
+ protected byte[] getPostBody() throws IOException {
+
+ int len = getContentLength();
+ byte[] formData = null;
+
+ if (len < CACHED_POST_LEN) {
+ if (postData == null)
+ postData = new byte[CACHED_POST_LEN];
+ formData = postData;
+ } else {
+ formData = new byte[len];
+ }
+ int actualLen = readPostBody(formData, len);
+ if (actualLen == len) {
+ return formData;
+ }
+
+ return null;
+ }
+ // END SJSAS 6346738
+
+
+ /**
+ * Read post body in an array.
+ */
+ protected int readPostBody(byte body[], int len)
+ throws IOException {
+
+ int offset = 0;
+ do {
+ int inputLen = getStream().read(body, offset, len - offset);
+ if (inputLen <= 0) {
+ return offset;
+ }
+ offset += inputLen;
+ } while ((len - offset) > 0);
+ return len;
+
+ }
+
+
+ /**
+ * Parse request locales.
+ */
+ protected void parseLocales() {
+
+ localesParsed = true;
+
+ Enumeration values = getHeaders("accept-language");
+
+ while (values.hasMoreElements()) {
+ String value = values.nextElement().toString();
+ parseLocalesHeader(value);
+ }
+
+ }
+
+
+ /**
+ * Parse accept-language header value.
+ */
+ protected void parseLocalesHeader(String value) {
+
+ // Store the accumulated languages that have been requested in
+ // a local collection, sorted by the quality value (so we can
+ // add Locales in descending order). The values will be ArrayLists
+ // containing the corresponding Locales to be added
+ TreeMap locales = new TreeMap();
+
+ // Preprocess the value to remove all whitespace
+ int white = value.indexOf(' ');
+ if (white < 0)
+ white = value.indexOf('\t');
+ if (white >= 0) {
+ StringBuffer sb = new StringBuffer();
+ int len = value.length();
+ for (int i = 0; i < len; i++) {
+ char ch = value.charAt(i);
+ if ((ch != ' ') && (ch != '\t'))
+ sb.append(ch);
+ }
+ value = sb.toString();
+ }
+
+ // Process each comma-delimited language specification
+ parser.setString(value); // ASSERT: parser is available
to us
+ int length = parser.getLength();
+ while (true) {
+
+ // Extract the next comma-delimited entry
+ int start = parser.getIndex();
+ if (start >= length)
+ break;
+ int end = parser.findChar(',');
+ String entry = parser.extract(start, end).trim();
+ parser.advance(); // For the following entry
+
+ // Extract the quality factor for this entry
+ double quality = 1.0;
+ int semi = entry.indexOf(";q=");
+ if (semi >= 0) {
+ try {
+ quality = Double.parseDouble(entry.substring(semi +
3));
+ } catch (NumberFormatException e) {
+ quality = 0.0;
+ }
+ entry = entry.substring(0, semi);
+ }
+
+ // Skip entries we are not going to keep track of
+ if (quality < 0.00005)
+ continue; // Zero (or effectively zero) quality
factors
+ if ("*".equals(entry))
+ continue; // FIXME - "*" entries are not handled
+
+ // Extract the language and country for this entry
+ String language = null;
+ String country = null;
+ String variant = null;
+ int dash = entry.indexOf('-');
+ if (dash < 0) {
+ language = entry;
+ country = "";
+ variant = "";
+ } else {
+ language = entry.substring(0, dash);
+ country = entry.substring(dash + 1);
+ int vDash = country.indexOf('-');
+ if (vDash > 0) {
+ String cTemp = country.substring(0, vDash);
+ variant = country.substring(vDash + 1);
+ country = cTemp;
+ } else {
+ variant = "";
+ }
+ }
+
+ // Add a new Locale to the list of Locales for this quality
level
+ Locale locale = new Locale(language, country, variant);
+ Double key = new Double(-quality); // Reverse the order
+ ArrayList values = (ArrayList) locales.get(key);
+ if (values == null) {
+ values = new ArrayList();
+ locales.put(key, values);
+ }
+ values.add(locale);
+
+ }
+
+ // Process the quality values in highest->lowest order (due to
+ // negating the Double value when creating the key)
+ Iterator keys = locales.keySet().iterator();
+ while (keys.hasNext()) {
+ Double key = (Double) keys.next();
+ ArrayList list = (ArrayList) locales.get(key);
+ Iterator values = list.iterator();
+ while (values.hasNext()) {
+ Locale locale = (Locale) values.next();
+ addLocale(locale);
+ }
+ }
+
+ }
+
+ // START SJSAS 6346226
+ /**
+ * Parses the value of the JROUTE cookie, if present.
+ */
+ void parseJrouteCookie() {
+
+ Cookies serverCookies = request.getCookies();
+ int count = serverCookies.getCookieCount();
+ if (count <= 0) {
+ return;
+ }
+
+ for (int i=0; i<count; i++) {
+ ServerCookie scookie = serverCookies.getCookie(i);
+ if (scookie.getName().equals(Constants.JROUTE_COOKIE)) {
+ setJrouteId(scookie.getValue().toString());
+ break;
+ }
+ }
+ }
+
+ /**
+ * Sets the jroute id of this request.
+ *
+ * @param jrouteId The jroute id
+ */
+ void setJrouteId(String jrouteId) {
+ this.jrouteId = jrouteId;
+ }
+
+ /**
+ * Gets the jroute id of this request, which may have been
+ * sent as a separate <code>JROUTE</code> cookie or appended to the
+ * session identifier encoded in the URI (if cookies have been
disabled).
+ *
+ * @return The jroute id of this request, or null if this request
does not
+ * carry any jroute id
+ */
+ public String getJrouteId() {
+ return jrouteId;
+ }
+
+ // END CR 6309511
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyResponse.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyResponse.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyResponse.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,1368 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+
+package com.sun.grizzly.tcp.http11;
+
+import com.sun.grizzly.tcp.Response;
+import com.sun.grizzly.util.buf.CharChunk;
+import com.sun.grizzly.util.buf.DateTool;
+import com.sun.grizzly.util.buf.UEncoder;
+import com.sun.grizzly.util.http.Cookie;
+import com.sun.grizzly.util.http.FastHttpDateFormat;
+import com.sun.grizzly.util.http.MimeHeaders;
+import com.sun.grizzly.util.http.ServerCookie;
+import com.sun.grizzly.util.res.StringManager;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.Vector;
+
+/**
+ * Wrapper object for the Coyote response.
+ *
+ * @author Remy Maucherat
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.2 $ $Date: 2006/11/02 20:01:44 $
+ */
+
+public class GrizzlyResponse {
+
+
+ // -----------------------------------------------------------
Constructors
+
+ public GrizzlyResponse() {
+ this(false,false);
+ }
+
+
+ public GrizzlyResponse(boolean chunkingDisabled, boolean
cacheEnabled) {
+ outputBuffer = new GrizzlyOutputBuffer(chunkingDisabled);
+ outputStream = new GrizzlyOutputStream(outputBuffer);
+ writer = new GrizzlyWriter(outputBuffer);
+
+ urlEncoder.addSafeCharacter('/');
+
+ this.cacheEnabled = cacheEnabled;
+ }
+ // END OF SJSAS 6231069
+
+ // ----------------------------------------------------- Instance
Variables
+ private boolean cacheEnabled = false;
+
+
+ // BEGIN S1AS 4878272
+ private String detailErrorMsg;
+ // END S1AS 4878272
+
+
+ /**
+ * The date format we will use for creating date headers.
+ */
+ protected SimpleDateFormat format = null;
+
+
+ /**
+ * Descriptive information about this Response implementation.
+ */
+ protected static final String info =
+ "com.sun.grizzly.util.tcp.GrizzlyResponse/1.0";
+
+
+ /**
+ * The string manager for this package.
+ */
+ protected static StringManager sm =
+ StringManager.getManager(Constants.Package);
+
+
+ // -------------------------------------------------------------
Properties
+ /**
+ * The request with which this response is associated.
+ */
+ protected GrizzlyRequest request = null;
+
+
+ /**
+ * Return the Request with which this Response is associated.
+ */
+ public GrizzlyRequest getRequest() {
+ return (this.request);
+ }
+
+ /**
+ * Set the Request with which this Response is associated.
+ *
+ * @param request The new associated request
+ */
+ public void setRequest(GrizzlyRequest request) {
+ this.request = request;
+ }
+
+ /**
+ * Coyote response.
+ */
+ protected Response coyoteResponse;
+
+ /**
+ * Set the Coyote response.
+ *
+ * @param response The Coyote response
+ */
+ public void setResponse(Response coyoteResponse) {
+ this.coyoteResponse = coyoteResponse;
+ outputBuffer.setResponse(coyoteResponse);
+ }
+
+ /**
+ * Get the Coyote response.
+ */
+ public Response getResponse() {
+ return (coyoteResponse);
+ }
+
+
+ /**
+ * The associated output buffer.
+ */
+ // START OF SJSAS 6231069
+ //protected OutputBuffer outputBuffer = new OutputBuffer();
+ protected GrizzlyOutputBuffer outputBuffer;
+ // END OF SJSAS 6231069
+
+ /**
+ * The associated output stream.
+ */
+ // START OF SJSAS 6231069
+ /*protected GrizzlyOutputStream outputStream =
+ new GrizzlyOutputStream(outputBuffer);*/
+ protected GrizzlyOutputStream outputStream;
+ // END OF SJSAS 6231069
+
+ /**
+ * The associated writer.
+ */
+ // START OF SJSAS 6231069
+ // protected GrizzlyWriter writer = new GrizzlyWriter(outputBuffer);
+ protected GrizzlyWriter writer;
+ // END OF SJSAS 6231069
+
+
+ /**
+ * The application commit flag.
+ */
+ protected boolean appCommitted = false;
+
+
+ /**
+ * The included flag.
+ */
+ protected boolean included = false;
+
+
+ /**
+ * The characterEncoding flag
+ */
+ private boolean isCharacterEncodingSet = false;
+
+ /**
+ * The contextType flag
+ */
+ private boolean isContentTypeSet = false;
+
+
+ /**
+ * The error flag.
+ */
+ protected boolean error = false;
+
+
+ /**
+ * The set of Cookies associated with this Response.
+ */
+ protected ArrayList cookies = new ArrayList();
+
+
+ /**
+ * Using output stream flag.
+ */
+ protected boolean usingOutputStream = false;
+
+
+ /**
+ * Using writer flag.
+ */
+ protected boolean usingWriter = false;
+
+
+ /**
+ * URL encoder.
+ */
+ protected UEncoder urlEncoder = new UEncoder();
+
+
+ /**
+ * Recyclable buffer to hold the redirect URL.
+ */
+ protected CharChunk redirectURLCC = new CharChunk();
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Release all object references, and initialize instance variables, in
+ * preparation for reuse of this object.
+ */
+ public void recycle() {
+
+ outputBuffer.recycle();
+ usingOutputStream = false;
+ usingWriter = false;
+ appCommitted = false;
+ included = false;
+ error = false;
+ isContentTypeSet = false;
+ isCharacterEncodingSet = false;
+ detailErrorMsg = null;
+
+ cookies.clear();
+
+ if (System.getSecurityManager() != null) {
+ if (outputStream != null) {
+ outputStream.clear();
+ outputStream = null;
+ }
+ if (writer != null) {
+ writer.clear();
+ writer = null;
+ }
+ } else {
+ writer.recycle();
+ }
+ cacheEnabled = false;
+
+ }
+
+
+ // ------------------------------------------------------- Response
Methods
+
+
+ /**
+ * Return the number of bytes actually written to the output stream.
+ */
+ public int getContentCount() {
+ return outputBuffer.getContentWritten();
+ }
+
+
+ /**
+ * Set the application commit flag.
+ *
+ * @param appCommitted The new application committed flag value
+ */
+ public void setAppCommitted(boolean appCommitted) {
+ this.appCommitted = appCommitted;
+ }
+
+
+ /**
+ * Application commit flag accessor.
+ */
+ public boolean isAppCommitted() {
+ return (this.appCommitted || isCommitted() || isSuspended()
+ || ((getContentLength() > 0)
+ && (getContentCount() >= getContentLength())));
+ }
+
+
+ /**
+ * Return the "processing inside an include" flag.
+ */
+ public boolean getIncluded() {
+ return included;
+ }
+
+
+ /**
+ * Set the "processing inside an include" flag.
+ *
+ * @param included <code>true</code> if we are currently inside a
+ * RequestDispatcher.include(), else <code>false</code>
+ */
+ public void setIncluded(boolean included) {
+ this.included = included;
+ }
+
+
+ /**
+ * Return descriptive information about this Response
implementation and
+ * the corresponding version number, in the format
+ * <code>&lt;description&gt;/&lt;version&gt;</code>.
+ */
+ public String getInfo() {
+ return (info);
+ }
+
+ /**
+ * Return the output stream associated with this Response.
+ */
+ public OutputStream getStream() {
+ if (outputStream == null) {
+ outputStream = new GrizzlyOutputStream(outputBuffer);
+ }
+ return outputStream;
+ }
+
+
+ /**
+ * Set the output stream associated with this Response.
+ *
+ * @param stream The new output stream
+ */
+ public void setStream(OutputStream stream) {
+ // This method is evil
+ }
+
+
+ /**
+ * Set the suspended flag.
+ *
+ * @param suspended The new suspended flag value
+ */
+ public void setSuspended(boolean suspended) {
+ outputBuffer.setSuspended(suspended);
+ }
+
+
+ /**
+ * Suspended flag accessor.
+ */
+ public boolean isSuspended() {
+ return outputBuffer.isSuspended();
+ }
+
+
+ /**
+ * Set the error flag.
+ */
+ public void setError() {
+ error = true;
+ }
+
+
+ /**
+ * Error flag accessor.
+ */
+ public boolean isError() {
+ return error;
+ }
+
+
+ // BEGIN S1AS 4878272
+ /**
+ * Sets detail error message.
+ *
+ * @param message detail error message
+ */
+ public void setDetailMessage(String message) {
+ this.detailErrorMsg = message;
+ }
+
+
+ /**
+ * Gets detail error message.
+ *
+ * @return the detail error message
+ */
+ public String getDetailMessage() {
+ return this.detailErrorMsg;
+ }
+ // END S1AS 4878272
+
+
+ /**
+ * Create and return a ServletOutputStream to write the content
+ * associated with this Response.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ public GrizzlyOutputStream createOutputStream()
+ throws IOException {
+ // Probably useless
+ if (outputStream == null) {
+ outputStream = new GrizzlyOutputStream(outputBuffer);
+ }
+ return outputStream;
+ }
+
+
+ /**
+ * Perform whatever actions are required to flush and close the output
+ * stream or writer, in a single operation.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ public void finishResponse()
+ throws IOException {
+ // Writing leftover bytes
+ try {
+ outputBuffer.close();
+ } catch(IOException e) {
+ ;
+ } catch(Throwable t) {
+ }
+ }
+
+
+ /**
+ * Return the content length that was set or calculated for this
Response.
+ */
+ public int getContentLength() {
+ return (coyoteResponse.getContentLength());
+ }
+
+
+ /**
+ * Return the content type that was set or calculated for this
response,
+ * or <code>null</code> if no content type was set.
+ */
+ public String getContentType() {
+ return (coyoteResponse.getContentType());
+ }
+
+
+ /**
+ * Return a PrintWriter that can be used to render error messages,
+ * regardless of whether a stream or writer has already been acquired.
+ *
+ * @return Writer which can be used for error reports. If the
response is
+ * not an error report returned using sendError or triggered by an
+ * unexpected exception thrown during the servlet processing
+ * (and only in that case), null will be returned if the response
stream
+ * has already been used.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ public PrintWriter getReporter() throws IOException {
+ if (outputBuffer.isNew()) {
+ outputBuffer.checkConverter();
+ if (writer == null) {
+ writer = new GrizzlyWriter(outputBuffer);
+ }
+ return writer;
+ } else {
+ return null;
+ }
+ }
+
+
+ // ------------------------------------------------ ServletResponse
Methods
+
+
+ /**
+ * Flush the buffer and commit this response.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ public void flushBuffer()
+ throws IOException {
+ outputBuffer.flush();
+ }
+
+
+ /**
+ * Return the actual buffer size used for this Response.
+ */
+ public int getBufferSize() {
+ return outputBuffer.getBufferSize();
+ }
+
+
+ /**
+ * Return the character encoding used for this Response.
+ */
+ public String getCharacterEncoding() {
+ return (coyoteResponse.getCharacterEncoding());
+ }
+
+
+ /**
+ * Return the servlet output stream associated with this Response.
+ *
+ * @exception IllegalStateException if <code>getWriter</code> has
+ * already been called for this response
+ * @exception IOException if an input/output error occurs
+ */
+ public GrizzlyOutputStream getOutputStream()
+ throws IOException {
+
+ if (usingWriter)
+ throw new IllegalStateException
+ (sm.getString("coyoteResponse.getOutputStream.ise"));
+
+ usingOutputStream = true;
+ if (outputStream == null) {
+ outputStream = new GrizzlyOutputStream(outputBuffer);
+ }
+ return outputStream;
+
+ }
+
+
+ /**
+ * Return the Locale assigned to this response.
+ */
+ public Locale getLocale() {
+ return (coyoteResponse.getLocale());
+ }
+
+
+ /**
+ * Return the writer associated with this Response.
+ *
+ * @exception IllegalStateException if <code>getOutputStream</code> has
+ * already been called for this response
+ * @exception IOException if an input/output error occurs
+ */
+ public PrintWriter getWriter()
+ throws IOException {
+
+ if (usingOutputStream)
+ throw new IllegalStateException
+ (sm.getString("coyoteResponse.getWriter.ise"));
+
+ /*
+ * If the response's character encoding has not been specified as
+ * described in <code>getCharacterEncoding</code> (i.e., the method
+ * just returns the default value <code>ISO-8859-1</code>),
+ * <code>getWriter</code> updates it to <code>ISO-8859-1</code>
+ * (with the effect that a subsequent call to getContentType() will
+ * include a charset=ISO-8859-1 component which will also be
+ * reflected in the Content-Type response header, thereby
satisfying
+ * the Servlet spec requirement that containers must
communicate the
+ * character encoding used for the servlet response's writer to the
+ * client).
+ */
+ setCharacterEncoding(getCharacterEncoding());
+
+ usingWriter = true;
+ outputBuffer.checkConverter();
+ if (writer == null) {
+ writer = new GrizzlyWriter(outputBuffer);
+ }
+ return writer;
+
+ }
+
+
+ /**
+ * Has the output of this response already been committed?
+ */
+ public boolean isCommitted() {
+ return (coyoteResponse.isCommitted());
+ }
+
+
+ /**
+ * Clear any content written to the buffer.
+ *
+ * @exception IllegalStateException if this response has already
+ * been committed
+ */
+ public void reset() {
+
+ if (included)
+ return; // Ignore any call from an included servlet
+
+ coyoteResponse.reset();
+ outputBuffer.reset();
+ }
+
+
+ /**
+ * Reset the data buffer but not any status or header information.
+ *
+ * @exception IllegalStateException if the response has already
+ * been committed
+ */
+ public void resetBuffer() {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (sm.getString("coyoteResponse.resetBuffer.ise"));
+
+ outputBuffer.reset();
+
+ }
+
+
+ /**
+ * Set the buffer size to be used for this Response.
+ *
+ * @param size The new buffer size
+ *
+ * @exception IllegalStateException if this method is called after
+ * output has been committed for this response
+ */
+ public void setBufferSize(int size) {
+
+ if (isCommitted() || !outputBuffer.isNew())
+ throw new IllegalStateException
+ (sm.getString("coyoteResponse.setBufferSize.ise"));
+
+ outputBuffer.setBufferSize(size);
+
+ }
+
+
+ /**
+ * Set the content length (in bytes) for this Response.
+ *
+ * @param length The new content length
+ */
+ public void setContentLength(int length) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ if (usingWriter)
+ return;
+
+ coyoteResponse.setContentLength(length);
+
+ }
+
+
+ /**
+ * Set the content type for this Response.
+ *
+ * @param type The new content type
+ */
+ public void setContentType(String type) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ // Ignore charset if getWriter() has already been called
+ if (usingWriter) {
+ if (type != null) {
+ int index = type.indexOf(";");
+ if (index != -1) {
+ type = type.substring(0, index);
+ }
+ }
+ }
+
+ coyoteResponse.setContentType(type);
+
+ // Check to see if content type contains charset
+ if (type != null) {
+ int index = type.indexOf(";");
+ if (index != -1) {
+ int len = type.length();
+ index++;
+ while (index < len &&
Character.isSpace(type.charAt(index))) {
+ index++;
+ }
+ if (index+7 < len
+ && type.charAt(index) == 'c'
+ && type.charAt(index+1) == 'h'
+ && type.charAt(index+2) == 'a'
+ && type.charAt(index+3) == 'r'
+ && type.charAt(index+4) == 's'
+ && type.charAt(index+5) == 'e'
+ && type.charAt(index+6) == 't'
+ && type.charAt(index+7) == '=') {
+ isCharacterEncodingSet = true;
+ }
+ }
+ }
+
+ isContentTypeSet = true;
+ }
+
+
+ /*
+ * Overrides the name of the character encoding used in the body
+ * of the request. This method must be called prior to reading
+ * request parameters or reading input using getReader().
+ *
+ * @param charset String containing the name of the chararacter
encoding.
+ */
+ public void setCharacterEncoding(String charset) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ // Ignore any call made after the getWriter has been invoked
+ // The default should be used
+ if (usingWriter)
+ return;
+
+ coyoteResponse.setCharacterEncoding(charset);
+ isCharacterEncodingSet = true;
+ }
+
+
+
+ /**
+ * Set the Locale that is appropriate for this response, including
+ * setting the appropriate character encoding.
+ *
+ * @param locale The new locale
+ */
+ public void setLocale(Locale locale) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ coyoteResponse.setLocale(locale);
+
+ // Ignore any call made after the getWriter has been invoked.
+ // The default should be used
+ if (usingWriter)
+ return;
+
+ if (isCharacterEncodingSet) {
+ return;
+ }
+
+ }
+
+
+ // --------------------------------------------------- HttpResponse
Methods
+
+
+ /**
+ * Return an array of all cookies set for this response, or
+ * a zero-length array if no cookies have been set.
+ */
+ public Cookie[] getCookies() {
+ return ((Cookie[]) cookies.toArray(new Cookie[cookies.size()]));
+ }
+
+
+ /**
+ * Return the value for the specified header, or <code>null</code>
if this
+ * header has not been set. If more than one value was added for this
+ * name, only the first is returned; use getHeaderValues() to
retrieve all
+ * of them.
+ *
+ * @param name Header name to look up
+ */
+ public String getHeader(String name) {
+ return coyoteResponse.getMimeHeaders().getHeader(name);
+ }
+
+
+ /**
+ * Return an array of all the header names set for this response, or
+ * a zero-length array if no headers have been set.
+ */
+ public String[] getHeaderNames() {
+
+ MimeHeaders headers = coyoteResponse.getMimeHeaders();
+ int n = headers.size();
+ String[] result = new String[n];
+ for (int i = 0; i < n; i++) {
+ result[i] = headers.getName(i).toString();
+ }
+ return result;
+
+ }
+
+
+ /**
+ * Return an array of all the header values associated with the
+ * specified header name, or an zero-length array if there are no such
+ * header values.
+ *
+ * @param name Header name to look up
+ */
+ public String[] getHeaderValues(String name) {
+
+ Enumeration e = coyoteResponse.getMimeHeaders().values(name);
+ Vector result = new Vector();
+ while (e.hasMoreElements()) {
+ result.addElement(e.nextElement());
+ }
+ String[] resultArray = new String[result.size()];
+ result.copyInto(resultArray);
+ return resultArray;
+
+ }
+
+
+ /**
+ * Return the error message that was set with <code>sendError()</code>
+ * for this Response.
+ */
+ public String getMessage() {
+ return coyoteResponse.getMessage();
+ }
+
+
+ /**
+ * Return the HTTP status code associated with this Response.
+ */
+ public int getStatus() {
+ return coyoteResponse.getStatus();
+ }
+
+
+ /**
+ * Reset this response, and specify the values for the HTTP status code
+ * and corresponding message.
+ *
+ * @exception IllegalStateException if this response has already been
+ * committed
+ */
+ public void reset(int status, String message) {
+ reset();
+ setStatus(status, message);
+ }
+
+
+ // -------------------------------------------- HttpServletResponse
Methods
+
+
+ /**
+ * Add the specified Cookie to those that will be included with
+ * this Response.
+ *
+ * @param cookie Cookie to be added
+ */
+ public void addCookie(final Cookie cookie) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ cookies.add(cookie);
+
+ final StringBuffer sb = new StringBuffer();
+ if (System.getSecurityManager() != null) {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run(){
+ ServerCookie.appendCookieValue
+ (sb, cookie.getVersion(), cookie.getName(),
+ cookie.getValue(), cookie.getPath(),
+ cookie.getDomain(), cookie.getComment(),
+ cookie.getMaxAge(), cookie.getSecure());
+ return null;
+ }
+ });
+ } else {
+ ServerCookie.appendCookieValue
+ (sb, cookie.getVersion(), cookie.getName(),
cookie.getValue(),
+ cookie.getPath(), cookie.getDomain(),
cookie.getComment(),
+ cookie.getMaxAge(), cookie.getSecure());
+ }
+
+ // the header name is Set-Cookie for both "old" and v.1 ( RFC2109 )
+ // RFC2965 is not supported by browsers and the Servlet spec
+ // asks for 2109.
+ addHeader("Set-Cookie", sb.toString());
+
+ }
+
+
+ /**
+ * Add the specified date header to the specified value.
+ *
+ * @param name Name of the header to set
+ * @param value Date value to be set
+ */
+ public void addDateHeader(String name, long value) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included) {
+ return;
+ }
+
+ if (format == null) {
+ format = new
SimpleDateFormat(DateTool.HTTP_RESPONSE_DATE_HEADER,
+ Locale.US);
+ format.setTimeZone(TimeZone.getTimeZone("GMT"));
+ }
+
+ addHeader(name, FastHttpDateFormat.formatDate(value, format));
+
+ }
+
+
+ /**
+ * Add the specified header to the specified value.
+ *
+ * @param name Name of the header to set
+ * @param value Value to be set
+ */
+ public void addHeader(String name, String value) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ coyoteResponse.addHeader(name, value);
+
+ }
+
+
+ /**
+ * Add the specified integer header to the specified value.
+ *
+ * @param name Name of the header to set
+ * @param value Integer value to be set
+ */
+ public void addIntHeader(String name, int value) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ addHeader(name, "" + value);
+
+ }
+
+
+ /**
+ * Has the specified header been set already in this response?
+ *
+ * @param name Name of the header to check
+ */
+ public boolean containsHeader(String name) {
+ return coyoteResponse.containsHeader(name);
+ }
+
+
+ /**
+ * Send an acknowledgment of a request.
+ *
+ * @exception IOException if an input/output error occurs
+ */
+ public void sendAcknowledgement()
+ throws IOException {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ coyoteResponse.acknowledge();
+
+ }
+
+
+ /**
+ * Send an error response with the specified status and a
+ * default message.
+ *
+ * @param status HTTP status code to send
+ *
+ * @exception IllegalStateException if this response has
+ * already been committed
+ * @exception IOException if an input/output error occurs
+ */
+ public void sendError(int status)
+ throws IOException {
+ sendError(status, null);
+ }
+
+
+ /**
+ * Send an error response with the specified status and message.
+ *
+ * @param status HTTP status code to send
+ * @param message Corresponding message to send
+ *
+ * @exception IllegalStateException if this response has
+ * already been committed
+ * @exception IOException if an input/output error occurs
+ */
+ public void sendError(int status, String message)
+ throws IOException {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (sm.getString("coyoteResponse.sendError.ise"));
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ setError();
+
+ coyoteResponse.setStatus(status);
+ coyoteResponse.setMessage(message);
+
+ // Clear any data content that has been buffered
+ resetBuffer();
+
+ // Cause the response to be finished (from the application
perspective)
+ setSuspended(true);
+
+ }
+
+
+ /**
+ * Send a temporary redirect to the specified redirect location URL.
+ *
+ * @param location Location URL to redirect to
+ *
+ * @exception IllegalStateException if this response has
+ * already been committed
+ * @exception IOException if an input/output error occurs
+ */
+ public void sendRedirect(String location)
+ throws IOException {
+
+ if (isCommitted())
+ throw new IllegalStateException
+ (sm.getString("coyoteResponse.sendRedirect.ise"));
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ // Clear any data content that has been buffered
+ resetBuffer();
+
+ // Generate a temporary redirect to the specified location
+ try {
+ String absolute;
+ absolute = toAbsolute(location);
+ // END RIMOD 4642650
+ setStatus(200);
+ setHeader("Location", absolute);
+ } catch (IllegalArgumentException e) {
+ setStatus(404);
+ }
+
+ // Cause the response to be finished (from the application
perspective)
+ setSuspended(true);
+
+ }
+
+
+ /**
+ * Set the specified date header to the specified value.
+ *
+ * @param name Name of the header to set
+ * @param value Date value to be set
+ */
+ public void setDateHeader(String name, long value) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included) {
+ return;
+ }
+
+ if (format == null) {
+ format = new
SimpleDateFormat(DateTool.HTTP_RESPONSE_DATE_HEADER,
+ Locale.US);
+ format.setTimeZone(TimeZone.getTimeZone("GMT"));
+ }
+
+ setHeader(name, FastHttpDateFormat.formatDate(value, format));
+
+ }
+
+
+ /**
+ * Set the specified header to the specified value.
+ *
+ * @param name Name of the header to set
+ * @param value Value to be set
+ */
+ public void setHeader(String name, String value) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ coyoteResponse.setHeader(name, value);
+
+ }
+
+
+ /**
+ * Set the specified integer header to the specified value.
+ *
+ * @param name Name of the header to set
+ * @param value Integer value to be set
+ */
+ public void setIntHeader(String name, int value) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ setHeader(name, "" + value);
+
+ }
+
+
+ /**
+ * Set the HTTP status to be returned with this response.
+ *
+ * @param status The new HTTP status
+ */
+ public void setStatus(int status) {
+ setStatus(status, null);
+ }
+
+
+ /**
+ * Set the HTTP status and message to be returned with this response.
+ *
+ * @param status The new HTTP status
+ * @param message The associated text message
+ *
+ * @deprecated As of Version 2.1 of the Java Servlet API, this method
+ * has been deprecated due to the ambiguous meaning of the message
+ * parameter.
+ */
+ public void setStatus(int status, String message) {
+
+ if (isCommitted())
+ return;
+
+ // Ignore any call from an included servlet
+ if (included)
+ return;
+
+ coyoteResponse.setStatus(status);
+ coyoteResponse.setMessage(message);
+
+ }
+
+
+ // ------------------------------------------------------ Protected
Methods
+
+ /**
+ * Convert (if necessary) and return the absolute URL that
represents the
+ * resource referenced by this possibly relative URL. If this URL is
+ * already absolute, return it unchanged.
+ *
+ * @param location URL to be (possibly) converted and then returned
+ *
+ * @exception IllegalArgumentException if a MalformedURLException is
+ * thrown when converting the relative URL to an absolute one
+ */
+ protected String toAbsolute(String location) {
+
+ if (location == null)
+ return (location);
+
+ boolean leadingSlash = location.startsWith("/");
+
+ if (leadingSlash
+ || (!leadingSlash && (location.indexOf("://") == -1))) {
+
+ redirectURLCC.recycle();
+
+ String scheme = request.getScheme();
+
+ String name = request.getServerName();
+ int port = request.getServerPort();
+
+ try {
+ redirectURLCC.append(scheme, 0, scheme.length());
+ redirectURLCC.append("://", 0, 3);
+ redirectURLCC.append(name, 0, name.length());
+ if ((scheme.equals("http") && port != 80)
+ || (scheme.equals("https") && port != 443)) {
+ redirectURLCC.append(':');
+ String portS = port + "";
+ redirectURLCC.append(portS, 0, portS.length());
+ }
+ if (!leadingSlash) {
+ String relativePath = request.getDecodedRequestURI();
+ int pos = relativePath.lastIndexOf('/');
+ relativePath = relativePath.substring(0, pos);
+
+ String encodedURI = null;
+ final String frelativePath = relativePath;
+
+ if (System.getSecurityManager() != null ){
+ try{
+ encodedURI =
(String)AccessController.doPrivileged(
+ new PrivilegedExceptionAction(){

+ public Object run() throws IOException{
+ return
urlEncoder.encodeURL(frelativePath);
+ }
+ });
+ } catch (PrivilegedActionException pae){
+ IllegalArgumentException iae =
+ new IllegalArgumentException(location);
+ iae.initCause(pae.getCause());
+ throw iae;
+ }
+ } else {
+ encodedURI = urlEncoder.encodeURL(relativePath);
+ }
+
+ redirectURLCC.append(encodedURI, 0,
encodedURI.length());
+ redirectURLCC.append('/');
+ }
+ redirectURLCC.append(location, 0, location.length());
+ } catch (IOException e) {
+ IllegalArgumentException iae =
+ new IllegalArgumentException(location);
+ iae.initCause(e);
+ throw iae;
+ }
+
+ return redirectURLCC.toString();
+
+ } else {
+
+ return (location);
+
+ }
+
+ }
+
+
+ /**
+ * Return the specified URL with the specified session identifier
+ * suitably encoded.
+ *
+ * @param url URL to be encoded with the session id
+ * @param sessionId Session id to be included in the encoded URL
+ */
+ protected String toEncoded(String url, String sessionId) {
+
+ if ((url == null) || (sessionId == null))
+ return (url);
+
+ String path = url;
+ String query = "";
+ String anchor = "";
+ int question = url.indexOf('?');
+ if (question >= 0) {
+ path = url.substring(0, question);
+ query = url.substring(question);
+ }
+ int pound = path.indexOf('#');
+ if (pound >= 0) {
+ anchor = path.substring(pound);
+ path = path.substring(0, pound);
+ }
+ StringBuffer sb = new StringBuffer(path);
+ if( sb.length() > 0 ) { // jsessionid can't be first.
+ sb.append(";jsessionid=");
+ sb.append(sessionId);
+ }
+
+ // START SJSAS 6337561
+ String jrouteId = request.getHeader(Constants.PROXY_JROUTE);
+ if (jrouteId != null) {
+ sb.append(":");
+ sb.append(jrouteId);
+ }
+ // END SJSAS 6337561
+
+ sb.append(anchor);
+ sb.append(query);
+ return (sb.toString());
+
+ }
+
+ /**
+ * Is the file cache enabled?
+ */
+ public boolean isCacheEnabled(){
+ return cacheEnabled;
+ }
+
+
+ /**
+ * Enable/disable the cache
+ */
+ public void enableCache(boolean cacheEnabled){
+ this.cacheEnabled = cacheEnabled;
+ outputBuffer.enableCache(cacheEnabled);
+ }
+
+
+ /**
+ * Return the underlying <code>OutputBuffer</code>
+ */
+ public GrizzlyOutputBuffer getOutputBuffer(){
+ return outputBuffer;
+ }
+
+}
+

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyWriter.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyWriter.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/GrizzlyWriter.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,325 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+
+package com.sun.grizzly.tcp.http11;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+
+/**
+ * Coyote implementation of the servlet writer.
+ *
+ * @author Remy Maucherat
+ */
+public class GrizzlyWriter
+ extends PrintWriter {
+
+
+ // --------------------------------------------------------------
Constants
+
+
+ private static final char[] LINE_SEP = { '\r', '\n' };
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ protected GrizzlyOutputBuffer ob;
+ protected boolean error = false;
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ public GrizzlyWriter(GrizzlyOutputBuffer ob) {
+ super(ob);
+ this.ob = ob;
+ }
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Prevent cloning the facade.
+ */
+ @Override
+ protected Object clone()
+ throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+
+ // -------------------------------------------------------- Package
Methods
+
+
+ /**
+ * Clear facade.
+ */
+ void clear() {
+ ob = null;
+ }
+
+ /**
+ * Recycle.
+ */
+ void recycle() {
+ error = false;
+ }
+
+
+ // --------------------------------------------------------- Writer
Methods
+
+
+ @Override
+ public void flush() {
+
+ if (error)
+ return;
+
+ try {
+ ob.flush();
+ } catch (IOException e) {
+ error = true;
+ }
+
+ }
+
+ @Override
+ public void close() {
+
+ // We don't close the PrintWriter - super() is not called,
+ // so the stream can be reused. We close ob.
+ try {
+ ob.close();
+ } catch (IOException ex ) {
+ ;
+ }
+ error = false;
+
+ }
+
+
+ @Override
+ public boolean checkError() {
+ flush();
+ return error;
+ }
+
+
+ @Override
+ public void write(int c) {
+
+ if (error)
+ return;
+
+ try {
+ ob.write(c);
+ } catch (IOException e) {
+ error = true;
+ }
+
+ }
+
+
+ @Override
+ public void write(char buf[], int off, int len) {
+
+ if (error)
+ return;
+
+ try {
+ ob.write(buf, off, len);
+ } catch (IOException e) {
+ error = true;
+ }
+
+ }
+
+
+ @Override
+ public void write(char buf[]) {
+ write(buf, 0, buf.length);
+ }
+
+
+ @Override
+ public void write(String s, int off, int len) {
+
+ if (error)
+ return;
+
+ try {
+ ob.write(s, off, len);
+ } catch (IOException e) {
+ error = true;
+ }
+
+ }
+
+
+ @Override
+ public void write(String s) {
+ write(s, 0, s.length());
+ }
+
+
+ // ---------------------------------------------------- PrintWriter
Methods
+
+
+ @Override
+ public void print(boolean b) {
+ if (b) {
+ write("true");
+ } else {
+ write("false");
+ }
+ }
+
+
+ @Override
+ public void print(char c) {
+ write(c);
+ }
+
+
+ @Override
+ public void print(int i) {
+ write(String.valueOf(i));
+ }
+
+
+ public void print(long l) {
+ write(String.valueOf(l));
+ }
+
+
+ @Override
+ public void print(float f) {
+ write(String.valueOf(f));
+ }
+
+
+ @Override
+ public void print(double d) {
+ write(String.valueOf(d));
+ }
+
+
+ @Override
+ public void print(char s[]) {
+ write(s);
+ }
+
+
+ @Override
+ public void print(String s) {
+ if (s == null) {
+ s = "null";
+ }
+ write(s);
+ }
+
+
+ @Override
+ public void print(Object obj) {
+ write(String.valueOf(obj));
+ }
+
+
+ @Override
+ public void println() {
+ write(LINE_SEP);
+ }
+
+
+ @Override
+ public void println(boolean b) {
+ print(b);
+ println();
+ }
+
+
+ @Override
+ public void println(char c) {
+ print(c);
+ println();
+ }
+
+
+ @Override
+ public void println(int i) {
+ print(i);
+ println();
+ }
+
+
+ @Override
+ public void println(long l) {
+ print(l);
+ println();
+ }
+
+
+ @Override
+ public void println(float f) {
+ print(f);
+ println();
+ }
+
+
+ @Override
+ public void println(double d) {
+ print(d);
+ println();
+ }
+
+
+ @Override
+ public void println(char c[]) {
+ print(c);
+ println();
+ }
+
+
+ @Override
+ public void println(String s) {
+ print(s);
+ println();
+ }
+
+
+ @Override
+ public void println(Object o) {
+ print(o);
+ println();
+ }
+
+ public GrizzlyOutputBuffer getOutputBuffer(){
+ return ob;
+ }
+}

Modified:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/InternalInputBuffer.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/InternalInputBuffer.java?view=diff&rev=742&p1=/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/http11/InternalInputBuffer.java&p2=trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/InternalInputBuffer.java&r1=741&r2=742
==============================================================================
---
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/http11/InternalInputBuffer.java
(original)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/InternalInputBuffer.java
2008-01-29 18:48:15+0000
@@ -418,7 +418,7 @@

          // Mark the current buffer position
          start = pos;
- int end = 0;
+ end = 0;
          int questionPos = -1;

          //

Modified:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/LocalStrings.properties
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/LocalStrings.properties?view=diff&rev=742&p1=/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/http11/LocalStrings.properties&p2=trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/LocalStrings.properties&r1=741&r2=742
==============================================================================
---
/trunk/modules/http/src/main/java/com/sun/grizzly/tcp/http11/LocalStrings.properties
(original)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/tcp/http11/LocalStrings.properties
2008-01-29 18:48:15+0000
@@ -11,17 +11,17 @@
  # Http11Protocol
  #

-http11protocol.endpoint.initerror=PWC4650: Error initializing endpoint
-http11protocol.endpoint.starterror=PWC4651: Error starting endpoint
-http11protocol.init=PWC4652: Initializing {1} on port {0}
-http11protocol.proto.error=PWC4653: Error reading request, ignored
-http11protocol.proto.ioexception.debug=PWC4654: IOException reading request
-http11protocol.proto.ioexception.info=PWC4655: IOException reading
request, ignored
-http11protocol.proto.socketexception.debug=PWC4656: SocketException
reading request
-http11protocol.proto.socketexception.info=PWC4657: SocketException
reading request, ignored
-http11protocol.setattribute=PWC4658: Attribute {0}: {1}
-http11protocol.socketfactory.initerror=PWC4659: Error initializing
socket factory
-http11protocol.start=PWC4660: Starting {1} on port {0}
+http11protocol.endpoint.initerror=Error initializing endpoint
+http11protocol.endpoint.starterror=Error starting endpoint
+http11protocol.init=Initializing {1} on port {0}
+http11protocol.proto.error=Error reading request, ignored
+http11protocol.proto.ioexception.debug=IOException reading request
+http11protocol.proto.ioexception.info=IOException reading request, ignored
+http11protocol.proto.socketexception.debug=SocketException reading request
+http11protocol.proto.socketexception.info=SocketException reading
request, ignored
+http11protocol.setattribute=Attribute {0}: {1}
+http11protocol.socketfactory.initerror=Error initializing socket factory
+http11protocol.start=Starting {1} on port {0}

  #
  # Http11Processor
@@ -31,6 +31,68 @@
  # InternalInputBuffer
  #

-iib.eof.error=PWC4661: Unexpected EOF read on the socket
-iib.requestheadertoolarge.error=PWC4662: Request header is too large
+iib.eof.error=Unexpected EOF read on the socket
+iib.requestheadertoolarge.error=Request header is too large
+
+
+#
+# CoyoteConnector
+#
+
+coyoteConnector.alreadyInitialized=The connector has already been
initialized
+coyoteConnector.alreadyStarted=The connector has already been started
+coyoteConnector.cannotRegisterProtocol=Cannot register MBean for the
Protocol
+coyoteConnector.notStarted=Coyote connector has not been started
+coyoteConnector.protocolHandlerDestroyFailed=Protocol handler destroy
failed: {0}
+coyoteConnector.protocolHandlerInitializationFailed=Protocol handler
initialization failed: {0}
+coyoteConnector.protocolHandlerInstantiationFailed=Protocol handler
instantiation failed: {0}
+coyoteConnector.protocolHandlerStartFailed=Protocol handler start
failed: {0}
+coyoteConnector.protocolRegistrationFailed=Protocol JMX registration failed
+
+#
+# CoyoteAdapter
+#
+
+coyoteAdapter.service=An exception or error occurred in the container
during the request processing
+coyoteAdapter.proxyAuthCertError=Error parsing client cert chain into
array of java.security.cert.X509Certificate instances
+coyoteAdapter.listenerOff=HTTP listener on port {0} has been disabled
+
+#
+# CoyoteResponse
+#
+
+coyoteResponse.getOutputStream.ise=getWriter() has already been called
for this response
+coyoteResponse.getWriter.ise=getOutputStream() has already been called
for this response
+coyoteResponse.resetBuffer.ise=Cannot reset buffer after response has
been committed
+coyoteResponse.sendError.ise=Cannot call sendError() after the response
has been committed
+coyoteResponse.sendRedirect.ise=Cannot call sendRedirect() after the
response has been committed
+coyoteResponse.setBufferSize.ise=Cannot change buffer size after data
has been written
+responseFacade.nullResponse=Null response object
+
+#
+# CoyoteRequest
+#
+
+coyoteRequest.getInputStream.ise=getReader() has already been called
for this request
+coyoteRequest.getReader.ise=getInputStream() has already been called
for this request
+coyoteRequest.setCharacterEncoding.ise=Unable to set character encoding
{0} because request parameters have already been read, or
ServletRequest.getReader() has been called
+coyoteRequest.sessionCreateCommitted=Cannot create a session after the
response has been committed
+coyoteRequest.setAttribute.namenull=Cannot call setAttribute with a
null name
+coyoteRequest.listenerStart=Exception sending context initialized event
to listener instance of class {0}
+coyoteRequest.listenerStop=Exception sending context destroyed event to
listener instance of class {0}
+coyoteRequest.attributeEvent=Exception thrown by attributes event listener
+coyoteRequest.postTooLarge=Parameters were not parsed because the size
of the posted data was too big. Use the maxPostSize attribute of the
connector to resolve this if the application should accept large POSTs.
+requestFacade.nullRequest=Null request object
+coyoteRequest.unknownHost=Unable to resolve IP address {0} into host name
+coyoteRequest.nullRemoteAddressFromProxy=Unable to determine client
remote address from proxy (returns null)
+
+#
+# MapperListener
+#
+
+mapperListener.registerContext=Register Context {0}
+mapperListener.unregisterContext=Unregister Context {0}
+mapperListener.registerWrapper=Register Wrapper {0} in Context {1}
+
+


Modified:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/buf/DateTool.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/buf/DateTool.java?view=diff&rev=742&p1=trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/buf/DateTool.java&p2=trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/buf/DateTool.java&r1=741&r2=742
==============================================================================
---
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/buf/DateTool.java
(original)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/buf/DateTool.java
2008-01-29 18:48:15+0000
@@ -27,12 +27,16 @@

  package com.sun.grizzly.util.buf;

-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.*;
-import java.text.*;
+

  import com.sun.grizzly.util.res.StringManager;
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;

  /**
   * Common place for date utils.
@@ -94,7 +98,13 @@
          rfc1036Format.setTimeZone(GMT_ZONE);
          asctimeFormat.setTimeZone(GMT_ZONE);
      }
-
+
+ /**
+ * Format for http response header date field
+ */
+ public static final String HTTP_RESPONSE_DATE_HEADER =
+ "EEE, dd MMM yyyy HH:mm:ss zzz";
+
      private static String rfc1123DS;
      private static long rfc1123Sec;


Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Cookie.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Cookie.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Cookie.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,546 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+package com.sun.grizzly.util.http;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+/**
+ *
+ * Creates a cookie, a small amount of information sent by a servlet to
+ * a Web browser, saved by the browser, and later sent back to the server.
+ * A cookie's value can uniquely
+ * identify a client, so cookies are commonly used for session management.
+ *
+ * <p>A cookie has a name, a single value, and optional attributes
+ * such as a comment, path and domain qualifiers, a maximum age, and a
+ * version number. Some Web browsers have bugs in how they handle the
+ * optional attributes, so use them sparingly to improve the
interoperability
+ * of your servlets.
+ *
+ * <p>The servlet sends cookies to the browser by using the
+ * {_at_link HttpServletResponse#addCookie} method, which adds
+ * fields to HTTP response headers to send cookies to the
+ * browser, one at a time. The browser is expected to
+ * support 20 cookies for each Web server, 300 cookies total, and
+ * may limit cookie size to 4 KB each.
+ *
+ * <p>The browser returns cookies to the servlet by adding
+ * fields to HTTP request headers. Cookies can be retrieved
+ * from a request by using the {_at_link HttpServletRequest#getCookies}
method.
+ * Several cookies might have the same name but different path attributes.
+ *
+ * <p>Cookies affect the caching of the Web pages that use them.
+ * HTTP 1.0 does not cache pages that use cookies created with
+ * this class. This class does not support the cache control
+ * defined with HTTP 1.1.
+ *
+ * <p>This class supports both the Version 0 (by Netscape) and Version 1
+ * (by RFC 2109) cookie specifications. By default, cookies are
+ * created using Version 0 to ensure the best interoperability.
+ *
+ *
+ * @author Various
+ * @version $Version$
+ *
+ */
+
+// XXX would implement java.io.Serializable too, but can't do that
+// so long as sun.servlet.* must run on older JDK 1.02 JVMs which
+// don't include that support.
+
+public class Cookie implements Cloneable {
+
+ private static final String LSTRING_FILE =
+ "com.sun.grizzly.util.http.LocalStrings";
+ private static ResourceBundle lStrings =
+ ResourceBundle.getBundle(LSTRING_FILE);
+
+ //
+ // The value of the cookie itself.
+ //
+
+ private String name; // NAME= ... "$Name" style is reserved
+ private String value; // value of NAME
+
+ //
+ // Attributes encoded in the header's cookie fields.
+ //
+
+ private String comment; // ;Comment=VALUE ... describes cookie's use
+ // ;Discard ... implied by maxAge < 0
+ private String domain; // ;Domain=VALUE ... domain that sees cookie
+ private int maxAge = -1; // ;Max-Age=VALUE ... cookies auto-expire
+ private String path; // ;Path=VALUE ... URLs that see the cookie
+ private boolean secure; // ;Secure ... e.g. use SSL
+ private int version = 0; // ;Version=1 ... means RFC 2109++ style
+
+
+
+ /**
+ * Constructs a cookie with a specified name and value.
+ *
+ * <p>The name must conform to RFC 2109. That means it can contain
+ * only ASCII alphanumeric characters and cannot contain commas,
+ * semicolons, or white space or begin with a $ character. The cookie's
+ * name cannot be changed after creation.
+ *
+ * <p>The value can be anything the server chooses to send. Its
+ * value is probably of interest only to the server. The cookie's
+ * value can be changed after creation with the
+ * <code>setValue</code> method.
+ *
+ * <p>By default, cookies are created according to the Netscape
+ * cookie specification. The version can be changed with the
+ * <code>setVersion</code> method.
+ *
+ *
+ * @param name a <code>String</code> specifying the name of the
cookie
+ *
+ * @param value a <code>String</code> specifying the value of the
cookie
+ *
+ * @throws IllegalArgumentException if the cookie name contains
illegal characters
+ * (for example, a comma, space, or semicolon)
+ * or it is one of the tokens reserved for use
+ * by the cookie protocol
+ * @see #setValue
+ * @see #setVersion
+ *
+ */
+
+ public Cookie(String name, String value) {
+ if (!isToken(name)
+ || name.equalsIgnoreCase("Comment") // rfc2019
+ || name.equalsIgnoreCase("Discard") // 2019++
+ || name.equalsIgnoreCase("Domain")
+ || name.equalsIgnoreCase("Expires") // (old cookies)
+ || name.equalsIgnoreCase("Max-Age") // rfc2019
+ || name.equalsIgnoreCase("Path")
+ || name.equalsIgnoreCase("Secure")
+ || name.equalsIgnoreCase("Version")
+ || name.startsWith("$")
+ ) {
+ String errMsg = lStrings.getString("err.cookie_name_is_token");
+ Object[] errArgs = new Object[1];
+ errArgs[0] = name;
+ errMsg = MessageFormat.format(errMsg, errArgs);
+ throw new IllegalArgumentException(errMsg);
+ }
+
+ this.name = name;
+ this.value = value;
+ }
+
+
+
+
+
+ /**
+ *
+ * Specifies a comment that describes a cookie's purpose.
+ * The comment is useful if the browser presents the cookie
+ * to the user. Comments
+ * are not supported by Netscape Version 0 cookies.
+ *
+ * @param purpose a <code>String</code> specifying the comment
+ * to display to the user
+ *
+ * @see #getComment
+ *
+ */
+
+ public void setComment(String purpose) {
+ comment = purpose;
+ }
+
+
+
+
+ /**
+ * Returns the comment describing the purpose of this cookie, or
+ * <code>null</code> if the cookie has no comment.
+ *
+ * @return a <code>String</code> containing the comment,
+ * or <code>null</code> if none
+ *
+ * @see #setComment
+ *
+ */
+
+ public String getComment() {
+ return comment;
+ }
+
+
+
+
+
+ /**
+ *
+ * Specifies the domain within which this cookie should be presented.
+ *
+ * <p>The form of the domain name is specified by RFC 2109. A domain
+ * name begins with a dot (<code>.foo.com</code>) and means that
+ * the cookie is visible to servers in a specified Domain Name System
+ * (DNS) zone (for example, <code>www.foo.com</code>, but not
+ * <code>a.b.foo.com</code>). By default, cookies are only returned
+ * to the server that sent them.
+ *
+ *
+ * @param pattern a <code>String</code> containing the domain name
+ * within which this cookie is visible;
+ * form is according to RFC 2109
+ *
+ * @see #getDomain
+ *
+ */
+
+ public void setDomain(String pattern) {
+ domain = pattern.toLowerCase(); // IE allegedly needs this
+ }
+
+
+
+
+
+ /**
+ * Returns the domain name set for this cookie. The form of
+ * the domain name is set by RFC 2109.
+ *
+ * @return a <code>String</code> containing the domain name
+ *
+ * @see #setDomain
+ *
+ */
+
+ public String getDomain() {
+ return domain;
+ }
+
+
+
+
+ /**
+ * Sets the maximum age of the cookie in seconds.
+ *
+ * <p>A positive value indicates that the cookie will expire
+ * after that many seconds have passed. Note that the value is
+ * the <i>maximum</i> age when the cookie will expire, not the cookie's
+ * current age.
+ *
+ * <p>A negative value means
+ * that the cookie is not stored persistently and will be deleted
+ * when the Web browser exits. A zero value causes the cookie
+ * to be deleted.
+ *
+ * @param expiry an integer specifying the maximum age of the
+ * cookie in seconds; if negative, means
+ * the cookie is not stored; if zero, deletes
+ * the cookie
+ *
+ *
+ * @see #getMaxAge
+ *
+ */
+
+ public void setMaxAge(int expiry) {
+ maxAge = expiry;
+ }
+
+
+
+
+ /**
+ * Returns the maximum age of the cookie, specified in seconds,
+ * By default, <code>-1</code> indicating the cookie will persist
+ * until browser shutdown.
+ *
+ *
+ * @return an integer specifying the maximum age of the
+ * cookie in seconds; if negative, means
+ * the cookie persists until browser shutdown
+ *
+ *
+ * @see #setMaxAge
+ *
+ */
+
+ public int getMaxAge() {
+ return maxAge;
+ }
+
+
+
+
+ /**
+ * Specifies a path for the cookie
+ * to which the client should return the cookie.
+ *
+ * <p>The cookie is visible to all the pages in the directory
+ * you specify, and all the pages in that directory's subdirectories.
+ * A cookie's path must include the servlet that set the cookie,
+ * for example, <i>/catalog</i>, which makes the cookie
+ * visible to all directories on the server under <i>/catalog</i>.
+ *
+ * <p>Consult RFC 2109 (available on the Internet) for more
+ * information on setting path names for cookies.
+ *
+ *
+ * @param uri a <code>String</code> specifying a path
+ *
+ *
+ * @see #getPath
+ *
+ */
+
+ public void setPath(String uri) {
+ path = uri;
+ }
+
+
+
+
+ /**
+ * Returns the path on the server
+ * to which the browser returns this cookie. The
+ * cookie is visible to all subpaths on the server.
+ *
+ *
+ * @return a <code>String</code> specifying a path that contains
+ * a servlet name, for example, <i>/catalog</i>
+ *
+ * @see #setPath
+ *
+ */
+
+ public String getPath() {
+ return path;
+ }
+
+
+
+
+
+ /**
+ * Indicates to the browser whether the cookie should only be sent
+ * using a secure protocol, such as HTTPS or SSL.
+ *
+ * <p>The default value is <code>false</code>.
+ *
+ * @param flag if <code>true</code>, sends the cookie from the browser
+ * to the server only when using a secure protocol;
+ * if <code>false</code>, sent on any protocol
+ *
+ * @see #getSecure
+ *
+ */
+
+ public void setSecure(boolean flag) {
+ secure = flag;
+ }
+
+
+
+
+ /**
+ * Returns <code>true</code> if the browser is sending cookies
+ * only over a secure protocol, or <code>false</code> if the
+ * browser can send cookies using any protocol.
+ *
+ * @return <code>true</code> if the browser uses a secure protocol;
+ * otherwise, <code>true</code>
+ *
+ * @see #setSecure
+ *
+ */
+
+ public boolean getSecure() {
+ return secure;
+ }
+
+
+
+
+
+ /**
+ * Returns the name of the cookie. The name cannot be changed after
+ * creation.
+ *
+ * @return a <code>String</code> specifying the cookie's name
+ *
+ */
+
+ public String getName() {
+ return name;
+ }
+
+
+
+
+
+ /**
+ *
+ * Assigns a new value to a cookie after the cookie is created.
+ * If you use a binary value, you may want to use BASE64 encoding.
+ *
+ * <p>With Version 0 cookies, values should not contain white
+ * space, brackets, parentheses, equals signs, commas,
+ * double quotes, slashes, question marks, at signs, colons,
+ * and semicolons. Empty values may not behave the same way
+ * on all browsers.
+ *
+ * @param newValue a <code>String</code> specifying the new value
+ *
+ *
+ * @see #getValue
+ * @see Cookie
+ *
+ */
+
+ public void setValue(String newValue) {
+ value = newValue;
+ }
+
+
+
+
+ /**
+ * Returns the value of the cookie.
+ *
+ * @return a <code>String</code> containing the cookie's
+ * present value
+ *
+ * @see #setValue
+ * @see Cookie
+ *
+ */
+
+ public String getValue() {
+ return value;
+ }
+
+
+
+
+ /**
+ * Returns the version of the protocol this cookie complies
+ * with. Version 1 complies with RFC 2109,
+ * and version 0 complies with the original
+ * cookie specification drafted by Netscape. Cookies provided
+ * by a browser use and identify the browser's cookie version.
+ *
+ *
+ * @return 0 if the cookie complies with the
+ * original Netscape specification; 1
+ * if the cookie complies with RFC 2109
+ *
+ * @see #setVersion
+ *
+ */
+
+ public int getVersion() {
+ return version;
+ }
+
+
+
+
+ /**
+ * Sets the version of the cookie protocol this cookie complies
+ * with. Version 0 complies with the original Netscape cookie
+ * specification. Version 1 complies with RFC 2109.
+ *
+ * <p>Since RFC 2109 is still somewhat new, consider
+ * version 1 as experimental; do not use it yet on production sites.
+ *
+ *
+ * @param v 0 if the cookie should comply with
+ * the original Netscape specification;
+ * 1 if the cookie should comply with RFC 2109
+ *
+ * @see #getVersion
+ *
+ */
+
+ public void setVersion(int v) {
+ version = v;
+ }
+
+ // Note -- disabled for now to allow full Netscape compatibility
+ // from RFC 2068, token special case characters
+ //
+ // private static final String tspecials = "()<>@,;:\\\"/[]?={} \t";
+
+ private static final String tspecials = ",; ";
+
+
+
+
+ /*
+ * Tests a string and returns true if the string counts as a
+ * reserved token in the Java language.
+ *
+ * @param value the <code>String</code> to be tested
+ *
+ * @return <code>true</code> if the <code>String</code> is
+ * a reserved token; <code>false</code>
+ * if it is not
+ */
+
+ private boolean isToken(String value) {
+ int len = value.length();
+
+ for (int i = 0; i < len; i++) {
+ char c = value.charAt(i);
+
+ if (c < 0x20 || c >= 0x7f || tspecials.indexOf(c) != -1)
+ return false;
+ }
+ return true;
+ }
+
+
+
+
+
+
+ /**
+ *
+ * Overrides the standard <code>java.lang.Object.clone</code>
+ * method to return a copy of this cookie.
+ *
+ *
+ */
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+}
+

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Enumerator.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Enumerator.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Enumerator.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,183 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+package com.sun.grizzly.util.http;
+
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+
+/**
+ * Adapter class that wraps an <code>Enumeration</code> around a Java2
+ * collection classes object <code>Iterator</code> so that existing APIs
+ * returning Enumerations can easily run on top of the new collections.
+ * Constructors are provided to easliy create such wrappers.
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.3 $ $Date: 2007/06/18 14:17:08 $
+ */
+
+public final class Enumerator implements Enumeration {
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ /**
+ * Return an Enumeration over the values of the specified Collection.
+ *
+ * @param collection Collection whose values should be enumerated
+ */
+ public Enumerator(Collection collection) {
+
+ this(collection.iterator());
+
+ }
+
+
+ /**
+ * Return an Enumeration over the values of the specified Collection.
+ *
+ * @param collection Collection whose values should be enumerated
+ * @param clone true to clone iterator
+ */
+ public Enumerator(Collection collection, boolean clone) {
+
+ this(collection.iterator(), clone);
+
+ }
+
+
+ /**
+ * Return an Enumeration over the values returned by the
+ * specified Iterator.
+ *
+ * @param iterator Iterator to be wrapped
+ */
+ public Enumerator(Iterator iterator) {
+
+ super();
+ this.iterator = iterator;
+
+ }
+
+
+ /**
+ * Return an Enumeration over the values returned by the
+ * specified Iterator.
+ *
+ * @param iterator Iterator to be wrapped
+ * @param clone true to clone iterator
+ */
+ public Enumerator(Iterator iterator, boolean clone) {
+
+ super();
+ if (!clone) {
+ this.iterator = iterator;
+ } else {
+ List list = new ArrayList();
+ while (iterator.hasNext()) {
+ list.add(iterator.next());
+ }
+ this.iterator = list.iterator();
+ }
+
+ }
+
+
+ /**
+ * Return an Enumeration over the values of the specified Map.
+ *
+ * @param map Map whose values should be enumerated
+ */
+ public Enumerator(Map map) {
+
+ this(map.values().iterator());
+
+ }
+
+
+ /**
+ * Return an Enumeration over the values of the specified Map.
+ *
+ * @param map Map whose values should be enumerated
+ * @param clone true to clone iterator
+ */
+ public Enumerator(Map map, boolean clone) {
+
+ this(map.values().iterator(), clone);
+
+ }
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ /**
+ * The <code>Iterator</code> over which the <code>Enumeration</code>
+ * represented by this class actually operates.
+ */
+ private Iterator iterator = null;
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Tests if this enumeration contains more elements.
+ *
+ * @return <code>true</code> if and only if this enumeration object
+ * contains at least one more element to provide, <code>false</code>
+ * otherwise
+ */
+ public boolean hasMoreElements() {
+
+ return (iterator.hasNext());
+
+ }
+
+
+ /**
+ * Returns the next element of this enumeration if this enumeration
+ * has at least one more element to provide.
+ *
+ * @return the next element of this enumeration
+ *
+ * @exception NoSuchElementException if no more elements exist
+ */
+ public Object nextElement() throws NoSuchElementException {
+
+ return (iterator.next());
+
+ }
+
+
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/FastDateFormat.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/FastDateFormat.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/FastDateFormat.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,132 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+package com.sun.grizzly.util.http;
+
+import java.util.Date;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+
+/**
+ * Fast date formatter that caches recently formatted date information
+ * and uses it to avoid too-frequent calls to the underlying
+ * formatter. Note: breaks fieldPosition param of format(Date,
+ * StringBuffer, FieldPosition). If you care about the field
+ * position, call the underlying DateFormat directly.
+ *
+ * @author Stan Bailes
+ * @author Alex Chaffee
+ **/
+public class FastDateFormat extends DateFormat {
+ DateFormat df;
+ long lastSec = -1;
+ StringBuffer sb = new StringBuffer();
+ FieldPosition fp = new
FieldPosition(DateFormat.MILLISECOND_FIELD);
+
+ public FastDateFormat(DateFormat df) {
+ this.df = df;
+ }
+
+ public Date parse(String text, ParsePosition pos) {
+ return df.parse(text, pos);
+ }
+
+ /**
+ * Note: breaks functionality of fieldPosition param. Also:
+ * there's a bug in SimpleDateFormat with "S" and "SS", use "SSS"
+ * instead if you want a msec field.
+ **/
+ public StringBuffer format(Date date, StringBuffer toAppendTo,
+ FieldPosition fieldPosition) {
+ long dt = date.getTime();
+ long ds = dt / 1000;
+ if (ds != lastSec) {
+ sb.setLength(0);
+ df.format(date, sb, fp);
+ lastSec = ds;
+ } else {
+ // munge current msec into existing string
+ int ms = (int)(dt % 1000);
+ int pos = fp.getEndIndex();
+ int begin = fp.getBeginIndex();
+ if (pos > 0) {
+ if (pos > begin)
+ sb.setCharAt(--pos, Character.forDigit(ms % 10, 10));
+ ms /= 10;
+ if (pos > begin)
+ sb.setCharAt(--pos, Character.forDigit(ms % 10, 10));
+ ms /= 10;
+ if (pos > begin)
+ sb.setCharAt(--pos, Character.forDigit(ms % 10, 10));
+ }
+ }
+ toAppendTo.append(sb.toString());
+ return toAppendTo;
+ }
+
+ public static void main(String[] args) {
+ String format = "yyyy-MM-dd HH:mm:ss.SSS";
+ if (args.length > 0)
+ format = args[0];
+ SimpleDateFormat sdf = new SimpleDateFormat(format);
+ FastDateFormat fdf = new FastDateFormat(sdf);
+ Date d = new Date();
+
+ d.setTime(1); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+ d.setTime(20); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+ d.setTime(500); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+ d.setTime(543); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+ d.setTime(999); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+ d.setTime(1050); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+ d.setTime(2543); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+ d.setTime(12345); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+ d.setTime(12340); System.out.println(fdf.format(d) + "\t" +
sdf.format(d));
+
+ final int reps = 100000;
+ {
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < reps; i++) {
+ d.setTime(System.currentTimeMillis());
+ fdf.format(d);
+ }
+ long elap = System.currentTimeMillis() - start;
+ System.out.println("fast: " + elap + " elapsed");
+ System.out.println(fdf.format(d));
+ }
+ {
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < reps; i++) {
+ d.setTime(System.currentTimeMillis());
+ sdf.format(d);
+ }
+ long elap = System.currentTimeMillis() - start;
+ System.out.println("slow: " + elap + " elapsed");
+ System.out.println(sdf.format(d));
+ }
+ }
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Globals.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Globals.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/Globals.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,319 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+package com.sun.grizzly.util.http;
+
+// END SJSAS
+
+/**
+ * Global constants that are applicable to multiple packages within
Catalina.
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.3 $ $Date: 2007/06/18 14:17:08 $
+ */
+
+public final class Globals {
+
+ /**
+ * The servlet context attribute under which we store the alternate
+ * deployment descriptor for this web application
+ */
+ public static final String ALT_DD_ATTR =
+ "org.apache.catalina.deploy.alt_dd";
+
+ /**
+ * The request attribute under which we store the array of
X509Certificate
+ * objects representing the certificate chain presented by our client,
+ * if any.
+ */
+ public static final String CERTIFICATES_ATTR =
+ "javax.servlet.request.X509Certificate";
+
+ /**
+ * SSL Certificate Request Attributite.
+ */
+ public static final String SSL_CERTIFICATE_ATTR =
"org.apache.coyote.request.X509Certificate";
+
+ /**
+ * The request attribute under which we store the name of the
cipher suite
+ * being used on an SSL connection (as an object of type
+ * java.lang.String).
+ */
+ public static final String CIPHER_SUITE_ATTR =
+ "javax.servlet.request.cipher_suite";
+
+
+ /**
+ * The servlet context attribute under which we store the class loader
+ * used for loading servlets (as an object of type
java.lang.ClassLoader).
+ */
+ public static final String CLASS_LOADER_ATTR =
+ "org.apache.catalina.classloader";
+
+ /**
+ * Request dispatcher state.
+ */
+ public static final String DISPATCHER_TYPE_ATTR =
+ "org.apache.catalina.core.DISPATCHER_TYPE";
+
+ /**
+ * Request dispatcher path.
+ */
+ public static final String DISPATCHER_REQUEST_PATH_ATTR =
+ "org.apache.catalina.core.DISPATCHER_REQUEST_PATH";
+
+ /**
+ * The JNDI directory context which is associated with the context.
This
+ * context can be used to manipulate static files.
+ */
+ public static final String RESOURCES_ATTR =
+ "org.apache.catalina.resources";
+
+
+ /**
+ * The servlet context attribute under which we store the class path
+ * for our application class loader (as an object of type String),
+ * delimited with the appropriate path delimiter for this platform.
+ */
+ public static final String CLASS_PATH_ATTR =
+ "org.apache.catalina.jsp_classpath";
+
+
+ /**
+ * The request attribute under which we forward a Java exception
+ * (as an object of type Throwable) to an error page.
+ */
+ public static final String EXCEPTION_ATTR =
+ "javax.servlet.error.exception";
+
+
+ /**
+ * The request attribute under which we forward the request URI
+ * (as an object of type String) of the page on which an error
occurred.
+ */
+ public static final String EXCEPTION_PAGE_ATTR =
+ "javax.servlet.error.request_uri";
+
+
+ /**
+ * The request attribute under which we forward a Java exception type
+ * (as an object of type Class) to an error page.
+ */
+ public static final String EXCEPTION_TYPE_ATTR =
+ "javax.servlet.error.exception_type";
+
+
+ /**
+ * The request attribute under which we forward an HTTP status message
+ * (as an object of type STring) to an error page.
+ */
+ public static final String ERROR_MESSAGE_ATTR =
+ "javax.servlet.error.message";
+
+
+ /**
+ * The request attribute under which the Invoker servlet will store
+ * the invoking servlet path, if it was used to execute a servlet
+ * indirectly instead of through a servlet mapping.
+ */
+ public static final String INVOKED_ATTR =
+ "org.apache.catalina.INVOKED";
+
+
+ /**
+ * The request attribute under which we expose the value of the
+ * <code>&lt;jsp-file&gt;</code> value associated with this servlet,
+ * if any.
+ */
+ public static final String JSP_FILE_ATTR =
+ "org.apache.catalina.jsp_file";
+
+
+ /**
+ * The request attribute under which we store the key size being
used for
+ * this SSL connection (as an object of type java.lang.Integer).
+ */
+ public static final String KEY_SIZE_ATTR =
+ "javax.servlet.request.key_size";
+
+
+ /**
+ * The servlet context attribute under which the managed bean Registry
+ * will be stored for privileged contexts (if enabled).
+ */
+ public static final String MBEAN_REGISTRY_ATTR =
+ "org.apache.catalina.Registry";
+
+
+ /**
+ * The servlet context attribute under which the MBeanServer will
be stored
+ * for privileged contexts (if enabled).
+ */
+ public static final String MBEAN_SERVER_ATTR =
+ "org.apache.catalina.MBeanServer";
+
+
+ /**
+ * The request attribute under which we store the servlet name on a
+ * named dispatcher request.
+ */
+ public static final String NAMED_DISPATCHER_ATTR =
+ "org.apache.catalina.NAMED";
+
+
+ /**
+ * The request attribute under which the request URI of the included
+ * servlet is stored on an included dispatcher request.
+ */
+ public static final String INCLUDE_REQUEST_URI_ATTR =
+ "javax.servlet.include.request_uri";
+
+
+ /**
+ * The request attribute under which the context path of the included
+ * servlet is stored on an included dispatcher request.
+ */
+ public static final String INCLUDE_CONTEXT_PATH_ATTR =
+ "javax.servlet.include.context_path";
+
+
+ /**
+ * The request attribute under which the path info of the included
+ * servlet is stored on an included dispatcher request.
+ */
+ public static final String INCLUDE_PATH_INFO_ATTR =
+ "javax.servlet.include.path_info";
+
+
+ /**
+ * The request attribute under which the servlet path of the included
+ * servlet is stored on an included dispatcher request.
+ */
+ public static final String INCLUDE_SERVLET_PATH_ATTR =
+ "javax.servlet.include.servlet_path";
+
+
+ /**
+ * The request attribute under which the query string of the included
+ * servlet is stored on an included dispatcher request.
+ */
+ public static final String INCLUDE_QUERY_STRING_ATTR =
+ "javax.servlet.include.query_string";
+
+
+ /**
+ * The request attribute under which the original request URI is stored
+ * on an forwarded dispatcher request.
+ */
+ public static final String FORWARD_REQUEST_URI_ATTR =
+ "javax.servlet.forward.request_uri";
+
+
+ /**
+ * The request attribute under which the original context path is
stored
+ * on an forwarded dispatcher request.
+ */
+ public static final String FORWARD_CONTEXT_PATH_ATTR =
+ "javax.servlet.forward.context_path";
+
+
+ /**
+ * The request attribute under which the original path info is stored
+ * on an forwarded dispatcher request.
+ */
+ public static final String FORWARD_PATH_INFO_ATTR =
+ "javax.servlet.forward.path_info";
+
+
+ /**
+ * The request attribute under which the original servlet path is
stored
+ * on an forwarded dispatcher request.
+ */
+ public static final String FORWARD_SERVLET_PATH_ATTR =
+ "javax.servlet.forward.servlet_path";
+
+
+ /**
+ * The request attribute under which the original query string is
stored
+ * on an forwarded dispatcher request.
+ */
+ public static final String FORWARD_QUERY_STRING_ATTR =
+ "javax.servlet.forward.query_string";
+
+
+ /**
+ * The request attribute under which we forward a servlet name to
+ * an error page.
+ */
+ public static final String SERVLET_NAME_ATTR =
+ "javax.servlet.error.servlet_name";
+
+
+ /**
+ * The name of the cookie used to pass the session identifier back
+ * and forth with the client.
+ */
+ public static final String SESSION_COOKIE_NAME = "JSESSIONID";
+
+
+ /**
+ * The name of the path parameter used to pass the session identifier
+ * back and forth with the client.
+ */
+ public static final String SESSION_PARAMETER_NAME = "jsessionid";
+
+
+ /**
+ * The request attribute under which we forward an HTTP status code
+ * (as an object of type Integer) to an error page.
+ */
+ public static final String STATUS_CODE_ATTR =
+ "javax.servlet.error.status_code";
+
+
+ /**
+ * The subject under which the AccessControlContext is running.
+ */
+ public static final String SUBJECT_ATTR =
+ "javax.security.auth.subject";
+
+
+ /**
+ * The servlet context attribute under which we record the set of
+ * welcome files (as an object of type String[]) for this application.
+ */
+ public static final String WELCOME_FILES_ATTR =
+ "org.apache.catalina.WELCOME_FILES";
+
+
+ /**
+ * The servlet context attribute under which we store a temporary
+ * working directory (as an object of type File) for use by servlets
+ * within this web application.
+ */
+ public static final String WORK_DIR_ATTR =
+ "javax.servlet.context.tempdir";
+
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings.properties
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings.properties?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings.properties
2008-01-29 18:48:15+0000
@@ -0,0 +1,10 @@
+propertyMap.locked=No modifications are allowed to a locked ParameterMap
+resourceSet.locked=No modifications are allowed to a locked ResourceSet
+hexUtil.bad=Bad hexadecimal digit
+hexUtil.odd=Odd number of hexadecimal digits
+#Default Messages Utilized by the ExtensionValidator
+extensionValidator.web-application-manifest=Web Application Manifest
+extensionValidator.extension-not-found-error=ExtensionValidator[{0}][{1}]:
Required extension "{2}" not found.
+extensionValidator.extension-validation-error=ExtensionValidator[{0}]:
Failure to find {1} required extension(s).
+SecurityUtil.doAsPrivilege=An exception occurs when running the
PrivilegedExceptionAction block.
+err.cookie_name_is_token=Cookie name \"{0}\" is a reserved token

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_es.properties
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_es.properties?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_es.properties
2008-01-29 18:48:15+0000
@@ -0,0 +1,6 @@
+# package org.apache.catalina.util
+
+propertyMap.locked=No se permiten modificaciones en un ParameterMap
bloqueado
+resourceSet.locked=No se permiten modificaciones en un ResourceSet
bloqueado
+hexUtil.odd=Número de dígitos hexadecimales impar
+hexUtil.bad=Dígito hexadecimal incorrecto

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_fr.properties
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_fr.properties?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_fr.properties
2008-01-29 18:48:15+0000
@@ -0,0 +1,10 @@
+propertyMap.locked=Aucune modification n''est authorisée sur un
ParameterMap vérrouillé
+resourceSet.locked=Aucune modification n''est authorisée sur un
ResourceSet vérrouillé
+hexUtil.bad=Mauvais digit hexadecimal
+hexUtil.odd=Nombre impair de digits hexadecimaux
+#Default Messages Utilized by the ExtensionValidator
+extensionValidator.web-application-manifest=Web Application Manifest
+extensionValidator.extension-not-found-error=ExtensionValidator[{0}][{1}]:
L''extension requise "{2}" est introuvable.
+extensionValidator.extension-validation-error=ExtensionValidator[{0}]:
Impossible de trouver {1} extension(s) requise(s).
+SecurityUtil.doAsPrivilege=Une exception s''est produite lors de
l''execution du bloc PrivilegedExceptionAction.
+

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_ja.properties
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_ja.properties?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/LocalStrings_ja.properties
2008-01-29 18:48:15+0000
@@ -0,0 +1,5 @@
+propertyMap.locked=\u30ed\u30c3\u30af\u3055\u308c\u305fParameterMap\u306f\u5909\u66f4\u304c\u8a31\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+resourceSet.locked=\u30ed\u30c3\u30af\u3055\u308c\u305fResourceSet\u306f\u5909\u66f4\u304c\u8a31\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+hexUtil.bad=\u7121\u52b9\u306a16\u9032\u6570\u5024\u3067\u3059
+hexUtil.odd=\u5947\u6570\u6841\u306e16\u9032\u6570\u5024\u3067\u3059
+

Copied:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/MimeType.java
(from r713,
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java)
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/MimeType.java?view=diff&rev=742&p1=/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java&p2=trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/MimeType.java&r1=713&r2=742
==============================================================================
---
/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java
(original)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/MimeType.java
2008-01-29 18:48:15+0000
@@ -24,31 +24,10 @@
   * Portions Copyright Apache Software Foundation.
   */

-package com.sun.grizzly.standalone;
+package com.sun.grizzly.util.http;

-import com.sun.grizzly.http.Constants;
-import com.sun.grizzly.http.FileCache;
-import com.sun.grizzly.http.FileCacheFactory;
-import com.sun.grizzly.http.SelectorThread;
-import com.sun.grizzly.http.SocketChannelOutputBuffer;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SocketChannel;
  import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import com.sun.grizzly.tcp.ActionCode;

-import com.sun.grizzly.tcp.Adapter;
-import com.sun.grizzly.tcp.Request;
-import com.sun.grizzly.tcp.Response;
-import com.sun.grizzly.tcp.http11.InternalOutputBuffer;
-import com.sun.grizzly.util.buf.Ascii;
-import com.sun.grizzly.util.buf.ByteChunk;
-import com.sun.grizzly.util.buf.MessageBytes;
-import com.sun.grizzly.util.http.MimeHeaders;

  /**
   * Hardcoded mime-type supported by default.

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/ParameterMap.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/ParameterMap.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/ParameterMap.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,222 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+package com.sun.grizzly.util.http;
+
+import com.sun.grizzly.util.res.StringManager;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Extended implementation of <strong>HashMap</strong> that includes a
+ * <code>locked</code> property. This class can be used to safely expose
+ * Catalina internal parameter map objects to user classes without having
+ * to clone them in order to avoid modifications. When first created, a
+ * <code>ParmaeterMap</code> instance is not locked.
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.4 $ $Date: 2007/06/18 17:41:35 $
+ */
+
+/* START PWC 6057385
+public final class ParameterMap extends HashMap {
+*/
+// START PWC 6057385
+public final class ParameterMap extends LinkedHashMap {
+// END PWC 6057385
+
+ // -----------------------------------------------------------
Constructors
+
+
+ /**
+ * Construct a new, empty map with the default initial capacity and
+ * load factor.
+ */
+ public ParameterMap() {
+
+ super();
+
+ }
+
+
+ /**
+ * Construct a new, empty map with the specified initial capacity and
+ * default load factor.
+ *
+ * @param initialCapacity The initial capacity of this map
+ */
+ public ParameterMap(int initialCapacity) {
+
+ super(initialCapacity);
+
+ }
+
+
+ /**
+ * Construct a new, empty map with the specified initial capacity and
+ * load factor.
+ *
+ * @param initialCapacity The initial capacity of this map
+ * @param loadFactor The load factor of this map
+ */
+ public ParameterMap(int initialCapacity, float loadFactor) {
+
+ super(initialCapacity, loadFactor);
+
+ }
+
+
+ /**
+ * Construct a new map with the same mappings as the given map.
+ *
+ * @param map Map whose contents are dupliated in the new map
+ */
+ public ParameterMap(Map map) {
+
+ super(map);
+
+ }
+
+
+ // -------------------------------------------------------------
Properties
+
+
+ /**
+ * The current lock state of this parameter map.
+ */
+ private boolean locked = false;
+
+
+ /**
+ * Return the locked state of this parameter map.
+ */
+ public boolean isLocked() {
+
+ return (this.locked);
+
+ }
+
+
+ /**
+ * Set the locked state of this parameter map.
+ *
+ * @param locked The new locked state
+ */
+ public void setLocked(boolean locked) {
+
+ this.locked = locked;
+
+ }
+
+
+ /**
+ * The string manager for this package.
+ */
+ private static final StringManager sm =
+ StringManager.getManager("com.sun.grizzly.util.http");
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+
+ /**
+ * Remove all mappings from this map.
+ *
+ * @exception IllegalStateException if this map is currently locked
+ */
+ public void clear() {
+
+ if (locked)
+ throw new IllegalStateException
+ (sm.getString("parameterMap.locked"));
+ super.clear();
+
+ }
+
+
+ /**
+ * Associate the specified value with the specified key in this
map. If
+ * the map previously contained a mapping for this key, the old
value is
+ * replaced.
+ *
+ * @param key Key with which the specified value is to be associated
+ * @param value Value to be associated with the specified key
+ *
+ * @return The previous value associated with the specified key, or
+ * <code>null</code> if there was no mapping for key
+ *
+ * @exception IllegalStateException if this map is currently locked
+ */
+ public Object put(Object key, Object value) {
+
+ if (locked)
+ throw new IllegalStateException
+ (sm.getString("parameterMap.locked"));
+ return (super.put(key, value));
+
+ }
+
+
+ /**
+ * Copy all of the mappings from the specified map to this one. These
+ * mappings replace any mappings that this map had for any of the keys
+ * currently in the specified Map.
+ *
+ * @param map Mappings to be stored into this map
+ *
+ * @exception IllegalStateException if this map is currently locked
+ */
+ public void putAll(Map map) {
+
+ if (locked)
+ throw new IllegalStateException
+ (sm.getString("parameterMap.locked"));
+ super.putAll(map);
+
+ }
+
+
+ /**
+ * Remove the mapping for this key from the map if present.
+ *
+ * @param key Key whose mapping is to be removed from the map
+ *
+ * @return The previous value associated with the specified key, or
+ * <code>null</code> if there was no mapping for that key
+ *
+ * @exception IllegalStateException if this map is currently locked
+ */
+ public Object remove(Object key) {
+
+ if (locked)
+ throw new IllegalStateException
+ (sm.getString("parameterMap.locked"));
+ return (super.remove(key));
+
+ }
+
+
+}

Added:
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/StringParser.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/StringParser.java?view=auto&rev=742
==============================================================================
--- (empty file)
+++
trunk/modules/http-utils/src/main/java/com/sun/grizzly/util/http/StringParser.java
2008-01-29 18:48:15+0000
@@ -0,0 +1,331 @@
+/*
+ * The contents of this file are subject to the terms
+ * of the Common Development and Distribution License
+ * (the "License"). You may not use this file except
+ * in compliance with the License.
+ *
+ * You can obtain a copy of the license at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt or
+ * https://glassfish.dev.java.net/public/CDDLv1.0.html.
+ * See the License for the specific language governing
+ * permissions and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL
+ * HEADER in each file and include the License file at
+ * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your
+ * own identifying information: Portions Copyright [yyyy]
+ * [name of copyright owner]
+ *
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Portions Copyright Apache Software Foundation.
+ */
+
+package com.sun.grizzly.util.http;
+
+
+/**
+ * Utility class for string parsing that is higher performance than
+ * StringParser for simple delimited text cases. Parsing is performed
+ * by setting the string, and then using the <code>findXxxx()</code> and
+ * <code>skipXxxx()</code> families of methods to remember significant
+ * offsets. To retrieve the parsed substrings, call the
<code>extract()</code>
+ * method with the appropriate saved offset values.
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.3 $ $Date: 2007/06/18 14:17:08 $
+ */
+
+public final class StringParser {
+
+
+ // -----------------------------------------------------------
Constructors
+
+
+ /**
+ * Construct a string parser with no preset string to be parsed.
+ */
+ public StringParser() {
+
+ this(null);
+
+ }
+
+
+ /**
+ * Construct a string parser that is initialized to parse the specified
+ * string.
+ *
+ * @param string The string to be parsed
+ */
+ public StringParser(String string) {
+
+ super();
+ setString(string);
+
+ }
+
+
+ // ----------------------------------------------------- Instance
Variables
+
+
+ /**
+ * The characters of the current string, as a character array. Stored
+ * when the string is first specified to speed up access to characters
+ * being compared during parsing.
+ */
+ private char chars[] = null;
+
+
+ /**
+ * The zero-relative index of the current point at which we are
+ * positioned within the string being parsed. <strong>NOTE</strong>:
+ * the value of this index can be one larger than the index of the last
+ * character of the string (i.e. equal to the string length) if you
+ * parse off the end of the string. This value is useful for
extracting
+ * substrings that include the end of the string.
+ */
+ private int index = 0;
+
+
+ /**
+ * The length of the String we are currently parsing. Stored when the
+ * string is first specified to avoid repeated recalculations.
+ */
+ private int length = 0;
+
+
+ /**
+ * The String we are currently parsing.
+ */
+ private String string = null;
+
+
+ // -------------------------------------------------------------
Properties
+
+
+ /**
+ * Return the zero-relative index of our current parsing position
+ * within the string being parsed.
+ */
+ public int getIndex() {
+
+ return (this.index);
+
+ }
+
+
+ /**
+ * Return the length of the string we are parsing.
+ */
+ public int getLength() {
+
+ return (this.length);
+
+ }
+
+
+ /**
+ * Return the String we are currently parsing.
+ */
+ public String getString() {
+
+ return (this.string);
+
+ }
+
+
+ /**
+ * Set the String we are currently parsing. The parser state is
also reset
+ * to begin at the start of this string.
+ *
+ * @param string The string to be parsed.
+ */
+ public void setString(String string) {
+
+ this.string = string;
+ if (string != null) {
+ this.length = string.length();
+ chars = this.string.toCharArray();
+ } else {
+ this.length = 0;
+ chars = new char[0];
+ }
+ reset();
+
+ }
+
+
+ // --------------------------------------------------------- Public
Methods
+
+
+ /**
+ * Advance the current parsing position by one, if we are not already
+ * past the end of the string.
+ */
+ public void advance() {
+
+ if (index < length)
+ index++;
+
+ }
+
+
+ /**
+ * Extract and return a substring that starts at the specified
position,
+ * and extends to the end of the string being parsed. If this is not
+ * possible, a zero-length string is returned.
+ *
+ * @param start Starting index, zero relative, inclusive
+ */
+ public String extract(int start) {
+
+ if ((start < 0) || (start >= length))
+ return ("");
+ else
+ return (string.substring(start));
+
+ }
+
+
+ /**
+ * Extract and return a substring that starts at the specified
position,
+ * and ends at the character before the specified position. If this is
+ * not possible, a zero-length string is returned.
+ *
+ * @param start Starting index, zero relative, inclusive
+ * @param end Ending index, zero relative, exclusive
+ */
+ public String extract(int start, int end) {
+
+ if ((start < 0) || (start >= end) || (end > length))
+ return ("");
+ else
+ return (string.substring(start, end));
+
+ }
+
+
+ /**
+ * Return the index of the next occurrence of the specified character,
+ * or the index of the character after the last position of the string
+ * if no more occurrences of this character are found. The current
+ * parsing position is updated to the returned value.
+ *
+ * @param ch Character to be found
+ */
+ public int findChar(char ch) {
+
+ while ((index < length) && (ch != chars[index]))
+ index++;
+ return (index);
+
+ }
+
+
+ /**
+ * Return the index of the next occurrence of a non-whitespace
character,
+ * or the index of the character after the last position of the string
+ * if no more non-whitespace characters are found. The current
+ * parsing position is updated to the returned value.
+ */
+ public int findText() {
+
+ while ((index < length) && isWhite(chars[index]))
+ index++;
+ return (index);
+
+ }
+
+
+ /**
+ * Return the index of the next occurrence of a whitespace character,
+ * or the index of the character after the last position of the string
+ * if no more whitespace characters are found. The current parsing
+ * position is updated to the returned value.
+ */
+ public int findWhite() {
+
+ while ((index < length) && !isWhite(chars[index]))
+ index++;
+ return (index);
+
+ }
+
+
+ /**
+ * Reset the current state of the parser to the beginning of the
+ * current string being parsed.
+ */
+ public void reset() {
+
+ index = 0;
+
+ }
+
+
+ /**
+ * Advance the current parsing position while it is pointing at the
+ * specified character, or until it moves past the end of the string.
+ * Return the final value.
+ *
+ * @param ch Character to be skipped
+ */
+ public int skipChar(char ch) {
+
+ while ((index < length) && (ch == chars[index]))
+ index++;
+ return (index);
+
+ }
+
+
+ /**
+ * Advance the current parsing position while it is pointing at a
+ * non-whitespace character, or until it moves past the end of the
string.
+ * Return the final value.
+ */
+ public int skipText() {
+
+ while ((index < length) && !isWhite(chars[index]))
+ index++;
+ return (index);
+
+ }
+
+
+ /**
+ * Advance the current parsing position while it is pointing at a
+ * whitespace character, or until it moves past the end of the string.
+ * Return the final value.
+ */
+ public int skipWhite() {
+
+ while ((index < length) && isWhite(chars[index]))
+ index++;
+ return (index);
+
+ }
+
+
+ // ------------------------------------------------------ Protected
Methods
+
+
+ /**
+ * Is the specified character considered to be whitespace?
+ *
+ * @param ch Character to be checked
+ */
+ protected boolean isWhite(char ch) {
+
+ if ((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n'))
+ return (true);
+ else
+ return (false);
+
+ }
+
+
+}

Modified:
trunk/modules/http/src/main/java/com/sun/grizzly/http/DefaultProcessorTask.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http/src/main/java/com/sun/grizzly/http/DefaultProcessorTask.java?view=diff&rev=742&p1=trunk/modules/http/src/main/java/com/sun/grizzly/http/DefaultProcessorTask.java&p2=trunk/modules/http/src/main/java/com/sun/grizzly/http/DefaultProcessorTask.java&r1=741&r2=742
==============================================================================
---
trunk/modules/http/src/main/java/com/sun/grizzly/http/DefaultProcessorTask.java
(original)
+++
trunk/modules/http/src/main/java/com/sun/grizzly/http/DefaultProcessorTask.java
2008-01-29 18:48:15+0000
@@ -986,7 +986,8 @@
                  }
              }
          } else if ( actionCode == ActionCode.ACTION_POST_REQUEST ) {
- if (response.getStatus() == 200 && handler != null){
+ if (response.getStatus() == 200 && handler != null
+ && compressionLevel == 0){
                  try{
 
handler.handle(request,Interceptor.RESPONSE_PROCEEDED);
                  } catch(IOException ex){

Modified:
trunk/modules/http/src/main/java/com/sun/grizzly/http/KeepAliveCountManager.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http/src/main/java/com/sun/grizzly/http/KeepAliveCountManager.java?view=diff&rev=742&p1=trunk/modules/http/src/main/java/com/sun/grizzly/http/KeepAliveCountManager.java&p2=trunk/modules/http/src/main/java/com/sun/grizzly/http/KeepAliveCountManager.java&r1=741&r2=742
==============================================================================
---
trunk/modules/http/src/main/java/com/sun/grizzly/http/KeepAliveCountManager.java
(original)
+++
trunk/modules/http/src/main/java/com/sun/grizzly/http/KeepAliveCountManager.java
2008-01-29 18:48:15+0000
@@ -358,7 +358,10 @@
      public void untrap(SelectionKey key){
          if ( maxKeepAliveRequests == -1) return;

- keepAliveCounts.remove(key);
+ Integer count = keepAliveCounts.remove(key);
+ if (keepAliveStats != null && count != null) {
+ keepAliveStats.decrementCountConnections();
+ }
          if (keepAliveStats != null) {
              keepAliveStats.decrementCountConnections();
          }

Modified:
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java?view=diff&rev=742&p1=trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java&p2=trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java&r1=741&r2=742
==============================================================================
---
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java
(original)
+++
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/DynamicContentAdapter.java
2008-01-29 18:48:15+0000
@@ -43,8 +43,12 @@
   * Abstract Adapter that contains all the common behaviour of the
Adapter implmentation
   * for standalone usage as well as embedded use.
   *
+ * This class is deprecated and moved under
+ * http-utils/src/main/java/com/sun/grizzly/tcp/
+ *
   * @author Jerome Dochez
   * @author Jean-Francois Arcand
+ * @depreacted
   */
  abstract public class DynamicContentAdapter extends
StaticResourcesAdapter {


Modified:
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/Main.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/Main.java?view=diff&rev=742&p1=trunk/modules/http/src/main/java/com/sun/grizzly/standalone/Main.java&p2=trunk/modules/http/src/main/java/com/sun/grizzly/standalone/Main.java&r1=741&r2=742
==============================================================================
---
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/Main.java
(original)
+++
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/Main.java
2008-01-29 18:48:15+0000
@@ -26,6 +26,9 @@
  import com.sun.grizzly.arp.DefaultAsyncHandler;
  import com.sun.grizzly.http.SelectorThread;
  import com.sun.grizzly.tcp.Adapter;
+import com.sun.grizzly.tcp.StaticResourcesAdapter;
+import com.sun.grizzly.tcp.DynamicContentAdapter;
+import com.sun.grizzly.tcp.StaticResourcesAdapter;
  import com.sun.grizzly.util.ClassLoaderUtil;
  import java.io.File;

@@ -57,7 +60,7 @@

      public static void main( String args[] ) throws Exception {
          Main main = new Main();
- main.start(args);
+ Main.start(args);
      }


@@ -99,16 +102,23 @@
 
.setAlgorithmClassName(StaticStreamAlgorithm.class.getName());
          }
          selectorThread.setPort(port);
- selectorThread.setWebAppRootPath(folder);

          String adapterClass = System.getProperty(ADAPTER);
          Adapter adapter;
          if (adapterClass == null){
- adapter = new StaticResourcesAdapter();
+ adapter = new StaticResourcesAdapter(folder);
          } else {
              adapter = (Adapter)loadInstance(adapterClass);
          }

+ if (adapter instanceof StaticResourcesAdapter){
+ ((StaticResourcesAdapter)adapter).setRootFolder(folder);
+ }
+
+ if (adapter instanceof DynamicContentAdapter){
+ ((DynamicContentAdapter)adapter).setContextRoot("/");
+ }
+
          boolean enableRcm =
Boolean.valueOf(System.getProperty(ENABLE_RCM));
          selectorThread.enableRcmSupport(enableRcm);

@@ -134,6 +144,7 @@
                      Thread.currentThread().getContextClassLoader());
              return className.newInstance();
          } catch (Throwable t) {
+ t.getCause().printStackTrace();
              t.printStackTrace();
              // Log me
          }

Modified:
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java?view=diff&rev=742&p1=trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java&p2=trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java&r1=741&r2=742
==============================================================================
---
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java
(original)
+++
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/MimeType.java
2008-01-29 18:48:15+0000
@@ -26,34 +26,14 @@

  package com.sun.grizzly.standalone;

-import com.sun.grizzly.http.Constants;
-import com.sun.grizzly.http.FileCache;
-import com.sun.grizzly.http.FileCacheFactory;
-import com.sun.grizzly.http.SelectorThread;
-import com.sun.grizzly.http.SocketChannelOutputBuffer;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SocketChannel;
  import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import com.sun.grizzly.tcp.ActionCode;

-import com.sun.grizzly.tcp.Adapter;
-import com.sun.grizzly.tcp.Request;
-import com.sun.grizzly.tcp.Response;
-import com.sun.grizzly.tcp.http11.InternalOutputBuffer;
-import com.sun.grizzly.util.buf.Ascii;
-import com.sun.grizzly.util.buf.ByteChunk;
-import com.sun.grizzly.util.buf.MessageBytes;
-import com.sun.grizzly.util.http.MimeHeaders;

  /**
   * Hardcoded mime-type supported by default.
   *
   * @author Jeanfrancois Arcand
+ * @deprecated
   */
  public class MimeType{


Modified:
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java?view=diff&rev=742&p1=trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java&p2=trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java&r1=741&r2=742
==============================================================================
---
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java
(original)
+++
trunk/modules/http/src/main/java/com/sun/grizzly/standalone/StaticResourcesAdapter.java
2008-01-29 18:48:15+0000
@@ -54,7 +54,12 @@
   * Simple HTTP based Web Server. Part of this class is from Tomcat
sandbox code
   * from Costin Manolache.
   *
+ * This class is deprecated and moved under
+ * http-utils/src/main/java/com/sun/grizzly/tcp/
+ *
+ *
   * @author Jeanfrancois Arcand
+ * @deprecated
   */
  public class StaticResourcesAdapter implements Adapter {


Modified:
trunk/modules/jruby/src/main/java/com/sun/grizzly/jruby/RailsAdapter.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/jruby/src/main/java/com/sun/grizzly/jruby/RailsAdapter.java?view=diff&rev=742&p1=trunk/modules/jruby/src/main/java/com/sun/grizzly/jruby/RailsAdapter.java&p2=trunk/modules/jruby/src/main/java/com/sun/grizzly/jruby/RailsAdapter.java&r1=741&r2=742
==============================================================================
---
trunk/modules/jruby/src/main/java/com/sun/grizzly/jruby/RailsAdapter.java
(original)
+++
trunk/modules/jruby/src/main/java/com/sun/grizzly/jruby/RailsAdapter.java
2008-01-29 18:48:15+0000
@@ -24,9 +24,7 @@

  import java.io.IOException;
  import java.io.InputStream;
-import java.io.InputStreamReader;
  import java.io.OutputStream;
-import java.io.Reader;

  import org.jruby.Ruby;
  import org.jruby.RubyException;
@@ -38,11 +36,12 @@
  import org.jruby.runtime.builtin.IRubyObject;

  import com.sun.grizzly.http.SelectorThread;
-import com.sun.grizzly.standalone.DynamicContentAdapter;
  import com.sun.grizzly.tcp.Adapter;
+import com.sun.grizzly.tcp.DynamicContentAdapter;
  import com.sun.grizzly.tcp.Request;
  import com.sun.grizzly.tcp.Response;
  import com.sun.grizzly.tcp.http11.InternalOutputBuffer;
+import com.sun.grizzly.util.buf.ByteChunk;

  /**
   * Adapter implementation that bridge JRuby on Rails with Grizzly.
@@ -134,4 +133,4 @@
              }
          }
      }
-}
\ No newline at end of file
+}

Modified:
trunk/modules/jruby/src/main/java/com/sun/grizzly/standalone/JRuby.java
Url:
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/jruby/src/main/java/com/sun/grizzly/standalone/JRuby.java?view=diff&rev=742&p1=trunk/modules/jruby/src/main/java/com/sun/grizzly/standalone/JRuby.java&p2=trunk/modules/jruby/src/main/java/com/sun/grizzly/standalone/JRuby.java&r1=741&r2=742
==============================================================================
---
trunk/modules/jruby/src/main/java/com/sun/grizzly/standalone/JRuby.java
(original)
+++
trunk/modules/jruby/src/main/java/com/sun/grizzly/standalone/JRuby.java
2008-01-29 18:48:15+0000
@@ -26,6 +26,7 @@

  import com.sun.grizzly.jruby.RailsSelectorThread;
  import com.sun.grizzly.tcp.Adapter;
+import com.sun.grizzly.tcp.StaticResourcesAdapter;
  import com.sun.grizzly.util.ClassLoaderUtil;
  import java.io.File;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe_at_grizzly.dev.java.net
For additional commands, e-mail: commits-help_at_grizzly.dev.java.net