# Advanced PSGI usage

LLNG is build on Plack, so it can be used with any compatible server:

- Starman

- Twiggy

- Twiggy::Prefork

- Starman

- uWSGI using uWSGI PSGI plugin

- Alternative: Node.js handler can be used as FastCGI server, only for application protection

uWSGI or Node.js FastCGI server may provide the highest performance.

## FastCGI server replacement

A `llng-server.psgi` is provided in example directory. It is designed to replace exactly FastCGI server. You can use it :

- with a FCGI Plack server, but you just have to change llng-fastcgi-server engine (in /etc/default/lemonldap-ng-fastcgi-server) to have the same result. Available engines:

  - FCGI (default). It can use the following managers:

    - FCGI::ProcManager (default)

    - FCGI::ProcManager::Constrained

    - FCGI::ProcManager::Dynamic

  - AnyEvent::FCGI

  - FCGI::EV

  - FCGI::Engine

  - FCGI::Engine::ProcManager

  - FCGI::Async

- with uWSGI (see below)

Attention

Starman, Twiggy,… are HTTP servers, not FastCGI ones !

You can also replace only a part of it to create a specialized FastCGI server (portal,…). Look at `llng-server.psgi` example and take the part you want to use.

There are also some other psgi files in examples directory.

### LLNG FastCGI Server

`llng-fastcgi-server` can be launched with the following options:

Command-line options | Environment variable | Explanation
--- | --- | ---
Short | Long |  |
-p | –pid | PID | Process PID
-u | –user | USER | Unix uid
-g | –group | GROUP | Unix gid
-n | –proc | NPROC | Number of process to launch (FCGI::ProcManager)
-s | –socket | SOCKET | Socket to listen to
-l | –listen | LISTEN | Listening address. Examples: `host:port`, `:port`, `/socket/path`
-f | –customFunctionsFile | CUSTOM_FUNCTIONS_FILE | File to load for custom functions
-e | –engine | ENGINE | Plack::Handler engine, default to FCGI (see below)
| –plackOptions |  | Other options to path to Plack. Can bu multi-valued. Values must look like `--key=value`

See `llng-fastcgi-server(1)` manpage.

#### Some examples

FCGI with FCGI::ProcManager::Constrained

    llng-fastcgi-server -u nobody -g nobody -s /run/llng.sock -n 10 -e FCGI \
                        --plackOptions=--manager=FCGI::ProcManager::Constrained

FCGI::Engine::ProcManager

    llng-fastcgi-server -u nobody -g nobody -s /run/llng.sock -n 10 \
                        -e FCGI::Engine::ProcManager

### Using uWSGI

You must install uWSGI PSGI plugin. Then for example, launch llng-server.psgi (simple example):

    /usr/bin/uwsgi --plugins psgi --socket :5000 --uid www-data --gid www-data --psgi /usr/share/lemonldap-ng/llng-server/llng-server.psgi

You will find in LLNG Nginx configuration files some comments that explain how to configure Nginx to use uWSGI instead of LLNG FastCGI server.

#### Using Debian lemonldap-ng-uwsgi-app package

lemonldap-ng-uwsgi-app installs a uWSGI application: `/etc/uwsgi/apps-available/llng-server.yaml`. To enable it, link it in `apps-enabled` and restart your uWSGI daemon:

    apt-get install uwsgi uwsgi-plugin-psgi
    cd /etc/uwsgi/apps-enabled
    ln -s ../apps-available/llng-server.yaml
    service uwsgi restart

Then adapt your Nginx configuration to use this uWSGI app.

#### Configuration

To serve large requests with uWSGI, you could have to modify in uWSGI and/or Nginx init files several options. Example:

    workers = 4
    buffer-size = 65535
    limit-post = 0

    client_max_body_size 300M;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    proxy_connect_timeout 600;
    uwsgi_read_timeout 120;
    uwsgi_send_timeout 120;

Note

Nginx natively includes support for upstream servers speaking the uwsgi protocol since version 0.8.40. To improve performances, you can switch from a TCP socket to an Unix Domain Socket by editing `llng-server.yaml`:

    uwsgi:
            plugins: psgi
            socket: /tmp/uwsgi.sock

and adapting Nignx configuration files:

    # OR TO USE uWSGI
    include /etc/nginx/uwsgi_params;
    uwsgi_pass unix:///tmp/uwsgi.sock;
    uwsgi_param LLTYPE psgi;
    uwsgi_param SCRIPT_FILENAME $document_root$sc;
    uwsgi_param SCRIPT_NAME $sc;
    # Uncomment this if you use Auth SSL:
    #uwsgi_param  SSL_CLIENT_S_DN_CN $ssl_client_s_dn_cn;

## Protect a PSGI application

LLNG provides `Plack::Middleware::Auth::LemonldapNG` that can be used to protect any PSGI application: it acts exactly like a LLNG handler. Simple example:

    use Plack::Builder;

    my $app   = sub { ... };
    builder {
        enable "Auth::LemonldapNG";
        $app;
    };

More advanced example:

    use Plack::Builder;

    my $app   = sub { ... };

    # Optionally ($proposedResponse is the PSGI response of Lemonldap::NG handler)
    sub on_reject {
        my($self,$env,$proposedResponse) = @_;
        # ...
    }

    builder {
        enable "Auth::LemonldapNG",
          llparams => {
            # ...
          },
          on_reject => \&on_reject;
        $app;
    };