net.http.server

Small wrapper around netty for HTTP servers. The objective here is to be mostly compatible with the vast number of available clojure HTTP server implementations.

In particular, we take inspiration from and try to be mostly compatible with jet.

The idea is that it should be feasible to write handlers that behave like synchronous ones.

The main function in this namespace is run-server

bad-request

Data representation of a bad request as given by Netty’s ObjectDecoder class

bad?

(bad? request)

close-channel

(close-channel ctx ch draining)

default-chunk-size

default-executor

(default-executor)

default-inbuf

executor?

get-host-port

(get-host-port {:keys [host port]})

Extract host and port from a server options map, providing defaults

get-response

(get-response {:keys [request version]} handler ctx executor)

When an aggregated request is done buffereing, Execute the handler on it and publish the response.

initializer

(initializer {:keys [chunk-size ring-handler idle-timeout], :or {chunk-size default-chunk-size}, :as opts})

An initializer is a per-connection context creator. For each incoming connections, the HTTP server codec is used.

netty-handler

(netty-handler handler {:keys [inbuf executor channel], :or {inbuf default-inbuf, allow-half-closure false}})

This is a stateful, per HTTP session adapter which wraps the user supplied function. We can use volatiles for keeping track of state due to the thread-safe nature of handler adapters.

notify-bad-request!

(notify-bad-request! handler msg ctx ch e)

request-data-keys

Keys to use when matching requests against pure data

run-server

(run-server options handler)(run-server options)

Create and run an HTTP server handler. HTTP server handlers rely on a handler function which must be provided separately in the 2-arity version or as the :ring-handler key in the options map in the 1-arity version.

Ring handler is a function of one argument, a correctly formed HTTP request of the following form (see ::request spec for full form):

{:request-method <method>
 :uri            <uri>
 :version        <version>
 :headers        <headers>
 :get-params     <map>
 :params         <map>
 :body           <buf-or-channel>}

When body is a channel, it will produce ByteBuf instances of up to the options chunk-size value.

The function should produce either a channel or map as a response. When the response is a channel, a single value will be consumed from it: the response map.

The response map should be of the form (see ::response spec for full form):

{:status         <http-status>
 :headers        <headers>
 :body           <buf-or-channel>}

When body is a channel, values will be consumed from it and sent out until it is closed. Otherwise, the contents will be sent out directly.

The options map is of the following form:

{:loop-thread-count       <threadcount>
 :disable-epoll           <boolean>
 :host                    <host>
 :port                    <port>
 :chunk-size              <chunk-size>
 :inbuf                   <input-channel-buffer>
 :bootstrap               <config as understood by net.ty.boostrap/server-bootstrap>
 :executor                <ExecutorService used to run/generate sync responses>}

run-server returns a function of no args which when called will shut down the server gracefully.

send-100-continue-fn

(send-100-continue-fn ctx msg)

set-so-backlog!

(set-so-backlog! bootstrap {:keys [so-backlog]})

Adjust Bootstrap socket backlog

write-raw-response

(write-raw-response ctx resp body)

Write an HTTP response out to a Netty Context

write-response

(write-response ctx version {:keys [body], :as resp})