diff --git a/socketIO_client/__init__.py b/socketIO_client/__init__.py index e966e3a..e4d5fa1 100644 --- a/socketIO_client/__init__.py +++ b/socketIO_client/__init__.py @@ -1,8 +1,10 @@ +from collections import namedtuple import logging import json +import parser import requests import time -from collections import namedtuple + try: from urllib import parse as parse_url except ImportError: @@ -367,8 +369,7 @@ def _parse_host(host, port): url_pack = parse_url(host) is_secure = url_pack.scheme == 'https' port = port or url_pack.port or (443 if is_secure else 80) - base_url = '%s:%d%s/socket.io/%s' % ( - url_pack.hostname, port, url_pack.path, PROTOCOL_VERSION) + base_url = '%s:%d%s/socket.io/%s' % (url_pack.hostname, port, url_pack.path, PROTOCOL_VERSION) return is_secure, base_url @@ -395,13 +396,23 @@ def _yield_elapsed_time(seconds=None): def _get_socketIO_session(is_secure, base_url, **kw): - server_url = '%s://%s/' % ('https' if is_secure else 'http', base_url) + server_url = '%s://%s/?transport=polling' % ('https' if is_secure else 'http', base_url) + _log.debug('[session] %s', server_url) try: response = _get_response(requests.get, server_url, **kw) except TimeoutError as e: raise ConnectionError(e) - response_parts = response.text.split(':') + + _log.debug("[response] %s", response.text); + decoded = parser.decode_response(response); + _log.debug("[decoded] %s", repr(decoded)); + return _SocketIOSession( - id=response_parts[0], - heartbeat_timeout=int(response_parts[1]), - server_supported_transports=response_parts[3].split(',')) + id = decoded["payload"]["sid"], + heartbeat_timeout = int(decoded["payload"]["pingInterval"]), + server_supported_transports = ["xhr-polling"]);#decoded["payload"]["upgrades"]); + + #return _SocketIOSession( + # id=response_parts[0], + # heartbeat_timeout=int(response_parts[1]), + # server_supported_transports=response_parts[3].split(',')) diff --git a/socketIO_client/parser.py b/socketIO_client/parser.py new file mode 100644 index 0000000..2231481 --- /dev/null +++ b/socketIO_client/parser.py @@ -0,0 +1,41 @@ +import logging +import json + +_log = logging.getLogger(__name__) + +""" Decodes a response from requests lib. +""" +def decode_response(response): + # TODO(sean): Should we use the 'raw' stream instead? + raw_bytes = response.content; + packet_type = "string" if ord(raw_bytes[0]) == 0 else "binary"; + _log.debug("Packet type: %s" % packet_type); + + if packet_type is "string": + length_bytes = []; + offset = 1; + while ord(raw_bytes[offset]) is not 255: + length_bytes.append(ord(raw_bytes[offset])); + offset += 1; + offset += 1; + + length = 0; + base = 1; + for digit in reversed(length_bytes): + length += (int(digit) * base); + base *= 10; + _log.debug("Packet length: %d" % length); + + message_type = raw_bytes[offset]; + offset += 1; + + message = {"type": message_type, "payload": json.loads(raw_bytes[offset:offset + length - 1])}; + _log.debug("Message: %s" % repr(message)); + return message; + else: + pass; + + return ""; + +def decode_packet(packet): + pass; diff --git a/socketIO_client/transports.py b/socketIO_client/transports.py index 172ca15..e1a0064 100644 --- a/socketIO_client/transports.py +++ b/socketIO_client/transports.py @@ -1,5 +1,6 @@ import json import logging +import parser import re import requests import six @@ -79,6 +80,7 @@ class _AbstractTransport(object): for packet_text in self.recv(): _log.debug('[packet received] %s', packet_text) try: + #packet = parser.decode_response(packet_text); packet_parts = packet_text.split(':', 3) except AttributeError: _log.warn('[packet error] %s', packet_text) @@ -167,7 +169,7 @@ class _XHR_PollingTransport(_AbstractTransport): def __init__(self, socketIO_session, is_secure, base_url, **kw): super(_XHR_PollingTransport, self).__init__() - self._url = '%s://%s/xhr-polling/%s' % ( + self._url = '%s://%s/?transport=polling&sid=%s' % ( 'https' if is_secure else 'http', base_url, socketIO_session.id) self._connected = True @@ -198,6 +200,7 @@ class _XHR_PollingTransport(_AbstractTransport): self._url, params=self._params, timeout=TIMEOUT_IN_SECONDS) + #response_text = response.content response_text = response.text if not response_text.startswith(BOUNDARY): yield response_text