SSH app server on Whisp with pluggable middleware, multiple apps, and session handling

Maintainers

Package info

github.com/asahasrabuddhe/dwaar

pkg:composer/asahasrabuddhe/dwaar

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-03-04 18:00 UTC

This package is auto-updated.

Last update: 2026-03-04 18:02:10 UTC


README

SSH app server on Whisp with pluggable middleware, multiple apps, and session handling.

Features

  • Session abstraction – Wish-style Session over Whisp Connection + Channel: user(), remoteAddr(), command(), pty(), writeToStdout / writeToStderr, exit().
  • Middleware pipeline – Compose middlewares (first registered = outermost). Innermost handler starts the app.
  • Built-in middlewares
    • Recover – Catch throwables in the chain or app, log and exit 1.
    • Logging – Log connect (user, remote, command, term, client version, public key) and disconnect with duration.
    • AccessControl – Restrict allowed exec commands; reject others with exit 1.
    • Activeterm – Require a PTY (interactive terminal); reject non-PTY with exit 1.
  • SessionOutput – Helpers for session I/O: print() / println(), error() / errorln(), fatal() / fatalln(), printf() / errorf() / fatalf().

Requirements

  • PHP 8.4+
  • ext-sockets, ext-pcntl
  • See Whisp for additional runtime requirements.

Installation

composer require asahasrabuddhe/dwaar

Usage

Use Dwaar\Server instead of Whisp\Server, register middlewares and apps. Each connection runs the middleware stack before starting the app.

<?php

require __DIR__ . '/vendor/autoload.php';

use Dwaar\Server;
use Dwaar\Middleware\AccessControl;
use Dwaar\Middleware\Logging;
use Dwaar\Middleware\Recover;
use Psr\Log\NullLogger;

$logger = new NullLogger(); // or any PSR-3 logger

$server = new Server(port: 2222, autoDiscoverApps: false);

$server
    ->middlewares([
        new Recover($logger),
        new Logging($logger),
        new AccessControl(['default', 'guestbook']),
    ])
    ->addApps([
        'default' => __DIR__ . '/apps/howdy.php',
        'guestbook' => __DIR__ . '/apps/guestbook.php',
    ])
    ->run();

Connect:

# Interactive shell (default app)
ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@127.0.0.1

# Exec command
ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@127.0.0.1 guestbook

Middleware order

Same as Wish: first registered = outermost (runs first on connect, last on disconnect). Typical order: Recover → Logging → AccessControl or Activeterm → app (innermost).

Examples

Run the example server and try the default app and the guestbook exec command:

php examples/server.php

See examples/README.md for what each part demonstrates.

TUIs

For terminal UIs over SSH, use Laravel Prompts or similar in your app scripts; Dwaar does not port Bubble Tea.

Development

composer test        # run tests
composer cs-fix      # fix code style
composer cs-check    # check code style (dry run)

License

MIT.