VCRProxy:在Capybara内部用VCR录制PhantomJS ajax呼叫
我已经在这方面做了一些研究,但没有find任何解决办法。 我有一个网站,其中asynchronousajax调用Facebook(使用JSONP)。 我用VCRlogging了所有的HTTP请求到Ruby端,所以我认为这个function也适用于AJAX调用。
所以我玩了一下,提出了一个代理尝试。 我使用PhantomJS作为Capybara内部集成的无头浏览器和微妙的手段。 Poltergeist现在被configuration为使用这样的代理:
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
出于testing目的,我写了一个基于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)
这与每个本地主机通话都很好,并且logging得很好。 HTML,JS和CSS文件由VCR录制。 然后我启用了c.ignore_localhost = true
选项,导致无用(在我看来)logging本地主机调用。
然后我再次尝试,但我必须弄清楚,在页面上的AJAX调用不logging。 更糟的是,他们不再在testing中工作了。
所以要说到这一点,我的问题是:为什么所有对本地主机上的JS文件的调用都被logging下来,JSONP不是调用外部资源? 它不能是jsonP的东西,因为这是一个“正常”的Ajax请求。 或者phantomjs里面有一个bug,AJAX调用是不是被代理的? 如果是这样,我们该如何解决?
如果它正在运行,我想要集成启动和停止程序
——- UPDATE ——-
我做了一些研究,得出以下结论:代理通过HTTPS调用HTTPS调用和二进制数据有一些问题。
我启动了服务器,并进行了一些curl调用:
curl --proxy 127.0.0.1:9100 http://d3jgo56a5b0my0.cloudfront.nethttp://img.dovov.comv7/application/stories_view/icons/bug.png
这个电话会被logging下来。 代理的请求和响应输出是
GET http://d3jgo56a5b0my0.cloudfront.nethttp://img.dovov.comv7/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
但是这个调用没有被logging下来,HTTPS肯定有一些问题:
curl --proxy 127.0.0.1:9100 https://d3jgo56a5b0my0.cloudfront.nethttp://img.dovov.comv7/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.nethttp://img.dovov.comv7/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
那么问题是什么? VCR处理HTTPS,代理处理HTTPS。 为什么他们不一起玩?
所以我做了一些研究,现在我有一个工作VCR代理服务器的基本示例,它将HTTPS调用作为MITM代理服务器处理(如果您停用客户端中的安全检查)。 如果有人能够贡献并帮助我实现这个目标,我将会非常高兴。
这里是github回购: https : //github.com/23tux/vcr_proxy