Я уже занимался некоторыми исследованиями в этой области, но не нашел решения. У меня есть сайт, на котором асинхронные вызовы 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, который интегрирует VCR:
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)
Это хорошо работает с каждым вызовом localhost, и они хорошо записываются. Файлы HTML, JS и CSS записываются видеомагнитофоном. Затем я включил параметр c.ignore_localhost = true
, поэтому бесполезно (по-моему) записывать вызовы localhost.
Затем я снова попытался, но мне пришлось выяснить, что вызовы AJAX, сделанные на странице, не записываются. Хуже того, они больше не работают внутри тестов.
Итак, чтобы ответить на этот вопрос, мой вопрос: почему все вызовы в JS файлы на локальном хосте записываются, а JSONP-вызовы на внешние ressources не? Это не может быть проблемой jsonP, потому что это "обычный" запрос ajax. Или есть ошибка внутри phantomjs, что вызовы AJAX не проксированы? Если да, то как мы можем это исправить?
Если он работает, я хочу интегрировать процедуру запуска и остановки внутри
------- UPDATE -------
Я провел некоторое исследование и пришел к следующему пункту: у прокси-сервера есть некоторые проблемы с вызовами HTTPS и двоичными данными через вызовы HTTPS.
Я запустил сервер и сделал несколько завитушек:
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-запросами. Но используя этот script, видеомагнитофон высмеивает 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. Почему они не играют вместе?