It’s been long enough since Turbinado V0.4 that I figured I’d skip V0.5 and go straight to announcing Turbinado V0.6. Lots of new excellent features:

By popular demand, support for CGI serving. Apparently some web hosts don’t support HTTP proxying, so some folks requested CGI support.

Statically compiled Layouts, Views, Controllers.

Support for “.format” in routes. If a request path is “/User/List.xml”, then the following View will be called: /App/Views/User/List Xml .hs.

.hs. Lower case paths.

Support for cookies (see here for examples).

Encrypted cookie sessions (see here to see how to use them).

Much easier installs using cabal-install.

Support for GHC 6.10. GHC 6.8 is no longer supported.

Turbinado V0.7 will be all about:

Documentation. (seriously.)

User authentication.

Tutorials.

Installation

Installation is pretty painless if you use cabal-install, so make sure that you have cabal-install installed first. See here: http://hackage.haskell.org/trac/hackage/wiki/CabalInstall.

To install Turbinado:

git clone git@github.com:alsonkemp/turbinado-website.git cd turbinado-website cabal install [This might fail, saying that "trhsx" can't be found. However, "trhsx" was built during the install and is probably at ~/.cabal/bin/trhsx, so copy "trhsx" to your path and re-run "cabal install".]

CGI Configuration

[Note: you don’t want to use CGI without statically compiling in some Controllers, Layouts and Views. See below.]

Usually, Turbinado is called with “-p” to specify the port the process should listen on (e.g. “turbinado -p 8080”). When called with the “-c” flag, Turbinado will handle CGI requests. However, because of the process setup and tear down times, responding to CGI requests takes about 250ms, which is considerably slower than responding to HTTP requests (about 1ms).

Again following Rails, Turbinado includes a CGI script called “dispatch.cgi” in the /static directory.

Apache Configuration

In order to use Turbinado’s CGI functionality with Apache, you’ll need to something like the following in order to tell Apache to allow CGI scripts in your Turbinado /static directory and to send all requests (e.g. “^(.\*)$”) to the “dispatch.cgi” script.



DocumentRoot /home/alson/turbinado-website/static <Directory "/home/alson/turbinado-website/static"> Options +FollowSymLinks +ExecCGI +Includes AddHandler cgi-script .cgi AllowOverride None Order allow,deny Allow from all </Directory> RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/dispatch.cgi [QSA,L]

Static Compilation Of Resources

Turbinado is designed to dynamically compile and link in the various resources (Controllers, Layouts, Views) needed to serve a request. However, it can take up to 15 seconds to complete that process the first time a particular page is requested (subsequent requests are very fast). With CGI, the server only ever sees the first request, so Turbinado would never be able to serve a CGI request faster than 10-20 seconds.

To fix this, you can now compile into the server particular resources. See Config/Routes.hs here. Turbinado stores a function along with the file path and function name in a tuple, so you just give Turbinado that information in the Routes.hs file and it’ll load those functions into the CodeStore at startup:



staticLayouts = [ ("App/Layouts/Default.hs", "markup", App.Layouts.Default.markup) ]

Support for “formats”

Rails has great support for file formats. Turbinado is trying to follow that lead. The system will try to figure out the MIME type based on the extension. According to the standard routes (Config/Routes.hs), the following path=>View mappings will occur:



/abba/ding => /App/Views/Abba/Ding.hs /abba/ding.xml => /App/Views/Abba/DingXml.hs /bloof/snort/1.csv => /App/Views/Bloof/SnortCsv.hs

The same Controller handles all formats; only the View will change. Also, usage of a format causes a blank Layout to be used (on the assumption that you don’t want a Layout used with a CSV, XML, etc output).

Lower case paths

Turbinado now defaults to using lower case paths (configured in Config/App.hs), so the following paths get mapped to Controllers and Views as follows:



/abba/ding_fling => /App/Controllers/Abba.hs : dingFling => /App/Views/Abba/DingFling.hs

Cookies

Cookies are now supported. Examples here.



setCookie $ mkCookie "counter" (show 0) v <- getCookieValue "counter" deleteCookie "counter"

Cookie Sessions

Session data is encrypted and stuffed into a cookie. The encryption key is set in Config/App.hs. Session usage examples are here.



setSessionValue "counter" "0" v <- setSessionValue "counter" deleteSessionKey "counter" abandonSession