How to get the client IP adress using HTTP.jl

Viewed 147

I'm trying to get the both the client request and IP address from http requests to my HTTP.jl server (based on the basic server example in the docs).

using HTTP
using Sockets

const APP = HTTP.Router()

# My request handler function can see the request's method
# and target but not the IP address it came from
HTTP.@register(APP,"GET","/",req::HTTP.Request -> begin
    println("$(req.method) request to $(req.target)")
    "Hello, world!"
end)

HTTP.serve(
    APP,
    Sockets.localhost,
    8081;
    # My tcpisvalid function can see the client's
    # IP address but not the HTTP request
    tcpisvalid=sock::Sockets.TCPSocket -> begin
        host, port = Sockets.getpeername(sock)
        println("Request from $host:$port")
        true
    end
)

My best guess would be that there's a way to parse the TCPSocket.buffer into an HTTP request but I can't find any methods to do it.

Can you suggest a way to get an HTTP.Request from a TCPSocket or a different way to approach this problem?

Thanks in advance!

1 Answers

The router (APP) is a (collection of) "request handler(s)" which can only access the HTTP.Request -- you can not get the stream from it. Instead you can define a "stream handler", which is passed the stream. From the stream you can get the client's IP adress using Sockets.getpeername (requires HTTP.jl version 0.9.7 when called on a HTTP.Stream as in the examples below).

using HTTP, Sockets

const APP = HTTP.Router()

function request_handler(req::HTTP.Request)
    println("$(req.method) request to $(req.target)")
    return "Hello, world!"
end

HTTP.@register APP "GET" "/" request_handler

function stream_handler(http::HTTP.Stream)
    host, port = Sockets.getpeername(http)
    println("Request from $host:$port")
    return HTTP.handle(APP, http) # regular handling
end

# HTTP.serve with stream=true to specify that stream_handler is a function
# that expects a HTTP.Stream as input (and not a HTTP.Request)
HTTP.serve(stream_handler, Sockets.localhost, 8081; stream=true) # <-- Note stream=true

# or HTTP.listen
HTTP.listen(stream_handler, Sockets.localhost, 8081)
Related