44

私はすでにこの分野でいくつかの研究をしましたが、解決策は見つかりませんでした。Facebookに対して非同期ajax呼び出しが行われるサイトがあります(JSONPを使用)。私はすべてのHTTPリクエストをVCRを使用してRuby側で記録しているので、この機能をAJAX呼び出しにも使用するのはクールだと思いました。

それで、私は少し遊んで、プロキシの試みを思いつきました。私はPhantomJSをヘッドレスブラウザおよびカピバラ内の統合のためのポルターガイストとして使用しています。これで、ポルターガイストは次のようなプロキシを使用するように構成されました。

  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

テストの目的で、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ファイルはVCRによって記録されます。次に、このオプションを有効にしましたc.ignore_localhost = true。ローカルホスト呼び出しを記録するのは(私の意見では)役に立たないためです。

それからもう一度試しましたが、ページで行われたAJAX呼び出しが記録されていないことを理解する必要がありました。さらに悪いことに、それらはもはやテスト内では機能しません。

つまり、私の質問は、ローカルホスト上のJSファイルへのすべての呼び出しが記録され、外部リソースへのJSONP呼び出しが記録されないのはなぜですか?それは「通常の」ajaxリクエストであるため、jsonPのものにすることはできません。または、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呼び出しの後にコンソールに出力を取得している限り)処理できます。それから私は、多分VCRは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

では、何が問題なのでしょうか。VCRはHTTPSを処理し、プロキシはHTTPSを処理します。なぜ彼らは一緒に遊んでいないのですか?

4

2 に答える 2

7

そこで私はいくつかの調査を行い、HTTPS呼び出しをMITMプロキシサーバーとして処理するVCRプロキシサーバーの非常に基本的な例を示しました(クライアントでセキュリティチェックを無効にした場合)。誰かが貢献してくれて、このことを実現するのを手伝ってくれたらとても嬉しいです。

githubリポジトリは次のとおりです:https ://github.com/23tux/vcr_proxy

于 2013-03-19T19:42:36.200 に答える
1

ビリーを膨らませることは非常に素晴らしいツールです。バイパスするドメインと、スタブする必要のあるURLを指定する必要があります。また、httpsのURLをスタブするのは少し注意が必要です。httpsのURLを次のようにスタブする必要がありますhttps://www.example.com:443/path/

于 2018-04-13T01:06:33.183 に答える