Есть ли способ присоединить запрос Ruby Net :: HTTP к определенному IP-адресу / сетевому интерфейсу? - PullRequest
11 голосов
/ 10 июня 2010

Я ищу способ использовать разные IP-адреса для каждого запроса GET со стандартной библиотекой Net :: HTTP. Сервер имеет 5 IP-адресов и при условии, что некоторые API блокируют доступ при достижении лимита запросов на IP. Итак, единственный способ сделать это - использовать другой сервер. Я не могу найти что-нибудь об этом в рубиновых документах.

Например, curl позволяет вам прикрепить его к определенному IP-адресу (в PHP):

$req = curl_init($url)
curl_setopt($req, CURLOPT_INTERFACE, 'ip.address.goes.here';
$result = curl_exec($req);

Есть ли способ сделать это с библиотекой Net :: HTTP? Как альтернатива - CURB (рубиновая завивка). Но это будет последнее, что я попробую.

Предложения / Идеи?

P.S. Решение с CURB (с грязными тестами, заменой ip):

require 'rubygems'
require 'curb'

ip_addresses = [
  '1.1.1.1',
  '2.2.2.2',
  '3.3.3.3',
  '4.4.4.4',
  '5.5.5.5'
]

ip_addresses.each do |address|
  url = 'http://www.ip-adress.com/'
  c = Curl::Easy.new(url)
  c.interface = address
  c.perform
  ip = c.body_str.scan(/<h2>My IP address is: ([\d\.]{1,})<\/h2>/).first
  puts "for #{address} got response: #{ip}"
end

Ответы [ 4 ]

6 голосов
/ 22 июля 2014

Я знаю, что это старо, но, надеюсь, кто-то найдет это полезным, так как мне это было нужно сегодня.Вы можете сделать следующее:

http = Net::HTTP.new(uri.host, uri.port)
http.local_host = ip
response = http.request(request)

Обратите внимание, что я не верю, что вы можете использовать Net :: HTTP.start, так как он не принимает local_host в качестве опции.

5 голосов
/ 28 января 2011

На самом деле есть способ сделать это, если вы обезьяны исправите TCPSocket:

https://gist.github.com/800214

Обуздать - это круто, но с Джруби работать не будет, поэтому я искал альтернативы ...

2 голосов
/ 10 июня 2010

Не похоже, что вы можете сделать это с помощью Net: HTTP.Вот источник

http://github.com/ruby/ruby/blob/trunk/lib/net/http.rb

В строке 644 открыто соединение

  s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }

Третий и четвертый аргументы TCPSocket.open - local_address и local_portпоскольку они не указаны, это невозможно.Похоже, тебе придется пойти с бордюром.

0 голосов
/ 03 января 2019

Конечно можно. Я сделал, как показано ниже:

# remote_host can be IP or hostname
uri     = URI.parse( "http://" + remote_host )
http    = Net::HTTP.new( uri.host, uri.port )
request = Net::HTTP::Get.new(uri.request_uri)
request.initialize_http_header( { "Host" => domain })
response = http.request( request )
...