Я уже провел некоторые исследования в этой области, но не нашел решения. У меня есть сайт, на котором асинхронные вызовы 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. Почему они не играют вместе?