ruby ajax https phantomjs vcr

ruby - VCRProxy: Grabe llamadas PhantomJS ajax con VCR dentro de Capybara



https (3)

Ya hice algunas investigaciones en este campo, pero no encontré ninguna solución. Tengo un sitio, donde las llamadas asynchron ajax se realizan en Facebook (usando JSONP). Estoy grabando todas mis solicitudes HTTP en el lado de Ruby con VCR, así que pensé que sería genial, usar esta función también para llamadas AJAX.

Así que jugué un poco, y se me ocurrió un intento de proxy. Estoy usando PhantomJS como navegador sin cabeza y poltergeist para la integración dentro de Capybara. Poltergeist ahora está configurado para usar un proxy como este:

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

Para fines de prueba, escribí un servidor proxy basado en WEbrick, que integra 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)

Esto funciona bien con cada llamada de localhost, y se graban bien. Los archivos HTML, JS y CSS se graban mediante VCR. Luego habilité la opción c.ignore_localhost = true , porque es inútil (en mi opinión) grabar llamadas locales.

Luego lo intenté de nuevo, pero tuve que descubrir que las llamadas AJAX que se hacen en la página no se graban. Peor aún, ya no funcionan dentro de las pruebas.

Entonces, para ir al grano, mi pregunta es: ¿por qué se registran todas las llamadas a los archivos JS en el host local y las llamadas JSONP a los recursos externos no? No puede ser lo más jSONP, porque es una solicitud ajax "normal". ¿O hay un error dentro de phantomjs, que las llamadas AJAX no tienen proxy? Si es así, ¿cómo podríamos arreglar eso?

Si se está ejecutando, quiero integrar el procedimiento de inicio y detención dentro

------- ACTUALIZACIÓN -------

Investigué un poco y llegué al siguiente punto: el proxy tiene algunos problemas con las llamadas HTTPS y los datos binarios a través de llamadas HTTPS.

Inicié el servidor e hice algunas llamadas curl:

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

Esta llamada se graba como debería. El resultado de solicitud y respuesta del proxy es

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

Pero esta llamada no se graba, debe haber algún problema con HTTPS:

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

El resultado del encabezado es:

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

Por lo tanto, pensé que tal vez el proxy no puede manejar HTTPS, pero puede (siempre y cuando obtenga la salida en la consola después de la llamada cURL). Entonces pensé, tal vez VCR no puede burlarse de las solicitudes HTTPS. Pero al usar esta secuencia de comandos, la videograbadora se burla de las solicitudes HTTPS, cuando yo no las uso dentro del 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

Entonces, ¿cuál es el problema? La videograbadora maneja HTTPS y el proxy maneja HTTPS. ¿Por qué no juegan juntos?


Así que investigué un poco y ahora tengo un ejemplo muy básico de un servidor proxy VCR que funciona, que maneja llamadas HTTPS como un servidor proxy MITM (si desactiva la verificación de seguridad en su cliente). Me sentiría muy feliz si alguien pudiera contribuir y ayudarme a darle vida a esto.

Aquí está el repositorio de github: https://github.com/23tux/vcr_proxy



Puffing Billy es una herramienta muy buena. Debe especificar qué dominios omitir y qué direcciones URL necesita. También es un poco difícil anotar https urls. Debes codificar las URL de https como https://www.example.com:443/path/