Exemplo n.º 1
0
 def test_secure_websocket_connection(self):
     ws = WebSocketClient('wss://127.0.0.1:5443/ws')
     ws.connect()
     print("Sending: 'Hello, World'...")
     ws.send("Hello, World")
     print("Sent")
     print("Receiving...")
     result = ws.receive()
     print("Received: {}".format(result))
     ws.close()
     self.assertEqual("Hello, World", str(result))
Exemplo n.º 2
0
 def publish(self, data, parsed_data):
     payload = parsed_data
     parsed = json.dumps(payload)
     evald = payload
     try:
         ws = WebSocketClient(socket_config['baseUrl'] +
                              str(evald['pipelineId']),
                              protocols=['http-only', 'chat'])
         ws.connect()
         ws.send(str(parsed))
         ws.close()
         return True
     except Exception as e:
         print e
         return False
Exemplo n.º 3
0
def proxy(url):
    with app.test_request_context():
        if websocket:
            while True:
                data = websocket.receive()
                websocket_url = 'ws://{}/{}'.format(PROXY_DOMAIN, url)
                if websocket_url not in websockets:
                    client = WebSocketClient(websocket_url,
                                             protocols=['http-only', 'chat'])
                    websockets[websocket_url] = client
                else:
                    client = websockets[websocket_url]
                client.connect()
                if data:
                    client.send(data)
                client_data = client.receive()
                if client_data:
                    websocket.send(client_data)
            return Response()
    if request.method == "GET":
        url_ending = "%s?%s" % (url, request.query_string)
        url = PROXY_FORMAT % url_ending
        resp = requests.get(url)
    elif request.method == "POST":
        if url == 'kernels':
            url_ending = "%s?%s" % (url, request.query_string)
            url = PROXY_FORMAT % url_ending
        else:
            url = PROXY_FORMAT % url
        resp = requests.post(url, request.data)
    else:
        url = PROXY_FORMAT % url
        resp = requests.request(url, request.method, request.data)
    content = resp.content
    if content:
        content = PROXY_REWRITE_REGEX.sub(r'\1/proxy/', content)
    headers = resp.headers
    if "content-type" in headers:
        mimetype = headers["content-type"].split(";")[0].split(",")[0]
    else:
        mimetype = None
    response = Response(
        content,
        headers=dict(headers),
        mimetype=mimetype,
        status=resp.status_code
    )
    return response
Exemplo n.º 4
0
def proxy(url):
    with app.test_request_context():
        if websocket:
            while True:
                data = websocket.receive()
                websocket_url = 'ws://{}/{}'.format(PROXY_DOMAIN, url)
                if websocket_url not in websockets:
                    client = WebSocketClient(websocket_url,
                                             protocols=['http-only', 'chat'])
                    websockets[websocket_url] = client
                else:
                    client = websockets[websocket_url]
                client.connect()
                if data:
                    client.send(data)
                client_data = client.receive()
                if client_data:
                    websocket.send(client_data)
            return Response()
    if request.method == "GET":
        url_ending = "%s?%s" % (url, request.query_string)
        url = PROXY_FORMAT % url_ending
        resp = requests.get(url)
    elif request.method == "POST":
        if url == 'kernels':
            url_ending = "%s?%s" % (url, request.query_string)
            url = PROXY_FORMAT % url_ending
        else:
            url = PROXY_FORMAT % url
        resp = requests.post(url, request.data)
    else:
        url = PROXY_FORMAT % url
        resp = requests.request(url, request.method, request.data)
    content = resp.content
    if content:
        content = PROXY_REWRITE_REGEX.sub(r'\1/proxy/', content)
    headers = resp.headers
    if "content-type" in headers:
        mimetype = headers["content-type"].split(";")[0].split(",")[0]
    else:
        mimetype = None
    response = Response(content,
                        headers=dict(headers),
                        mimetype=mimetype,
                        status=resp.status_code)
    return response
Exemplo n.º 5
0
class WebsocketTransport(Transport):
    name = 'websocket'

    def __init__(self, *args, **kwargs):
        super(WebsocketTransport, self).__init__(*args, **kwargs)
        self.websocket = None
        self.read_job = None

    def do_open(self):
        url = self.uri()
        self.websocket = WebSocketClient(url)
        self.websocket.connect()
        self.on_open()
        self.read_job = gevent.spawn(self._read)

    def _read(self):
        while True:
            msg = self.websocket.receive()
            if msg is not None:
                if msg.is_text:
                    self.on_data(str(msg.data))
                else:
                    self.on_data(bytearray(msg.data))
            else:
                break

    def write(self, packets):
        self.writable = False

        for packet in packets:
            encoded_packet = parser.Parser.encode_packet(
                packet, self.supports_binary)
            try:
                binary = type(encoded_packet) is bytearray
                self.websocket.send(encoded_packet, binary=binary)
            except RuntimeError, e:
                self.on_error(
                    'The websocket clsoed without a close packet (%s)', e)
        self.on_drain()
Exemplo n.º 6
0
class WebsocketTransport(Transport):
    name = 'websocket'

    def __init__(self, *args, **kwargs):
        super(WebsocketTransport, self).__init__(*args, **kwargs)
        self.websocket = None
        self.read_job = None

    def do_open(self):
        url = self.uri()
        self.websocket = WebSocketClient(url)
        self.websocket.connect()
        self.on_open()
        self.read_job = gevent.spawn(self._read)

    def _read(self):
        while True:
            msg = self.websocket.receive()
            if msg is not None:
                if msg.is_text:
                    self.on_data(str(msg.data))
                else:
                    self.on_data(bytearray(msg.data))
            else:
                break

    def write(self, packets):
        self.writable = False

        for packet in packets:
            encoded_packet = parser.Parser.encode_packet(packet, self.supports_binary)
            try:
                binary = type(encoded_packet) is bytearray
                self.websocket.send(encoded_packet, binary=binary)
            except RuntimeError, e:
                self.on_error('The websocket clsoed without a close packet (%s)', e)
        self.on_drain()
Exemplo n.º 7
0
class WebSocketTransport(object):
    def __init__(self):
        self.__connected = False
        self.__pool = Pool(1)
        self.__on_messsage = None
        self.__connection = None

    def set_on_message(self, func):
        def wrapper():
            while True:
                m = self.__connection.receive()
                if m is not None:
                    func(m.data)
                else:
                    break

        self.__on_message = wrapper

    #TODO: Flag to make sure only one connection
    def connect(self, url):
        if self.__connected == True:
            raise RuntimeError("Connect twice")
        self.__connection = WebSocketClient(url)
        self.__connection.connect()
        #self.__connected = True
        if self.__on_message is not None:
            self.__pool.spawn(self.__on_message)
        self.__connected == True

    def send(self, msg, is_binary=False):
        self.__connection.send(msg, is_binary)

    def close(self):
        self.__pool.join(timeout=0)
        self.__connection.close()
        self.__connected = False
Exemplo n.º 8
0
                ws.close()
                break
        else:
            break
    print("Connection closed!")


def outgoing(ws):
    for i in range(0, 40, 5):
        ws.send("*" * i)

    # We won't get this back
    ws.send("Foobar")

if __name__ == '__main__':
    ws = WebSocketClient('ws://127.0.0.1:8080/websocket', protocols=['http-only', 'chat'])
    ws.connect()

    for n in range(50):
        msg = json.dumps(dict(msg="Hello world", no=n))
        ws.send(msg)
        resp = str(ws.receive())
        print json.loads(resp)
    ws.close()

    # greenlets = [
        # gevent.spawn(incoming, ws),
        # gevent.spawn(outgoing, ws),
    # ]
    # gevent.joinall(greenlets)
Exemplo n.º 9
0
class TunnelClient(Service):
    def __init__(self, local_port, name, broker_address):
        self.local_port = local_port
        self.ws = WebSocketClient('http://%s/t/%s' % (broker_address, name))
        self.connections = {}
        self._send_lock = Semaphore()

    def do_start(self):
        self.ws.connect()
        self.spawn(self.listen)
        #gevent.spawn(self.visual_heartbeat)

    def visual_heartbeat(self):
        while True:
            print "."
            gevent.sleep(1)

    def listen(self):
        while True:
            msg = self.ws.receive(msg_obj=True)
            if msg is None:
                print "Trying to stop"
                self.stop()
            if msg.is_text:
                parsed = json.loads(str(msg))
                print str(msg)
                conn_id, event = parsed[0:2]
                if event == 'open':
                    self.local_open(conn_id)
                elif event == 'closed':
                    self.local_close(conn_id)
            elif msg.is_binary:
                conn_id, data = decode_data_packet(msg.data)
                self.local_send(conn_id, data)

    def local_open(self, conn_id):
        socket = create_connection(('0.0.0.0', self.local_port))
        self.connections[conn_id] = socket
        self.spawn(self.local_recv, conn_id)

    def local_close(self, conn_id):
        socket = self.connections.pop(conn_id)
        try:
            socket.shutdown(0)
            socket.close()
        except:
            pass

    def local_send(self, conn_id, data):
        self.connections[conn_id].send(data)

    def local_recv(self, conn_id):
        while True:
            data = self.connections[conn_id].recv(1024)
            if not data:
                break
            self.tunnel_send(conn_id, data)
        self.tunnel_send(conn_id, open=False)

    def tunnel_send(self, conn_id, data=None, open=None):
        if open is False:
            msg = [conn_id, 'closed']
            with self._send_lock:
                self.ws.send(json.dumps(msg))
        elif data:
            msg = encode_data_packet(conn_id, data)
            with self._send_lock:
                self.ws.send(msg, binary=True)
        else:
            return
Exemplo n.º 10
0
class TunnelClient(Service):
    
    def __init__(self, local_port, name, broker_address):
        self.local_port = local_port
        self.ws = WebSocketClient('http://%s/t/%s' % (broker_address, name))
        self.connections = {}
        self._send_lock = Semaphore()
    
    def do_start(self):
        self.ws.connect()
        self.spawn(self.listen)
        #gevent.spawn(self.visual_heartbeat)
    
    def visual_heartbeat(self):
        while True:
            print "."
            gevent.sleep(1)
    
    def listen(self):
        while True:
            msg = self.ws.receive(msg_obj=True)
            if msg is None:
                print "Trying to stop"
                self.stop()
            if msg.is_text:
                parsed = json.loads(str(msg))
                print str(msg)
                conn_id, event = parsed[0:2]
                if event == 'open':
                    self.local_open(conn_id)
                elif event == 'closed':
                    self.local_close(conn_id)
            elif msg.is_binary:
                conn_id, data = decode_data_packet(msg.data)
                self.local_send(conn_id, data)

    def local_open(self, conn_id):
        socket = create_connection(('0.0.0.0', self.local_port))
        self.connections[conn_id] = socket
        self.spawn(self.local_recv, conn_id)

    def local_close(self, conn_id):
        socket = self.connections.pop(conn_id)
        try:
            socket.shutdown(0)
            socket.close()
        except:
            pass

    def local_send(self, conn_id, data):
        self.connections[conn_id].send(data)

    def local_recv(self, conn_id):
        while True:
            data = self.connections[conn_id].recv(1024)
            if not data:
                break
            self.tunnel_send(conn_id, data)
        self.tunnel_send(conn_id, open=False)
    
    def tunnel_send(self, conn_id, data=None, open=None):
        if open is False:
            msg = [conn_id, 'closed']
            with self._send_lock:
                self.ws.send(json.dumps(msg))
        elif data:
            msg = encode_data_packet(conn_id, data)
            with self._send_lock:
                self.ws.send(msg, binary=True)
        else:
            return
Exemplo n.º 11
0
            if len(m) == 35:
                ws.close()
                break
        else:
            break
    print("Connection closed!")


def outgoing(ws):
    for i in range(0, 40, 5):
        ws.send("*" * i)

    # We won't get this back
    ws.send("Foobar")

if __name__ == '__main__':
    ws = WebSocketClient('ws://127.0.0.1:8080/websocket', protocols=['http-only', 'chat'])
    ws.connect()

    ws.send("Hello world")
    print(ws.receive())

    ws.send("Hello world again")
    print(ws.receive())

    greenlets = [
        gevent.spawn(incoming, ws),
        gevent.spawn(outgoing, ws),
    ]
    gevent.joinall(greenlets)
Exemplo n.º 12
0
class WebSocketThread(WorkerThread):
    """
	Websocket.receive() blocks until there is a response.
	It also hangs indefinitely until there is socket.close() call in the server side
	If the server shuts down unexpectedly the client socket.recieve() will hang forever.
	
	"""
    def __init__(self, notify_window):
        #self.webSocketReconnect() #because threads have been "geventified" they no longer run in parallel, but rather asynchronously. So if this runs not within a greenlet, it will block the mainloop... gevent.sleep(1) only yields to another greenlet or couroutine (like wx.Yield) when it is called from within a greenlet.

        self.last_sent = self.last_alive = datetime.datetime.now()

        self.containers_in_server = {}

        WorkerThread.__init__(self, notify_window)

    def webSocketReconnect(self):
        """
		WSock.receive sometimes hangs, as in the case of a disconnect
		Receive blocks, but send does not, so we use send as a tester
		An ideal connection will have a 1:1 ratio of send and receive
		However, bad connections will have poorer ratios such as 10:1
		If ratio reaches 20:1 then this function will force reconnect
		This function is triggered when CLIENT_LATEST_CLIP is set, but
		SERVER_LATEST_CLIP is not, and the outgoing loop keeps calling
		"""
        while 1:
            if self.KEEP_RUNNING:
                try:
                    self.wsock.close_connection(
                    )  # Terminate Nones the environ and stream attributes, which is for servers
                except AttributeError:
                    pass
                try:
                    self.last_sent = self.last_alive = datetime.datetime.now()

                    login = self._notify_window.getLogin()
                    self.wsock = WebSocketClient(
                        URL(
                            "ws",
                            DEFAULT_DOMAIN,
                            DEFAULT_PORT,
                            "ws",
                            email=login.get("email") or "",
                            password=login.get("password" or ""),
                        )
                    )  #email="*****@*****.**", password="******" #keep static to guarantee one socket for all instances

                    self.wsock.connect()
                    break
                except (SocketError, exc.HandshakeError, RuntimeError):
                    print "no connection..."
                    self._notify_window.destroyBusyDialog()
                    self._notify_window.sb.toggleStatusIcon(
                        msg="Unable to connect to the internet.", icon="bad")
            gevent.sleep(1)

    def keepAlive(self,
                  heartbeat=100,
                  timeout=1000
                  ):  #increment of 60s times 20 unresponsive = 20 minutes
        """
		Since send is the only way we can test a connection's status,
		and since send is only triggered when CLIENT_LATEST_CLIP has a
		change, we need to test the connection incrementally too, and
		therefore we can account for when the user is idle.
		"""
        now = datetime.datetime.now()
        if self.FORCE_RECONNECT or (now - self.last_alive).seconds > timeout:
            self.webSocketReconnect()
            self.FORCE_RECONNECT = False
        elif (now - self.last_sent).seconds > heartbeat:
            self.last_sent = datetime.datetime.now()
            return True
        return False

    def incoming(self):
        #pdb.set_trace()
        #print "start incoming..."
        while 1:
            if self.KEEP_RUNNING:
                #if CLIENT_LATEST_CLIP.get() != SERVER_LATEST_CLIP.get():
                #print "getting... c:%s, s:%s"%(CLIENT_LATEST_CLIP.get(),SERVER_LATEST_CLIP.get())
                try:
                    received = self.wsock.receive(
                    )  #WebSocket run method is implicitly called, "Performs the operation of reading from the underlying connection in order to feed the stream of bytes." According to WS4PY This method is blocking and should likely be run in a thread.

                    if received == None:
                        raise SocketError  #disconnected!

                    delivered = json.loads(
                        str(received)
                    )  #EXTREME: this can last forever, and when creating new connection, this greenlet will hang forever. #receive returns txtmessage object, must convert to string!!!

                    if delivered["message"] == "Error!":
                        print delivered["data"]
                        self.pause()
                        self._notify_window.sb.toggleStatusIcon(
                            msg=delivered["data"], icon="bad")

                    if delivered["message"] == "Salt!":
                        print "\nSalt! %s\n" % delivered["data"]
                        self.ACCOUNT_SALT = delivered["data"]

                    if delivered["message"] == "Update!":
                        server_latest_clip_rowS = delivered['data']
                        server_latest_clip_row = server_latest_clip_rowS[0]
                        #print server_latest_clip_row

                        SERVER_LATEST_CLIP.set(
                            server_latest_clip_row
                        )  #should move this to after postevent or race condition may occur, but since this is gevent, it might not be necessary
                        CLIENT_LATEST_CLIP.set(server_latest_clip_row)

                        #print "GET %s"% server_latest_clip_row['clip_hash_fast']

                        wx.PostEvent(self._notify_window,
                                     EVT_RESULT(server_latest_clip_rowS))

                    elif delivered["message"] == "Upload!":
                        self.containers_in_server.update(delivered['data'])

                    elif delivered["message"] == "Alive!":
                        print "Alive!"
                        self.last_alive = datetime.datetime.now()

                #except (SocketError, RuntimeError, AttributeError, ValueError, TypeError): #gevent traceback didn't mention it was a socket error, just "error", but googling the traceback proved it was. #if received is not None: #test if socket can send
                except:
                    #print "can't get...%s"%str(sys.exc_info()[0])
                    self.webSocketReconnect()

            gevent.sleep(0.25)

    def outgoing(self):
        #pdb.set_trace()
        #print "start outgoing..."
        while 1:
            if self.KEEP_RUNNING:

                sendit = False

                if self.keepAlive(
                ):  #also send alive messages and reset connection if receive block indefinitely
                    sendit = dict(message="Alive?")

                if not self.ACCOUNT_SALT:
                    print "Salt?"
                    sendit = dict(message="Salt?", )

                elif CLIENT_LATEST_CLIP.get().get(
                        'clip_hash_secure') != SERVER_LATEST_CLIP.get().get(
                            'clip_hash_secure'
                        ):  #start only when there is something to send

                    send_clip = CLIENT_LATEST_CLIP.get()

                    #print "sending...%s"%send_clip

                    container_name = send_clip['container_name']
                    container_path = os.path.join(TEMP_DIR, container_name)

                    #response = requests.get(URL(arg="file_exists/%s"%container_name,port=8084,scheme="http"))
                    #file_exists = json.loads(response.content)
                    if not container_name in self.containers_in_server:
                        print "UPLOAD? %s" % container_name
                        sendit = dict(
                            message="Upload?",
                            data=container_name,
                        )
                    else:
                        try:
                            if self.containers_in_server[
                                    container_name] == False:
                                r = requests.post(URL("http", DEFAULT_DOMAIN,
                                                      DEFAULT_PORT, "upload"),
                                                  files={
                                                      "upload":
                                                      open(
                                                          container_path, 'rb')
                                                  })
                                print r
                        except requests.exceptions.ConnectionError:
                            #self.destroyBusyDialog()
                            #self.sb.toggleStatusIcon(msg="Unable to connect to the internet.", icon=False)
                            self.webSocketReconnect()
                        else:
                            sendit = dict(
                                message="Update?",
                                data=CLIENT_LATEST_CLIP.get(),
                            )

                            print "\nSEND %s... %s\n" % (
                                CLIENT_LATEST_CLIP.get().get(
                                    'clip_hash_secure'),
                                SERVER_LATEST_CLIP.get().get(
                                    'clip_hash_secure'))

                if sendit:
                    try:
                        self.wsock.send(json.dumps(sendit))

                        self.last_sent = datetime.datetime.now()

                    #except (SocketError, RuntimeError, AttributeError, ValueError, TypeError): #if self.wsock.stream: #test if socket can get
                    except:
                        #print "can't send...%s"%str(sys.exc_info()[0])
                        self.webSocketReconnect()

            gevent.sleep(0.25)  #yield to next coroutine.

    def run(self):
        greenlets = [
            gevent.spawn(self.outgoing),
            gevent.spawn(self.incoming),
        ]
        gevent.joinall(greenlets)
Exemplo n.º 13
0
# -*- coding: utf-8 -*-
from gevent import monkey; monkey.patch_all()

import gevent
from ws4py.client.geventclient import WebSocketClient

if __name__ == '__main__':
    ws = WebSocketClient('ws://127.0.0.1:9000/ws', protocols=['http-only', 'chat'])
    ws.connect()

    ws.send("Hello world")
    print((ws.receive(),))

    ws.send("Hello world again")
    print((ws.receive(),))

    def incoming():
        while True:
            m = ws.receive()
            if m is not None:
                m = str(m)
                print((m, len(m)))
                if len(m) == 35:
                    ws.close()
                    break
            else:
                break
        print(("Connection closed!",))

    def outgoing():
        for i in range(0, 40, 5):
Exemplo n.º 14
0
                ws.close()
                break
        else:
            break
    print("Connection closed!")


def outgoing(ws):
    for i in range(0, 40, 5):
        ws.send("*" * i)

    # We won't get this back
    ws.send("Foobar")

if __name__ == '__main__':
    ws = WebSocketClient('ws://127.0.0.1:8080/websocket', protocols=['http-only', 'chat'])
    ws.connect()

    for n in range(50):
        msg = msgpack.dumps(dict(msg="Hello world", no=n))
        ws.send(msg, binary=True)
        resp = str(ws.receive())
        print msgpack.loads(resp)
    ws.close()

    # greenlets = [
        # gevent.spawn(incoming, ws),
        # gevent.spawn(outgoing, ws),
    # ]
    # gevent.joinall(greenlets)
Exemplo n.º 15
0
    def handle(self, source, address):
        '''
            1. parse browser socks5 message
            2. establishes WebSocket connection to a remote server
            3. encrypt data using RC4
            4. forward with both the local and remote server
        '''
        log('New connection from %s:%s' % address)

        log('greenlet is %r', gevent.getcurrent())

        rfile = source.makefile('rb', -1)

        try:
            recvcount = source.recv(262)
            log("recv count: %r: %r " % (recvcount, type(recvcount)))

            source.send(b'\x05\x00')

            wsdata = ''
            data = rfile.read(4)
            log('second pack %r: %r' % (type(data), data))

            cmd = ord(data[1])  # CMD
            addrtype = ord(data[3])  # ADDR type 0x01 Ipv4 address

            wsdata = data[3]  # append type of address

            if addrtype == 1:  # IPv4
                addrStr = rfile.read(4)
                addr = socket.inet_ntoa(addrStr)
                wsdata += addrStr
            elif addrtype == 3:  # Domain name
                domainlen = ord(rfile.read(1)[0])
                domain = rfile.read(domainlen)
                log('domain len and name: %d %s' % (domainlen, domain))
                # addr = handle_dns(domain)
                addr = socket.inet_ntoa('\x00\x00\x00\x00')  # 16777343
                wsdata += chr(domainlen)
                wsdata += domain

            portstr = rfile.read(2)
            port = struct.unpack('>H', portstr)
            wsdata += portstr  # append port

            if cmd == 1:
                reply = b"\x05\x00\x00\x01" + socket.inet_aton(
                    addr) + struct.pack(">H", port[0])
                log("send replay %r" % reply)

                source.send(reply)
                log('Begin data, %s:%s' % (addr, port[0]))

                ws = WebSocketClient(self.remotehost, protocols=['binary'])
                try:
                    # gevent.monkey 阻塞
                    ws.connect()
                    log("connect remote websocket server!")
                    log('send data %r:%r:%r' %
                        (wsdata, type(wsdata), len(wsdata)))

                    encryptor = RC4(self.key)
                    generator = encryptor.encrypter()
                    out = ''
                    for wc in wsdata:
                        out += chr((ord(wc) ^ generator.next()))

                    # send socks5 message
                    ws.send(out, True)

                    l1 = gevent.spawn(self.forward, source, ws, generator)
                    l2 = gevent.spawn(self.incoming, ws, source)

                    gevent.joinall([l1, l2])

                except socket.error as e:
                    log('Conn refused, %s:%s:%s' % (addr, port[0], e.message))
                    # Connection refused
                    reply = b'\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00'
                    source.send(reply)
                    raise e
                finally:
                    log('close websocket: ---------------------------')
                    ws.close()
            else:
                log('Unsupported cmd: %r' % cmd)
                reply = b"\x05\0x07\0x00\0x01"
                source.send(reply)
        except socket.error, (value, message):
            log('socks_handle socket error, %s' % (message))