ANN: Salvia-1.0.0

Hi all, Straight from Zurihac: I'm very pleased to announce the 1.0.0 release of the Salvia web server. Salvia is a feature rich web server and web application framework that can be used to write dynamic websites in Haskell. From the lower level protocol code up to the high level application code, everything is written as a Salvia handler. This approach makes the framework extremely modular and extensible. This release include the following stack of packages: * salvia-protocol: Protocol stack containing URI, HTTP, Cookie and Mime. * salvia: Basic server interface and implementation. * salvia-extras: Additional server handlers and back end implementation. * salvia-sessions: Session and user management support. * salvia-websocket: Cutting edge HTML5 web socket support. * salvia-demo: Demo servers showing how to use Salvia. All the code is on Hackage[1] and the source repositories can be found on GitHub[2]. Most of the basic ideas of the previous Salvia release are still in these package, but all the code has been cleaned up considerably. There is now a very strong separation between interface and implementation making it more easy to plug-in new back-ends for your web application. To do a full install first run `cabal update' followed by `cabal install salvia-demo'. Now you can run the salvia-demo command and point your browser to http://localhost:8080/ . Thanks to the people that helped me with coding, suggestions and bug-reports. Any comments/suggestions are welcome! Have fun, -- Sebatiaan Visser [1] http://hackage.haskell.org/package/salvia (-protocol, -demo, etc) [2] http://github.com/sebastiaanvisser/salvia (-protocol, -demo, etc)

On Sun, 21 Mar 2010 17:07:01 +0100
"Sebastiaan" ==
wrote:
Sebastiaan> Straight from Zurihac: I'm very pleased to announce the Sebastiaan> 1.0.0 release of the Salvia web server. Congrats for the "new kid on the haskell's web block". :-) Sebastiaan> Salvia is a feature rich web server and web application Sebastiaan> framework that can be used to write dynamic websites in Sebastiaan> Haskell. From the lower level protocol code up to the high Sebastiaan> level application code, everything is written as a Salvia Sebastiaan> handler. This approach makes the framework extremely Sebastiaan> modular and extensible. Am I right, that it uses its own protocol, i.e. no WAI? Sebastiaan> * salvia-demo: Demo servers showing how to use Salvia. Is there some docs available besides the above package? Sebastiaan> Most of the basic ideas of the previous Salvia release are Sebastiaan> still in these package, but all the code has been cleaned Sebastiaan> up considerably. There is now a very strong separation Sebastiaan> between interface and implementation making it more easy to Sebastiaan> plug-in new back-ends for your web application. Any info how much resources it requires, i.e. is it in the category of Happs or one can deploy it on shared hosting? Does it play with other servers as proxy? Any support for database back-end? Sebastiaan> Thanks to the people that helped me with coding, Sebastiaan> suggestions and bug-reports. Any comments/suggestions are Sebastiaan> welcome! Excuse me for maybe dumb questions, but I'd like to hear more before venturing into installing several apps. Sincerely, Gour -- Gour | Hlapicina, Croatia | GPG key: F96FF5F6 ----------------------------------------------------------------

On Mar 21, 2010, at 5:41 PM, Gour wrote:
On Sun, 21 Mar 2010 17:07:01 +0100
"Sebastiaan" ==
wrote: Straight from Zurihac: I'm very pleased to announce the 1.0.0 release of the Salvia web server. Congrats for the "new kid on the haskell's web block". :-)
Thanks! :-)
Salvia is a feature rich web server and web application framework that can be used to write dynamic websites in Haskell. From the lower level protocol code up to the high level application code, everything is written as a Salvia handler. This approach makes the framework extremely modular and extensible.
Am I right, that it uses its own protocol, i.e. no WAI?
To answer your question: yes, Salvia uses its own protocol. Athough the term `protocol' might mean different things when looked at from different perspectives. How do I put this delicately? I do not think WAI is the way to go. On the Hackage page of WAI I read: "Provides a common protocol for communication between web aplications and web servers." This means that WAI is a proposed standardized interface intended to sit between server and a web application. There several reasons why I don't like the idea of a standardized interface between the application server and the web application. First of all, no one will ever agree on this type of interface. Not on the level of abstraction, not on the actual naming of the datatypes, not on the amount of documentation, not on the placement of the parenthesis. I, for example, don't like WAI at all: I do not want be forced to use enumerators for the output, ByteStrings for the input, only 10 predefined response codes, etc. Secondly, this type of interface will degrade projects like Happstack and Salvia to be mere `back-ends', which they are not. They are both server implementations _and_ interfaces to the programmer. Salvia for example is designed to be a combinator library (not a fixed API) in which some low-level protocol aspects, like keep-alive, http-range support, REST, serving HEAD requests are implemented in the same paradigm as the higher level web controllers. I truly like this idea and this will be totally invalidated by something like WAI of Hack. What I do like to see though, is something like the Ruby Rack interface, which calls itself a "a Ruby Webserver Interface". This is an interface between the actual OS/network and the application server, not an interface between an application server and the web application. Call it WSI not WAI, this subtle difference actually means a lot. This WSI would just give me file handle/socket and possible a pre-parsed HTTP message, but that is all. A Rack-like interface would allow me to run my Salvia web applications on any backend, like CGI, or in mod_haskell, in the blazingly fast iteratee based Hyena or behind an Apache proxy. But still, the web application is written against Salvia (or the framework you like most) and can piggy bag on all the neat features it supplies. Salvia itself has such a WSI, although I'm pretty sure this one is to abstract and high level to be a true candidate for any form of standardization.
* salvia-demo: Demo servers showing how to use Salvia.
Is there some docs available besides the above package?
No unfortunately, there is currently only the examples and the haddock documentation. We are working on a tutorial, but that will have to wait for a while. Sorry for that.
Most of the basic ideas of the previous Salvia release are still in these package, but all the code has been cleaned up considerably. There is now a very strong separation between interface and implementation making it more easy to plug-in new back-ends for your web application.
Any info how much resources it requires, i.e. is it in the category of Happs or one can deploy it on shared hosting?
It can run on its own server (like Happs) or as CGI. Whether you can easily deploy it probably depends on your hosting party, not on Salvia.
Does it play with other servers as proxy?
It can run as CGI or behind existing apache proxies without any problem. The codebase has some experimental support for running Salvia itself as a proxy server, but this code is not released yet because it needs some additional coding/polish/testing.
Any support for database back-end?
No, this is a web server package not a database. Off course you can use it to build database backed web applications, using any datastore you like. The Salvia project will never have built-in support for any form of data storage, I prefer to keep these aspects totally separated.
Thanks to the people that helped me with coding, suggestions and bug-reports. Any comments/suggestions are welcome!
Excuse me for maybe dumb questions, but I'd like to hear more before venturing into installing several apps.
At TypLAB[1] we use Happstack as our server back-end which works `pretty well', but we are sometimes a bit disappointed by it lack of matureness. The codebase is a bit messy and lacks some important features that you'll need when building `real applications'. I feel that Haskell is the true candidate for being the perfect web language, but we still have a long way to go. We should just keep on playing with new ideas and abstractions until we all see the big picture. Some standards will arise eventually.
Sincerely, Gour
Sincerely, -- Sebastiaan Visser [1] https://blog.typlab.com/

On Mon, 2010-03-22 at 15:59 +0100, Sebastiaan Visser wrote:
We should just keep on playing with new ideas and abstractions until we all see the big picture. Some standards will arise eventually.
Absolutely! It certainly strikes me as being too early to try to build the "one web framework/API" in Haskell. I share some reservations about WAI. It's certainly better than using lazy I/O for high-volume web servers, but the enumerator/iteratee stuff is far less obvious than lazy I/O as an abstraction. Let's spend some more time playing before building up pressure to rewrite web code using WAI. There's just no way we can know what other ideas people will come up with in the next few months or years. -- Chris Smith

On Mar 22, 2010, at 7:59 AM, Sebastiaan Visser wrote:
Am I right, that it uses its own protocol, i.e. no WAI?
To answer your question: yes, Salvia uses its own protocol. Athough the term `protocol' might mean different things when looked at from different perspectives.
How do I put this delicately? I do not think WAI is the way to go. ... First of all, no one will ever agree on this type of interface. Not on the level of abstraction, not on the actual naming of the datatypes, not on the amount of documentation, not on the placement of the parenthesis.
I don't entirely agree. The python community, for example, eventually standardized on WSGI for exactly that role (standard interface between webserver and webapp or framework). The difference, of course, is that Python had a decade-long history of dozens and dozens of different web app frameworks. There were a handful of different possible targets, though: mod_python, cgi, fastcgi, scgi, bespoke stuff. If you implemented one, you'd get constant feature requests for others. Eventually WSGI happened, and it's all been a good deal calmer since. It's very much in the haskell way of thinking to try and learn from other languages' problems. WAI, though, seems to be addressing a community problem instead of a language problem. In other words, i think it's a fine idea, but it won't be widely used until the haskell community actually goes through the sort of pain and suffering that forged the resolve to use WSGI in python. We have to learn that lesson the hard way. That's my take on it, anyhow, having watched the WSGI process firsthand. -john

On Mon, Mar 22, 2010 at 7:59 AM, Sebastiaan Visser
Am I right, that it uses its own protocol, i.e. no WAI?
To answer your question: yes, Salvia uses its own protocol. Athough the term `protocol' might mean different things when looked at from different perspectives.
How do I put this delicately? I do not think WAI is the way to go.
On the Hackage page of WAI I read: "Provides a common protocol for communication between web aplications and web servers." This means that WAI is a proposed standardized interface intended to sit between server and a web application. There several reasons why I don't like the idea of a standardized interface between the application server and the web application.
First of all, no one will ever agree on this type of interface. Not on the level of abstraction, not on the actual naming of the datatypes, not on the amount of documentation, not on the placement of the parenthesis. I, for example, don't like WAI at all: I do not want be forced to use enumerators for the output, ByteStrings for the input, only 10 predefined response codes, etc.
[..]
What I do like to see though, is something like the Ruby Rack interface,
which calls itself a "a Ruby Webserver Interface". This is an interface between the actual OS/network and the application server, not an interface between an application server and the web application. Call it WSI not WAI, this subtle difference actually means a lot.
This WSI would just give me file handle/socket and possible a pre-parsed HTTP message, but that is all. A Rack-like interface would allow me to run my Salvia web applications on any backend, like CGI, or in mod_haskell, in the blazingly fast iteratee based Hyena or behind an Apache proxy. But still, the web application is written against Salvia (or the framework you like most) and can piggy bag on all the neat features it supplies.
Salvia itself has such a WSI, although I'm pretty sure this one is to abstract and high level to be a true candidate for any form of standardization.
I'm not really sure what distinction you're trying to make here. Hack is (as I understand it) a direct port of Rack to Haskell. (I've never used Rack, so correct me if I'm wrong.) WAI is at the same level of abstraction as Hack, so it seems strange to say Rack == Good, Hack/WAI == Bad.
I'm also not certain what you mean by Rack being an interface between the OS and the webserver. I would think of POSIX as being an interface between the OS and the webserver. And yes, no one will ever agree on the right interface; but WAI (I believe) is general enough to work with most web programming approaches without sacrificing performance. Want to produce responses as lazy bytestrings? Go ahead, there's a built-in converter from a lazy bytestring to an enumerator. Finally, I think it's not that case that WAI degrades Happstack or Salvia to mere backends; instead, it *splits* them into backends and frontends. Happstack is experimenting with a WAI port right now, and if it works, the result will be a Happstack WAI-compliant server and a Happstack WAI-compliant application framework*. Michael * I know it's not exactly true to classify Happstack as that since they are really splitting it into a set of libraries, but it's a close approximation.

On Mar 22, 2010, at 7:51 PM, Michael Snoyman wrote:
On Mon, Mar 22, 2010 at 7:59 AM, Sebastiaan Visser
...
Salvia itself has such a WSI, although I'm pretty sure this one is to abstract and high level to be a true candidate for any form of standardization.
I'm not really sure what distinction you're trying to make here. Hack is (as I understand it) a direct port of Rack to Haskell. (I've never used Rack, so correct me if I'm wrong.) WAI is at the same level of abstraction as Hack, so it seems strange to say Rack == Good, Hack/WAI == Bad.
Isn't Hack the other way around? When I look at Hack.Handler.Happstack, I see the function `appToServerPart' which allows you to convert Hack applications to Happstack server parts. This means that it allows me to run my Hack applications on Happstack. That exactly the opposite of what I want, I want to run my Happstack applications on Hack. So I can use my favorite interface and my app will be deployable anywhere. Please correct me if I totally miss the point here. -- Sebastiaan Visser

great question! check hack-frontend-happstack :)
On Tue, Mar 23, 2010 at 4:10 PM, Sebastiaan Visser
On Mar 22, 2010, at 7:51 PM, Michael Snoyman wrote: On Mon, Mar 22, 2010 at 7:59 AM, Sebastiaan Visser
wrote: ...
Salvia itself has such a WSI, although I'm pretty sure this one is to abstract and high level to be a true candidate for any form of standardization.
I'm not really sure what distinction you're trying to make here. Hack is (as I understand it) a direct port of Rack to Haskell. (I've never used Rack, so correct me if I'm wrong.) WAI is at the same level of abstraction as Hack, so it seems strange to say Rack == Good, Hack/WAI == Bad.
Isn't Hack the other way around?
When I look at Hack.Handler.Happstack, I see the function `appToServerPart' which allows you to convert Hack applications to Happstack server parts.
This means that it allows me to run my Hack applications on Happstack. That exactly the opposite of what I want, I want to run my Happstack applications on Hack. So I can use my favorite interface and my app will be deployable anywhere.
Please correct me if I totally miss the point here.
-- Sebastiaan Visser
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel
-- jinjing

Just wanna point out it was MIchael Snoyman who came up with the
frontend idea and the first implementation: hack-handler-cgi.
It's simple but wasn't that obvious.
On Tue, Mar 23, 2010 at 4:12 PM, Jinjing Wang
great question! check hack-frontend-happstack :)
On Tue, Mar 23, 2010 at 4:10 PM, Sebastiaan Visser
wrote: On Mar 22, 2010, at 7:51 PM, Michael Snoyman wrote: On Mon, Mar 22, 2010 at 7:59 AM, Sebastiaan Visser
wrote: ...
Salvia itself has such a WSI, although I'm pretty sure this one is to abstract and high level to be a true candidate for any form of standardization.
I'm not really sure what distinction you're trying to make here. Hack is (as I understand it) a direct port of Rack to Haskell. (I've never used Rack, so correct me if I'm wrong.) WAI is at the same level of abstraction as Hack, so it seems strange to say Rack == Good, Hack/WAI == Bad.
Isn't Hack the other way around?
When I look at Hack.Handler.Happstack, I see the function `appToServerPart' which allows you to convert Hack applications to Happstack server parts.
This means that it allows me to run my Hack applications on Happstack. That exactly the opposite of what I want, I want to run my Happstack applications on Hack. So I can use my favorite interface and my app will be deployable anywhere.
Please correct me if I totally miss the point here.
-- Sebastiaan Visser
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel
-- jinjing
-- jinjing

Well, my thanks to you both. I have found Hack useful for - switching between happstack, hyena, simpleserver back ends to compare performance and identify bugs. - clarifying the boundary between my app and the web stack, reducing learning costs (better docs would have helped) - somewhat future-proofing my code, reducing churn as web stacks evolve - providing new options for my app almost for free via middleware and handlers (webkit handler!) I assume WAI would provide similar benefits in time, and more. Jinjing, what's your position on WAI ? Will you keep working on Hack, or should WAI replace it ?

I'm pretty satisfied with Hack, actually I have no complain at all.
The only thing the interface might change is to use bytestring through
out, but the performance benefit has not been properly measured, and
the current string interface is not entirely slow for general web apps
anyway, so until further benchmark provides concrete evidence in real
world applications, the interface is likely to stay as is.
I am personally using and probably will continue to use Hack, since I
don't need O(1) memory ( I use reverse proxy to serve static files,
and my html aren't that big ), I also don't need precise control over
resources ( wishful thinking here, hoping to solve it by using
strictness annotation ), so an enumerator approach, even thought it
provides great potentials, is not what I need right now.
But still, any development on WAI or WSI other interfaces are
extremely welcome, as those will not be wasted at all, at least from
my point of view, since the only thing I need is either a frontend or
a backend, and I can be sure that all my code will continue to work or
even benefit from other development.
I am only speaking for myself though and the website I made are not
high tech apps, just some stupid blog, some facebook apps and some
remote services for iphone and stuff like that.
So if you are lazy like me, then Hack is not a bad choice, in my
opinion, it's the best, why else would I make it like that? simple and
easy. If you need something else, then well you have to use something
else, or improve Hack, whatever ...
Best regards,
On Tue, Mar 23, 2010 at 9:34 PM, Simon Michael
Well, my thanks to you both. I have found Hack useful for
- switching between happstack, hyena, simpleserver back ends to compare performance and identify bugs. - clarifying the boundary between my app and the web stack, reducing learning costs (better docs would have helped) - somewhat future-proofing my code, reducing churn as web stacks evolve - providing new options for my app almost for free via middleware and handlers (webkit handler!)
I assume WAI would provide similar benefits in time, and more. Jinjing, what's your position on WAI ? Will you keep working on Hack, or should WAI replace it ?
_______________________________________________ web-devel mailing list web-devel@haskell.org http://www.haskell.org/mailman/listinfo/web-devel
-- jinjing

On Mon, 22 Mar 2010 15:59:24 +0100
"Sebastiaan" == Sebastiaan Visser
wrote:
Sebastiaan> How do I put this delicately? I do not think WAI is the way Sebastiaan> to go. OK. Sebastiaan> Secondly, this type of interface will degrade projects like Sebastiaan> Happstack and Salvia to be mere `back-ends', which they are Sebastiaan> not. I saw there is a recent thread in Happs mailing list entitled "experimental port of happstack-server to wai", and although I cannot comment on technical issues, it looks that they do not consider that Happs will become degraded? Sebastiaan> What I do like to see though, is something like the Ruby Sebastiaan> Rack interface, which calls itself a "a Ruby Webserver Sebastiaan> Interface". This is an interface between the actual Sebastiaan> OS/network and the application server, not an interface Sebastiaan> between an application server and the web application. Call Sebastiaan> it WSI not WAI, this subtle difference actually means a lot. Well, I'm not attached whether it is called WSI or WAI, just to see that the web-development market is not so fragmented, so that we can get some decent frameworks in order to make it easier to do web programming in Haskell. Sebastiaan> No unfortunately, there is currently only the examples and Sebastiaan> the haddock documentation. We are working on a tutorial, Sebastiaan> but that will have to wait for a while. Sorry for that. Heh, this is common scenario. :-) Sebastiaan> It can run on its own server (like Happs) or as CGI. What about FastCGI? Sebastiaan> Whether you can easily deploy it probably depends on your Sebastiaan> hosting party, not on Salvia. Well, I'm curious if one can deploy it on shared-hosting like e.g. Webfaction since not everyone can afford or like to admin VPS. Sebastiaan> It can run as CGI or behind existing apache proxies without Sebastiaan> any problem. The codebase has some experimental support for Sebastiaan> running Salvia itself as a proxy server, but this code is Sebastiaan> not released yet because it needs some additional Sebastiaan> coding/polish/testing. Good. I use Cherokee on webfaction - that's why I'm asking. Sebastiaan> No, this is a web server package not a database. Off course Sebastiaan> you can use it to build database backed web applications, Sebastiaan> using any datastore you like. The Salvia project will never Sebastiaan> have built-in support for any form of data storage, I Sebastiaan> prefer to keep these aspects totally separated. Ahh, I read announcement where it says that "Salvia is a feature rich web server and web application framework", so based on my experiences with e.g. Python frameworks, there is usually some kind of ORM support so that one can plug database easily. That's why I am expecting to see the easy way to e.g. use HDBC or something. Sebastiaan> I feel that Haskell is the true candidate for being the Sebastiaan> perfect web language, but we still have a long way to go. Heh, I've similar feeling...lot of potential, but (too) many different solutions. Sebastiaan> We should just keep on playing with new ideas and Sebastiaan> abstractions until we all see the big picture. Some Sebastiaan> standards will arise eventually. Well, I know some people who object about HP thinking that it is not good that some libs (from the same category) were preferred ove the others, but I still feel that having HP or Haskell's 'batteries included' is good stuff to consolidate things a bit and provide assurance there is some 'standard set' of libs playing nicely together and that it will be supported. That's why I fail to understand why joining the forces and trying to evolve some 'standard practice' for web development is considered pre-mature? Similarly to HP, nobody is forced to use it and there is always free choise to choose whatever is suitable for someone, but HP is appreciated by many who wants stable & supported development platform. Although I'd like that it does not happen, it seems there is (some) truth in words of John who wrote in another reply: "...i think it's a fine idea, but it won't be widely used until the haskell community actually goes through the sort of pain and suffering that forged the resolve to use WSGI in python. We have to learn that lesson the hard way." Until then, Ruby & Python will continue increasing their web 'share' - "Avoid success at all costs." :-D Sincerely, Gour -- Gour | Hlapicina, Croatia | GPG key: F96FF5F6 ----------------------------------------------------------------

On Mon, Mar 22, 2010 at 9:59 AM, Sebastiaan Visser
How do I put this delicately? I do not think WAI is the way to go.
On the Hackage page of WAI I read: "Provides a common protocol for communication between web aplications and web servers." This means that WAI is a proposed standardized interface intended to sit between server and a web application. There several reasons why I don't like the idea of a standardized interface between the application server and the web application.
First of all, no one will ever agree on this type of interface. Not on the level of abstraction, not on the actual naming of the datatypes, not on the amount of documentation, not on the placement of the parenthesis. I, for example, don't like WAI at all: I do not want be forced to use enumerators for the output, ByteStrings for the input, only 10 predefined response codes, etc.
I am not thrilled about certain aspects of Wai. For example, the Status type names the constructors after their numeric value instead of their more human friendly names. But at the same time, happstack users are not really going to know the difference. If you look at: http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happsta... you will see that happstack provides it's own combinators for handling the response code -- so the end user won't even see a difference between the normal happstack server and the wai based one. In a similar vain, being 'forced to use enumerators for the output' is not really a big deal for happstack. Responses are often created by calling toResponse from the ToMessage class: http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happsta... It is easy to just stick in a call to fromLBS (from lazy bytestring) to convert the existing lazy bytestring classes to use enumerators. (You don't get the fully power of enumerators that way, but it does mean that enumerators don't have to be invasive). I don't see the bytestring input as being an issue either.. the network libraries are giving us either Strings or ByteStrings, so it seems like a good starting point. Once again, the happstack libraries already provide abstractions so that you can get the processed data in a variety of different formats. The low-level representation is not often seen directly by the end the user.
Secondly, this type of interface will degrade projects like Happstack and Salvia to be mere `back-ends', which they are not. They are both server implementations _and_ interfaces to the programmer. Salvia for example is designed to be a combinator library (not a fixed API) in which some low-level protocol aspects, like keep-alive, http-range support, REST, serving HEAD requests are implemented in the same paradigm as the higher level web controllers. I truly like this idea and this will be totally invalidated by something like WAI of Hack.
I think Wai has a lot to offer to Happstack. As I have demonstrated already, swapping out the lazy I/O server in happstack with Wai is almost not noticeable to the end user. But we get a few nice things 'for free'. The user now has the option of constructing responses that use enumerators instead of only being able to use lazy ByteStrings. And we can get other middleware for free. At present, happstack has it's own private code for supporting compressed output. But with wai, would we get that for free and could have spent the time doing something new instead. It should also make it easier for non-happstack projects to use happstack things like ServerMonad with out being tied to the happstack lazy I/O server. Seems like there are still a lot of people interested in CGI and shared servers. In happstack-wai the ServerMonad module does not depend on any other happstack specific modules. So we could actually split that into a standalone library that is usuable with any Wai based app. This would allow people to get a taste of happstack with out having to commit to our whole framework. What I do like to see though, is something like the Ruby Rack interface,
which calls itself a "a Ruby Webserver Interface". This is an interface between the actual OS/network and the application server, not an interface between an application server and the web application. Call it WSI not WAI, this subtle difference actually means a lot.
This WSI would just give me file handle/socket and possible a pre-parsed HTTP message, but that is all. A Rack-like interface would allow me to run my Salvia web applications on any backend, like CGI, or in mod_haskell, in the blazingly fast iteratee based Hyena or behind an Apache proxy. But still, the web application is written against Salvia (or the framework you like most) and can piggy bag on all the neat features it supplies.
I am not really clear on what your vision here is. A file handle/socket sounds pretty low-level. CGI passes information differently than a direct HTTP connection. Would you want your application to have to know about those differences and to handle them specifically? In what ways does the Request type in Wai not meet your desire for a pre-parsed HTTP message ? If you wanted to use your app with Hyena, then wouldn't your app need to return an iteratee based response? My apps run unmodified when I stick them behind an Apache proxy.. what does Wai / Rack need to provide? I think the interesting part of happstack server is what it does to build functions of the type Request -> IO Response. The low-level part where it actually has to talk to a socket and parse something into a Request or send the Response over the network is not a very innovative part of happstack-server. I would much prefer to let a project like hyena focus on that aspect. Your goals for Salvia are likely different than happstack's and so wai may not be good for you. I just wanted to give you a picture of why the happstack project might be excited by Wai rather than feeling like it is being relegated to a boring backend. If anything I think that is backwards -- Wai is providing the 'backend' and happstack is the frontend. Wai gives us the ability to swap in different backends with no changes to a happstack application. That means we can get out of the business of backends and focus on the parts of happstack that deliver unique value. - jeremy

On Tue, Mar 23, 2010 at 10:00 AM, Jeremy Shaw
I am not thrilled about certain aspects of Wai. For example, the Status type names the constructors after their numeric value instead of their more human friendly names. But at the same time, happstack users are not really going to know the difference. If you look at:
http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happsta...
you will see that happstack provides it's own combinators for handling the response code -- so the end user won't even see a difference between the normal happstack server and the wai based one.
I would just like to make two comments on this. Firstly, I think layering a library on top of WAI is a perfect method for interacting with it the way you want to. Secondly, WAI is not yet entrenched enough to be "set in stone," and there are most definitely design decisions which are sub-optimal. If anyone is interested in changing the interface for WAI, I suggest they bring up the ideas sooner rather than later. I can think of a few issues that have been broached so far: * "I don't like enumerators." Well, that one is going to be sticking around, sorry. It's the whole impetus for WAI. If you want lazy bytestrings, use Hack, it's a great package. Or even better: just layer your lazy bytestrings on top of WAI; the reason the request body is a Source instead of an Enumerator is so that it can be easily converted to a lazy bytestring. * "It's using the wrong type of enumerators." I don't think it makes sense at this point to add an iteratee dependency, since it appears that package is young and unstable. If someone wants to suggest a different definition for the Enumerator type *and explain why it's better,* I'm all ears. * "Request and response headers should not have their own data types." I'm open to discussion on this issue, though it's very pertinent to the next point. * "Request and response headers should have case-insensitive match for the Eq instance." I'm thinking that this is the correct approach to take, and would like input on it. (Thanks Gregory. * "Status200 -> StatusOK." Once again, I have no strong feelings on this, but I thought it was less debatable to use numeric codes than to pick a name. For example, can anyone agree on what we should call code 302? I'll make sure that WAI follows the PVP, so making these changes should not affect code in use. Michael

On Tue, 2010-03-23 at 13:53 -0700, Michael Snoyman wrote:
If anyone is interested in changing the interface for WAI, I suggest they bring up the ideas sooner rather than later.
For my part, since I did say something about this, my concern wasn't really anything I'd like to see changed in WAI, so much as to say that it seems a tad early to be spreading an expectation that web app stuff in Haskell will be done via WAI. So I was not objecting to WAI itself; but rather to seeing the announcement of Salvia greeted with a nearly-immediate "is it WAI compliant?" I also won't hide my distaste for the enumerator-based approach; but it's a distaste that is so far not accompanied by having a better alternative. -- Chris Smith

On Tue, 23 Mar 2010 15:18:12 -0600
"Chris" == Chris Smith wrote:
Hello Chris, Chris> So I was not objecting to WAI itself; but rather to seeing the Chris> announcement of Salvia greeted with a nearly-immediate "is it Chris> WAI compliant?" Hmm, you wrote: "I share some reservations about WAI. It's certainly better than using lazy I/O for high-volume web servers, but the enumerator/iteratee stuff is far less obvious than lazy I/O as an abstraction.", so it might be (due to not being native speaker) that I do not understand it properly, but, otoh, my reasoning is that if Happstack which is kind of veteran in the young Haskell web-development scene sees the value of having WAI and providing port for it, then it I believe my question is not so much off. Sincerely, Gour -- Gour | Hlapicina, Croatia | GPG key: F96FF5F6 ----------------------------------------------------------------

Michael Snoyman
* "Request and response headers should have case-insensitive match for the Eq instance." I'm thinking that this is the correct approach to take, and would like input on it. (Thanks Gregory.
Here's our (dead simple) code for this:
------------------------------------------------------------------------
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.CIByteString
( CIByteString
, toCI
, unCI
) where
-- for IsString instance
import Data.ByteString.Char8 ()
import Data.ByteString (ByteString)
import Data.ByteString.Internal (c2w, w2c)
import qualified Data.ByteString as S
import Data.Char
import Data.String
-- | A case-insensitive newtype wrapper for ByteString
data CIByteString = CIByteString { unCI :: !ByteString
, _lowercased :: !ByteString }
toCI :: ByteString -> CIByteString
toCI s = CIByteString s t
where
t = lowercase s
instance Show CIByteString where
show (CIByteString s _) = show s
lowercase :: ByteString -> ByteString
lowercase = S.map (c2w . toLower . w2c)
instance Eq CIByteString where
(CIByteString _ a) == (CIByteString _ b) = a == b
(CIByteString _ a) /= (CIByteString _ b) = a /= b
instance Ord CIByteString where
(CIByteString _ a) <= (CIByteString _ b) = a <= b
instance IsString CIByteString where
fromString = toCI . fromString
------------------------------------------------------------------------
Note that we store the downcased version in the datatype, otherwise
Eq/Ord has to perform the downcase a zillion times, only to throw it
away afterwards. Note also that we ignore any encoding issues -- we can
get away w/ this because HTTP header names are constrained by the
protocol to be ASCII-only.
This datatype also has an "IsString" instance so you can use string
literals with "{-# LANGUAGE OverloadedStrings #-}" turned on.
G.
--
Gregory Collins

On Tue, Mar 23, 2010 at 3:53 PM, Michael Snoyman
I would just like to make two comments on this. Firstly, I think layering a library on top of WAI is a perfect method for interacting with it the way you want to. Secondly, WAI is not yet entrenched enough to be "set in stone," and there are most definitely design decisions which are sub-optimal.
Right. I figured the only way it was going to actually get good is if people were using it :) Some people have suggested it is not the right thing and we should wait until we have more experience before creating something like WAI. But I figure WAI is a good start, and trying to actually use it is what will uncover the problems. My only complaint would be if it *was* set in stone to early.
If anyone is interested in changing the interface for WAI, I suggest they bring up the ideas sooner rather than later. I can think of a few issues that have been broached so far:
* "Request and response headers should not have their own data types." I'm open to discussion on this issue, though it's very pertinent to the next point.
It does feel a bit weird that some headers will have constructors, and other won't. Uniformity feels pretty. Unfortunately, there is no way to extend data types in 3rd party libraries. But we could add functions that add new headers in other libraries. For example, if you look at FilterT in happstack-wai, it has a bunch of functions for the different status codes. If a user wants to add additional functions in their own library, they can -- and they will feel just like the built-in functions. No idea if something similar would make sense for wai and the http headers.
* "Request and response headers should have case-insensitive match for the Eq instance." I'm thinking that this is the correct approach to take, and would like input on it. (Thanks Gregory.
I have dealt with this at all, so no idea. * "Status200 -> StatusOK." Once again, I have no strong feelings on this,
but I thought it was less debatable to use numeric codes than to pick a name. For example, can anyone agree on what we should call code 302?
Found? I would just camel case all the names provided on this page: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html Though, I don't really care all that much, because the code for FilterT has already been written, so I'll never have to see the constructors again :p - jeremy
participants (9)
-
Chris Smith
-
Gour
-
Gregory Collins
-
Jeremy Shaw
-
Jinjing Wang
-
John Melesky
-
Michael Snoyman
-
Sebastiaan Visser
-
Simon Michael