Ejemplo 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))
Ejemplo n.º 2
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
Ejemplo 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
Ejemplo n.º 4
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()
Ejemplo 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()
Ejemplo n.º 6
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)
Ejemplo n.º 7
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
Ejemplo n.º 8
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
Ejemplo n.º 9
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)
# -*- coding: utf-8 -*-
from gevent import monkey; monkey.patch_all()

import gevent
from ws4py.client.geventclient import WebSocketClient

if __name__ == '__main__':
    ws = WebSocketClient('ws://localhost: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):
Ejemplo n.º 11
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)
Ejemplo n.º 12
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):