Repository navigation
Major release: the public API moves under namespace orbit, HTTP/1.1
requests are parsed by llhttp, and an App can run several event loops.
Code written for 1.x keeps compiling (see the upgrade notes); everyone on
v1.6.x or earlier should upgrade for the security fix below.
Upgrade notes
See docs/migration.md for details and examples.
- Namespace. Everything lives under
orbit(orbit::server::App,
orbit::http::HttpRequest, ...). The 1.x names (server::,http::, ...)
remain available as aliases; defineORBIT_NO_LEGACY_NAMESPACESto drop
them if your own code uses names likeserverorhttp. The aliases will
be removed in 3.0. (#157) - HTTP/1.1 parsing is done by llhttp,
a new build dependency handled by vcpkg, Conan and system packages. It is
strict: an unknown method token gets501; a repeatedContent-Lengthis
rejected with400even when the values match; a request to a stream
route withoutContent-LengthorTransfer-Encodinghas no body, so its
stream ends at once. (#147, #148) - Removed:
http::parse_framing(),http::MessageFraming,
http::decode_chunked()andhttp::ChunkedStatus.
http::HttpParser::parse()returnsstd::nulloptfor an incomplete
request. (#152) - Command line. Invalid numeric values (
--port 70000,--port abc,
--threads 0or-1) print an error and exit with status 1 instead of
wrapping, throwing or being accepted. (#136) - gRPC wrapper is experimental. Built without gRPC (the default),
GrpcServer::start()andadd_service()throw;start()throws when the
server cannot start. (#146) - Graceful shutdown. The first
SIGTERM/SIGINT(orapp.shutdown())
drains in-flight requests up toshutdown_timeout; a second signal stops at
once. (#107) - Compression matches
Accept-Encodingtokens exactly and honours
q-values. (#95)
Security
- Multipart uploads are written to a private per-process directory (mode
0700) under random 128-bit names, opened exclusively with mode 0600,
rather than to predictable names in a shared directory. (#115)
Added
- Event loops:
ServerConfig::event_loops/--event-loops Nruns N
loops, each with its ownSO_REUSEPORTlistening socket (Linux; default
1).max_connectionsstays one exact limit across them.
App::connections_per_event_loop()reports their load. (#156) - HTTP: asynchronous outbound HTTP client (#130); form fields,
Expect: 100-continue, multipart uploads streamed to disk (#121); brotli
and zstd compression (#122). - HTTP/2 and HTTP/3: h2c with prior knowledge (#123); HTTP/3 requests go
through the Router (#119). - TLS: SNI certificates, and reloading certificates without a restart
(#124). - Middleware:
security_headers()andtrusted_proxies()(#108); a
session store API with memory and Redis stores (#109); RS256 and ES256 for
jwt_auth, with PEM keys or a JWKS URL (#110). - Server: graceful shutdown with a deadline, and health endpoints (#107);
configurable request limits and WebSocket keep-alive pings (#111). - Observability: JSON logs, access log, request IDs, tracing and richer
metrics (#113). - Database: typed PostgreSQL rows, a prepared-statement cache,
transactions, timeouts and reconnect (#125); pool health checks and
reconnect with backoff (#126); ORMupdate,remove,count,
order_by,limit/offsetand identifier quoting (#127). - Build: backend libraries are optional vcpkg features, all enabled by
default (#100).
Changed
- WebSocket: RFC 6455 conformance and thread-safe sending (#94).
- OpenAPI docs page: Swagger UI is pinned with Subresource Integrity, and
its assets can be self-hosted (#102). - App: start/stop data races fixed; each
Apphas its own OpenAPI
registry; signals reach everyApp(#106).
Fixed
- An
on_errorhandler that throws no longer leaves the client without a
response (#145). - Keep-alive connections no longer hang after a streamed upload (#148).
- Creating a
MongoClientafter another was destroyed no longer crashes
(#142). - Redis
get()of a key holding""returns the empty value instead of
"missing" (#142). /swagger.jsonis valid JSON for inline response schemas and control
characters (#143).- A pooled plain connection with unread data is no longer reused (#143).
/metricsvalues keep full precision past a million (#139).- io_uring releases requests still in flight at shutdown (#135).
- HTTP/2 closes finished sessions and dispatches requests with trailers
(#116); QUIC transport fixes for acknowledged data, flow control, timers
and connection cleanup (#117);Connection: closeis sent as soon as
shutdown is requested (#118);Content-Length: 0is sent for empty
response bodies (#129).
Testing and CI
- Line coverage rose from 27% to 90%; the suite runs on both epoll and
io_uring, against real PostgreSQL, Redis, MariaDB and MongoDB servers
(#134–#144, #135, #142). - Fuzzing for WebSocket, multipart, HTTP/2 and the llhttp parser (#114,
#147); h2spec and Autobahn in CI (#116, #138); ASan/UBSan and TSan jobs
(#99).
Verifying this release. Every file has a .sigstore.json bundle.
See docs/release-process.md.