diff --git a/lib/em-websocket/handshake.rb b/lib/em-websocket/handshake.rb index daeea7c..ec36f54 100644 --- a/lib/em-websocket/handshake.rb +++ b/lib/em-websocket/handshake.rb @@ -48,12 +48,12 @@ def headers_downcased # Returns the request path (excluding any query params) # def path - URI.parse(@parser.request_url).path + @path end # Returns the query params as a string foo=bar&baz=... def query_string - URI.parse(@parser.request_url).query.to_s + @query_string end def query @@ -77,6 +77,20 @@ def process(headers, remains) raise HandshakeError, "Must be GET request" end + # Validate request path + # + # According to http://tools.ietf.org/search/rfc2616#section-5.1.2, an + # invalid Request-URI should result in a 400 status code, but + # HandshakeError's currently result in a WebSocket abort. It's not + # clear which should take precedence, but an abort will do just fine. + begin + uri = URI.parse(@parser.request_url) + @path = uri.path + @query_string = uri.query || "" + rescue URI::InvalidURIError + raise HandshakeError, "Invalid request URI: #{@parser.request_url}" + end + # Validate Upgrade unless @parser.upgrade? raise HandshakeError, "Not an upgrade request" diff --git a/spec/unit/handshake_spec.rb b/spec/unit/handshake_spec.rb index a63b2cf..2754ba7 100644 --- a/spec/unit/handshake_spec.rb +++ b/spec/unit/handshake_spec.rb @@ -207,4 +207,10 @@ def handshake(request, secure = false) handshake(@request).should succeed_with_upgrade(@response) end + + it "should fail if the request URI is invalid" do + @request[:path] = "/%" + handshake(@request).should \ + fail_with_error(EM::WebSocket::HandshakeError, 'Invalid request URI: /%') + end end