AgentStack
SKILL verified MIT Self-run

Mormot2 Net

skill-flydev-fr-mormot2-superpowers-mormot2-net · by flydev-fr

Use for HTTP transport in mORMot 2: TRestHttpServer modes (useHttpAsync, useBidirAsync), WebSockets, OpenAPI, TLS/ACME. Do NOT use for SOA shape (mormot2-rest-soa) or crypto (mormot2-auth-security).

No reviews yet
0 installs
10 views
0.0% view→install

Install

$ agentstack add skill-flydev-fr-mormot2-superpowers-mormot2-net

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Mormot2 Net? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

mormot2-net

mORMot 2 networking and transport layer: HTTP/HTTPS servers and clients, WebSocket protocols, OpenAPI client generation, ACME (Let's Encrypt / ZeroSSL) certificate automation, and HTTP tunnels. This skill is authoritative for the mormot.net.* namespace plus mormot.rest.http.server and mormot.rest.http.client (the HTTP wrappers around TRestServer / TRestClientUri). It assumes the conventions defined in mormot2-core (RawUtf8, RTTI). Sibling skills cover adjacent concerns: mormot2-rest-soa defines the REST and SOA service shape that this skill transports, mormot2-auth-security covers cryptographic primitives (JWT, AES, ECC) that may sit on top of TLS, and mormot2-deploy covers reverse-proxy fronting and OS-level service hosting.

When to use

  • Choosing among useHttpAsync, useBidirAsync, useHttpSocket, or useHttpApi (Windows HTTP.SYS) when constructing a TRestHttpServer.
  • Standing up a raw THttpAsyncServer or THttpServer outside of REST, e.g. for a static-file endpoint, a webhook receiver, or a custom router.
  • Adding a WebSocket upgrade path with TWebSocketAsyncServerRest (modern, async) or TWebSocketServerRest (classic threaded), and registering a TWebSocketProtocolJson / TWebSocketProtocolBinary.
  • Generating Pascal client code from an OpenAPI / Swagger JSON file via TOpenApiParser in mormot.net.openapi.
  • Automating Let's Encrypt / ZeroSSL certificate issuance and renewal with TAcmeLetsEncryptServer (port 80 challenge listener) plus OnNetTlsAcceptServerName SNI hook.
  • Running an HTTP request through TSimpleHttpClient, THttpClientSocket, or the higher-level IJsonClient / TJsonClient.
  • Setting up a tunneled or relayed TCP connection with mormot.net.tunnel, mormot.net.relay, or DNS/DHCP/TFTP services.

When NOT to use

  • Defining the REST routes, method-based services, or IInvokable contracts that the HTTP server transports. Use mormot2-rest-soa.
  • Generating or verifying JWTs, ECC key pairs, AES-GCM payloads, password hashes. Use mormot2-auth-security.
  • Choosing the deployment topology (nginx/IIS reverse proxy, systemd unit, Windows service install). Use mormot2-deploy.
  • Selecting a SQL provider or tuning a connection pool. Use mormot2-db.
  • Foundational types and JSON conventions (RawUtf8, TDocVariant, RTTI registration). Use mormot2-core.

Core idioms

1. TRestHttpServer engine selection

TRestHttpServer (unit mormot.rest.http.server) wraps any TRestServer and serves it over HTTP. The fifth constructor argument picks the engine. Pick by traffic profile, not by feel.

uses
  mormot.rest.http.server;

var
  HttpServer: TRestHttpServer;
begin
  HttpServer := TRestHttpServer.Create(
    '8080',           // port
    [RestServer],     // one or more TRestServer instances
    '+',              // domain name ('+' = bind all)
    useHttpAsync,     // engine: event-driven, scales to many concurrent connections
    32);              // worker thread count
  try
    // server is running; HttpServer.Shutdown is implicit on Free
  finally
    HttpServer.Free;  // free the HTTP wrapper BEFORE the TRestServer
  end;
end;

Engines, in one line each:

  • useHttpAsync: event-driven sockets, best general-purpose choice for many connections.
  • useBidirAsync: same as above plus WebSocket upgrade (TWebSocketAsyncServerRest).
  • useHttpSocket: classic one-thread-per-connection server (THttpServer); simple, scales worse.
  • useHttpApi / useHttpApiRegisteringURI: Windows HTTP.SYS kernel listener; only on Windows, integrates with IIS-style URL ACLs.

2. WebSocket upgrade with async server

useBidirAsync swaps in TWebSocketAsyncServerRest. Register protocols by name; the client negotiates them in the Sec-WebSocket-Protocol header.

uses
  mormot.rest.http.server,
  mormot.net.ws.async,
  mormot.net.ws.core;

var
  HttpServer: TRestHttpServer;
  Ws: TWebSocketAsyncServerRest;
begin
  HttpServer := TRestHttpServer.Create('8080', [RestServer], '+', useBidirAsync);
  Ws := HttpServer.WebSocketsEnable(RestServer, 'encryption-key', false);
  // Ws.WebSocketProtocols.Add(TWebSocketProtocolJson.Create('chat', '/chatroom'));
  // Now /chatroom accepts WebSocket upgrades using TWebSocketProtocolJson.
end;

Use TWebSocketProtocolJson for human-readable framing during development and TWebSocketProtocolBinary for production: it adds optional AES encryption and is significantly more compact on the wire.

3. Generate a Pascal client from OpenAPI

TOpenApiParser reads a Swagger 2 or OpenAPI 3 JSON document and emits two Pascal units: a DTO unit (records and enums) and a client unit (one method per operation). The client speaks JSON via IJsonClient.

uses
  mormot.net.openapi;

var
  Parser: TOpenApiParser;
begin
  Parser := TOpenApiParser.Create('Petstore', [opoClientOnlySummary]);
  try
    Parser.ParseFile('petstore.openapi.json');
    Parser.ExportToDirectory('generated/');
    // emits Petstore.dto.pas + Petstore.client.pas
  finally
    Parser.Free;
  end;
end;

Add the generated units to your project, then construct TPetstoreClient.Create(IJsonClient.Create('https://api.example.com')) and call methods directly.

4. ACME (Let's Encrypt / ZeroSSL) automation

TAcmeLetsEncryptServer runs a small HTTP listener on port 80, answers the HTTP-01 challenge, redirects everything else to HTTPS, and renews certificates twice a day in the background. The HTTPS server itself stays a normal THttpAsyncServer / TRestHttpServer.

uses
  mormot.net.acme,
  mormot.net.async,
  mormot.core.log;

var
  Acme: TAcmeLetsEncryptServer;
  Https: THttpAsyncServer;
begin
  // HTTPS server is set up first; pass nil HttpsServer here and assign later if needed.
  Acme := TAcmeLetsEncryptServer.Create(
    TSynLog,
    '/var/lib/myapp/acme/',     // key store folder (one set per domain)
    ACME_LETSENCRYPT_URL,        // production directory; use ACME_LETSENCRYPT_DEBUG_URL while testing
    'x509-es256',
    '');                         // optional private-key password
  Acme.LoadFromKeyStoreFolder;
  Acme.CheckCertificatesBackground;  // renews any cert within RenewBeforeEndDays of expiry
  // Wire the SNI callback into the HTTPS listener so it picks the right cert per host.
  Https.SetTlsServerNameCallback(Acme.OnNetTlsAcceptServerName);
end;

Set Acme.RenewBeforeEndDays (default 30) and Acme.RenewWaitForSeconds (default 30) when tuning. The folder layout is one ##.json + ##.acme.pem + ##.crt.pem + ##.key.pem per domain.

5. JSON HTTP client

For raw HTTP+JSON without REST/SOA, use TJsonClient. It owns the connection, retries, sets Content-Type, and rolls in custom RTTI for the request/response records.

uses
  mormot.net.client;

var
  Client: IJsonClient;
  Out: TMyResponse;
begin
  Client := TJsonClient.Create('https://api.example.com');
  Client.Request('GET', 'v1/items/42', [], [], TypeInfo(TMyResponse), Out);
end;

The interface is reference-counted, so no explicit Free. Pass [jcoNoEncodeUriQuery] and friends in TJsonClientOptions to tune URI encoding and error handling.

Common pitfalls

  • Picking useHttpSocket for a high-connection workload. useHttpSocket runs one thread per connection. Under a few hundred concurrent connections you exhaust the thread pool and tail latencies explode. Use useHttpAsync for almost any modern server; reserve useHttpSocket for low-connection-count internal services where its simpler accept loop is easier to reason about.
  • Freeing TRestServer before TRestHttpServer. The HTTP server holds references into the REST server; free it first, then the REST server, then the model. The wrong order leaves the listener accepting requests that dispatch into freed memory.
  • Mixing TWebSocketProtocolJson and TWebSocketProtocolBinary clients on the same path. Negotiation uses the Sec-WebSocket-Protocol header. If a JSON client connects to a binary-only path, the upgrade succeeds but every frame fails to deserialize. Pin protocols per route, or accept both and dispatch on Sender.ClassType.
  • Forgetting to call WebSocketsEnable after TRestHttpServer.Create(useBidirAsync). useBidirAsync allocates the WebSocket-capable server instance, but the route table is empty until you call WebSocketsEnable (and add protocols). Without it, the server happily serves HTTP and rejects every WebSocket upgrade.
  • Skipping the ACME staging directory. ACME_LETSENCRYPT_URL is the production endpoint and rate-limits issuance per domain (50 certs/week). During development, point DirectoryUrl at ACME_LETSENCRYPT_DEBUG_URL so a misconfigured deploy loop does not get you blocked.
  • No HTTP-01 listener on port 80. ACME HTTP-01 requires a publicly reachable listener at http:///.well-known/acme-challenge/. If port 80 is firewalled or already taken (often by an old web server), CheckCertificates raises and renewal silently stops. Either bind TAcmeLetsEncryptServer on port 80 directly or proxy that one path through your reverse proxy.
  • Calling OnNetTlsAcceptServerName only at startup. The callback must remain wired for the lifetime of the listener, not just at construction. If the HTTPS server is recreated (graceful restart, hot reload), reattach Acme.OnNetTlsAcceptServerName on the new listener instance.
  • IPv6 binding on dual-stack hosts. mORMot binds to 0.0.0.0 (IPv4) by default. To accept IPv6, pass '::' (or '[::]:8080') as the port argument. On Linux, also confirm net.ipv6.bindv6only=0 if you want a single socket to serve both stacks.

See also

  • $MORMOT2_DOC_PATH/mORMot2-SAD-Chapter-11.md - Client-Server Architecture
  • $MORMOT2_DOC_PATH/mORMot2-SAD-Chapter-20.md - Hosting
  • references/async-http.md
  • references/websockets.md
  • references/openapi-export.md
  • references/tls-acme.md
  • mormot2-rest-soa for service contracts on top of this transport
  • mormot2-auth-security for JWT, ECC, AES primitives
  • mormot2-deploy for reverse-proxy fronting and OS-level service hosting

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.