I see that when a web browser connects to a HTTP server the following lines are sent:
GET / HTTP/1.1
Content-Length: 13
Hello, world!
I want to write a program that takes an InputStream
, reads these lines and returns a Ring request map according to the ring specification.
Could you please suggest a Clojure library for this purpose? I took a quick look at web server source codes with ring support (for example http-kit) but with no success so far.
This surely can be achieved with http-kit library. But there are 2 problems:
org.httpkit.server.ClojureRing
is private. You have to access its method via reflection. :remote-addr
value is read from InetSocketAddress
object assigned to request, or you need to to have X-Forwarded-For
header in your request string.Here is working demo:
(let [request "POST / HTTP/1.1\nContent-Length: 13\nX-Forwarded-For: 127.0.0.1\n\nHello, world!"
bytes (java.nio.ByteBuffer/wrap (.getBytes request))
decoder (org.httpkit.server.HttpDecoder.
8388608 4096 ProxyProtocolOption/DISABLED)
method (.getMethod org.httpkit.server.ClojureRing
"buildRequestMap"
(into-array [org.httpkit.server.HttpRequest]))]
(.setAccessible method true)
(.invoke method nil (object-array [(.decode decoder bytes)])))
=>
{:remote-addr "127.0.0.1",
:headers {"content-length" "13", "x-forwarded-for" "127.0.0.1"},
:async-channel nil,
:server-port 80,
:content-length 13,
:websocket? false,
:content-type nil,
:character-encoding "utf8",
:uri "/",
:server-name nil,
:query-string nil,
:body #object[org.httpkit.BytesInputStream 0x4f078b2 "BytesInputStream[len=13]"],
:scheme :http,
:request-method :post}