Skip to content

v1.2

Latest

Choose a tag to compare

@mobius1qwe mobius1qwe released this 27 Oct 11:59
Immutable release. Only release title and notes can be modified.

PascalRAL v1.2

What's Changed?

  • About 235 bugs fixed across 65 commits since 1.1. About 68 of them are security fixes.
  • New transports: HTTP/2 on the client and the mORMot2 server, a QUIC engine (MsQuic) for Windows, Linux and Android, and two new Android client engines (OkHttp and Kwik).
  • A much more capable WebModule: HTTP caching, byte ranges, files streamed from disk, working sessions and an index page.
  • Safer defaults: CORS closed by default, certificate host checks on every engine, no downgrade from TLS on redirects, and new opt-in protections (HideErrorDetails, SecurityHeaders, SameSite cookies, PBKDF2 for AES).
  • Exact data on the wire: NUMERIC/DECIMAL values keep every digit, dates and times keep their milliseconds, memos travel as Unicode text and JSON nulls stay null.
  • Faster request handling: an indexed param lookup, cheaper route matching, and bodies that are no longer copied before they go out.
  • Easier to use in the IDE: the Object Inspector hides properties the selected engine cannot use, and the access violation that happened when a package was reloaded is gone.
  • 5 breaking changes and 1 deprecation. Read Highlight Changes before you upgrade.

New Features

Transports and protocols

  • HTTP/2: TRALClient.HTTPVersion requests it, and ProtocolVersion reports what was actually negotiated. It works with netHTTP (Windows) and OkHttp (Android) on the client, and with TRALSynopseServer in smHttpSys mode on the server.
  • MsQuic engine (TRALMsQuicServer / TRALMsQuicClientHTTP): RAL's own frame over QUIC streams, for Windows, Linux and Android 9+, client and server. It gives one stream per request and a 1-RTT handshake. Both ends must be RAL, because it is not HTTP/3.
  • Kwik engine: a pure-Java QUIC client for Android 8+. It uses the same wire format as MsQuic.
  • OkHttp engine for Android: HTTP/2 and certificate pinning, with the OkHttpRAL design package.
  • Connection pool on TRALClient (PoolConnection), plus ShareConnection and KeepAliveInterval (HTTP/2 PING).
  • mORMot2 server modes: smThreads, smAsync (event loop) and smHttpSys (Windows kernel, HTTP/2).
  • MaxConnections works the same way on all servers, and TRALClientInfo.ConnectionID identifies the connection behind each request.

WebModule

  • HTTP caching with ETag, Last-Modified and 304 Not Modified.
  • Byte ranges (206 / 416, If-Range).
  • Files streamed from disk instead of loaded into memory.
  • New properties: CacheControl (per extension), ServePrecompressed (.br / .gz files next to the original), MaxFileSize, FileCacheTime, IndexFile (index.html), FollowLinks and BlockedExtensions.
  • HEAD on the file route, which is now listed in the Swagger and Postman exports.
  • Working sessions (OpenSession, SessionTimeout), with secure cookies.

Security (opt-in)

  • TRALServer.HideErrorDetails: a 500 answer no longer exposes driver messages or SQL.
  • TRALServer.SecurityHeaders: nosniff, X-Frame-Options, Referrer-Policy, HSTS and CSP.
  • TRALServerJWTAuth.CookieSameSite. The session cookie is SameSite=Lax.
  • PBKDF2-HMAC-SHA256 key derivation for the AES body cipher (RALCriptoKeyDerivation := rkdPBKDF2).
  • OnValidateSQL and OnValidateApplyUpdates on the FireDAC DAO.

Routes and API

  • TRALRequest.Route (the route answering the request) and OutputParams on routes.
  • Chainable Allow() and SkipAuth() helpers for AllowedMethods and SkipAuthMethods.
  • TRALServer.GetServerAddress and RALGetLocalAddress: find the IP the server is reachable at (IPv4 and the stable IPv6 address).
  • NativeConnection / GetNativeConnection on the DBWare drivers.

Data

  • New sftBCD field type: exact NUMERIC/DECIMAL values in every storage (BIN, JSON, BSON, CSV) and in DBWare params.
  • RALLegacyWire lets a 1.2 side talk to older RAL peers.
  • The FireDAC memtable's design-time fields match the server's native types.
  • CountUpdatedRecords on the memtables.

Documentation

  • SSL/TLS manual for every engine (src/engine/SSL.md), with the openssl commands.
  • HTTP/2 manual (src/engine/HTTP2.md).

Highlight Changes

The most important differences from 1.1:

Security

  • An empty DocumentRoot in the WebModule and the FireDAC DAO no longer serves the executable's folder (.ini files, certificates, databases).
  • BlockedExtensions can no longer be bypassed with NTFS stream names, 8.3 short names or trailing dots.
  • CR, LF and NUL in a header or cookie can no longer split the response.
  • Certificate host names are checked on OkHttp and mORMot2 (OpenSSL), and Indy no longer trusts a chain that ends in an unknown CA.
  • Redirects never take a request off TLS when TLS is required, so the token is never resent in plain text.
  • Brute-force protection now counts the token route, and only accepted credentials reset the count.
  • Unknown HTTP methods are answered 501 instead of running the GET handler.
  • Forged input read before authentication (JWTs, storage streams, enum bytes) is validated. Infinite loops on ?&a=1 and on an empty brotli body are gone.

Breaking changes

  • CORS lets no origin in by default. Set CORSOptions.AllowOrigin := '*' (or list your origins) if a browser app calls your server. Forms saved with '*' keep it.
  • Client calls are synchronous by default. ebSingleThread, ShareConnection and PoolConnection.Enabled are now on by default. Pass ebMultiThread where a call must not block the UI.
  • Params are filed by where they came from on every engine: query, form field, header or cookie. Code that reads params by kind may see different results. ParamByName behaves as before.
  • NUMERIC/DECIMAL travel as exact text, and milliseconds are kept. A RAL older than 1.2 cannot read these values. Set RALLegacyWire := True on a side whose peers are still on an older version.
  • The memtables' ApplyUpdates and ExecSQL raise on failure, as the DAO does. A record that was changed or deleted by someone else is no longer reported as saved. CountUpdatedRecords turns the row count check off.
  • Deprecated: reading TRALParams.Body and TRALParam.AsStream, which allocate an object on every read. Use Content, SaveToStream, Count(rpkBODY) or SingleBody instead.

Reliability

  • Indy: a late answer after a timeout is no longer delivered to the next request.
  • fpHTTP: no longer writes into connections the server has closed, and no longer reports every request as HTTP/1.0.
  • Client: failover to the next BaseURL works on every path, and a 401 no longer throws away a freshly fetched token.
  • Cookies: each client has its own cookie jar, merged with the application's cookies in a single Cookie header.
  • Databases:
    • Saving a record with a BLOB column through a memtable now works on Delphi.
    • Memos, times and null values are no longer corrupted on their way through the storages.
    • A failed Open no longer leaks its query.
    • sqldb now commits each statement.
    • The DAO no longer waits for a main thread that will never come (services, console apps).
  • A server saved with Active = True in a form now reads Port, SSL and IPConfig before it starts.
  • Range and overflow checks ($R+ $Q+) are supported. The build was fixed for Android, Linux, FPC, Delphi XE2 and Delphi 10.0 Seattle.

Performance

  • Looking up a param by name uses an index: 20,000 query params now take 16 ms instead of 2.3 s.
  • Routes are matched without allocating memory for each route.
  • Response bodies and DBWare results are no longer copied several times. Serving a 64 MB file raised the server's memory use by 192 MB in 1.1, and by less than 1 MB in 1.2.
  • Content that is already compressed (images, video, archives, fonts) is not compressed again.
  • Brotli uses a single encoder per body, which also fixed a 1 KB leak on every response.

Full Changelog: Changelog
1.1...1.2