# 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)

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:

uWsgi.ini

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

nginx.conf

      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;

## 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:

app.psgi

      use Plack::Builder;

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

More advanced example:

app.psgi

      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;
      };