44 votes

VCRProxy: Enregistrez des appels ajax PhantomJS avec un magnétoscope à l'intérieur de Capybara

J'ai déjà fait quelques recherches dans ce domaine, mais n'a pas trouvé de solution. J'ai un site, où asynchron appels ajax sont apportées à facebook (à l'aide de JSONP). J'enregistre toutes mes requêtes HTTP sur le Ruby côté avec MAGNÉTOSCOPE, j'ai donc pensé qu'il serait cool, pour utiliser cette fonction pour les appels AJAX.

J'ai donc joué un peu partout, et est venu avec une tentative de proxy. Je suis l'aide de PhantomJS comme un headless browser et lutin pour l'intégration à l'intérieur de Capybara. Poltergeist est maintenant configuré pour utiliser un proxy comme ceci:

  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

Pour des fins de test, j'ai écrit un serveur proxy basé sur WEbrick, qui intègre un MAGNÉTOSCOPE:

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)

Cela fonctionne bien avec tous localhost appel, et qu'ils soient bien enregistrés. Le HTML, CSS et JS, les fichiers sont enregistrés par un MAGNÉTOSCOPE. Ensuite j'ai activé l' c.ignore_localhost = true option, parce que c'est inutile (à mon avis) pour enregistrer localhost appels.

Ensuite, j'ai essayé de nouveau, mais j'ai dû comprendre, que les appels AJAX qui sont faites sur la page ne sont pas enregistrées. Pire encore, ils ne fonctionnent pas à l'intérieur de l'tests plus.

Alors, pour en venir à ce point, ma question est la suivante: Pourquoi tous les appels à la JS fichiers sur le localhost enregistré, et JSONP des appels à des ressources externes pas? Il ne peut pas être le jsonP chose, parce que c'est "normal" de la requête ajax. Ou est-il d'un bug à l'intérieur de phantomjs, que les appels AJAX ne sont pas mandatées? Si oui, comment pourrions-nous résoudre ce problème?

Si il fonctionne, je souhaite intégrer le démarrer et arrêter la procédure à l'intérieur

------- Mise à JOUR -------

J'ai fait quelques recherches et est venu au point suivant: le proxy a quelques problèmes avec HTTPS appels et des données binaires via HTTPS appels.

J'ai commencé le serveur, et fait quelques curl appels:

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

Cet appel est enregistré comme il se doit. La demande et la réponse de la sortie de la procuration est

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

Mais cet appel n'est enregistré, il doit y avoir un problème avec HTTPS:

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

L'en-tête de sortie est:

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

Alors, j'ai pensé peut-être que le proxy ne peut pas gérer HTTPS, mais il peut (aussi longtemps que je me fais de la sortie sur la console après la boucle d'appel). Puis j'ai pensé, peut-être que le MAGNÉTOSCOPE ne peut pas se moquer de requêtes HTTPS. Mais l'utilisation de ce script, MAGNÉTOSCOPE se moque de sortir les requêtes HTTPS, quand je ne l'utilise pas à l'intérieur du proxy:

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

Quel est donc le problème? MAGNÉTOSCOPE poignées de HTTPS et le proxy gère le protocole HTTPS. Pourquoi ils ne jouent pas ensemble?

7voto

23tux Points 2859

J'ai donc fait quelques recherches et j'ai maintenant un exemple très basique de serveur proxy de magnétoscope en état de fonctionnement, qui traite les appels HTTPS en tant que serveur proxy MITM (si vous désactivez le contrôle de sécurité de votre client). Je serais très heureux si quelqu'un pouvait contribuer et m'aider à donner vie à cette chose.

Voici le repo de github: https://github.com/23tux/vcr_proxy

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X