On this page:
1.1 Dispatching Server Signatures
dispatch-server^
serve
serve-ports
dispatch-server-connect^
port->real-ports
dispatch-server-config*^
port
listen-ip
read-request
dispatch
safety-limits
dispatch-server-config^
max-waiting
initial-connection-timeout
1.2 Safety Limits
safety-limits?
make-safety-limits
nonnegative-length/  c
positive-count/  c
timeout/  c
make-unlimited-safety-limits
1.3 Dispatching Server Unit
dispatch-server-with-connect@
dispatch-server@
1.4 Threads and Custodians

1 Dispatching Server🔗ℹ

The Web Server is just a configuration of a dispatching server.

1.1 Dispatching Server Signatures🔗ℹ

signature

dispatch-server^ : signature

The dispatch-server^ signature is an alias for web-server^.

procedure

(serve [#:confirmation-channel confirmation-ach])  (-> any)

  confirmation-ach : 
(or/c #f (async-channel/c
          (or/c exn? port-number?)))
 = #f
Runs the server. The confirmation channel, if provided, will be sent an exception if one occurs while starting the server or the port number if the server starts successfully.

Calling the returned procedure shuts down the server.

procedure

(serve-ports ip op)  any

  ip : input-port?
  op : output-port?
Asynchronously serves a single connection represented by the ports ip and op.

signature

dispatch-server-connect^ : signature

The dispatch-server-connect^ signature abstracts the conversion of connection ports (e.g., to implement SSL) as used by the dispatch server.

procedure

(port->real-ports ip op)  
input-port? output-port?
  ip : input-port?
  op : output-port?
Converts connection ports as necessary.

The connection ports are normally TCP ports, but an alternate implementation of tcp^ linked to the dispatcher can supply different kinds of ports.

signature

dispatch-server-config*^ : signature

Added in version 1.6 of package web-server-lib.

Specifies the port to serve on.

value

listen-ip : (or/c string? #f)

Passed to tcp-listen.

procedure

(read-request c p port-addresses)  
any/c boolean?
  c : connection?
  p : listen-port-number?
  port-addresses : (input-port? . -> . (values string? string?))
Defines the way the server reads requests off connections to be passed to dispatch. The port-addresses argument should be a procedure like tcp-addresses.

The first result of read-request is ordinarily a request value, but that is not a requirement at the dispatch-server level. The second result is #true if the connection c should be closed after handling this request, or #false if the connection may be reused.
Used to handle requests. The second argument to dispatch is ordinarily a request value, like the first result of read-request, but that is not a requirement at the dispatch-server level.
A safety limits value specifying the policies to be used while reading and handling requests.

signature

dispatch-server-config^ : signature

NOTE: This signature is deprecated; use dispatch-server-config*^, instead.

(make-safety-limits
 #:max-waiting max-waiting
 #:request-read-timeout initial-connection-timeout)

Changed in version 1.6 of package web-server-lib: Deprecated in favor of dispatch-server-config*^. See compatability note.

Passed to make-safety-limits.
Passed to make-safety-limits as its #:request-read-timeout argument.

Changed in version 1.6 of package web-server-lib: Loosened contract for consistency with make-safety-limits.

1.2 Safety Limits🔗ℹ

 (require web-server/safety-limits) package: web-server-lib

procedure

(safety-limits? v)  boolean?

  v : any/c

procedure

(make-safety-limits 
  [#:max-concurrent max-concurrent 
  #:max-waiting max-waiting 
  #:request-read-timeout request-read-timeout 
  #:max-request-line-length max-request-line-length 
  #:max-request-headers max-request-headers 
  #:max-request-header-length max-request-header-length 
  #:max-request-body-length max-request-body-length 
  #:max-form-data-parts max-form-data-parts 
  #:max-form-data-header-length max-form-data-header-length 
  #:max-form-data-files max-form-data-files 
  #:max-form-data-file-length max-form-data-file-length 
  #:form-data-file-memory-threshold form-data-file-memory-threshold 
  #:max-form-data-fields max-form-data-fields 
  #:max-form-data-field-length max-form-data-field-length 
  #:response-timeout response-timeout 
  #:response-send-timeout response-send-timeout]) 
  safety-limits?
  max-concurrent : positive-count/c = 10000
  max-waiting : exact-nonnegative-integer? = 511
  request-read-timeout : timeout/c = 60
  max-request-line-length : nonnegative-length/c
   = (* 8 1024) ; 8 KiB
  max-request-headers : nonnegative-length/c = 100
  max-request-header-length : nonnegative-length/c
   = (* 8 1024) ; 8 KiB
  max-request-body-length : nonnegative-length/c
   = (* 1 1024 1024) ; 1 MiB
  max-form-data-parts : nonnegative-length/c
   = (+ max-form-data-fields max-form-data-files)
  max-form-data-header-length : nonnegative-length/c
   = (* 8 1024) ; 8 KiB
  max-form-data-files : nonnegative-length/c = 100
  max-form-data-file-length : nonnegative-length/c
   = (* 10 1024 1024) ; 10 MiB
  form-data-file-memory-threshold : nonnegative-length/c
   = (* 1 1024 1024) ; 1 MiB
  max-form-data-fields : nonnegative-length/c = 100
  max-form-data-field-length : nonnegative-length/c
   = (* 8 1024) ; 8 KiB
  response-timeout : timeout/c = 60
  response-send-timeout : timeout/c = 60

value

nonnegative-length/c : flat-contract?

 = (or/c exact-nonnegative-integer? +inf.0)

value

positive-count/c : flat-contract?

 = (or/c exact-positive-integer? +inf.0)

value

timeout/c : flat-contract? = (>=/c 0)

The web server uses opaque safety limits values, recognized by the predicate safety-limits?, to encapsulate policies for protection against misbehaving or malicious clients and servlets. Construct safety limits values using make-safety-limits, which supplies reasonably safe default policies that should work for most applications. See the compatability note and make-unlimited-safety-limits for further details.

The arguments to make-safety-limits are used as follows:
  • The max-concurrent argument limits the number of open concurrent connections to the server. Once the limit is reached, new connections are queued at the TCP level (see max-waiting) until existing connections finish or time out.

  • The max-waiting argument is passed to tcp-listen to specify the maximum number of client connections that can be waiting for acceptance. When max-waiting clients are waiting for acceptance, no new client connections can be made.

  • The request-read-timeout limits how long, in seconds, the standard read-request implementation (e.g. from serve or web-server@) will wait for request data to come in from the client before it closes the connection. If you need to support large file uploads over slow connections, you may need to adjust this value.

  • The max-request-line-length limits the length (in bytes) of the the first line of an HTTP request (the “request line”), which specifies the request method, path, and protocol version. Requests with a first line longer than max-request-line-length are rejected by the standard read-request implementation (e.g. from serve or web-server@). Increase this if you have very long URLs, but see also is-url-too-big?.

  • The max-request-headers and max-request-header-length arguments limit the number of headers allowed per HTTP request and the length, in bytes, of an individual request header, respectively. Requests that exceed these limits are rejected by the standard read-request implementation (e.g. from serve or web-server@).

  • The max-request-body-length limits the size, in bytes, of HTTP request bodies—but it does not apply to multipart (file upload) requests: see max-form-data-files and related limits, below. Requests with bodies longer than max-request-body-length are rejected by the standard read-request implementation (e.g. from serve or web-server@).

  • The max-form-data-files, max-form-data-fields, max-form-data-file-length, max-form-data-field-length, max-form-data-parts, form-data-file-memory-threshold, and max-form-data-header-length arguments control the handling of multipart/form-data (file upload) requests by the standard read-request implementation (e.g. from serve or web-server@).

    The number of files and non-file “fields” per request are limited by max-form-data-files and max-form-data-fields, respectively, and max-form-data-file-length and max-form-data-field-length limit the length, in bytes, of an individual file or non-file field. Additionally, the total number of “parts,” which includes both files and fields, must not exceed max-form-data-parts. Requests that exceed these limits are rejected.

    Files longer than request-file-memory-threshold, in bytes, are automatically offloaded to disk as temporary files to avoid running out of memory.

    The max-form-data-header-length argument limits the length of a header for an individual part (file or field). Since such headers are already tightly constrained by RFC 7578 §4.8., it should be especially rare to need to increase this limit, but doing so could allow for exceptionally long file or field names.

  • The response-timeout and response-send-timeout arguments limit the time for which individual request handlers (as in dispatch) are allowed to run.

    The response-timeout specifies the maximum time, in seconds, that a handler is allowed to run after the request has been read before it writes its first byte of response data. If no data is written within this time limit, the connection is killed.

    The response-send-timeout specifies the maximum time, in seconds, that the server will wait for a chunk of response data. Each time a chunk of data is sent to the client, this timeout resets. If your application uses streaming responses or long polling, either adjust this value or make sure that your request handler sends data periodically, such as a no-op, to avoid hitting this limit.

Compatibility note: The safety limits type may be extended in the future to provide additional protections. Creating safety limits values with make-safety-limits will allow applications to take advantage of reasonable default values for any new limits that are added. However, adding new limits does have the potential to break some existing applications: as an alternative, the make-unlimited-safety-limits constructor uses default values that avoid imposing any limits that aren’t explicitly specified. (In most cases, this means a default of +inf.0.) Of course, applications using make-unlimited-safety-limits may remain vulnerable to threats which the values from make-safety-limits would have protected against.

The safety limits type was introduced in version 1.6 of the web-server-lib package. Previous versions of this library only supported the max-waiting limit and (in some cases) an initial-connection-timeout limit, which was similar to request-read-timeout, but had some problems. These limits were specified through dispatch-server-config^, web-config^, and optional arguments to functions like serve: if values weren’t explicitly supplied, the default behavior was closest to using (make-unlimited-safety-limits #:request-read-timeout 60).

However, version 1.6 adopted (make-safety-limits) as the default, as most applications would benefit from using reasonable protections. When porting from earlier versions of this library, if you think your application may be especially resource-intensive, you may prefer to use make-unlimited-safety-limits while determining limits that work for your application.

Added in version 1.6 of package web-server-lib.

Changed in version 1.11 of package web-server-lib: added the max-concurrent limit

procedure

(make-unlimited-safety-limits 
  [#:max-concurrent max-concurrent 
  #:max-waiting max-waiting 
  #:request-read-timeout request-read-timeout 
  #:max-request-line-length max-request-line-length 
  #:max-request-headers max-request-headers 
  #:max-request-header-length max-request-header-length 
  #:max-request-body-length max-request-body-length 
  #:max-request-files max-request-files 
  #:max-request-file-length max-request-file-length 
  #:request-file-memory-threshold request-file-memory-threshold 
  #:max-form-data-parts max-form-data-parts 
  #:max-form-data-header-length max-form-data-header-length 
  #:max-form-data-files max-form-data-files 
  #:max-form-data-file-length max-form-data-file-length 
  #:form-data-file-memory-threshold form-data-file-memory-threshold 
  #:max-form-data-fields max-form-data-fields 
  #:max-form-data-field-length max-form-data-field-length 
  #:response-timeout response-timeout 
  #:response-send-timeout response-send-timeout]) 
  safety-limits?
  max-concurrent : positive-count/c = +inf.0
  max-waiting : exact-nonnegative-integer? = 511
  request-read-timeout : timeout/c = +inf.0
  max-request-line-length : nonnegative-length/c = +inf.0
  max-request-headers : nonnegative-length/c = +inf.0
  max-request-header-length : nonnegative-length/c = +inf.0
  max-request-body-length : nonnegative-length/c = +inf.0
  max-request-files : nonnegative-length/c = +inf.0
  max-request-file-length : nonnegative-length/c = +inf.0
  request-file-memory-threshold : nonnegative-length/c = +inf.0
  max-form-data-parts : nonnegative-length/c = +inf.0
  max-form-data-header-length : nonnegative-length/c = +inf.0
  max-form-data-files : nonnegative-length/c = +inf.0
  max-form-data-file-length : nonnegative-length/c = +inf.0
  form-data-file-memory-threshold : nonnegative-length/c
   = +inf.0
  max-form-data-fields : nonnegative-length/c = +inf.0
  max-form-data-field-length : nonnegative-length/c = +inf.0
  response-timeout : timeout/c = +inf.0
  response-send-timeout : timeout/c = +inf.0
Like make-safety-limits, but with default values that avoid imposing any limits that aren’t explicitly specified, rather than the safer defaults of make-safety-limits. Think carefully before using make-unlimited-safety-limits, as it may leave your application vulnerable to denial of service attacks or other threats that the default values from make-safety-limits would mitigate. See the compatability note for more details.

Note that the default value for max-waiting is 511, not +inf.0, due to the contract of tcp-listen.

Added in version 1.6 of package web-server-lib.

Changed in version 1.11 of package web-server-lib: added the max-concurrent limit

1.3 Dispatching Server Unit🔗ℹ

 (require web-server/private/dispatch-server-unit)
  package: web-server-lib

The web-server/private/dispatch-server-unit module provides the unit that actually implements a dispatching server.

value

dispatch-server-with-connect@

 : 
(unit/c (import tcp^
                dispatch-server-connect^
                dispatch-server-config*^)
        (export dispatch-server^))
Runs the dispatching server config in a very basic way, except that it uses Connection Manager to manage connections.

Added in version 1.1 of package web-server-lib.
Changed in version 1.6: Use dispatch-server-config*^ rather than dispatch-server-config^. See compatability note.

value

dispatch-server@ : 
(unit/c (import tcp^
                dispatch-server-config*^)
        (export dispatch-server^))

Changed in version 1.6 of package web-server-lib: Use dispatch-server-config*^ rather than dispatch-server-config^. See compatability note.

1.4 Threads and Custodians🔗ℹ

The dispatching server runs in a dedicated thread. Every time a connection is initiated, a new thread is started to handle it. Connection threads are created inside a dedicated custodian that is a child of the server’s custodian. When the server is used to provide servlets, each servlet also receives a new custodian that is a child of the server’s custodian not the connection custodian.