from ucollections import namedtuple
import websocket_mask
LOGGER = log.getLogger(__name__)
-import usys
+
# Opcodes
OP_CONT = 0x0
OP_TEXT = 0x1
self.open = True
self.debug = debug
-
def __enter__(self):
return self
return data
elif opcode == OP_CLOSE:
self._close()
- return "websocket close"
+ return
elif opcode == OP_PONG:
# Ignore this frame, keep waiting for a data frame
continue
"""Close the websocket."""
if not self.open:
return
- try:
- buf = struct.pack('!H', code) + reason.encode('utf-8')
- self.write_frame(OP_CLOSE, buf)
- except Exception as e:
- usys.print_exception(e)
+ buf = struct.pack('!H', code) + reason.encode('utf-8')
+
+ self.write_frame(OP_CLOSE, buf)
self._close()
def _close(self):
if self.debug: LOGGER.info("Connection closed")
- self.sock.close()
self.open = False
+ self.sock.close()
+
class WebsocketClient(Websocket):
is_client = True
uri.hostname, uri.port)
sock = socket.socket()
- try:
- #sock.settimeout(6)
- addr = socket.getaddrinfo(uri.hostname, uri.port, socket.AF_INET)
- sock.connect(addr[0][4])
-
-
- if uri.protocol == 'wss':
- import ussl
- sock = ussl.wrap_socket(sock)
-
- def send_header(header, *args):
- if debug: LOGGER.info(str(header), *args)
- sock.write(header % args + '\r\n')
-
- # Sec-WebSocket-Key is 16 bytes of random base64 encoded
- key = binascii.b2a_base64(bytes(random.getrandbits(8) for _ in range(16)))[:-1]
- send_header(b'GET %s HTTP/1.1', uri.path or '/')
- send_header(b'Host: %s:%s', uri.hostname, uri.port)
- send_header(b'Connection: Upgrade')
- send_header(b'Upgrade: websocket')
- send_header(b'Sec-WebSocket-Key: %s', key)
- send_header(b'Sec-WebSocket-Version: 13')
- send_header(b'Origin: http://{hostname}:{port}'.format(
- hostname=uri.hostname,
- port=uri.port)
- )
- for k, v in headers.items():
- send_header('{}:{}'.format(k, v).encode())
- send_header(b'')
-
+ addr = socket.getaddrinfo(uri.hostname, uri.port)
+ sock.connect(addr[0][4])
+
+ if uri.protocol == 'wss':
+ import ussl
+ sock = ussl.wrap_socket(sock)
+
+ def send_header(header, *args):
+ if debug: LOGGER.info(str(header), *args)
+ sock.write(header % args + '\r\n')
+
+ # Sec-WebSocket-Key is 16 bytes of random base64 encoded
+ key = binascii.b2a_base64(bytes(random.getrandbits(8) for _ in range(16)))[:-1]
+ send_header(b'GET %s HTTP/1.1', uri.path or '/')
+ send_header(b'Host: %s:%s', uri.hostname, uri.port)
+ send_header(b'Connection: Upgrade')
+ send_header(b'Upgrade: websocket')
+ send_header(b'Sec-WebSocket-Key: %s', key)
+ send_header(b'Sec-WebSocket-Version: 13')
+ send_header(b'Origin: http://{hostname}:{port}'.format(
+ hostname=uri.hostname,
+ port=uri.port)
+ )
+ for k, v in headers.items():
+ send_header('{}:{}'.format(k, v).encode())
+ send_header(b'')
+
+ header = sock.readline()[:-2]
+ assert header.startswith(b'HTTP/1.1 101 '), header
+
+ # We don't (currently) need these headers
+ # FIXME: should we check the return key?
+ while header:
+ if debug: LOGGER.info(str(header))
header = sock.readline()[:-2]
- assert header.startswith(b'HTTP/1.1 101 '), header
-
- # We don't (currently) need these headers
- # FIXME: should we check the return key?
- while header:
- if debug: LOGGER.info(str(header))
- header = sock.readline()[:-2]
- except Exception as e:
- usys.print_exception(e)
- sock.close()
- return
+
return WebsocketClient(sock, debug)