oesmith / puffing-billy

A rewriting web proxy for testing interactions between your browser and external sites. Works with ruby + rspec.
MIT License
656 stars 170 forks source link

ActionCable sockets not connecting with selenium_chrome_billy driver #252

Closed frostblooded closed 5 years ago

frostblooded commented 5 years ago

I am using the selenium_chrome_billy driver for testing with Capybara. I have some ActionCable sockets, but they are not able to connect from the client side to the Rails server. This issue is not present when using the selenium_chrome driver.

In the console the websockets give the following message:

WebSocket connection to 'ws://127.0.0.1:44643/cable' failed: Connection closed before receiving a handshake response

ronwsmith commented 5 years ago

Do you see anything prefixed with Billy in the logs?

frostblooded commented 5 years ago

I am seeing a lot of things prefixed with puffing-billy, but they are all for HTTP requests like puffing-billy: PROXY GET succeeded for 'https://ajax.googleapis.com:443/ajax/libs/jqueryui/1.7.2/themes/redmond/jquery-ui.css'. Unfortunately I don't see any requests to 127.0.0.1:3000/cable or anything similar, which is the URL to which the socket connects.

In the logs I see only HTTP requests. As far as I know ActionCable uses WebSockets, which are different, but I am not sure how puffing-billy handles them or how they work exactly.

I am having a brief discussion on Reddit with someone that has encountered this problem, but I couldn't quite make his solution work.

frostblooded commented 5 years ago

If this is of any help, in the browser console I am seeing an error

WebSocket connection to 'ws://127.0.0.1:45801/cable' failed: Connection closed before receiving a handshake response

and warnings after that when it retries the connection

WebSocket connection to 'ws://127.0.0.1:45801/cable' failed: WebSocket is closed before the connection is established.

ronwsmith commented 5 years ago

Can you share your billy config?

frostblooded commented 5 years ago

I don't have anything configured. I suppose I am using the defaults.

ronwsmith commented 5 years ago

Please read through the README, especially this section: https://github.com/oesmith/puffing-billy#caching

frostblooded commented 5 years ago

Maybe I am completely misunderstanding something, but I am not sure what this problem has to do with caching. I am reading though the options, but I don't understand what I need from there for the websocket connection that doesn't even get logged.

ronwsmith commented 5 years ago

What are you trying to accomplish with this gem?

frostblooded commented 5 years ago

I am trying to stub a direct upload to S3 and I have done that, but I also have ActionCable sockets on my site and for some reason they give these errors when using the puffing billy driver. I would like to have the direct uploads stubbed while also having the sockets to my server work.

ronwsmith commented 5 years ago

Hmm, I'm not familiar with ActionCable sockets so I'm not sure how much help I can be. Have you tried to disable the caching? Do you get the same error with other drivers that use puffing-billy?

frostblooded commented 5 years ago

I disabled the cache with

Billy.configure do |c|
#   c.record_requests = true
  c.cache = false
  c.cache_request_headers = false
  c.persist_cache = false
  c.ignore_cache_port = false # defaults to true
  c.non_successful_cache_disabled = true
  c.cache_path = 'spec/req_cache/'
  c.proxy_host = 'localhost' # defaults to localhost
  c.proxy_port = 12345 # defaults to random
  c.proxied_request_host = nil
  c.proxied_request_port = 80
end

Unfortunately that didn't change anything. The normal JS drivers work correctly (selenium, selenium_chrome), but the selenium_billy driver doesn't even show the socket connection in the Network tab on the browser and the selenium_chrome_billy is the one with the original problem in this issue.

As far as I know, the HTTP request that needs to pass in order for the socket to connect is seen here.

If we don't find a solution to this, I might be able to solve my issues without this gem, but it would be nice to fix the problem.

ronwsmith commented 5 years ago

If you're not seeing the requests at all, the WebSocket must be bypassing the proxy completely. There are some drivers that bypass proxies for localhost/127.0.0.1 intentionally. I'd suggest looking into driver settings and see if you can force the WebSocket connections through a proxy and then use the Billy proxy manually (by just adding the proxy to your driver config as the gem does for the *_billy drivers here).

ronwsmith commented 5 years ago

@frostblooded is this still an issue for you?

frostblooded commented 5 years ago

I don't really understand how to do any of this. Sorry. I also am not using this gem any longer as I couldn't make this work.

Looking back on it though, I see that maybe it isn't expected for this gem to work with websockets as they work differently from normal HTTP request. I suppose it is okay to close this issue now if you think this is something that isn't supposed to be supported.

0xGuybrush commented 4 years ago

I've hit a similar issue with Pusher's JavaScript client which uses secure websockets to their server.

I bypassed them from the proxy by using my own Chrome driver instance and setting flags to

bill_setup.rb

Billy.configure do |c|
  c.proxy_port = 1234
  # … other config…
end

spec_helper.rb

browser_options = Selenium::WebDriver::Chrome::Options.new(args: %w[
  # … other config args …
  proxy-server=http://localhost:1234
  proxy-bypass-list=wss://*
])
zedtux commented 2 years ago

Thank you @another-dave, you solution works fine !

In my case, a dockerized project, with a container running Chrome, I had to update the container's environments in order to add both flags --proxy-server and --proxy-bypass-list and my issues are gone.