Невозможно получить полный заголовок из внешнего URL-адреса в приложении Ruby on Rails

Фон:
Приложение rails, над которым я работаю, открывает статьи с других веб-сайтов в iframe. Но некоторые веб-сайты издателей (например, pitchfork.com, vox.com, medium.com) не открываются в окнах iframe, задавая в заголовке «X-Frame-Options: SAMEORIGIN». Итак, учитывая URL-адрес статьи, я пытаюсь изучить заголовок и либо открыть его в iframe (по умолчанию), либо открыть исходный сайт на новой вкладке (когда я обнаруживаю X-Frame-Options в заголовке).


Проблема:
Заголовок, который я извлекаю в Rails, иногда оказывается неполным, когда я извлекаю его (и печатаю в консоль) со следующим кодом:

puts y['site'] # example: "vox.com"
puts y['head'] # example: "/2016/1/25/10829662/obama-on-clinton-media"
require 'net/http'
http = Net::HTTP.start(y['site'])
resp = http.head(y['head'])
resp.each { |k, v| puts "#{k}: #{v}" }
http.finish

Пример: заголовок, который тянет rails для этой статьи vox.com (http://www.vox.com/2016/1/25/10829662/obama-on-clinton-media) выглядит следующим образом:

server: nginx/1.6.2
date: Fri, 29 Jan 2016 22:05:17 GMT
content-type: text/html
content-length: 184
connection: keep-alive
location: http://www.vox.com/2016/1/25/10829662/obama-on-clinton-media

Но когда я пытаюсь открыть iframe, хромированная консоль сообщает мне, что это невозможно, потому что для X-Frame-Options установлено значение SAMEORIGIN. После дальнейшего исследования на вкладке «Сеть» я смог изучить полный заголовок, и он выглядит следующим образом:

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=utf-8
Status: 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: max-age=0, must-revalidate
X-Request-Id: 693f75c9be4dde491ba3cd78232ac4870c4f82e2
X-Runtime: 0.404545
Content-Encoding: gzip
Via: 1.1 varnish-v4
Content-Length: 26450
Accept-Ranges: bytes
Date: Fri, 29 Jan 2016 22:10:47 GMT
Via: 1.1 varnish
Age: 106
Connection: keep-alive
X-Served-By: cache-jfk1034-JFK
X-Cache: MISS
X-Cache-Hits: 0
X-Timer: S1454105446.991771,VS0,VE12
Vary: Accept-Encoding, Origin, X-Forwarded-Proto

Эта проблема возникает не для всех сайтов. Например, заголовок, который я извлекаю с сайта pitchfork.com, четко указывает на то, что для него установлены параметры x-frame-options. Но с такими сайтами, как vox.com и medium.com, заголовок, который я извлекаю, не показывает параметры x-frame (как и многие другие элементы, которые не учитываются).

Как я могу вытащить правильный / полный заголовок в моем контроллере Rails таким образом, чтобы всегда определять, есть ли в заголовке URL-адреса X-Frame-Options?


person drajan    schedule 29.01.2016    source источник


Ответы (1)


Я попробовал здесь, в консоли IRB, и заметил, что запрос на веб-сайт vox.com возвращает 301 Moved Permanently, и он отправил новое местоположение в заголовке.

irb(main):001:0> y = {}
=> {}
irb(main):002:0> y['site'] = "vox.com"
=> "vox.com"
irb(main):003:0> y['head'] = "/2016/1/25/10829662/obama-on-clinton-media"
=> "/2016/1/25/10829662/obama-on-clinton-media"
irb(main):004:0> require 'net/http'
=> true
irb(main):005:0> http = Net::HTTP.start(y['site'])
=> #<Net::HTTP vox.com:80 open=true>
irb(main):006:0> resp = http.head(y['head'])
=> #<Net::HTTPMovedPermanently 301 Moved Permanently readbody=true> (HERE)
irb(main):007:0> resp.each { |k, v| puts "#{k}: #{v}" }
server: nginx/1.6.2
date: Fri, 29 Jan 2016 22:40:07 GMT
content-type: text/html
content-length: 184
connection: keep-alive
location: http://www.vox.com/2016/1/25/10829662/obama-on-clinton-media
=> {"server"=>["nginx/1.6.2"], "date"=>["Fri, 29 Jan 2016 22:40:07 GMT"], "content-type"=>["text/html"], "content-length"=>["184"], "connection"=>["keep-alive"], "location"=>["http://www.vox.com/2016/1/25/10829662/obama-on-clinton-media"]}
irb(main):008:0> http.finish
=> nil

Единственная разница между URL-адресом, который вы использовали, и местоположением, которое сервер отправил для перенаправления, - это «www». Попробуйте использовать с www и посмотрите, работает ли это.

Вы можете улучшить свой код, чтобы прочитать код ответа, и, если он 301, попробуйте еще раз с URL-адресом, отправленным сервером.

person Manoel Amaro    schedule 29.01.2016
comment
Я могу подтвердить то же поведение. OP делает запрос www.vox.com в браузере и vox.com в Rails, отсюда и разница. - person Jordan Running; 30.01.2016
comment
Ага, я вижу, что проблема. Итак, vox.com должен быть www.vox.com, но я не могу понять, на какой medium.com следует перенаправлять? Как я могу прочитать код ответа и URL-адрес, который отправляет сервер? - person drajan; 30.01.2016
comment
Вы можете использовать resp.code для получения статуса ответа (301) и resp['location'] для получения URL-адреса, отправленного сервером. - person Manoel Amaro; 30.01.2016
comment
Спасибо, это сработало с одним исключением: статьи с medium.com (пример: medium.com/the-coffeelicious/) дает статус ответа 301, но затем дает мне тот же URL-адрес, что и исходный запрос, когда я использую resp ['location']. Есть идеи, что там происходит? - person drajan; 31.01.2016