Fixing empty-query-string compatibility that mcarter reported, added unit tests for it, too.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
=====================================
|
||||
|
||||
This module provides a simple way to create a `websocket
|
||||
<http://dev.w3.org/html5/websockets/>` server. It works with a few
|
||||
<http://dev.w3.org/html5/websockets/>`_ server. It works with a few
|
||||
tweaks in the :mod:`~eventlet.wsgi` module that allow websockets to
|
||||
coexist with other WSGI applications.
|
||||
|
||||
|
@@ -81,7 +81,7 @@ class WebSocketWSGI(object):
|
||||
environ.get('PATH_INFO')
|
||||
)
|
||||
qs = environ.get('QUERY_STRING')
|
||||
if qs:
|
||||
if qs is not None:
|
||||
location += '?' + qs
|
||||
if self.protocol_version == 75:
|
||||
handshake_reply = ("HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
|
||||
@@ -212,9 +212,11 @@ class WebSocket(object):
|
||||
return msgs
|
||||
|
||||
def send(self, message):
|
||||
"""Send a message to the browser. *message* should be
|
||||
convertable to a string; unicode objects should be encodable
|
||||
as utf-8."""
|
||||
"""Send a message to the browser.
|
||||
|
||||
*message* should be convertable to a string; unicode objects should be
|
||||
encodable as utf-8. Raises socket.error with errno of 32
|
||||
(broken pipe) if the socket has already been closed by the client."""
|
||||
packed = self._pack_message(message)
|
||||
# if two greenthreads are trying to send at the same time
|
||||
# on the same socket, sendlock prevents interleaving and corruption
|
||||
@@ -225,8 +227,12 @@ class WebSocket(object):
|
||||
self._sendlock.release()
|
||||
|
||||
def wait(self):
|
||||
"""Waits for and deserializes messages. Returns a single
|
||||
message; the oldest not yet processed."""
|
||||
"""Waits for and deserializes messages.
|
||||
|
||||
Returns a single message; the oldest not yet processed. If the client
|
||||
has already closed the connection, returns None. This is different
|
||||
from normal socket behavior because the empty string is a valid
|
||||
websocket message."""
|
||||
while not self._msgs:
|
||||
# Websocket might be closed already.
|
||||
if self.websocket_closed:
|
||||
|
@@ -402,12 +402,10 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
env['REQUEST_METHOD'] = self.command
|
||||
env['SCRIPT_NAME'] = ''
|
||||
|
||||
if '?' in self.path:
|
||||
path, query = self.path.split('?', 1)
|
||||
else:
|
||||
path, query = self.path, ''
|
||||
env['PATH_INFO'] = urllib.unquote(path)
|
||||
env['QUERY_STRING'] = query
|
||||
pq = self.path.split('?', 1)
|
||||
env['PATH_INFO'] = urllib.unquote(pq[0])
|
||||
if len(pq) > 1:
|
||||
env['QUERY_STRING'] = pq[1]
|
||||
|
||||
if self.headers.typeheader is None:
|
||||
env['CONTENT_TYPE'] = self.headers.type
|
||||
|
@@ -145,6 +145,58 @@ class TestWebSocket(_TestBase):
|
||||
'Sec-WebSocket-Origin: http://localhost:%s' % self.port,
|
||||
'Sec-WebSocket-Protocol: ws',
|
||||
'Sec-WebSocket-Location: ws://localhost:%s/echo\r\n\r\n8jKS\'y:G*Co,Wxa-' % self.port]))
|
||||
|
||||
|
||||
def test_query_string(self):
|
||||
# verify that the query string comes out the other side unscathed
|
||||
connect = [
|
||||
"GET /echo?query_string HTTP/1.1",
|
||||
"Upgrade: WebSocket",
|
||||
"Connection: Upgrade",
|
||||
"Host: localhost:%s" % self.port,
|
||||
"Origin: http://localhost:%s" % self.port,
|
||||
"Sec-WebSocket-Protocol: ws",
|
||||
"Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5",
|
||||
"Sec-WebSocket-Key2: 12998 5 Y3 1 .P00",
|
||||
]
|
||||
sock = eventlet.connect(
|
||||
('localhost', self.port))
|
||||
|
||||
sock.sendall('\r\n'.join(connect) + '\r\n\r\n^n:ds[4U')
|
||||
result = sock.recv(1024)
|
||||
self.assertEqual(result,
|
||||
'\r\n'.join(['HTTP/1.1 101 WebSocket Protocol Handshake',
|
||||
'Upgrade: WebSocket',
|
||||
'Connection: Upgrade',
|
||||
'Sec-WebSocket-Origin: http://localhost:%s' % self.port,
|
||||
'Sec-WebSocket-Protocol: ws',
|
||||
'Sec-WebSocket-Location: ws://localhost:%s/echo?query_string\r\n\r\n8jKS\'y:G*Co,Wxa-' % self.port]))
|
||||
|
||||
def test_empty_query_string(self):
|
||||
# verify that a single trailing ? doesn't get nuked
|
||||
connect = [
|
||||
"GET /echo? HTTP/1.1",
|
||||
"Upgrade: WebSocket",
|
||||
"Connection: Upgrade",
|
||||
"Host: localhost:%s" % self.port,
|
||||
"Origin: http://localhost:%s" % self.port,
|
||||
"Sec-WebSocket-Protocol: ws",
|
||||
"Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5",
|
||||
"Sec-WebSocket-Key2: 12998 5 Y3 1 .P00",
|
||||
]
|
||||
sock = eventlet.connect(
|
||||
('localhost', self.port))
|
||||
|
||||
sock.sendall('\r\n'.join(connect) + '\r\n\r\n^n:ds[4U')
|
||||
result = sock.recv(1024)
|
||||
self.assertEqual(result,
|
||||
'\r\n'.join(['HTTP/1.1 101 WebSocket Protocol Handshake',
|
||||
'Upgrade: WebSocket',
|
||||
'Connection: Upgrade',
|
||||
'Sec-WebSocket-Origin: http://localhost:%s' % self.port,
|
||||
'Sec-WebSocket-Protocol: ws',
|
||||
'Sec-WebSocket-Location: ws://localhost:%s/echo?\r\n\r\n8jKS\'y:G*Co,Wxa-' % self.port]))
|
||||
|
||||
|
||||
def test_sending_messages_to_websocket_75(self):
|
||||
connect = [
|
||||
|
Reference in New Issue
Block a user