Service Modes

LaiRu can serve Lasso pages in three ways:

All three modes render .lasso, .lasso9, and .lp files and serve everything else as a static asset.

TCP Service

lairu serve --addr 127.0.0.1:9010 --docroot /var/www/html

nginx reverse proxy

server {
    listen 80;
    server_name example.test;
    location / {
        proxy_pass http://127.0.0.1:9010;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Apache reverse proxy

ProxyPreserveHost On
ProxyPass "/" "http://127.0.0.1:9010/"
ProxyPassReverse "/" "http://127.0.0.1:9010/"

Unix Socket

lairu serve --unix /run/lairu/lairu.sock --docroot /var/www/html

nginx (unix socket)

location / {
    proxy_pass http://unix:/run/lairu/lairu.sock:;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

FastCGI — lairu-fpm

lairu fpm and the standalone lairu-fpm binary implement a FastCGI responder. A non-empty DOCUMENT_ROOT from the web server overrides the process default, so multiple virtual hosts can share one FPM process.

lairu-fpm --unix /run/lairu/lairu-fpm.sock --docroot /var/www/html --max-children 8

nginx (FastCGI)

server {
    listen 80;
    server_name example.test;
    root /var/www/html;
    location / {
        include fastcgi_params;
        fastcgi_param DOCUMENT_ROOT $document_root;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_pass unix:/run/lairu/lairu-fpm.sock;
    }
}

Configuration (.ini)

Service and FPM commands accept --config path/to/lairu.ini. Without --config, LaiRu searches config/ next to the binary, then /etc/lairu/config/.

[paths]
installation_root = /etc/lairu
document_root     = /var/www/html
session_dir       = /var/lib/lairu/sessions

[interpreter]
template_cache    = on
parse_cache       = on
runtime_pool_size = 8
max_request_body  = 10485760
max_upload_bytes  = 5242880
trust_proxy       = on
session_store     = memory

[sessions]
store  = file
secret = change-me

[service]
listen = 127.0.0.1:9010

[liru-fpm]
listen       = 127.0.0.1:9000
max_children = 4
multiplex    = on

Request Handling

Request context available to templates

request_method           // 'GET', 'POST', etc.
request_path             // '/some/page'
request_host             // 'example.com'
request_scheme           // 'https' or 'http'
request_client_ip        // remote IP
request_query            // raw query string
request_param('id')      // query + form parameter
request_query_param('q') // query string only
request_form_param('email') // POST form field
request_header('Accept') // any request header
request_cookie('session_id')
request_body             // raw body (empty for multipart)

Response control

response_status(201)
response_header('X-App', 'lairu')
response_content_type('application/json')
response_redirect('/login')
response_no_cache
response_cookie('theme', 'dark', -path='/', -httpOnly, -secure, -sameSite='Strict')
response_expire_cookie('old_cookie')

Sessions

LaiRu uses a lairu_session cookie. Sessions are in-memory by default. Set LAIRU_SESSION_STORE=file and LAIRU_SESSION_DIR to persist sessions to disk. Set LAIRU_SESSION_SECRET to sign session cookies with HMAC-SHA256.

session_start
session_set('user', 'Ada')
session_get('user')
session_id
session_regenerate_id
session_destroy

File Uploads (multipart)

Multipart POST bodies are parsed part-by-part with robust binary boundary scanning. Files are spooled to a temp directory for large parts. Each uploaded file exposes:

local(f) = request_file('avatar')
#f->filename
#f->size
#f->content_type

Security and Admin Policies

security_set_user('ada', array('editor'), array('publish'))
security_is_authenticated   // true / false
security_has_role('editor') // true / false
security_require_permission('publish')   // fails if not granted

security_policy_allow('beta_feature')
security_policy_check('beta_feature')    // true

systemd

[Unit]
Description=LaiRu 0.1 Lasso runtime
After=network.target

[Service]
Type=simple
User=www-data
RuntimeDirectory=lairu
ExecStart=/usr/local/bin/lairu serve \
  --config /etc/lairu/config/lairu.ini \
  --unix /run/lairu/lairu.sock
Restart=on-failure

[Install]
WantedBy=multi-user.target