IoWebServer class final
An HTTP server on dart:io's HttpServer, made by
IoWebServerFactory.
start binds the socket (with TLS when settings have ssl), and
every request goes to handler as a ServerHttpRequest and
ServerHttpResponse. A port in use is a PortInUseException, any
other failure to listen a WebServerException. Some requests are
answered before the handler, with a problem
(application/problem+json):
- a method that
HttpMethoddoes not list: 501; - with
server.ssl.client-auth=need, no client certificate: 403; - a malformed
Hostheader, an HTTP/1.1 request without one, or an absolute target (GET http://a.example/ HTTP/1.1) whose host is not theHostheader's: 400, as Tomcat answers; - an encoded
/,\or NUL in the path (%2F,%5C,%00): 400, as Tomcat answers by default, so..%2F..%2Fsecretnever reaches a path variable; - a
.or..segment that is left once matrix parameters are cut off (/files/..;x/secret): 400, so..never reaches a path variable either; - a
%escape in the path or the query that is malformed or not UTF-8 (/%FF,/%C0%AF,?id=%FF): 400, as Tomcat answers.
dart:io keeps only the last of two Host headers, so a request with
two is served for the last one (Tomcat answers 400). It also parses
the request target before the server sees it, and keeps no raw form:
a raw \ becomes /, so ..\ segments are resolved
(/files/..\..\secret arrives as /secret), and raw bytes past
ASCII are read as Latin-1 (Tomcat answers 400 to both). The router
and the security rules see the same path, but a proxy in front that
checks paths must refuse \ itself.
A request body that sends nothing for server.connection-timeout
(60 s, Tomcat's connectionTimeout) while it is read fails with a
408 problem, and the connection closes after the answer. A body
nobody reads is read and dropped after the answer: up to 2 MB, for at
most 5 seconds, so the connection can serve the next request (as
Tomcat's max-swallow-size); a longer or slower one closes the
connection. An idle connection closes after the same timeout. There
is no limit on the number of connections (Tomcat's
max-connections, 8192): put a proxy in front, or rely on the
system's limit of open files.
When a handler fails after the response was committed (the status and headers are out), the connection is dropped without finishing the response (no final chunk), as Tomcat does, so the client sees a broken response rather than a complete one.
A response header whose name or value dart:io cannot send (a
non-ASCII character, a line break) fails before anything is sent: the
header is dropped and the error answered as usual (a 500 problem).
stop follows server.shutdown: gracefully, running requests may
finish within the timeout; event streams and WebSocket sessions are
closed at once in both modes.
dart:io itself accepts a request with both Content-Length and
Transfer-Encoding: chunked (it reads the body as chunked), where
RFC 9112 asks a server to refuse it; behind a proxy that reads such a
request differently, requests can be smuggled. Put a proxy in front
that refuses them (most do).
The Server header is not sent, nor X-XSS-Protection; dart:io's
X-Frame-Options: SAMEORIGIN and X-Content-Type-Options: nosniff
stay. dart:io's default Content-Type: text/plain; charset=utf-8 is
not sent either: an answer whose type the application did not set
has none, as with Tomcat. An answer that has no body by its status
(1xx, 204, 304) gets no Content-Length and no
Transfer-Encoding (RFC 9110 §8.6), a 304 or 1xx no Content-Type,
and what is written to it is dropped, as Tomcat does.
The starter's lifecycle bean starts and stops it with the context; applications do not create one directly.
- Implemented types
Constructors
- IoWebServer(HttpHandler handler, ServerProperties settings)
-
A server that hands requests to
handlerand listens assettingssay.
Properties
- handler → HttpHandler
-
Answers every request; in the application, the
dispatcherHandler.final - hashCode → int
-
The hash code for this object.
no setterinherited
- port → int
-
The port the server listens on (the real one when
server.portis 0), or-1before it started.no setteroverride - runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- settings → ServerProperties
-
The
server.*settings: address, port, TLS, compression, shutdown.final
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
start(
) → Future< void> -
Binds the socket and starts answering requests; completes once the
server listens. Throws a PortInUseException when the port is
taken, a WebServerException for other failures.
override
-
stop(
{Duration? timeout}) → Future< void> -
Stops the server. With
server.shutdown=gracefulit stops accepting connections and lets running requests finish for up totimeout(30 seconds whennull), then closes what is left; open event streams and WebSocket sessions are closed at once.override -
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited