https://github.com/faye/websocket-driver-ruby/commit/3a2931751c6893e312ee24d9c6392bd096a798fd From 3a2931751c6893e312ee24d9c6392bd096a798fd Mon Sep 17 00:00:00 2001 From: James Coglan Date: Sat, 10 Sep 2022 15:37:55 +0100 Subject: [PATCH] Fix handling of default ports on Ruby 3.1 --- a/lib/websocket/driver.rb +++ b/lib/websocket/driver.rb @@ -42,6 +42,7 @@ def Mask.mask(payload, mask) end MAX_LENGTH = 0x3ffffff + PORTS = { 'ws' => 80, 'wss' => 443 } STATES = [:connecting, :open, :closing, :closed] ConnectEvent = Struct.new(nil) @@ -209,6 +210,14 @@ def self.encode(data, encoding = nil) data.force_encoding(encoding) end + def self.host_header(uri) + host = uri.host + if uri.port and uri.port != PORTS[uri.scheme] + host += ":#{uri.port}" + end + host + end + def self.validate_options(options, valid_keys) options.keys.each do |key| unless valid_keys.include?(key) --- a/lib/websocket/driver/client.rb +++ b/lib/websocket/driver/client.rb @@ -23,11 +23,10 @@ def initialize(socket, options = {}) raise URIError, "#{ socket.url } is not a valid WebSocket URL" end - host = uri.host + (uri.port ? ":#{ uri.port }" : '') path = (uri.path == '') ? '/' : uri.path @pathname = path + (uri.query ? '?' + uri.query : '') - @headers['Host'] = host + @headers['Host'] = Driver.host_header(uri) @headers['Upgrade'] = 'websocket' @headers['Connection'] = 'Upgrade' @headers['Sec-WebSocket-Key'] = @key --- a/lib/websocket/driver/proxy.rb +++ b/lib/websocket/driver/proxy.rb @@ -4,8 +4,6 @@ class Driver class Proxy include EventEmitter - PORTS = { 'ws' => 80, 'wss' => 443 } - attr_reader :status, :headers def initialize(client, origin, options) @@ -20,7 +18,7 @@ def initialize(client, origin, options) @state = 0 @headers = Headers.new - @headers['Host'] = @origin.host + (@origin.port ? ":#{ @origin.port }" : '') + @headers['Host'] = Driver.host_header(@origin) @headers['Connection'] = 'keep-alive' @headers['Proxy-Connection'] = 'keep-alive' --- a/spec/websocket/driver/client_spec.rb +++ b/spec/websocket/driver/client_spec.rb @@ -121,6 +121,54 @@ end end + describe "with an explicit port" do + let(:url) { "ws://www.example.com:3000/socket" } + + it "includes the port in the Host header" do + expect(socket).to receive(:write).with( + "GET /socket HTTP/1.1\r\n" + + "Host: www.example.com:3000\r\n" + + "Upgrade: websocket\r\n" + + "Connection: Upgrade\r\n" + + "Sec-WebSocket-Key: 2vBVWg4Qyk3ZoM/5d3QD9Q==\r\n" + + "Sec-WebSocket-Version: 13\r\n" + + "\r\n") + driver.start + end + end + + describe "with a wss: URL" do + let(:url) { "wss://www.example.com/socket" } + + it "does not include the port in the Host header" do + expect(socket).to receive(:write).with( + "GET /socket HTTP/1.1\r\n" + + "Host: www.example.com\r\n" + + "Upgrade: websocket\r\n" + + "Connection: Upgrade\r\n" + + "Sec-WebSocket-Key: 2vBVWg4Qyk3ZoM/5d3QD9Q==\r\n" + + "Sec-WebSocket-Version: 13\r\n" + + "\r\n") + driver.start + end + end + + describe "with a wss: URL and explicit port" do + let(:url) { "wss://www.example.com:3000/socket" } + + it "includes the port in the Host header" do + expect(socket).to receive(:write).with( + "GET /socket HTTP/1.1\r\n" + + "Host: www.example.com:3000\r\n" + + "Upgrade: websocket\r\n" + + "Connection: Upgrade\r\n" + + "Sec-WebSocket-Key: 2vBVWg4Qyk3ZoM/5d3QD9Q==\r\n" + + "Sec-WebSocket-Version: 13\r\n" + + "\r\n") + driver.start + end + end + describe "with custom headers" do before do driver.set_header "User-Agent", "Chrome"