programing

VCRPoxy: 레코드 팬텀Capybara 내의 VCR을 사용한JS ajax 콜

magicmemo 2023. 3. 17. 20:33
반응형

VCRPoxy: 레코드 팬텀Capybara 내의 VCR을 사용한JS ajax 콜

저는 이미 이 분야에서 조사를 해봤지만 해결책을 찾지 못했습니다.페이스북(JSONP를 사용하여)에 비동기 Ajax 콜을 발신하는 사이트가 있습니다.저는 VCR에서 모든 HTTP 요청을 Ruby 쪽에서 기록하고 있기 때문에, AJAX 콜에서도 이 기능을 사용하는 것이 좋다고 생각했습니다.

그래서 저는 조금 놀다가 대리 시도를 떠올렸습니다.팬텀 사용 중JS는 Capybara 내부 통합을 위한 헤드리스 브라우저 및 폴터가이스트입니다.이제 다음과 같은 프록시를 사용하도록 Poltergeist가 설정되었습니다.

  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 콜이 녹음되지 않는 이유는 무엇입니까?jsonP일 리가 없어요.일반적인 아약스 요청이기 때문입니다.아니면 phantomjs에 AJAX 콜이 프록시되지 않는 버그가 있습니까?그렇다면 어떻게 고칠 수 있을까요?

실행 중인 경우 시작 및 중지 절차를 내부로 통합합니다.

------- UPDATE -------

조사를 해보니 다음과 같습니다.프록시는 HTTPS 콜과 HTTPS 콜을 통한 바이너리 데이터에 문제가 있습니다.

서버를 시작하고 몇 가지 콜을 했습니다.

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를 처리합니다.왜 같이 안 놀아요?

그래서 조사를 해봤더니 HTTPS 콜을 MITM 프록시 서버로서 처리하는 VCR 프록시 서버의 기본적인 예를 소개합니다(클라이언트에서 보안 체크를 비활성화한 경우).누군가 이 일을 실현시킬 수 있도록 도움을 줄 수 있다면 매우 기쁠 것입니다.

다음은 github repo입니다.https://github.com/23tux/vcr_proxy

빌리를 피우는 것은 매우 좋은 도구이다.우회할 도메인과 스터브할 URL을 지정해야 합니다.또한 약간 까다로운 stubbing https URL도 있습니다.https URL을 stub으로 해야 합니다.https://www.example.com:443/path/

언급URL : https://stackoverflow.com/questions/13039251/vcrproxy-record-phantomjs-ajax-calls-with-vcr-inside-capybara

반응형