从 Rails 应用上的 Ruby 发出 HTTP 请求的传出端口
Outgoing ports for making HTTP requests from Ruby on Rails app
我的应用程序(Ruby 在 Rails 上使用 jRuby,在 Puma 上,在 CentOS 6 上的 nginx 上)想要向远程 REST 发出直接的服务器到服务器请求API 服务。
我的应用与服务网络位于不同的网络中,这意味着 IT 部门必须配置防火墙以允许这些请求。
他们想知道
- 源(IP 和端口)和
- 目标(IP 和端口)
除了 源端口 之外,一切都非常简单。甚至可以让我的应用程序只使用一个端口吗?如果没有,我至少可以提供一系列端口吗?这是如何配置的?
解决方案
我刚看到 httparty,您可以使用 :local_port
和 :local_host
请求选项:
显然,如果要指定 local_port,则必须指定 local_host,这是一直到 Socket
的限制,可能还有事件 [=15] =]
# 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
如果我们想覆盖本地端口,我们必须同时指定 local_host 和 local_port 的原因是 Socket 使用 Addrinfo.getaddrinfo
,returns 环回地址,如果仅指定了端口。
这是由于 getaddrinfo(3)
:
If the AI_PASSIVE flag is not set in hints.ai_flags, then the returned socket addresses will be suitable for use with connect(2), sendto(2), or sendmsg(2). If node is NULL, then the network address will be set to the loopback interface address (INADDR_LOOPBACK for IPv4 addresses, IN6ADDR_LOOPBACK_INIT for IPv6 address); this is used by applications that intend to communicate with peers running on the same host.
并且AI_PASSIVE在这种情况下没有设置,因为我们不想bind
而是connect
。
使用loopback地址,外网不可达,所以还要指定local_host
原回答
您可以通过首先创建 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
local_port
是一个attr_accessor
,@local_port
直接用于打开TCP套接字:TCPSocket.open(conn_address, conn_port, @local_host, @local_port)
我的应用程序(Ruby 在 Rails 上使用 jRuby,在 Puma 上,在 CentOS 6 上的 nginx 上)想要向远程 REST 发出直接的服务器到服务器请求API 服务。 我的应用与服务网络位于不同的网络中,这意味着 IT 部门必须配置防火墙以允许这些请求。
他们想知道
- 源(IP 和端口)和
- 目标(IP 和端口)
除了 源端口 之外,一切都非常简单。甚至可以让我的应用程序只使用一个端口吗?如果没有,我至少可以提供一系列端口吗?这是如何配置的?
解决方案
我刚看到 httparty,您可以使用 :local_port
和 :local_host
请求选项:
显然,如果要指定 local_port,则必须指定 local_host,这是一直到 Socket
的限制,可能还有事件 [=15] =]
# 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
如果我们想覆盖本地端口,我们必须同时指定 local_host 和 local_port 的原因是 Socket 使用 Addrinfo.getaddrinfo
,returns 环回地址,如果仅指定了端口。
这是由于 getaddrinfo(3)
:
If the AI_PASSIVE flag is not set in hints.ai_flags, then the returned socket addresses will be suitable for use with connect(2), sendto(2), or sendmsg(2). If node is NULL, then the network address will be set to the loopback interface address (INADDR_LOOPBACK for IPv4 addresses, IN6ADDR_LOOPBACK_INIT for IPv6 address); this is used by applications that intend to communicate with peers running on the same host.
并且AI_PASSIVE在这种情况下没有设置,因为我们不想bind
而是connect
。
使用loopback地址,外网不可达,所以还要指定local_host
原回答
您可以通过首先创建 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
local_port
是一个attr_accessor
,@local_port
直接用于打开TCP套接字:TCPSocket.open(conn_address, conn_port, @local_host, @local_port)