82 Commits

Author SHA1 Message Date
James Coglan 370ac9b944 Emit binary frames as binary strings by default, and make Driver.frame() treat such strings as binary frames 2025-05-24 13:16:00 +01:00
James Coglan 3a2931751c Fix handling of default ports on Ruby 3.1 2022-09-10 15:37:55 +01:00
Daniel Morrison 0e950c5134 Flag files that modify string literals
When running in an environment that freezes string literals by default, `hybi.rb` raises exceptions as it modifies the `'C2'` string.

Adding the magic comment supports this use case without modifying behavior for anyone else. I added it to one spec too, so that running specs this way (`RUBYOPT="--enable=frozen-string-literal" rspec`) keeps them all passing.
2021-09-13 10:15:25 -04:00
James Coglan 586c27f44e Clarify behaviour of Driver.encode to convert strings to UTF-8 and arrays to ASCII-8BIT 2021-06-12 16:53:51 +01:00
James Coglan 219c409844 Use the Ruby Encoding constants instead of their string names 2021-02-26 14:44:50 +00:00
pjaspers 202e1800e0 Allow rack.input.read to return a frozen string
We're seeing this occasionally in our error logs, where the `env`
passed into to the driver will return a frozen string when read.

The stack trace always includes ActionCable in to the mix, so
something like this:

      "/app/vendor/bundle/ruby/2.6.0/gems/websocket-driver-0.7.0/lib/websocket/driver/draft76.rb" line 11 in force_encoding
      "/app/vendor/bundle/ruby/2.6.0/gems/websocket-driver-0.7.0/lib/websocket/driver/draft76.rb" line 11 in initialize
      "/app/vendor/bundle/ruby/2.6.0/gems/websocket-driver-0.7.0/lib/websocket/driver.rb" line 162 in new
      "/app/vendor/bundle/ruby/2.6.0/gems/websocket-driver-0.7.0/lib/websocket/driver.rb" line 162 in rack
      "/app/vendor/bundle/ruby/2.6.0/gems/actioncable-5.2.3/lib/action_cable/connection/client_socket.rb" line 47 in initialize
      "/app/vendor/bundle/ruby/2.6.0/gems/actioncable-5.2.3/lib/action_cable/connection/web_socket.rb" line 10 in new
      "/app/vendor/bundle/ruby/2.6.0/gems/actioncable-5.2.3/lib/action_cable/connection/web_socket.rb" line 10 in initialize
      "/app/vendor/bundle/ruby/2.6.0/gems/actioncable-5.2.3/lib/action_cable/connection/base.rb" line 59 in new
      "/app/vendor/bundle/ruby/2.6.0/gems/actioncable-5.2.3/lib/action_cable/connection/base.rb" line 59 in initialize
      "/app/vendor/bundle/ruby/2.6.0/gems/actioncable-5.2.3/lib/action_cable/server/base.rb" line 30 in new
      "/app/vendor/bundle/ruby/2.6.0/gems/actioncable-5.2.3/lib/action_cable/server/base.rb" line 30 in call

I still don't quite know why someone is sometimes returning a frozen
string (it could also have to with any of the current rack middleware
we're using), but I do know that we can handle it here.

So this adds a spec and some behavior to fix that.
2020-05-14 16:22:20 +01:00
James Coglan e568366f82 Formatting change: {...} should have spaces inside the braces 2019-06-11 16:12:52 +01:00
James Coglan 2ec898c6a1 If any driver encounters a validation error in the request headers, it can throw an error and Driver#start will catch that and send a 400 response to the client. 2017-11-23 23:01:26 +00:00
James Coglan bed599ae32 Don't require rubygems, this has not been necessary since Ruby 1.8. 2017-08-08 23:41:48 +01:00
James Coglan cd38349f9a Make the ping/pong tests check the content of the events. 2017-08-02 21:54:59 +01:00
Matthew O'Riordan f22c97f977 Emit :ping and :pong events in the driver 2017-05-16 15:00:10 +01:00
James Coglan 9ce857b3d4 Revise uses of encoding APIs.
When originally implemented, we still supported Ruby 1.8, which
necessitated checking for encoding methods and using a regex to validate
UTF-8. These checks are now gone.

We tagged many strings as binary when not strictly necessary, either
because we were just going to iterate their bytes or because we were
going to hand them off to the caller which should just write them
directly to a socket. Strings used as buffers to accumulate streaming
input are still tagged as binary to avoid encoding
collision/conversion.

The places where we do need to tag as UTF-8 (i.e. just before emitting
to the application) remain, but copy the string if necessary. This
allows us to work with frozen strings.

Finally, strings passed in via the Driver#text method should be
*transcoded* to UTF-8 if necessary, not merely tagged. The Ruby
String#encode method produces a new string so this should also be safe
with frozen strings.
2016-05-19 21:08:22 +01:00
James Coglan 115d82bebb Silence all -W2 warnings. 2016-05-18 22:42:16 +01:00
James Coglan 4ae198b1d3 Throw a more helpful error if a client driver is created with an invalid URL. 2015-10-17 21:37:13 +01:00
James Coglan c63220194c Close the connection if a draft-76 client sends a Sec-WebSocket-Key header where the numeric value is a non-integer multiple of the number of spaces. 2015-10-02 21:32:35 +01:00
James Coglan bc7d29cb52 Emit a protocol error when a closing frame has a 1-byte payload. 2015-07-17 22:02:51 +01:00
James Coglan 59940290c9 Emit close code 1000 if the closing frame does not contain one. 2015-07-16 08:19:05 +01:00
James Coglan 8919430801 Add tests for exception safety in the Draft75 parser. 2015-07-07 21:24:33 +01:00
James Coglan 587704d752 Test that exceptions are not masked by the parser. 2015-07-07 08:47:08 +01:00
James Coglan 9385764c09 Test that the parser continues working if a message listener raises an error. 2015-07-06 21:19:25 +01:00
James Coglan fa11841bfa Don't catch errors from event listeners. Instead, make sure that in all parsing methods in Hybi, @stage is set before any user called is invoked so the parser is in the right state before code that might raise is called. 2015-07-05 18:52:53 +01:00
James Coglan f218999304 If an event listener emits an error, close the connection with code 1011. 2015-07-04 20:54:42 +01:00
James Coglan d69cdaba97 Allow event listeners to be passed as normal rather than block arguments.
This discourages the inappropriate use of 'return' inside event
listeners. Also, we return the listener, so that the caller has a
reference to it in case they do pass a block.
2015-07-04 19:28:49 +01:00
James Coglan 7af53b5be0 Add a pong() command for sending unsolicited pong frames. 2015-07-04 18:49:46 +01:00
James Coglan d6b147f2e0 Fail the connection when the server receives an invalid Sec-WebSocket-Extensions header. 2015-03-26 09:43:59 +00:00
James Coglan b78ed7706d Don't send a close frame in response to receiving one, if we already sent a close frame. 2015-03-14 10:03:26 +00:00
James Coglan eb20069011 Migrate the internal representation of buffers from arrays to ASCII-8BIT strings, since this is what we're planning on handing off to extensions. 2014-12-05 09:17:09 +00:00
James Coglan ec6803e19c Remove the start_tls protocol and replace it by the proxy emitting a 'connect' event. 2014-11-08 16:45:06 +00:00
James Coglan 0a200bbdef Refactor proxy support into a separate class that represents the proxy connection as a real object. 2014-11-06 23:37:13 +00:00
James Coglan 8392f77a58 Add support for connecting via HTTP proxies. 2014-10-27 21:49:40 +00:00
James Coglan 58c19e7659 If driver.close is called before driver.start, the driver should close. 2014-10-03 00:36:50 +01:00
James Coglan 907ff98bb9 Silence all the RSpec deprecation notices. 2014-06-16 21:09:23 +01:00
James Coglan 1b3f32bbc7 Trailing blank lines are bad. 2014-05-17 00:34:48 +01:00
James Coglan 2f8f281615 Correct the draft-76 status line reason phrase. 2014-04-17 02:22:19 +01:00
James Coglan e3587fcbb1 Add a max_length option to the Hybi/Client class. 2013-12-02 21:55:43 +00:00
James Coglan eae69314f1 Add support for Basic Auth URLs to the client driver. 2013-09-09 20:28:29 +01:00
James Coglan de8a5c4a8d Silence RSpec deprecation warnings. 2013-09-09 20:17:29 +01:00
James Coglan ac3bb51cbd Adjust encoding operations so that encoding is explicit at the call site, and all strings written to I/O are ASCII-8BIT. 2013-07-02 09:46:29 +01:00
James Coglan b0fa32b9c5 Move a couple of tests. 2013-05-11 22:27:08 +01:00
James Coglan 074a8a2f16 Add #status and #headers methods to the Client driver. 2013-05-11 20:42:06 +01:00
James Coglan 5a7fadbcbe Add API for setting custom handshake headers. 2013-05-11 20:28:36 +01:00
James Coglan ba696e8e2c Implement a proper streaming HTTP response parser. This makes the client-side parser more robust and also gives a way to building a driver for TCP servers. 2013-05-11 16:56:29 +01:00
James Coglan be1f1cdc35 Rename the module to websocket-driver. 2013-05-04 16:43:25 +01:00
James Coglan f61a5e60f2 Add more robust error handling for Hybi and Client and emit error events when the protocol goes wrong. 2013-05-02 00:09:34 +01:00
James Coglan 38f0d2dca7 Remove the UTF-8 validation tests, let Autobahn deal with that. 2013-04-30 23:37:19 +01:00
James Coglan 7b0daf6f3c Implement the EventEmitter interface. 2013-04-30 08:53:33 +01:00
James Coglan 38b19487c5 A few corrections I made while porting to Node. 2013-04-29 20:28:47 +01:00
James Coglan 2662d43b08 Some small refactorings I spotted while porting this to Node. 2013-04-29 00:14:45 +01:00
James Coglan 10da09afbd Always emit the empty string instead of nil as the closure reason in Hybi. 2013-04-20 22:04:24 +01:00
James Coglan 787697dc59 Some more large renaming, this time putting everything inside the WebSocket::Protocol namespace. 2013-04-20 18:22:09 +01:00