Repository navigation
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,SameSitecookies, 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.HTTPVersionrequests it, andProtocolVersionreports what was actually negotiated. It works with netHTTP (Windows) and OkHttp (Android) on the client, and withTRALSynopseServerinsmHttpSysmode 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
OkHttpRALdesign package. - Connection pool on
TRALClient(PoolConnection), plusShareConnectionandKeepAliveInterval(HTTP/2 PING). - mORMot2 server modes:
smThreads,smAsync(event loop) andsmHttpSys(Windows kernel, HTTP/2). MaxConnectionsworks the same way on all servers, andTRALClientInfo.ConnectionIDidentifies the connection behind each request.
WebModule
- HTTP caching with
ETag,Last-Modifiedand304 Not Modified. - Byte ranges (
206/416,If-Range). - Files streamed from disk instead of loaded into memory.
- New properties:
CacheControl(per extension),ServePrecompressed(.br/.gzfiles next to the original),MaxFileSize,FileCacheTime,IndexFile(index.html),FollowLinksandBlockedExtensions. HEADon 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 isSameSite=Lax.- PBKDF2-HMAC-SHA256 key derivation for the AES body cipher (
RALCriptoKeyDerivation := rkdPBKDF2). OnValidateSQLandOnValidateApplyUpdateson the FireDAC DAO.
Routes and API
TRALRequest.Route(the route answering the request) andOutputParamson routes.- Chainable
Allow()andSkipAuth()helpers forAllowedMethodsandSkipAuthMethods. TRALServer.GetServerAddressandRALGetLocalAddress: find the IP the server is reachable at (IPv4 and the stable IPv6 address).NativeConnection/GetNativeConnectionon the DBWare drivers.
Data
- New
sftBCDfield type: exact NUMERIC/DECIMAL values in every storage (BIN, JSON, BSON, CSV) and in DBWare params. RALLegacyWirelets a 1.2 side talk to older RAL peers.- The FireDAC memtable's design-time fields match the server's native types.
CountUpdatedRecordson the memtables.
Documentation
- SSL/TLS manual for every engine (
src/engine/SSL.md), with theopensslcommands. - HTTP/2 manual (
src/engine/HTTP2.md).
Highlight Changes
The most important differences from 1.1:
Security
- An empty
DocumentRootin the WebModule and the FireDAC DAO no longer serves the executable's folder (.inifiles, certificates, databases). BlockedExtensionscan 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
501instead of running the GET handler. - Forged input read before authentication (JWTs, storage streams, enum bytes) is validated. Infinite loops on
?&a=1and 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,ShareConnectionandPoolConnection.Enabledare now on by default. PassebMultiThreadwhere 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.
ParamByNamebehaves as before. - NUMERIC/DECIMAL travel as exact text, and milliseconds are kept. A RAL older than 1.2 cannot read these values. Set
RALLegacyWire := Trueon a side whose peers are still on an older version. - The memtables'
ApplyUpdatesandExecSQLraise on failure, as the DAO does. A record that was changed or deleted by someone else is no longer reported as saved.CountUpdatedRecordsturns the row count check off. - Deprecated: reading
TRALParams.BodyandTRALParam.AsStream, which allocate an object on every read. UseContent,SaveToStream,Count(rpkBODY)orSingleBodyinstead.
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
BaseURLworks on every path, and a401no longer throws away a freshly fetched token. - Cookies: each client has its own cookie jar, merged with the application's cookies in a single
Cookieheader. - 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
Openno 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 = Truein a form now readsPort,SSLandIPConfigbefore 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.