dev@grizzly.java.net

Re: Processing HTTP post request

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Thu, 17 Jan 2008 18:28:15 -0500

Salut,

thomas.campbell_at_accenture.com wrote:
> I am considering using Grizzly as a simple embedded HTTP server in for a
> project that I’m working on. I need the ability to receive HTTP post
> requests and process the contents of those requests. I was looking
> around your site for an example of how to do this but the closest I
> could find was this:
> http://jlorenzen.blogspot.com/2007/06/using-grizzly-to-create-simple-http.html
> . Could you give me some pointers to complete this code to receive a
> post request? Thanks and have a great day!

Take a look at that one:

http://weblogs.java.net/blog/jfarcand/archive/2006/12/understanding_g.html

Mainly, you need to extend/implement an interface called
com.sun.grizzly.tcp.Adapter and set it on the SelectorThread. As an
example, here is the code used by the Grizzly WebServer:


> 92 SelectorThread selectorThread = null;
[...]
> 97 selectorThread = new SelectorThread();
> 98 selectorThread
> 99 .setAlgorithmClassName(StaticStreamAlgorithm.class.getName());
> 100 }
> 101 selectorThread.setPort(port);
> 102 selectorThread.setWebAppRootPath(folder);
> 103
> 104 String adapterClass = System.getProperty(ADAPTER);
> 105 Adapter adapter;
> 106 if (adapterClass == null){
> 107 adapter = new StaticResourcesAdapter();
> 108 } else {
> 109 adapter = (Adapter)loadInstance(adapterClass);
> 110 }
> 111
[...]
> 120
> 121 selectorThread.setAdapter(adapter);
> 122 selectorThread.setDisplayConfiguration(true);
> 123 selectorThread.listen();

Mainly, you first create the SelectorThread object, the set your adapter
using the System.getProperty() if you want to re-use the main class
under the http module:

grizzly/modules/http/src/main/java/com/sun/grizzly/standalone/Main.java

or you might want to embed the code inside your own started class. The
Adapter classes has one important method called
service(Request,Response) where you can do your stuff. Below is an example.


> 88 public void service(Request req, final Response res) throws Exception {
> 89 MessageBytes mb = req.requestURI();
> 90 ByteChunk requestURI = mb.getByteChunk();
> 91 String uri = req.requestURI().toString();
> 92 if (uri.indexOf("..") >= 0) {
> 93 res.setStatus(404);
> 94 return;
> 95 }
> 102
> 103 // local file
> 104 File resource = cache.get(uri);
> 105 if (resource == null){
> 106 resource = new File(rootFolderF, uri);
> 107 cache.put(uri,resource);
> 108 }
> 109
> 110 if (resource.isDirectory()) {
> 111 resource = new File(resource, "index.html");
> 112 cache.put(uri,resource);
> 113 }
> 114
> 115 if (!resource.exists()) {
> 116 SelectorThread.logger().log(Level.INFO,"File not found " + resource);
> 117 res.setStatus(404);
> 118 return;
> 119 }
> 120 res.setStatus(200);
> 121
> 122 int dot=uri.lastIndexOf(".");
> 123 if( dot > 0 ) {
> 124 String ext=uri.substring(dot+1);
> 125 String ct= MimeType.get(ext);
> 126 if( ct!=null) {
> 127 res.setContentType(ct);
> 128 }
> 129 } else {
> 130 res.setContentType(MimeType.get("html"));
> 131 }
> 132
> 133 res.setContentLength((int)resource.length());
> 134 res.sendHeaders();
> 135
> 136 /* Workaround Linux NIO bug
> 137 * 6427312: (fc) FileChannel.transferTo() throws IOException "system call interrupted"
> 138 * 5103988: (fc) FileChannel.transferTo should return -1 for EAGAIN instead throws IOException
> 139 * 6253145: (fc) FileChannel.transferTo on Linux fails when going beyond 2GB boundary
> 140 * 6470086: (fc) FileChannel.transferTo(2147483647, 1, channel) cause "Value too large" exception
> 141 */
> 142 FileInputStream fis = new FileInputStream(resource);
> 143 byte b[] = new byte[8192];
> 144 ByteChunk chunk = new ByteChunk();
> 145 int rd = 0;
> 146 while ((rd = fis.read(b)) > 0) {
> 147 chunk.setBytes(b, 0, rd);
> 148 res.doWrite(chunk);
> 149 }
> 150
> 151 try{
> 152 req.action( ActionCode.ACTION_POST_REQUEST , null);
> 153 }catch (Throwable t) {
> 154 t.printStackTrace();
> 155 }
> 156
> 157 res.finish();
> 158 }

You can browse the code online as well:

https://grizzly.dev.java.net/nonav/xref/com/sun/grizzly/standalone/StaticResourcesAdapter.html
https://grizzly.dev.java.net/nonav/xref/com/sun/grizzly/standalone/Main.html

I'm currently working on a more high level
GrizzlyRequest/GrizzlyResponse object (which are similar to the
HttpServletRequest/Response) with Read, Input/OutputStream to manipulate
String etc. I should have commit something soon, but since those classes
  are fairly new I would first take a look at the classes above (the are
low level, but quite performant.

Hope that help.

-- Jeanfrancois

>
>
>
> - Tom
>
> This message is for the designated recipient only and may contain
> privileged, proprietary, or otherwise private information. If you have
> received it in error, please notify the sender immediately and delete
> the original. Any other use of the email by you is prohibited.
>