[Haskell-cafe] [web-devel] Looking for criticism and comments on web-mongrel2.

Michael Snoyman michael at snoyman.com
Fri Jan 21 15:26:25 CET 2011


On Fri, Jan 21, 2011 at 3:55 PM, Clint Moore <cmoore at wamboli.com> wrote:
> On Fri, Jan 21, 2011 at 5:44 AM, Michael Snoyman <michael at snoyman.com> wrote:
>> Glad to hear you were already working on the bytestring switch, I hope
>> I didn't focus on that too much ;). If you *are* planning on writing a
>
> Naw, you didn't.  Using bytestrings as much as possible especially
> when dealing with network services are a definite best practice.
>
>> WAI handler for this, you will need to provide something more powerful
>> for the response body than lazy bytestrings. Well, either that, or use
>> some ugly forkIO/unsafeInterleaveIO tricks that I don't mention in
>> polite company.
>
> Well, then I'll have to figure something out.  I'm morally opposed to unsafe*
>
> No, forkIO I love.  But haven't yet had to resort to using anything
> unsafe, though I haven't done any FFI or other things that apparently
> make it necessary.

The most powerful interface (powerful meaning user can do whatever
they want) is a simple ByteString -> IO () function that can be called
multiple times to keep sending data to the client. Since you need to
send the headers first, you could consider some kind of interface
similar to:

Application :: Request -> (Status -> Headers -> IO (ByteString -> IO
()) -> IO ()

This would basically mean that an application is given a request and
function to call. That function, after taking the status code and
headers (however you encode them) would return a *new* function that
would allow you to send chunks of data to the client. You could also
completely skip the status/headers part and make it the user's
responsibility to add them. Another option is using blaze-builder
Builders instead of ByteStrings.

Now that I looked more closely at the response_template, a few questions:

* Why are you sending Connection: close?
* I'm not sure if it can ever cause a problem, but it's probably a bad
idea to give a message of OK for every status code.
* Not every content type will have a charset associated with it (eg, image/png).

>> Out of curiosity, does mongrel2 provide any kind of optimization for
>> serving files via a sendfile system call? I would be surprised if it
>> didn't.
>
> I don't know.  I'll check that out and report back.
>
> As far as handling files, one thing that I really like about M2 is the
> way it handles file uploads.  From the manual:
>
> "Mongrel2 uses an asynchronous method of doing uploads that helps you
> avoid receiving files you either can't accept or shouldn't accept. It
> does this by sending your handler an initial message with just the
> headers, streaming the file to disk, and then a final message so you
> can read the resulting file. If you don't want the upload, then you
> can send a kill message (a 0 length message) and the connection
> closes, and the file never lands."
>
> I'm going to write a couple of simple examples later today, one of
> them being a file upload handler to illustrate how to use it from the
> application side.
>

That sounds like a nice interface if you're just targeting mongrel
directly. However:

* How does it handle request which are neither url-encoded or
multipart form data?
* To provide a proper WAI backend, it would need to provide the raw
request body. Does mongrel2 support that in any way?

Michael



More information about the Haskell-Cafe mailing list