0

My websocket server runs this way:

ws_hdl = WebSocketHandler.new do |ws|

    # here we should determine the IP address of an incoming connection

end

srv = Server.new ws_hdl
srv.listen("0.0.0.0", 8080)

Is it possible to obtain an IP address of the remote host? It is required for logging and for security reasons as well.

Thanks in advance for any good advice!

Untied
  • 11
  • 4

2 Answers2

0

I don't know what you use but with Kemal i would do that:

require "kemal"

ws "/" do |socket, env|
  p env.request
end

Kemal.run

Headers look like this:

HTTP::Headers{"Host" => "example.com:80", "User-Agent" => "curl/7.49.1", "Accept" => "/", "Connection" => "Upgrade", "Upgrade" => "websocket", "Origin" => "http://example.com:80", "Sec-WebSocket-Key" => "SGVsbG8sIHdvcmxkIQ==", "Sec-WebSocket-Version" => "13"}

And then need to setup proxy like Nginx in front of the client for add IP to headers: https://stackoverflow.com/a/27458651/1597964

Sergey Fedorov
  • 3,696
  • 2
  • 17
  • 21
  • I use just the standard Crystal API to hold websocket connections. Don't think that it's a good idea to use Kemal for tasks that can be solved with the standard API. Thanks for idea to add the additional headers with Nginx! – Untied Oct 24 '18 at 22:29
0

Sorry I can't test this properly, but I think I have a solution.

The block has the web socket ws, but can also have a HTTP::Context as a second argument. This will then contain a HTTP::Request, containing the headers. Including something like REMOTE_ADDR.

ws_hdl = WebSocketHandler.new do |ws, context|

  context.request.headers # all headers
  context.request.headers["REMOTE_ADDR"]? # Should be the IP address

end

srv = Server.new ws_hdl
srv.listen("0.0.0.0", 8080)
Samual
  • 188
  • 1
  • 7
  • NOPE!!! The information about the remote host is NOT transferred through HTTP headers! The web server can determine itself the remote client address and provide it to server's API. But unfortunately Crystal's built-in web server do not provide this information. So for this moment the only way to log the remote client's IP is to proxify the connection through nginx server and add an extra header to the request. I guess it's a very big fault of Crystal's web server api! – Untied Oct 27 '18 at 23:02