users@jersey.java.net

Re: Grizzly Container is completely wrong, if I read it correctly

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Wed, 28 Nov 2007 17:49:31 -0500

Salut,

attached is the first patch. You will need to pullout the Grizzly's jat
from here[1]. Why first, it's because there seems to be an encoding
problem (which was also with Grizzly 1.0) I need to look at because a
simple query test fail. I'm attaching the tests as well so you can take
a look to see if the bug is in Grizzly or not. My guess is not. I think
the way the response is constructed is the problem as bytes as written
without any char to bytes conversion.

At least now you can use Grizzly 1.6.x and find more bugs :-).

Let me know what you think.

A+

-- Jeanfrancois

[1] http://download.java.net/maven/2/com/sun/grizzly/

Paul Sandoz wrote:
> Jeanfrancois Arcand wrote:
>>> My preference would be to only support the latest greatest stable
>>> Grizzly.
>>
>> Agree...and the latest is faster :-)
>>
>> I've ported the code (it compile with the latest Grizzlies jars)...
>
> Great!
>
>
>> now I don't recall how to test it (as usual)....any pointers of what I
>> should run/try before submitting the patch will be helpful!
>>
>
> Perhaps the best thing to do is copy a unit test from the LW HTTP server.
>
> See the test package:
>
> com.sun.ws.rest.impl.container.httpserver
>
> and the classes:
>
> AbstractHttpServerTester
> QueryParamTest
>
> You could copy these classes to the package
>
> com.sun.ws.rest.impl.container.grizzly
>
> and modify accordingly.
>
> Note that we do plan to improve the unit testing framework to make it
> easy to test independent of the container but we are not their yet so it
> is necessary to duplicate such tests.
>
> Paul.
>


Index: nbproject/project.properties
===================================================================
--- nbproject/project.properties (revision 531)
+++ nbproject/project.properties (working copy)
@@ -20,7 +20,10 @@
 file.reference.activation.jar=lib/activation.jar
 file.reference.asm-3.0.jar=lib/asm-3.0.jar
 file.reference.comresrcgen.jar=lib/comresrcgen.jar
-file.reference.grizzly-1.0.13.jar=lib/grizzly-1.0.13.jar
+file.reference.grizzly-http-1.x=lib/http-1.6-SNAPSHOT.jar
+file.reference.grizzly-util-1.x=lib/http-utils-1.6-SNAPSHOT.jar
+file.reference.grizzly-rcm-1.x=lib/rcm-1.6-SNAPSHOT.jar
+file.reference.grizzly-core-1.x=lib/framework-1.6-SNAPSHOT.jar
 file.reference.http.jar=lib/http.jar
 file.reference.jaxb-api.jar=lib/jaxb-api.jar
 file.reference.jaxb-impl.jar=lib/jaxb-impl.jar
@@ -58,7 +61,10 @@
     ${file.reference.persistence-api-1.0.jar}:\
     ${file.reference.servlet.jar}:\
     ${file.reference.jaxws-api.jar}:\
- ${file.reference.grizzly-1.0.13.jar}:\
+ ${file.reference.grizzly-http-1.x}:\
+ ${file.reference.grizzly-util-1.x}:\
+ ${file.reference.grizzly-rcm-1.x}:\
+ ${file.reference.grizzly-core-1.x}:\
     ${file.reference.http.jar}:\
     ${file.reference.asm-3.0.jar}:\
     ${file.reference.localizer.jar}:\
Index: src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyResponseAdaptor.java
===================================================================
--- src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyResponseAdaptor.java (revision 531)
+++ src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyResponseAdaptor.java (working copy)
@@ -27,10 +27,10 @@
 import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
-import org.apache.coyote.Response;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.MimeHeaders;
+import com.sun.grizzly.tcp.Response;
+import com.sun.grizzly.util.buf.ByteChunk;
+import com.sun.grizzly.util.buf.MessageBytes;
+import com.sun.grizzly.util.http.MimeHeaders;
 
 /**
  *
Index: src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyContainerProvider.java
===================================================================
--- src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyContainerProvider.java (revision 531)
+++ src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyContainerProvider.java (working copy)
@@ -26,7 +26,7 @@
 import com.sun.ws.rest.api.core.ResourceConfig;
 import com.sun.ws.rest.spi.container.ContainerProvider;
 import com.sun.ws.rest.spi.container.WebApplication;
-import org.apache.coyote.Adapter;
+import com.sun.grizzly.tcp.Adapter;
 
 /**
  *
Index: src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyContainer.java
===================================================================
--- src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyContainer.java (revision 531)
+++ src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyContainer.java (working copy)
@@ -28,10 +28,10 @@
 import com.sun.ws.rest.spi.container.WebApplication;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import org.apache.coyote.ActionCode;
-import org.apache.coyote.Adapter;
-import org.apache.coyote.Request;
-import org.apache.coyote.Response;
+import com.sun.grizzly.tcp.ActionCode;
+import com.sun.grizzly.tcp.Adapter;
+import com.sun.grizzly.tcp.Request;
+import com.sun.grizzly.tcp.Response;
 
 /**
  *
@@ -41,10 +41,17 @@
     
     private WebApplication application;
     
+ public GrizzlyContainer(){
+ }
+
     public GrizzlyContainer(WebApplication app) throws ContainerException {
         this.application = app;
     }
 
+ public void setWebApplication(WebApplication application){
+ this.application = application;
+ }
+
     public void service(Request request, Response response) throws Exception {
         GrizzlyRequestAdaptor requestAdaptor = new GrizzlyRequestAdaptor(request);
         GrizzlyResponseAdaptor responseAdaptor = new GrizzlyResponseAdaptor(response, requestAdaptor);
Index: src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyRequestAdaptor.java
===================================================================
--- src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyRequestAdaptor.java (revision 531)
+++ src/impl/com/sun/ws/rest/impl/container/grizzly/GrizzlyRequestAdaptor.java (working copy)
@@ -23,17 +23,21 @@
 package com.sun.ws.rest.impl.container.grizzly;
 
 import com.sun.ws.rest.spi.container.AbstractContainerRequest;
-import com.sun.ws.rest.impl.http.header.HttpHeaderFactory;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
+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 com.sun.grizzly.util.buf.MessageBytes;
+import com.sun.grizzly.util.http.MimeHeaders;
+import com.sun.grizzly.util.http.Parameters;
+import com.sun.ws.rest.impl.http.header.HttpHeaderFactory;
 import java.util.Enumeration;
 import javax.ws.rs.core.MultivaluedMap;
-import org.apache.coyote.Request;
-import org.apache.tomcat.util.buf.ByteChunk;
-import org.apache.tomcat.util.http.MimeHeaders;
 
 /**
  *
@@ -55,7 +59,7 @@
     private void initiateUriInfo() {
         /**
          * TODO find out exactly what the URI related methods
- * on org.apache.coyote.Request actually return.
+ * on com.sun.grizzly.tcp.Request actually return.
          * If URI components are returned are they in encoded or decoded form?
          * If URIs are returned what components to they contain?
          */
@@ -70,6 +74,26 @@
                     null,
                     null);
             
+ // URI decoding
+ MessageBytes decodedURI = request.decodedURI();
+ try {
+ decodedURI.duplicate(request.requestURI());
+
+ request.getURLDecoder().convert(decodedURI, false);
+ convertURI(decodedURI);
+ } catch (Exception ioe) {
+ throw new RuntimeException(ioe);
+ }
+
+ if(request.queryString() != null){
+ Parameters parameters = request.getParameters();
+ parameters.setEncoding
+ (com.sun.grizzly.tcp.Constants.DEFAULT_CHARACTER_ENCODING);
+ parameters.setQueryStringEncoding
+ (com.sun.grizzly.tcp.Constants.DEFAULT_CHARACTER_ENCODING);
+ parameters.handleQueryParameters();
+ }
+
             this.completeUri = new URI(
                     request.scheme().toString(),
                     null,
@@ -84,6 +108,33 @@
         }
     }
     
+ /**
+ * Character conversion of the URI.
+ */
+ protected void convertURI(MessageBytes uri)
+ throws Exception {
+
+ ByteChunk bc = uri.getByteChunk();
+ CharChunk cc = uri.getCharChunk();
+ int length = bc.getLength();
+ cc.allocate(length, -1);
+
+ String enc = "utf-8";
+ B2CConverter conv = conv = new B2CConverter(enc);
+ conv.convert(bc, cc);
+ uri.setChars(cc.getBuffer(), cc.getStart(),
+ cc.getLength());
+
+ // Default encoding: fast conversion
+ byte[] bbuf = bc.getBuffer();
+ char[] cbuf = cc.getBuffer();
+ int start = bc.getStart();
+ for (int i = 0; i < length; i++) {
+ cbuf[i] = (char) (bbuf[i + start] & 0xff);
+ }
+ uri.setChars(cbuf, 0, length);
+ }
+
     private void copyHttpHeaders() {
         MultivaluedMap<String, String> headers = getRequestHeaders();