VCRProxy: запись ajax-вызовов PhantomJS с помощью видеомагнитофона внутри Capybara

Я уже провел некоторые исследования в этой области, но не нашел решения. У меня есть сайт, на котором асинхронные вызовы ajax выполняются в facebook (с использованием JSONP). Я записываю все свои HTTP-запросы на стороне Ruby с помощью видеомагнитофона, поэтому я подумал, что было бы здорово использовать эту функцию и для вызовов AJAX.

Так что я немного поиграл и придумал попытку прокси. Я использую PhantomJS в качестве безголового браузера и полтергейста для интеграции внутри Capybara. Полтергейст теперь настроен на использование такого прокси:

  Capybara.register_driver :poltergeist_vcr do |app|
    options = {
      :phantomjs_options => [
        "--proxy=127.0.0.1:9100",
        "--proxy-type=http",
        "--ignore-ssl-errors=yes",
        "--web-security=no"
      ],
      :inspector => true
    }
    Capybara::Poltergeist::Driver.new(app, options)
  end
  Capybara.javascript_driver = :poltergeist_vcr

В целях тестирования я написал прокси-сервер на основе WEbrick, который интегрирует видеомагнитофон:

require 'io/wait'
require 'webrick'
require 'webrick/httpproxy'

require 'rubygems'
require 'vcr'

module WEBrick
  class VCRProxyServer < HTTPProxyServer
    def service(*args)
      VCR.use_cassette('proxied') { super(*args) }
    end
  end
end

VCR.configure do |c|
  c.stub_with :webmock
  c.cassette_library_dir = '.'
  c.default_cassette_options = { :record => :new_episodes }
  c.ignore_localhost = true
end

IP   = '127.0.0.1'
PORT = 9100

reader, writer = IO.pipe

@pid = fork do
  reader.close
  $stderr = writer
  server = WEBrick::VCRProxyServer.new(:BindAddress => IP, :Port => PORT)
  trap('INT') { server.shutdown }
  server.start
end

raise 'VCR Proxy did not start in 10 seconds' unless reader.wait(10)

Это хорошо работает с каждым локальным вызовом, и они хорошо записываются. Файлы HTML, JS и CSS записываются видеомагнитофоном. Затем я включил опцию c.ignore_localhost = true, потому что (на мой взгляд) бесполезно записывать вызовы localhost.

Затем я попробовал еще раз, но мне пришлось выяснить, что вызовы AJAX, сделанные на странице, не записываются. Хуже того, они больше не работают внутри тестов.

Итак, чтобы перейти к делу, мой вопрос: почему все вызовы JS-файлов на локальном хосте записываются, а вызовы JSONP к внешним ресурсам - нет? Это не может быть вещь jsonP, потому что это «обычный» запрос ajax. Или внутри phantomjs есть ошибка, что вызовы AJAX не передаются через прокси? Если да, то как мы можем это исправить?

Если он работает, я хочу интегрировать процедуру запуска и остановки внутри

------- ОБНОВЛЕНИЕ -------

Я провел небольшое исследование и пришел к следующему выводу: у прокси есть некоторые проблемы с HTTPS-вызовами и бинарными данными через HTTPS-вызовы.

Я запустил сервер и сделал несколько вызовов curl:

curl --proxy 127.0.0.1:9100 http://d3jgo56a5b0my0.cloudfront.net/images/v7/application/stories_view/icons/bug.png

Этот звонок записывается, как и должно быть. Вывод запроса и ответа от прокси-сервера

GET http://d3jgo56a5b0my0.cloudfront.net/images/v7/application/stories_view/icons/bug.png HTTP/1.1
User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
Host: d3jgo56a5b0my0.cloudfront.net
Accept: */*
Proxy-Connection: Keep-Alive

HTTP/1.1 200 OK 
Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-10-12)
Date: Tue, 20 Nov 2012 10:13:10 GMT
Content-Length: 0
Connection: Keep-Alive

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

curl --proxy 127.0.0.1:9100 https://d3jgo56a5b0my0.cloudfront.net/images/v7/application/stories_view/icons/bug.png

Вывод заголовка:

CONNECT d3jgo56a5b0my0.cloudfront.net:443 HTTP/1.1
Host: d3jgo56a5b0my0.cloudfront.net:443
User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
Proxy-Connection: Keep-Alive

HTTP/1.1 200 OK 
Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-10-12)
Date: Tue, 20 Nov 2012 10:15:48 GMT
Content-Length: 0
Connection: close

Итак, я подумал, что, возможно, прокси-сервер не может обрабатывать HTTPS, но он может (пока я получаю вывод на консоли после вызова cURL). Тогда я подумал, может быть, видеомагнитофон не может имитировать HTTPS-запросы. Но с помощью этого скрипта VCR имитирует HTTPS-запросы, когда я не использую его внутри прокси:

require 'vcr'

VCR.configure do |c|
  c.hook_into :webmock
  c.cassette_library_dir = 'cassettes'
end

uri = URI("https://d3jgo56a5b0my0.cloudfront.net/images/v7/application/stories_view/icons/bug.png")

VCR.use_cassette('https', :record => :new_episodes) do
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  response = http.request_get(uri.path)
  puts response.body
end

Так в чем проблема? Видеомагнитофон обрабатывает HTTPS, а прокси-сервер обрабатывает HTTPS. Почему они не играют вместе?


person 23tux    schedule 23.10.2012    source источник
comment
Отличные вопросы... Хотел бы я помочь, но я мало использовал полтергейст или phantomJS, и похоже, что проблема, вероятно, здесь, а не в настройках вашего видеомагнитофона. Ваш прокси-код видеомагнитофона выглядит нормально.   -  person Myron Marston    schedule 24.10.2012
comment
К сожалению, я пока не нашел решения. Я думал о написании проблемы Github для phantomjs (если их вызовы ajax не проходят через прокси), но отправить проблемы невозможно. Возможно, вызов (jsonp) отличается от обычных вызовов. У кого-нибудь есть идея?   -  person 23tux    schedule 25.10.2012
comment
Привет @23tux, вы можете сообщить о проблемах с phantomjs здесь: code.google.com/p/ фантомы/проблемы/список   -  person mooreds    schedule 23.12.2012
comment
@ 23tux Я не уверен, поможет ли это, но в прошлом году у меня была проблема с фантомами и невозможностью подключиться к https-соединениям. Единственный способ, которым я мог заставить фантомы подключаться к https, - это запустить fiddler в Windows. Я предполагаю, что fiddler перехватывал трафик, действующий как прокси, и смог расшифровать его для использования phantomjs   -  person Justin Bicknell    schedule 28.02.2013


Ответы (2)


Итак, я провел небольшое исследование, и теперь у меня есть очень простой пример работающего прокси-сервера VCR, который обрабатывает вызовы HTTPS как прокси-сервер MITM (если вы отключите проверку безопасности в своем клиенте). Я был бы очень рад, если бы кто-то мог внести свой вклад и помочь мне воплотить эту вещь в жизнь.

Вот репозиторий github: https://github.com/23tux/vcr_proxy.

person 23tux    schedule 19.03.2013
comment
Я все еще работаю над интеграцией в RSpec с капибарой. Когда закончу, выложу ссылку сюда - person 23tux; 25.03.2013
comment
Мы создаем приложение Rails, которое использует PhantomJS + Poltergeist + Capybara для автоматизации взаимодействия с сайтами и захвата моментальных снимков, и только что обнаружили, что VCR и близко не подходит для захвата этих вызовов PhantomJS. Так что огромное спасибо за работу, которую вы проделали до сих пор, мы посмотрим и обязательно сообщим вам, поможет ли ваш драгоценный камень удовлетворить наши потребности. - person Topher Hunt; 27.08.2014
comment
Спасибо;) Через несколько недель мне это снова понадобится для проекта, возможно, я смогу выпустить обновленную версию для текущей версии VCR и RSpec (которая немного лучше интегрируется) - person 23tux; 28.08.2014

Puffing Billy — очень хороший инструмент. Вам нужно указать, какие домены нужно обойти, а какие URL-адреса нужно заглушить. Также немного сложно заглушить URL-адреса https. Вам нужно заглушить URL-адреса https как https://www.example.com:443/path/

person Kamal Rizk    schedule 13.04.2018