1 <a href="http://tarantool.org">
2 <img src="https://avatars2.githubusercontent.com/u/2344919?v=2&s=250"
6 # HTTP server for Tarantool 1.7.5+
8 [![Build Status](https://travis-ci.org/tarantool/http.png?branch=tarantool-1.7)](https://travis-ci.org/tarantool/http)
10 > **Note:** In Tarantool 1.7.5+, a full-featured HTTP client is available aboard.
11 > For Tarantool 1.6.5+, both HTTP server and client are available
12 > [here](https://github.com/tarantool/http/tree/tarantool-1.6).
16 * [Prerequisites](#prerequisites)
17 * [Installation](#installation)
19 * [Creating a server](#creating-a-server)
20 * [Using routes](#using-routes)
21 * [Contents of app\_dir](#contents-of-app_dir)
22 * [Route handlers](#route-handlers)
23 * [Fields and methods of the Request object](#fields-and-methods-of-the-request-object)
24 * [Fields and methods of the Response object](#fields-and-methods-of-the-response-object)
25 * [Examples](#examples)
26 * [Working with stashes](#working-with-stashes)
27 * [Special stash names](#special-stash-names)
28 * [Working with cookies](#working-with-cookies)
29 * [Rendering a template](#rendering-a-template)
30 * [Template helpers](#template-helpers)
32 * [handler(httpd, req)](#handlerhttpd-req)
33 * [before\_dispatch(httpd, req)](#before_dispatchhttpd-req)
34 * [after\_dispatch(cx, resp)](#after_dispatchcx-resp)
35 * [See also](#see-also)
39 * Tarantool 1.7.5+ with header files (`tarantool` && `tarantool-dev` packages)
45 * clone the repository and build the `http` module using CMake:
48 git clone https://github.com/tarantool/http.git
49 cd http && cmake . -DCMAKE_BUILD_TYPE=RelWithDebugInfo
54 * install the `http` module using `tarantoolctl`:
57 tarantoolctl rocks install http
60 * install the `http` module using LuaRocks
61 (see [TarantoolRocks](https://github.com/tarantool/rocks) for
62 LuaRocks configuration details):
65 luarocks install https://raw.githubusercontent.com/tarantool/http/master/http-scm-1.rockspec --local
70 The server is an object which is configured with HTTP request
71 handlers, routes (paths), templates, and a port to bind to.
72 Unless Tarantool is running under a superuser, port numbers
73 below 1024 may be unavailable.
75 The server can be started and stopped anytime. Multiple
76 servers can be created.
80 1. [Create it](#creating-a-server) with `httpd = require('http.server').new(...)`.
81 2. [Configure routing](#using-routes) with `httpd:route(...)`.
82 3. Start it with `httpd:start()`.
84 To stop the server, use `httpd:stop()`.
89 httpd = require('http.server').new(host, port[, { options } ])
92 `host` and `port` must contain the interface and port to bind to.
94 `options` may contain:
96 * `max_header_size` (default is 4096 bytes) - a limit for
97 HTTP request header size.
98 * `header_timeout` (default: 100 seconds) - a timeout until
99 the server stops reading HTTP headers sent by the client.
100 The server closes the client connection if the client doesn't
101 send its headers within the given amount of time.
102 * `app_dir` (default is '.', the server working directory) -
103 a path to the directory with HTML templates and controllers.
104 * `handler` - a Lua function to handle HTTP requests (this is
105 a handler to use if the module "routing" functionality is not
107 * `charset` - the character set for server responses of
108 type `text/html`, `text/plain` and `application/json`.
109 * `display_errors` - return application errors and backtraces to the client
111 * `log_errors` - log application errors using `log.error()`.
112 * `log_requests` - log incoming requests.
116 It is possible to automatically route requests between different
117 handlers, depending on the request path. The routing API is inspired
118 by [Mojolicious](http://mojolicio.us/perldoc/Mojolicious/Guides/Routing) API.
120 Routes can be defined using:
122 * an exact match (e.g. "index.php")
123 * simple regular expressions
124 * extended regular expressions
129 '/' -- a simple route
130 '/abc' -- a simple route
131 '/abc/:cde' -- a route using a simple regular expression
132 '/abc/:cde/:def' -- a route using a simple regular expression
133 '/ghi*path' -- a route using an extended regular expression
136 To configure a route, use the `route()` method of the `httpd` object:
139 httpd:route({ path = '/path/to' }, 'controller#action')
140 httpd:route({ path = '/', template = 'Hello <%= var %>' }, handle1)
141 httpd:route({ path = '/:abc/cde', file = 'users.html.el' }, handle2)
142 httpd:route({ path = '/objects', method = 'GET' }, handle3)
146 The first argument for `route()` is a Lua table with one or more keys:
148 * `file` - a template file name (can be relative to.
149 `{app_dir}/templates`, where `app_dir` is the path set when creating the
150 server). If no template file name extension is provided, the extension is
151 set to ".html.el", meaning HTML with embedded Lua.
152 * `template` - template Lua variable name, in case the template
153 is a Lua variable. If `template` is a function, it's called on every
154 request to get template body. This is useful if template body must be
155 taken from a database.
156 * `path` - route path, as described earlier.
157 * `name` - route name.
158 * `method` - method on the route like `POST`, `GET`, `PUT`, `DELETE`
160 The second argument is the route handler to be used to produce
161 a response to the request.
163 The typical usage is to avoid passing `file` and `template` arguments,
164 since they take time to evaluate, but these arguments are useful
165 for writing tests or defining HTTP servers with just one "route".
167 The handler can also be passed as a string of the form 'filename#functionname'.
168 In that case, the handler body is taken from a file in the
169 `{app_dir}/controllers` directory.
171 ## Contents of `app_dir`
173 * `public` - a path to static content. Everything stored on this path
174 defines a route which matches the file name, and the HTTP server serves this
175 file automatically, as is. Notice that the server doesn't use `sendfile()`,
176 and it reads the entire content of the file into the memory before passing
177 it to the client. ??? Caching is not used, unless turned on. So this is not
178 suitable for large files, use nginx instead.
179 * `templates` - a path to templates.
180 * `controllers` - a path to *.lua files with Lua controllers. For example,
181 the controller name 'module.submodule#foo' is mapped to
182 `{app_dir}/controllers/module.submodule.lua`.
186 A route handler is a function which accepts one argument (**Request**) and
187 returns one value (**Response**).
190 function my_handler(req)
191 -- req is a Request object
192 -- resp is a Response object
193 local resp = req:render({text = req.method..' '..req.path })
194 resp.headers['x-test-header'] = 'test';
200 ### Fields and methods of the Request object
202 * `req.method` - HTTP request type (`GET`, `POST` etc).
203 * `req.path` - request path.
204 * `req.query` - request arguments.
205 * `req.proto` - HTTP version (for example, `{ 1, 1 }` is `HTTP/1.1`).
206 * `req.headers` - normalized request headers. A normalized header
207 is in the lower case, all headers joined together into a single string.
208 * `req.peer` - a Lua table with information about the remote peer
209 (like `socket:peer()`).
210 * `tostring(req)` - returns a string representation of the request.
211 * `req:request_line()` - returns the request body.
212 * `req:read(delimiter|chunk|{delimiter = x, chunk = x}, timeout)` - reads the
213 raw request body as a stream (see `socket:read()`).
214 * `req:json()` - returns a Lua table from a JSON request.
215 * `req:post_param(name)` - returns a single POST request a parameter value.
216 If `name` is `nil`, returns all parameters as a Lua table.
217 * `req:query_param(name)` - returns a single GET request parameter value.
218 If `name` is `nil`, returns a Lua table with all arguments.
219 * `req:param(name)` - any request parameter, either GET or POST.
220 * `req:cookie(name)` - to get a cookie in the request.
221 * `req:stash(name[, value])` - get or set a variable "stashed"
222 when dispatching a route.
223 * `req:url_for(name, args, query)` - returns the route's exact URL.
224 * `req:render({})` - create a **Response** object with a rendered template.
225 * `req:redirect_to` - create a **Response** object with an HTTP redirect.
227 ### Fields and methods of the Response object
229 * `resp.status` - HTTP response code.
230 * `resp.headers` - a Lua table with normalized headers.
231 * `resp.body` - response body (string|table|wrapped\_iterator).
232 * `resp:setcookie({ name = 'name', value = 'value', path = '/', expires = '+1y', domain = 'example.com'))` -
233 adds `Set-Cookie` headers to `resp.headers`.
238 function my_handler(req)
241 headers = { ['content-type'] = 'text/html; charset=utf8' },
244 <body>Hello, world!</body>
251 ## Working with stashes
255 local id = self:stash('id') -- here is :id value
256 local user = box.space.users:select(id)
258 return self:redirect_to('/users_not_found')
260 return self:render({ user = user })
263 httpd = box.httpd.new('127.0.0.1', 8080)
265 { path = '/:id/view', template = 'Hello, <%= user.name %>' }, hello)
269 ### Special stash names
271 * `controller` - the controller name.
272 * `action` - the handler name in the controller.
273 * `format` - the current output format (e.g. `html`, `txt`). Is
274 detected automatically based on the request's `path` (for example, `/abc.js`
275 sets `format` to `js`). When producing a response, `format` is used
276 to serve the response's 'Content-type:'.
278 ## Working with cookies
280 To get a cookie, use:
283 function show_user(self)
285 local uid = self:cookie('id')
287 if uid ~= nil and string.match(uid, '^%d$') ~= nil then
289 local user = box.select(users, 0, uid)
290 return self:render({ user = user })
293 return self:redirect_to('/login')
297 To set a cookie, use the `cookie()` method as well, but pass to it a Lua
298 table defining the cookie to be set:
301 function user_login(self)
303 local login = self:param('login')
304 local password = self:param('password')
306 local user = box.select(users, 1, login, password)
308 return self:redirect_to('/'):
309 set_cookie({ name = 'uid', value = user[0], expires = '+1y' })
312 -- to login again and again and again
313 return self:redirect_to('/login')
317 The table must contain the following fields:
321 * `path` (optional; if not set, the current request path is used)
322 * `domain` (optional)
323 * `expires` - cookie expire date, or expire offset, for example:
328 * `+1m` - 1 month (30 days)
329 * `+1y` - 1 year (365 days)
331 ## Rendering a template
333 Lua can be used inside a response template, for example:
338 <title><%= title %></title>
343 <li><%= item[i].key %>: <%= item[i].value %></li>
350 To embed Lua code into a template, use:
352 * `<% lua-here %>` - insert any Lua code, including multi-line.
353 Can be used anywhere in the template.
354 * `% lua-here` - a single-line Lua substitution. Can only be
355 present at the beginning of a line (with optional preceding spaces
356 and tabs, which are ignored).
358 A few control characters may follow `%`:
360 * `=` (e.g., `<%= value + 1 %>`) - runs the embedded Lua code
361 and inserts the result into HTML. Special HTML characters,
362 such as `<`, `>`, `&`, `"`, are escaped.
363 * `==` (e.g., `<%== value + 10 %>`) - the same, but without
366 A Lua statement inside the template has access to the following
369 1. Lua variables defined in the template,
370 1. stashed variables,
371 1. variables standing for keys in the `render` table.
375 Helpers are special functions that are available in all HTML
376 templates. These functions must be defined when creating an `httpd` object.
378 Setting or deleting a helper:
382 httpd:helper('time', function(self, ...) return box.time() end)
384 httpd:helper('some_name', nil)
387 Using a helper inside an HTML template:
391 Current timestamp: <%= time() %>
395 A helper function can receive arguments. The first argument is
396 always the current controller. The rest is whatever is
397 passed to the helper from the template.
401 It is possible to define additional functions invoked at various
402 stages of request processing.
404 ### `handler(httpd, req)`
406 If `handler` is present in `httpd` options, it gets
407 involved on every HTTP request, and the built-in routing
408 mechanism is unused (no other hooks are called in this case).
410 ### `before_dispatch(httpd, req)`
412 Is invoked before a request is routed to a handler. The first
413 argument of the hook is the HTTP request to be handled.
414 The return value of the hook is ignored.
416 This hook could be used to log a request, or modify request headers.
418 ### `after_dispatch(cx, resp)`
420 Is invoked after a handler for a route is executed.
422 The arguments of the hook are the request passed into the handler,
423 and the response produced by the handler.
425 This hook can be used to modify the response.
426 The return value of the hook is ignored.
430 * [Tarantool project][Tarantool] on GitHub
431 * [Tests][] for the `http` module
433 [Tarantool]: http://github.com/tarantool/tarantool
434 [Tests]: https://github.com/tarantool/http/tree/tarantool-1.7/test