【问题标题】:Is it possible to get the IP address of an incoming websocket connection?是否可以获取传入 websocket 连接的 IP 地址?
【发布时间】:2018-10-23 13:31:09
【问题描述】:

我的 websocket 服务器是这样运行的:

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)

是否可以获取远程主机的IP地址? 它是日志记录和安全原因所必需的。

提前感谢任何好的建议!

【问题讨论】:

    标签: crystal-lang


    【解决方案1】:

    我不知道你用的是什么,但Kemal 我会这样做:

    require "kemal"
    
    ws "/" do |socket, env|
      p env.request
    end
    
    Kemal.run
    

    标题如下所示:

    HTTP::Headers{"Host" => "example.com:80", "User-Agent" => “curl/7.49.1”、“接受”=>“/”、“连接”=>“升级”、“升级” => "websocket", "Origin" => "http://example.com:80", "Sec-WebSocket-Key" => "SGVsbG8sIHdvcmxkIQ==", "Sec-WebSocket-Version" => "13"}

    然后需要在客户端前面设置像 Nginx 这样的代理来添加 IP 到 headers:https://stackoverflow.com/a/27458651/1597964

    【讨论】:

    • 我只使用标准的 Crystal API 来保持 websocket 连接。不要认为将 Kemal 用于可以使用标准 API 解决的任务是一个好主意。感谢您使用 Nginx 添加附加标头的想法!
    【解决方案2】:

    抱歉,我无法正确测试,但我想我有一个解决方案。

    该块具有网络套接字ws,但也可以具有HTTP::Context 作为第二个参数。这将包含一个HTTP::Request,其中包含标题。包括像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)
    

    【讨论】:

    • 不!有关远程主机的信息不通过 HTTP 标头传输! Web 服务器可以自行确定远程客户端地址并将其提供给服务器的 API。但不幸的是,Crystal 的内置 Web 服务器不提供此信息。因此,目前记录远程客户端 IP 的唯一方法是通过 nginx 服务器代理连接并在请求中添加额外的标头。估计是Crystal的web server api的一个很大的毛病!
    猜你喜欢
    • 1970-01-01
    • 2012-03-06
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 2018-08-21
    • 2011-07-31
    • 1970-01-01
    相关资源
    最近更新 更多