ruby сбой запроса ipv6 rest-client с Apache 2.2.31

Я застрял с этим около двух дней...

Я использую ruby ​​(версия 2.3.3p222) gem rest-client (v2.0.0) для отправки запроса GET с URL-адресом ipv6 на сервер (Apache/2.2.31):

url =  'https://[fd36:4928:8040:dc10:0000:0000:0000:0160]:8080/resources/1'
resource = RestClient::Resource.new(url, :ssl_version => 'TLSv1', :verify_ssl => false, :headers => {'Authorization' => 'Basic cm9vdDAbCdEfwYXNzMSE='})

ресурс.получить

Я получил неверный ответ 400, а тело говорит: «Ваш браузер отправил запрос, который этот сервер не может понять. Кроме того, при попытке использовать ErrorDocument для обработки запроса произошла ошибка 400 Bad Request».

Однако я могу использовать команду curl с теми же параметрами и получить правильный ответ, поэтому я подозреваю, что, возможно, что-то не так с заголовком моего запроса на отдых-клиент.

PS: я также тестировал добавление «хоста»

header: {'Authorization' =>  'Basic cm9vdDAbCdEfwYXNzMSE=', 'host' => '[fd36:4928:8040:dc10:0000:0000:0000:0160]:8080' }

Это все еще не удалось с тем же плохим ответом.

Я только что заметил ошибку appache для этого запроса: "httpd[29124]: [ошибка] Имя хоста fd36:4928:8040:dc10:0000:0000:0000:0160, предоставленное через SNI и имя хоста fd36:4928: 8040:dc10:0000:0000:0000, предоставленные через HTTP, отличаются "


person Hailong Cao    schedule 13.03.2017    source источник
comment
Можете ли вы показать свою команду curl?   -  person Joe    schedule 13.03.2017
comment
@Joe curl --user admin:password -k https://[fd36:4928:8040:dc10:0000:0000:0000:0160]:8080/resources/1   -  person Hailong Cao    schedule 13.03.2017
comment
Верните заголовок хоста и исправьте заголовок авторизации, как показано ниже, и повторите попытку — есть ли ошибки в журнале apache?   -  person Joe    schedule 13.03.2017
comment
@Joe похоже на эту проблему: bugs.chromium.org/p/ хром/проблемы/detail?id=500981   -  person Hailong Cao    schedule 13.03.2017
comment
В коде вопроса опечатка header:, а не headers:. Это также то, с чем вы тестировали? Когда я пытаюсь передать явный заголовок Host, я получаю исключение, вызванное Net::HTTP, что, похоже, указывает на ошибку Ruby. URI::InvalidComponentError: bad component(expected host component): [   -  person A B    schedule 14.03.2017


Ответы (3)


Предоставленная вами команда curl преобразует --user admin:password в следующий заголовок:

Authorization: Basic YWRtaW46cGFzc3dvcmQ=

Однако вы отправляете

Basic: cm9vdDAbCdEfwYXNzMSE=

что не одно и то же... так что сервер, вероятно, жалуется на то, что не получил правильную авторизацию...

person beny23    schedule 13.03.2017
comment
извините за опечатку, это было "Авторизация" => "Базовый cm9vdDAbCdEfwYXNzMSE=" и это не сработало. - person Hailong Cao; 13.03.2017

После отладки и гугления в течение еще одного дня эта проблема кажется ясной:

Из аналогичного отчета об ошибке в chrome https://bugs.chromium.org/p/chromium/issues/detail?id=500981, "SNI – это только имена хостов, которые никогда не должны содержать IP-адреса". Однако ruby ​​использует ip в качестве имени хоста (в этом случае rest-client не в чем винить, поскольку он просто делегирует все функции ruby ​​lib). Вы можете найти доказательства в Net::HTTP#connect (около строки 922):

      # Server Name Indication (SNI) RFC 3546
      s.hostname = @address if s.respond_to? :hostname=

Просто закомментируйте последнюю строку, она будет работать (чтобы обойти это, вам нужно сделать патч для обезьян). Кроме того, как указал @alberge, заголовок хоста не содержит скобок, окончательный заголовок хоста запроса выглядит следующим образом: «FD36: 4928: 8040: DC10:: 162», без «[]».

Также на стороне Apache он делает что-то не так, поскольку просто удаляет все, начиная с последнего двоеточия, чтобы получить имя хоста без дополнительной проверки - это все еще существует в версии 2.4.10, не уверен, исправлено это или нет.

person Hailong Cao    schedule 14.03.2017

Похоже, это либо ошибка в rest-client, либо регресс в Ruby Net::HTTP.

https://github.com/rest-client/rest-client/issues/ 583

Какую версию Руби вы используете? Пробовали ли вы использовать Ruby 2.1, чтобы проверить, работает ли он там?

ИЗМЕНИТЬ:

Это Ruby Bug #12642. Заголовок Host для адреса IPv6 отправляется без включения [ ].

Ruby в 2.1.6 - 2.1.10 не имеет ошибки, но затрагивает версии >= 2.2.0.

И что еще хуже, есть ошибка с установкой явного заголовка хоста IPv6, поэтому вы получаете исключение URI::InvalidComponentError: bad component(expected host component): [

person A B    schedule 14.03.2017
comment
Я использую ruby ​​2.3.3p222 (версия 56859 21 ноября 2016 г.) [i386-mingw32], кажется, он включает скобки. (Я проверил это, добавив p req.to_hash в конец ruby ​​lib /net/http.rb#begin_transport). Мой случай больше похож на этот: bugs.chromium.org/p/chromium /issues/detail?id=500981. Ruby использует строку ip в качестве хоста SNI (чего не должно быть), а Apache по ошибке усекает имя хоста ipv6... - person Hailong Cao; 14.03.2017
comment
Поэтому я не изучал материал SNI, но я вполне уверен, что связанная ошибка влияет на вас. begin_transport вызывается перед Net::HTTPGenericRequest#exec, где правильное поведение присутствует в Ruby 2.1, но было удалено github .com/ruby/ruby/commit/70a2eb63. Поскольку заголовок Host не содержит квадратных скобок, Apache рассматривает последний :0160 как порт, а не как часть IP-адреса. Я бы посоветовал посмотреть заголовки с сервером netcat или подобным. - person A B; 14.03.2017
comment
вы правы после перепроверки, скобки отсутствуют! И после проверки со ссылкой на коммит эта строка: if host = self['host'] host.sub!(/:.*/s, ''.freeze) явно глючит для адреса ipv6. Вау, рубиновые парни должны это заметить... - person Hailong Cao; 14.03.2017