diff --git a/lib/websocket/extensions.rb b/lib/websocket/extensions.rb index 14ca7ab..0b246d2 100644 --- a/lib/websocket/extensions.rb +++ b/lib/websocket/extensions.rb @@ -75,6 +75,7 @@ def generate_offer def activate(header) responses = Parser.parse_header(header) @sessions = [] + activated = {} responses.each_offer do |name, params| unless record = @index[name] @@ -83,6 +84,11 @@ def activate(header) ext, session = *record + if activated[name] + raise ExtensionError, %Q{Server sent multiple responses for extension "#{ name }"} + end + activated[name] = true + if reserved = reserved?(ext) raise ExtensionError, %Q{Server sent two extension responses that use the RSV#{ reserved[0] }} + %Q{bit: "#{ reserved[1] }" and "#{ ext.name }"} diff --git a/spec/websocket/extensions_spec.rb b/spec/websocket/extensions_spec.rb index ccb305d..d566778 100644 --- a/spec/websocket/extensions_spec.rb +++ b/spec/websocket/extensions_spec.rb @@ -120,6 +120,13 @@ expect { @extensions.activate("tar") }.not_to raise_error end + it "rejects duplicate responses for an extension without reserved bits" do + allow(@ext).to receive(:rsv1).and_return(false) + expect(@session).to receive(:activate).with({}).exactly(1).and_return(true) + + expect { @extensions.activate("deflate, deflate") }.to raise_error(ExtensionError) + end + it "raises if two extensions conflict on RSV bits" do expect { @extensions.activate("deflate, tar") }.to raise_error(ExtensionError) end