[email protected]
[Top] [All Lists]

Re: [Haskell-cafe] PROPOSAL: Web application interface

Subject: Re: [Haskell-cafe] PROPOSAL: Web application interface
From: Mark Lentczner
Date: Sun, 17 Jan 2010 22:54:16 -0800
I like this project! Thanks for resurrecting it!

Some thoughts:

Methods in HTTP are extensible. The type RequestMethod should probably have a 
"catchall" constructor
        | Method B.ByteString

Other systems (the WAI proposal on the Wiki, Hack, etc...) have broken the path 
into two parts: scriptName and pathInfo. While I'm not particularly fond of 
those names, they do break the path into "traversed" and "non-traversed" 
portions of the URL. This is very useful for achieving "location independence" 
of one's code. While this API is trying to stay agnostic to the web framework, 
some degree of traversal is pretty universal, and I think it would benefit 
being in here.

The fields serverPort, serverName, and urlScheme are typically only used by an 
application to "reconstruct" URLs for inclusion in the response. This is a 
constant source of bugs in many web sites. It is also a problem in creating 
modular web frameworks, since the application can't be unaware of its context 
(unless the server interprets and re-writes HTML and other content on the fly - 
which isn't realistic.) Perhaps a better solution would be to pass a "URL 
generating" function in the Request and hide all this. Of course, web 
frameworks *could* use these data to dispatch on "virtual host" like 
configurations. Though, perhaps that is the provenance of the server side of 
the this API? I don't have a concrete proposal here, just a gut that the 
inclusion of these breaks some amount of encapsulation we'd like to achieve for 
the Applications.

The HTTP version information seems to have been dropped from Request. Alas, 
this is often needed when deciding what response headers to generate. I'm in 
favor of a simple data type for this:
        data HttpVersion = Http09 | Http10 | Http11

Using ByteString for all the non-body values I find awkward. Take headers, for 
example. The header names are going to come from a list of about 50 well known 
ones. It seems a shame that applications will be littered with expressions like:

        [(B.pack "Content-Type", B.pack "text/html;charset=UTF-8")]
Seems to me that it would be highly beneficial to include a module, say 
Network.WAI.Header, that defined these things:

        [(Hdr.contentType, Hdr.mimeTextHtmlUtf8)]

Further, since non-fixed headers will be built up out of many little String 
bits, I'd just as soon have the packing and unpacking be done by the server 
side of this API, and let the applications deal with Strings for these little 
snippets both in the Request and the Response.

For header names, in particular, it might be beneficial (and faster) to treat 
them like RequestMethod and make them a data type with nullary constructors for 
all 47 defined headers, and one ExtensionHeader String constructor.

Finally, note that HTTP/1.1 actually does well define the character encoding of 
these parts of the protocol. It is a bit hard to find in the spec, but the 
request line, status line and headers are all transmitted in ISO-8859-1, (with 
some restrictions), with characters outside the set encoded as per RFC 2047 
(MIME Message Header extensions). Mind you, I believe that most web servers 
*don't* do the 2047 decoding, and only either a) pass the strings as ISO-8859-1 
strings, or decode that to native Unicode strings.

        - Mark

Mark Lentczner
IRC: mtnviewmark

Haskell-Cafe mailing list
[email protected]

<Prev in Thread] Current Thread [Next in Thread>