turbo.web – Core web framework

The Turbo.lua Web framework is modeled after the framework offered by Tornado (http://www.tornadoweb.org/), which again is based on web.py (http://webpy.org/) and Google’s webapp (http://code.google.com/appengine/docs/python/tools/webapp/) Some modifications has been made to make it fit better into the Lua eco system. The web framework utilizes asynchronous features that allow it to scale to large numbers of open connections (thousands). The framework support comet polling.

Create a web server that listens to port 8888 and prints the canoncial Hello world on a GET request is very easy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
     local turbo = require('turbo')

     local ExampleHandler = class("ExampleHandler", turbo.web.RequestHandler)
     function ExampleHandler:get()
             self:write("Hello world!")
     end

     local application = turbo.web.Application({
             {"^/$", ExampleHandler}
     })
     application:listen(8888)
     turbo.ioloop.instance():start()

RequestHandler class

Base RequestHandler class. The heart of Turbo.lua. The usual flow of using Turbo.lua is sub-classing the RequestHandler class and implementing the HTTP request methods described in self.SUPPORTED_METHODS. The main goal of this class is to wrap a HTTP request and offer utilities to respond to the request. Requests are deligated to RequestHandler’s by the Application class. The RequestHandler class are implemented so that it should be subclassed to process HTTP requests.

It is possible to modify self.SUPPORT_METHODS to add support for more methods if that is wanted.

Entry points

RequestHandler:on_create(kwargs)

Redefine this method if you want to do something straight after the class has been initialized. This is called after a request has been received, and before the HTTP method has been verified against supported methods. So if a not supported method is requested, this method is still called.

Parameters:kwargs (Table) – The keyword arguments that you initialize the class with.
RequestHandler:prepare()

Redefine this method if you want to do something after the class has been initialized. This method unlike on_create, is only called if the method has been found to be supported.

RequestHandler:on_finish()

Called after the end of a request. Useful for e.g a cleanup routine.

RequestHandler:set_default_headers()

Redefine this method to set HTTP headers at the beginning of all the request received by the RequestHandler. For example setting some kind of cookie or adjusting the Server key in the headers would be sensible to do in this method.

Subclass RequestHandler and implement any of the following methods to handle the corresponding HTTP request. If not implemented they will provide a 405 (Method Not Allowed). These methods receive variable arguments, depending on what the Application instance calling them has captured from the pattern matching of the request URL. The methods are run protected, so they are error safe. When a error occurs in the execution of these methods the request is given a 500 Internal Server Error response. In debug mode, the stack trace leading to the crash is also a part of the response. If not debug mode is set, then only the status code is set.

RequestHandler:get(...)

HTTP GET reqests handler.

Parameters:.. – Parameters from matched URL pattern with braces. E.g /users/(.*)$ would provide anything after /users/ as first parameter.
RequestHandler:post(...)

HTTP POST reqests handler.

Parameters:.. – Parameters from matched URL pattern with braces.
RequestHandler:head(...)

HTTP HEAD reqests handler.

Parameters:.. – Parameters from matched URL pattern with braces.
RequestHandler:delete(...)

HTTP DELETE reqests handler.

Parameters:.. – Parameters from matched URL pattern with braces.
RequestHandler:put(...)

HTTP PUT reqests handler.

Parameters:.. – Parameters from matched URL pattern with braces.
RequestHandler:options(...)

HTTP OPTIONS reqests handler.

Parameters:.. – Parameters from matched URL pattern with braces.

Input

RequestHandler:get_argument(name, default, strip)

Returns the value of the argument with the given name. If default value is not given the argument is considered to be required and will result in a raise of a HTTPError 400 Bad Request if the argument does not exist.

Parameters:
  • name (String) – Name of the argument to get.
  • default (String) – Optional fallback value in case argument is not set.
  • strip (Boolean) – Remove whitespace from head and tail of string.
Return type:

String

RequestHandler:get_arguments(name, strip)

Returns the values of the argument with the given name. Should be used when you expect multiple arguments values with same name. Strip will take away whitespaces at head and tail where applicable. Returns a empty table if argument does not exist.

Parameters:
  • name (String) – Name of the argument to get.
  • strip (Boolean) – Remove whitespace from head and tail of string.
Return type:

Table

RequestHandler:get_json(force)

Returns JSON request data as a table. By default, it only parses request with “application/json” as content-type header.

Parameters:force (Boolean) – If force is set to true, all request will be parsed regardless of content-type header.
Return type:Table or nil
RequestHandler:get_cookie(name, default)

Get cookie value from incoming request.

Parameters:
  • name (String) – The name of the cookie to get.
  • default (String) – A default value if no cookie is found.
Return type:

String or nil if not found

RequestHandler:get_secure_cookie(name, default, max_age)

Get a signed cookie value from incoming request.

If the cookie can not be validated, then an error with a string error is raised.

Hash-based message authentication code (HMAC) is used to be able to verify that the cookie has been created with the “cookie_secret” set in the Application class kwargs. This is simply verifing that the cookie has been signed by your key, IT IS NOT ENCRYPTING DATA.

Parameters:
  • name (String) – The name of the cookie to get.
  • default (String) – A default value if no cookie is found.
  • max_age (Number) – Timestamp used to sign cookie must be not be older than this value in seconds.
Return type:

String or nil if not found

RequestHandler:set_cookie(name, value, domain, expire_hours)

Set a cookie with value to response.

Note: Expiring relies on the requesting browser and may or may not be respected. Also keep in mind that the servers time is used to calculate expiry date, so the server should ideally be set up with NTP server.

Parameters:
  • name (String) – The name of the cookie to set.
  • value (String) – The value of the cookie:
  • domain (String) – The domain to apply cookie for.
  • expire_hours (Number) – Set cookie to expire in given amount of hours.
RequestHandler:set_secure_cookie(name, value, domain, expire_hours)

Set a signed cookie value to response.

Hash-based message authentication code (HMAC) is used to be able to verify that the cookie has been created with the “cookie_secret” set in the Application class kwargs. This is simply verifing that the cookie has been signed by your key, IT IS NOT ENCRYPTING DATA.

Note: Expiring relies on the requesting browser and may or may not be respected. Also keep in mind that the servers time is used to calculate expiry date, so the server should ideally be set up with NTP server.

Parameters:
  • name (String) – The name of the cookie to set.
  • value (String) – The value of the cookie:
  • domain (String) – The domain to apply cookie for.
  • expire_hours (Number) – Set cookie to expire in given amount of hours.
RequestHandler.request:
 turbo.httpserver.HTTPRequest class instance for this request. This object contains e.g turbo.httputil.HTTPHeader and the body payload etc. See the documentation for the classes for more details.

Output

RequestHandler:write(chunk)

Writes the given chunk to the output buffer. To write the output to the network, call the turbo.web.RequestHandler:flush() method. If the given chunk is a Lua table, it will be automatically stringifed to JSON.

Parameters:chunk (String) – Data chunk to write to underlying connection.
RequestHandler:finish(chunk)

Finishes the HTTP request. This method can only be called once for each request. This method flushes all data in the write buffer.

Parameters:chunk (String) – Final data to write to stream before finishing.
RequestHandler:flush(callback)

Flushes the current output buffer to the IO stream.

If callback is given it will be run when the buffer has been written to the socket. Note that only one callback flush callback can be present per request. Giving a new callback before the pending has been run leads to discarding of the current pending callback. For HEAD method request the chunk is ignored and only headers are written to the socket.

Parameters:callback (Function) – Function to call after the buffer has been flushed.
RequestHandler:clear()

Reset all headers, empty write buffer in a request.

RequestHandler:add_header(name, value)

Add the given name and value pair to the HTTP response headers.

Parameters:
  • name (String) – Key string for header field.
  • value (String) – Value for header field.
RequestHandler:set_header(name, value)

Set the given name and value pair of the HTTP response headers. If name exists then the value is overwritten.

Parameters:
  • name (String) – Key string for header field.
  • value (String) – Value for header field.
RequestHandler:get_header(name)

Returns the current value of the given name in the HTTP response headers. Returns nil if not set.

Parameters:name (String) – Name of value to get.
Return type:String or nil
RequestHandler:set_status(code)

Set the status code of the HTTP response headers. Must be number or error is raised.

Parameters:code (Number) – HTTP status code to set.
RequestHandler:get_status()

Get the curent status code of the HTTP response headers.

Return type:Number
RequestHandler:redirect(url, permanent)

Redirect client to another URL. Sets headers and finish request. User can not send data after this.

Parameters:
  • url (String) – The URL to redirect to.
  • permanent (Boolean) – Flag this as a permanent redirect or temporary.

Misc

RequestHandler:set_async(bool)

Set handler to not call finish() when request method has been called and returned. Default is false. When set to true, the user must explicitly call finish.

Parameters:bool (Boolean) –

HTTPError class

This error is raisable from RequestHandler instances. It provides a convinent and safe way to handle errors in handlers. E.g it is allowed to do this:

1
2
3
4
5
6
7
     function MyHandler:get()
         local item = self:get_argument("item")
          if not find_in_store(item) then
              error(turbo.web.HTTPError(400, "Could not find item in store"))
          end
          ...
     end

The result is that the status code is set to 400 and the message is sent as the body of the request. The request is always finished on error.

HTTPError(code, message)

Create a new HTTPError class instance.

Parameters:
  • code (Number) – The HTTP status code to send to send to client.
  • message (String) – Optional message to pass as body in the response.

StaticFileHandler class

A static file handler for files on the local file system. All files below user defined _G.TURBO_STATIC_MAX or default 1MB in size are stored in memory after initial request. Files larger than this are read from disk on demand. If TURBO_STATIC_MAX is set to -1 then cache is disabled.

Usage:

local app = turbo.web.Application:new({
        {"^/$", turbo.web.StaticFileHandler, "/var/www/index.html"},
        {"^/(.*)$", turbo.web.StaticFileHandler, "/var/www/"}
})

Paths are not checked until intial hit on handler. The file is then cached in memory if it is a valid path. Notice that paths postfixed with / indicates that it should be treated as a directory. Paths with no / is treated as a single file.

RedirectHandler class

A simple redirect handler that simply redirects the client to the given URL in 3rd argument of a entry in the Application class’s routing table.

local application = turbo.web.Application({
    {"^/redirector$", turbo.web.RedirectHandler, "http://turbolua.org"}
})

Application class

The Application class is a collection of request handler classes that make together up a web application. Example:

1
2
3
4
5
     local application = turbo.web.Application({
             {"^/static/(.*)$", turbo.web.StaticFileHandler, "/var/www/"},
             {"^/$", ExampleHandler},
             {"^/item/(%d*)", ItemHandler}
     })

The constructor of this class takes a “map” of URL patterns and their respective handlers. The third element in the table are optional parameters the handler class might have. E.g the turbo.web.StaticFileHandler class takes the root path for your static handler. This element could also be another table for multiple arguments.

The first element in the table is the URL that the application class matches incoming request with to determine how to serve it. These URLs simply be a URL or a any kind of Lua pattern.

The ItemHandler URL pattern is an example on how to map numbers from URL to your handlers. Pattern encased in parantheses are used as parameters when calling the request methods in your handlers.

Note: Patterns are matched in a sequential manner. If a request matches multiple handler pattern’s only the first handler matched is delegated the request. Therefore, it is important to write good patterns.

A good read on Lua patterns matching can be found here: http://www.wowwiki.com/Pattern_matching.

Application(handlers, kwargs)

Initialize a new Application class instance.

Parameters:
  • handlers (Table) – As described above. Table of tables with pattern to handler binding.
  • kwargs (Table) – Keyword arguments

Keyword arguments supported:

  • “default_host” (String) - Redirect to this URL if no matching handler is found.
  • “cookie_secret” (String) - Sequence of bytes used to sign secure cookies.
Application:add_handler(pattern, handler, arg)

Add handler to Application.

Parameters:
  • pattern (String) – Lua pattern string.
  • handler (RequestHandler based class) –
  • arg – Argument for handler.
Application:listen(port, address, kwargs)

Starts an HTTP server for this application on the given port. This is really just a convinence method. The same effect can be achieved by creating a turbo.httpserver.HTTPServer class instance and assigning the Application instance to its request_callback parameter and calling its listen() method.

Parameters:
  • port (Number) – Port to bind server to.
  • address (String or number.) – Address to bind server to. E.g “127.0.0.1”.
  • kwargs (Table) – Keyword arguments passed on to turbo.httpserver.HTTPServer. See documentation for available options. This is used to set SSL certificates amongst other things.
Application:set_server_name(name)

Sets the name of the server. Used in the response headers.

Parameters:name (String) – The name used in HTTP responses. Default is “Turbo vx.x”
Application:get_server_name()

Gets the current name of the server. :rtype: String

Mustache Templating

Turbo.lua has a small and very fast Mustache parser built-in. Mustache templates are logic-less templates, which are supposed to help you keep your business logic outside of templates and inside “controllers”. It is widely known by Javascript developers and very simple to understand.

For more information on the Mustache markup, please see this: http://mustache.github.io/mustache.5.html

Mustache.compile(template)

Compile a Mustache highlighted string into its intermediate state before rendering. This function does some validation on the template. If it finds syntax errors a error with a message is raised. It is always a good idea to cache pre-compiled frequently used templates before rendering them. Although compiling each time is usally not a big overhead. This function can throw errors if the template contains invalid logic.

Parameters:template – (String) Template in string form.
Return type:Parse table that can be used for Mustache.render function
Mustache.render(template, obj, partials, allow_blank)

Render a template. Accepts a parse table compiled by Mustache.compile or a uncompiled string. Obj is the table with keys. This function can throw errors in case of un-compiled string being compiled with Mustache.compile internally.

Parameters:
  • template – Accepts a pre-compiled template or a un-compiled string.
  • obj (Table) – Parameters for template rendering.
  • partials (Table) – Partial snippets. Will be treated as static and not compiled...
  • allow_blank – Halt with error if key does not exist in object table.

Example templating:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 <body>
     <h1>
             {{heading }}
     </h1>
     {{!
         Some comment section that
         even spans across multiple lines,
         that I just have to have to explain my flawless code.
     }}
     <h2>
         {{{desc}}} {{! No escape with triple mustaches allow HTML tags! }}
         {{&desc}} {{! No escape can also be accomplished by & char }}
     </h2>
     <p>I am {{age}} years old. What would you like to buy in my shop?</p>
     {{  #items }}  {{! I like spaces alot!          }}
         Item: {{item}}
         {{#types}}
                 {{! Only print items if available.}}
                 Type available: {{type}}
         {{/types}}
         {{^types}}  Only one type available.
         {{! Apparently only one type is available because types is not set,
         determined by the hat char ^}}
         {{/types}}
     {{/items}}
     {{^items}}
             No items available!
     {{/items}}
 </body>

With a render table likes this:

{
    heading="My website!",
    desc="<b>Big important website</b>",
    age=27,
    items={
              {item="Bread",
                  types={
                      {type="light"},
                      {type="fatty"}
                  }
          },
          {item="Milk"},
          {item="Sugar"}
   }
}

Will produce this output after rendering:

<body>
    <h1>
        My%20website%21
    </h1>
    <h2>
        <b>Big important website</b>
        <b>Big important website</b>
    </h2>
    <p>I am 27 years old. What would you like to buy in my shop?</p>
        Item: Bread
            Type available: light
            Type available: fatty
        Item: Milk
            Only one type available.
        Item: Sugar
            Only one type available.
</body>

Mustache.TemplateHelper class

A simple class that simplifies the loading of Mustache templates, pre-compile and cache them for future use.

Mustache.TemplateHelper(base_path)

Create a new TemplateHelper class instance.

Parameters:base_path (String) – Template base directory. This will be used as base path when loading templates using the load method.
Return type:Mustache.TemplateHelper class
Mustache.TemplateHelper:load(template)

Pre-load a template.

Parameters:template (String) – Template name, e.g file name in base directory.
Mustache.TemplateHelper:render(template, table, partials, allow_blank)

Render a template by name. If called twice the template will be cached from first time.

Parameters:
  • template (String) – Template name, e.g file name in base directory.
  • obj (Table) – Parameters for template rendering.
  • partials (Table) – Partial snippets. Will be treated as static and not compiled...
  • allow_blank – Halt with error if key does not exist in object table.