代码之家  ›  专栏  ›  技术社区  ›  Alexander Presber

用于从Ruby on Rails应用程序发出HTTP请求的传出端口

  •  1
  • Alexander Presber  · 技术社区  · 6 年前

    我的应用程序(RubyonRails使用JRuby、Puma、Centos6上的nginx)希望直接向远程RESTAPI服务发出服务器到服务器的请求。 我的应用程序位于与服务网络不同的网络中,这意味着IT部门必须配置防火墙,以便允许这些请求。

    他们想知道

    • 源(IP和端口)和
    • 目标(IP和端口)

    除了 源端口 . 甚至可以让我的应用程序只使用一个端口吗?如果没有,我能至少提供一系列端口吗?这是如何配置的?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Jaffa    6 年前

    解决方案

    我刚看到 ,您可以使用 :local_port :local_host 请求选项:

    显然,如果要指定本地端口,必须指定本地主机,这是一个一直到 Socket 可能是事件 connect(2)

    # Get the first local IP address which is not the loopback
    # There are far better way of doing this, this is just for the example
    addr = Socket.ip_address_list.select(&:ipv4?).detect{|addr| addr.ip_address != '127.0.0.1'}
    
    # Start a connection using a predefined port
    HTTParty.get 'http://google.com', local_port: 60000, local_host: addr.ip_address
    

    如果要覆盖本地端口,则必须同时指定本地主机和本地端口的原因是套接字使用 Addrinfo.getaddrinfo ,如果只指定端口,则返回环回地址。

    这是由于 getaddrinfo(3) :

    如果未在hints.ai_标志中设置ai_被动标志,则返回的套接字地址将适合用于connect(2)、sendto(2)或sendmsg(2)。如果节点为空,则网络地址将被设置为环回接口地址(对于IPv4地址为inaddr_loopback,对于ipv6地址为in6addr_loopback_init);这供打算与同一主机上运行的对等机通信的应用程序使用。

    在这种情况下,我们不想设置人工智能被动模式 bind 但要 connect .

    因此,使用环回地址,外部网络是不可访问的,这也是我们需要指定本地主机的原因。


    原始答案

    您可以通过首先创建 Net::HTTP 实例,然后配置 local_port (R/W属性)在启动连接之前。

    如果您使用任何其他方法来建立连接,您可能需要检查文档以查看是否有这种方法可用。

    http = Net::HTTP.new(address, port)
    http.local_port = 666
    http.local_host = 'your ip address'
    http.start do
      # whatever
    end
    

    这个 本地\端口 是一个 attr_accessor @local_port 直接用于打开TCP套接字: TCPSocket.open(conn_address, conn_port, @local_host, @local_port)