Skip to main content

Module lenient_uri

Module lenient_uri 

Source
Expand description

Accepting the request targets PostgREST clients actually send.

select=data->>id is ordinary PostgREST usage: it is what curl puts on the wire and what the PostgREST documentation shows. Haskell’s Warp, which serves PostgREST, hands those bytes to the application unexamined.

hyper builds an http::Uri from the request target, and that rejects three printable characters – ", < and > – along with everything from 0x80 up. httparse, which reads the request line first, is happy with all of them. So the request is answered 400 with an empty body before any routing, handler, or error formatting of ours runs, and there is no point above the connection where it can be caught.

This adapter percent-encodes those bytes in the request target, and only there. The query string is percent-decoded when it is parsed, so nothing above this sees a difference.

§Not touching anything else

A request line appears only at the start of a message, and mistaking body bytes for one would corrupt the body. So the adapter follows the framing: it reads each request line, then the header block, and uses Content-Length to know how many body bytes to pass through before another request line can begin.

The moment framing becomes something it does not model – a chunked body, a header block too large to buffer, a request line it cannot make sense of, a request asking to Upgrade the connection to another protocol – it stops rewriting for the remainder of the connection and copies bytes through verbatim. That degrades to exactly hyper’s own behaviour. It is never left guessing whether the bytes in hand are a request line.

Structs§

LenientListener
A TcpListener whose connections normalise request targets.
LenientStream
A connection whose request targets are normalised as they are read.
LenientUnixListener
The same leniency over a Unix domain socket, for server_unix_socket.