HTTP Range middleware for the Clojure Ring server
Given a response body and a valid Range header, this middleware fulfills the request's Range header. If the content length of the body is known, the bytes are streamed to the client. Otherwise, serverside buffering is required (options can be passed for buffer size).
The middleware looks for the following to determine the content length:
- if the body is a string, File, or byte-array, the length can be determined directly
- the response Content-Length
- Clojure >=1.0 (I think? 1.7+ definitely works)
- Ring core >=1.6
- Ring servlet or Ring jetty adapter >=1.6
- The middleware replaces the body with another body on which
ring.core.protocols/write-body-to-stream
needs to be called to stream the bytes to the client. The servlet and jetty adapter do this automatically. If you aren't using these, you will need to find a way to call this protocol method.
- The middleware replaces the body with another body on which
Leinengen
[ring-range-middleware "0.1.0"]
You can use it like normal Ring middleware.
(require [ring-range-middleware.core :as range-middleware])
...
(-> your-handler
...
(range-middleware/wrap-range-header)
...)
You can use the handler with options.
(-> your-handler
...
(range-middleware/wrap-range-header opts)
...)
opts
is a map with the following keys:
:boundary-generator-fn
- a function that generates a boundary string
- default: an autogenerated 30-character alphanumeric string
:max-num-ranges
- the maximum number of ranges to accept in a Range request
- default: 10
:max-buffer-size-per-range-bytes
- when the content length is unknown, the max buffer size for each range. If the buffer size is surpassed, the range is discarded.
- default: 1MiB
MIT