Ejemplo n.º 1
0
Archivo: http.py Proyecto: wmoss/diesel
    def request(self, method, path, headers, body=None, timeout=None):
        '''Issues a `method` request to `path` on the
        connected server.  Sends along `headers`, and
        body.

        Very low level--you must set "host" yourself,
        for example.  It will set Content-Length,
        however.
        '''
        timeout_handler = TimeoutHandler(timeout or 60)
        req = HttpRequest(method, path, '1.1')

        if body:
            headers.set('Content-Length', len(body))

        send('%s\r\n%s\r\n\r\n' % (req.format(), headers.format()))

        if body:
            send(body)

        ev, val = first(until_eol=True, sleep=timeout_handler.remaining())
        if ev == 'sleep': timeout_handler.timeout()

        resp_line = val

        try:
            version, code, reason = resp_line.split(None, 2)
        except ValueError:
            # empty reason string
            version, code = resp_line.split(None, 1)
            reason = ''

        code = int(code)

        ev, val = first(until="\r\n\r\n", sleep=timeout_handler.remaining())
        if ev == 'sleep': timeout_handler.timeout()

        header_block = val

        heads = HttpHeaders()
        heads.parse(header_block)

        if method == 'HEAD':
            body = None
        elif heads.get_one('Transfer-Encoding') == 'chunked':
            body = handle_chunks(heads, timeout_handler.remaining())
        elif heads.get_one(
                'Connection') == 'close' and 'Content-Length' not in heads:
            body = ''
            try:
                while True:
                    s = receive(2**16)
                    body += s
            except ConnectionClosed, e:
                if e.buffer:
                    body += e.buffer
Ejemplo n.º 2
0
Archivo: http.py Proyecto: wmoss/diesel
    def request(self, method, path, headers, body=None, timeout=None):
        '''Issues a `method` request to `path` on the
        connected server.  Sends along `headers`, and
        body.

        Very low level--you must set "host" yourself,
        for example.  It will set Content-Length,
        however.
        '''
        timeout_handler = TimeoutHandler(timeout or 60)
        req = HttpRequest(method, path, '1.1')

        if body:
            headers.set('Content-Length', len(body))

        send('%s\r\n%s\r\n\r\n' % (req.format(),
        headers.format()))

        if body:
            send(body)

        ev, val = first(until_eol=True, sleep=timeout_handler.remaining())
        if ev == 'sleep': timeout_handler.timeout()

        resp_line = val

        try:
            version, code, reason = resp_line.split(None, 2)
        except ValueError:
            # empty reason string
            version, code = resp_line.split(None, 1)
            reason = ''

        code = int(code)

        ev, val = first(until="\r\n\r\n", sleep=timeout_handler.remaining())
        if ev == 'sleep': timeout_handler.timeout()

        header_block = val

        heads = HttpHeaders()
        heads.parse(header_block)

        if method == 'HEAD':
            body = None
        elif heads.get_one('Transfer-Encoding') == 'chunked':
            body = handle_chunks(heads, timeout_handler.remaining())
        elif heads.get_one('Connection') == 'close' and 'Content-Length' not in heads:
            body = ''
            try:
                while True:
                    s = receive(2**16)
                    body += s
            except ConnectionClosed, e:
                if e.buffer:
                    body += e.buffer
Ejemplo n.º 3
0
 def wait(self, timeout=None):
     kw = dict(waits=[self])
     if timeout:
         kw['sleep'] = timeout
     mark, data = first(**kw)
     if mark != self:
         raise EventTimeout()
Ejemplo n.º 4
0
def pubsub_socket(req, inq, outq):
    c = hub.make_client()
    with hub.subq('foo') as group:
        while True:
            q, v = first(waits=[inq, group])
            if q == inq:  # getting message from client
                print "(inq) %s" % v
                cmd = v.get("cmd", "")
                if cmd == "":
                    print "published message to %i subscribers" % c.publish(
                        "foo",
                        dumps({
                            'nick': cgi.escape(v['nick'].strip()),
                            'message': cgi.escape(v['message'].strip()),
                        }))
                else:
                    outq.put(dict(message="test bot"))
            elif q == group:  # getting message for broadcasting
                chan, msg_str = v
                try:
                    msg = loads(msg_str)
                    data = dict(message=msg['message'], nick=msg['nick'])
                    print "(outq) %s" % data
                    outq.put(data)
                except JSONDecodeError:
                    print "error decoding message %s" % msg_str
            elif isinstance(
                    v, WebSocketDisconnect):  # getting a disconnect signal
                return
            else:
                print "oops %s" % v
Ejemplo n.º 5
0
    def get(self, waiting=True, timeout=None):
        start = time()
        while not self.inp and waiting:
            if timeout:
                remaining = timeout - (time() - start)
                if remaining <= 0:
                    raise QueueTimeout()
                else:
                    first(waits=[self.wait_id], sleep=remaining)
            else:
                wait(self.wait_id)

        if self.inp:
            return self.inp.popleft()
        elif not waiting:
            raise QueueEmpty()
Ejemplo n.º 6
0
 def _handle_client_requests_and_responses(self, remote_client):
     assert self.nitro_socket
     queues = [remote_client.incoming]
     try:
         while True:
             (evt, value) = diesel.first(waits=queues, sleep=self.timeout)
             if evt is remote_client.incoming:
                 assert isinstance(value, Message)
                 remote_client.async_frame = value.orig_frame
                 resp = self.handle_client_packet(value.data, remote_client.context)
                 if resp:
                     if isinstance(resp, basestring):
                         output = [resp]
                     else:
                         output = iter(resp)
                     for part in output:
                         msg = Message(
                             value.orig_frame,
                             remote_client.identity,
                             self.serialize_message(remote_client.identity, part),
                         )
                         self.outgoing.put(msg)
             elif evt == 'sleep':
                 break
     finally:
         self._cleanup_client(remote_client)
Ejemplo n.º 7
0
def pubsub_socket(req, inq, outq):
    c = hub.make_client()
    with hub.subq('foo') as group:
        while True:
            q, v = first(waits=[inq, group])
            if q == inq: # getting message from client
                print "(inq) %s" % v
                cmd = v.get("cmd", "")
                if cmd=="":
                    print "published message to %i subscribers" % c.publish("foo", dumps({
                    'nick' : cgi.escape(v['nick'].strip()),
                    'message' : cgi.escape(v['message'].strip()),
                    }))
                else:
                    outq.put(dict(message="test bot"))
            elif q == group: # getting message for broadcasting
                chan, msg_str = v
                try:
                    msg = loads(msg_str)
                    data = dict(message=msg['message'], nick=msg['nick'])
                    print "(outq) %s" % data
                    outq.put(data)
                except JSONDecodeError:
                    print "error decoding message %s" % msg_str
            elif isinstance(v, WebSocketDisconnect): # getting a disconnect signal
                return
            else:
                print "oops %s" % v
Ejemplo n.º 8
0
 def _handle_client_requests_and_responses(self, remote_client):
     assert self.nitro_socket
     queues = [remote_client.incoming]
     try:
         while True:
             (evt, value) = diesel.first(waits=queues, sleep=self.timeout)
             if evt is remote_client.incoming:
                 assert isinstance(value, Message)
                 remote_client.async_frame = value.orig_frame
                 resp = self.handle_client_packet(value.data,
                                                  remote_client.context)
                 if resp:
                     if isinstance(resp, basestring):
                         output = [resp]
                     else:
                         output = iter(resp)
                     for part in output:
                         msg = Message(
                             value.orig_frame,
                             remote_client.identity,
                             self.serialize_message(remote_client.identity,
                                                    part),
                         )
                         self.outgoing.put(msg)
             elif evt == 'sleep':
                 break
     finally:
         self._cleanup_client(remote_client)
Ejemplo n.º 9
0
def consumer(q, done):
    for i in xrange(OPERATIONS):
        evt, data = diesel.first(waits=[q], sleep=10000)
        if evt == "sleep":
            print "sleep was triggered!"
            break
    done.tick()
Ejemplo n.º 10
0
def test_Signal_instances_trigger_multiple_times():
    usr1 = Signal(signal.SIGUSR1)
    for i in xrange(5):
        os.kill(os.getpid(), signal.SIGUSR1)
        evt, _ = diesel.first(sleep=0.1, waits=[usr1])
        assert evt is usr1, evt
        usr1.rearm()
Ejemplo n.º 11
0
def consumer(q, done):
    for i in xrange(OPERATIONS):
        evt, data = diesel.first(waits=[q], sleep=10000)
        if evt == "sleep":
            print "sleep was triggered!"
            break
    done.tick()
Ejemplo n.º 12
0
def hi_server(addr):
    while 1:
        ev, val = first(until_eol=True, sleep=3)
        if ev == 'sleep':
            log.warn('%s timeout!' % time.asctime())
        else:
            send("you said %s" % val)
Ejemplo n.º 13
0
    def get(self, waiting=True, timeout=None):
        start = time()
        while not self.inp and waiting:
            if timeout:
                remaining = timeout - (time() - start)
                if remaining <= 0:
                    raise QueueTimeout()
                else:
                    first(waits=[self.wait_id], sleep=remaining)
            else:
                wait(self.wait_id)

        if self.inp:
            return self.inp.popleft()
        elif not waiting:
            raise QueueEmpty()
Ejemplo n.º 14
0
 def _handle_client_requests_and_responses(self, remote_client):
     assert self.zmq_socket
     queues = [remote_client.incoming, remote_client.outgoing]
     try:
         while True:
             (evt, value) = diesel.first(waits=queues, sleep=self.timeout)
             if evt is remote_client.incoming:
                 assert isinstance(value, Message)
                 resp = self.handle_client_packet(value.data, remote_client.context)
             elif evt is remote_client.outgoing:
                 resp = value
             elif evt == 'sleep':
                 break
             if resp:
                 if isinstance(resp, basestring):
                     output = [resp]
                 else:
                     output = iter(resp)
                 for part in output:
                     msg = Message(
                         remote_client.identity,
                         part,
                     )
                     msg.zmq_return = remote_client.zmq_return
                     self.outgoing.put(msg)
     finally:
         self._cleanup_client(remote_client)
Ejemplo n.º 15
0
 def _handle_client_requests_and_responses(self, remote_client):
     assert self.zmq_socket
     queues = [remote_client.incoming, remote_client.outgoing]
     try:
         while True:
             (evt, value) = diesel.first(waits=queues, sleep=self.timeout)
             if evt is remote_client.incoming:
                 assert isinstance(value, Message)
                 # Update return path with latest (in case of reconnect)
                 remote_client.zmq_return = value.zmq_return
                 resp = self.handle_client_packet(value.data,
                                                  remote_client.context)
             elif evt is remote_client.outgoing:
                 resp = value
             elif evt == 'sleep':
                 break
             if resp:
                 if isinstance(resp, basestring):
                     output = [resp]
                 else:
                     output = iter(resp)
                 for part in output:
                     msg = Message(
                         remote_client.identity,
                         part,
                     )
                     msg.zmq_return = remote_client.zmq_return
                     self.outgoing.put(msg)
     finally:
         self._cleanup_client(remote_client)
Ejemplo n.º 16
0
 def wait(self, timeout=None):
     kw = dict(waits=[self])
     if timeout:
         kw['sleep'] = timeout
     mark, data = first(**kw)
     if mark != self:
         raise EventTimeout()
Ejemplo n.º 17
0
Archivo: DNS.py Proyecto: 1angxi/diesel
 def _actually_resolve(self, name, timeout):
     timeout = timeout / float(len(self.nameservers))
     try:
         for server in self.nameservers:
             # Try each nameserver in succession.
             self.addr = server
             query = make_query(name, A)
             send(query.to_wire())
             start = time.time()
             remaining = timeout
             while True:
                 # Handle the possibility of responses that are not to our
                 # original request - they are ignored and we wait for a
                 # response that matches our query.
                 item, data = first(datagram=True, sleep=remaining)
                 if item == "datagram":
                     response = from_wire(data)
                     if query.is_response(response):
                         if response.answer:
                             a_records = [r for r in response.answer if r.rdtype == A]
                             return [item.address for item in a_records[0].items]
                         raise NotFound
                     else:
                         # Not a response to our query - continue waiting for
                         # one that is.
                         remaining = remaining - (time.time() - start)
                 elif item == "sleep":
                     break
         else:
             raise Timeout(name)
     finally:
         self.addr = self.primary
Ejemplo n.º 18
0
def test_overwriting_custom_signal_handler_fails():
    readings = []
    success = Event()
    failure = Event()

    def append_reading(sig, frame):
        readings.append(sig)
        signal.signal(signal.SIGUSR1, signal.SIG_DFL)

    signal.signal(signal.SIGUSR1, append_reading)

    def overwriter():
        try:
            diesel.signal(signal.SIGUSR1)
        except diesel.ExistingSignalHandler:
            success.set()
        else:
            failure.set()

    diesel.fork(overwriter)
    diesel.sleep()
    os.kill(os.getpid(), signal.SIGUSR1)
    evt, _ = diesel.first(waits=[success, failure])
    assert evt is success
    assert readings
Ejemplo n.º 19
0
def hi_server(addr):
    while 1:
        ev, val = first(until_eol=True, sleep=3)
        if ev == 'sleep':
            log.warn('%s timeout!' % time.asctime())
        else:
            send("you said %s" % val)
Ejemplo n.º 20
0
    def handle_rfc_6455_frames(self, inq, outq):
        disconnecting = False
        while True:
            typ, val = first(receive=2, waits=[outq])
            if typ == 'receive':
                b1, b2 = unpack(">BB", val)

                opcode = b1 & 0x0f
                fin = (b1 & 0x80) >> 7
                has_mask = (b2 & 0x80) >> 7

                assert has_mask == 1, "Frames must be masked"

                if opcode == 8:
                    inq.put(WebSocketDisconnect())
                    if disconnecting:
                        break
                    disconnecting = True
                assert opcode in [1,8], "Currently only opcodes 1 & 8 are supported (opcode=%s)" % opcode
                length = b2 & 0x7f
                if length == 126:
                    length = unpack('>H', receive(2))[0]
                elif length == 127:
                    length = unpack('>L', receive(8))[0]

                mask = unpack('>BBBB', receive(4))
                if length:
                    payload = array('B', receive(length))
                    if disconnecting:
                        continue
                    for i in xrange(len(payload)):
                        payload[i] ^= mask[i % 4]

                    try:
                        data = loads(payload.tostring())
                        inq.put(data)
                    except JSONDecodeError:
                        pass
            elif typ == outq:
                if type(val) is WebSocketDisconnect:
                    b1 = 0x80 | (8 & 0x0f) # FIN + opcode
                    send(pack('>BB', b1, 0))
                    if disconnecting:
                        break
                    disconnecting = True
                else:
                    payload = dumps(val)

                    b1 = 0x80 | (1 & 0x0f) # FIN + opcode

                    payload_len = len(payload)
                    if payload_len <= 125:
                        header = pack('>BB', b1, payload_len)
                    elif payload_len > 125 and payload_len < 65536:
                        header = pack('>BBH', b1, 126, payload_len)
                    elif payload_len >= 65536:
                        header = pack('>BBQ', b1, 127, payload_len)

                    send(header + payload)
Ejemplo n.º 21
0
def chat_server(addr):
    my_nick = until_eol().strip()
    while True:
        evt, data = first(until_eol=True, waits=["chat_message"])
        if evt == "until_eol":
            fire("chat_message", (my_nick, data.strip()))
        else:
            nick, message = data
            send("<%s> %s\r\n" % (nick, message))
Ejemplo n.º 22
0
def chat_server(addr):
    my_nick = until_eol().strip()
    while True:
        evt, data = first(until_eol=True, waits=['chat_message'])
        if evt == 'until_eol':
            fire('chat_message', (my_nick, data.strip()))
        else:
            nick, message = data
            send("<%s> %s\r\n" % (nick, message))
Ejemplo n.º 23
0
 def read(self, size=None):
     assert size is not None, "Sorry, have to pass a size to read()"
     if size == 0:
         return ''
     evt, data = diesel.first(sleep=self._timeout, receive=size)
     if evt == 'sleep':
         self._timeout = None
         raise requests.exceptions.Timeout
     return data
Ejemplo n.º 24
0
 def read(self, size=None):
     assert size is not None, "Sorry, have to pass a size to read()"
     if size == 0:
         return ''
     evt, data = diesel.first(sleep=self._timeout, receive=size)
     if evt == 'sleep':
         self._timeout = None
         raise requests.exceptions.Timeout
     return data
Ejemplo n.º 25
0
Archivo: chat.py Proyecto: dowski/aspen
def chat_server(addr):
    my_nick = until_eol().strip()
    while True:
        ev, val = first(until_eol=True, waits=['chat_message'])
        if ev == 'until_eol':
            fire('chat_message', (my_nick, val.strip()))
        else:
            nick, message = val
            send("<%s> %s\r\n"  % (nick, message))
Ejemplo n.º 26
0
Archivo: http.py Proyecto: HVF/diesel
    def request(self, method, url, headers={}, body=None, timeout=None):
        '''Issues a `method` request to `path` on the
        connected server.  Sends along `headers`, and
        body.

        Very low level--you must set "host" yourself,
        for example.  It will set Content-Length,
        however.
        '''
        url_info = urlparse(url)
        fake_wsgi = dict(
        (cgi_name(n), v) for n, v in headers.iteritems())
        fake_wsgi.update({
            'HTTP_METHOD' : method,
            'SCRIPT_NAME' : '',
            'PATH_INFO' : url_info[2],
            'QUERY_STRING' : url_info[4],
            'wsgi.version' : (1,0),
            'wsgi.url_scheme' : 'http', # XXX incomplete
            'wsgi.input' : cStringIO.StringIO(body or ''),
            'wsgi.errors' : FileLikeErrorLogger(hlog),
            'wsgi.multithread' : False,
            'wsgi.multiprocess' : False,
            'wsgi.run_once' : False,
            })
        req = Request(fake_wsgi)

        timeout_handler = TimeoutHandler(timeout or 60)

        send('%s %s HTTP/1.1\r\n%s' % (req.method, req.url, str(req.headers)))

        if body:
            send(body)

        h = HttpParser()
        body = []
        data = None
        while True:
            if data:
                used = h.execute(data, len(data))
                if h.is_headers_complete():
                    body.append(h.recv_body())
                if h.is_message_complete():
                    data = data[used:]
                    break
            ev, val = first(receive_any=True, sleep=timeout_handler.remaining())
            if ev == 'sleep': timeout_handler.timeout()
            data = val

        resp = Response(
            response=''.join(body),
            status=h.get_status_code(),
            headers=h.get_headers(),
            )

        return resp
Ejemplo n.º 27
0
 def setup(self):
     self.result = Event()
     self.queue = Queue()
     self.timeouts = 0
     diesel.fork(self.consumer, 0.01)
     diesel.fork(self.producer, 0.05)
     diesel.fork(self.consumer, 0.10)
     ev, val = diesel.first(sleep=TIMEOUT, waits=[self.result])
     if ev == 'sleep':
         assert 0, 'timed out'
Ejemplo n.º 28
0
 def chat(self):
     fork(self.input_handler)
     nick = self.input.get()
     send("%s\r\n" % nick)
     while True:
         evt, data = first(until_eol=True, waits=[self.input])
         if evt == "until_eol":
             print data.strip()
         else:
             send("%s\r\n" % data)
Ejemplo n.º 29
0
 def setup(self):
     self.result = Event()
     self.queue = Queue()
     self.timeouts = 0
     diesel.fork(self.consumer, 0.01)
     diesel.fork(self.producer, 0.05)
     diesel.fork(self.consumer, 0.10)
     ev, val = diesel.first(sleep=TIMEOUT, waits=[self.result])
     if ev == 'sleep':
         assert 0, 'timed out'
Ejemplo n.º 30
0
 def chat(self):
     fork(self.input_handler)
     nick = self.input.get()
     send("%s\r\n" % nick)
     while True:
         evt, data = first(until_eol=True, waits=[self.input])
         if evt == "until_eol":
             print data.strip()
         else:
             send("%s\r\n" % data)
Ejemplo n.º 31
0
    def websocket_protocol(self, req):
        """Runs the WebSocket protocol after the handshake is complete.

        Creates two `Queue` instances for incoming and outgoing messages and
        passes them to the `web_socket_handler` that was supplied to the
        `WebSocketServer` constructor.

        """
        inq = Queue()
        outq = Queue()

        if req.rfc_handshake:
            handle_frames = self.handle_rfc_6455_frames
        else:
            # Finish the non-RFC handshake
            key1 = req.headers.get('Sec-WebSocket-Key1')
            key2 = req.headers.get('Sec-WebSocket-Key2')

            # The final key can be in two places. The first is in the
            # `Request.data` attribute if diesel is *not* being proxied
            # to by a smart proxy that parsed HTTP requests. If it is being
            # proxied to, that data will not have been sent until after our
            # initial 101 Switching Protocols response, so we will need to
            # receive it here.

            if req.data:
                key3 = req.data
            else:
                evt, key3 = first(receive=8, sleep=5)
                assert evt == "receive", "timed out while finishing handshake"

            num1 = int(''.join(c for c in key1 if c in '0123456789'))
            num2 = int(''.join(c for c in key2 if c in '0123456789'))
            assert num1 % key1.count(' ') == 0
            assert num2 % key2.count(' ') == 0
            final = pack('!II8s', num1 / key1.count(' '),
                         num2 / key2.count(' '), key3)
            handshake_finish = hashlib.md5(final).digest()
            send(handshake_finish)

            handle_frames = self.handle_non_rfc_frames

        def wrap(req, inq, outq):
            self.web_socket_handler(req, inq, outq)
            outq.put(WebSocketDisconnect())

        handler_loop = fork(wrap, req, inq, outq)

        try:
            handle_frames(inq, outq)
        except ConnectionClosed:
            if handler_loop.running:
                inq.put(WebSocketDisconnect())
            raise
Ejemplo n.º 32
0
def main():
    usr1 = Signal(SIGUSR1)
    ticks = 0
    log.fields(pid=os.getpid()).info('started')
    while True:
        evt, _ = diesel.first(sleep=1, waits=[usr1])
        if evt == 'sleep':
            ticks += 1
        elif evt == usr1:
            log.fields(ticks=ticks).info('stats')
            # must rearm() to use again
            evt.rearm()
Ejemplo n.º 33
0
def get_messages():
    outsock = DieselZMQSocket(zctx.socket(zmq.DEALER), bind="tcp://127.0.0.1:5000")

    for x in xrange(1000):
        t, m = first(sleep=1.0, waits=[outsock])

        if t == 'sleep':
            print "sleep timeout!"
        else:
            print "zmq:", m

    quickstop()
Ejemplo n.º 34
0
    def do_upgrade(self, req):
        if req.headers.get_one('Upgrade') != 'WebSocket':
            return self.web_handler(req)

        # do upgrade response
        org = req.headers.get_one('Origin')

        send(
'''HTTP/1.1 101 Web Socket Protocol Handshake\r
Upgrade: WebSocket\r
Connection: Upgrade\r
WebSocket-Origin: %s\r
WebSocket-Location: %s\r
WebSocket-Protocol: diesel-generic\r
\r
''' % (org, self.ws_location))
        
        inq = Queue()
        outq = Queue()

        def wrap(inq, outq):
            self.web_socket_handler(inq, outq)
            outq.put(WebSocketDisconnect())

        fork(wrap, inq, outq)
                                    
        while True:
            try:
                typ, val = first(receive=1, waits=[outq.wait_id])
                if typ == 'receive':
                    assert val == '\x00'
                    val = until('\xff')[:-1]
                    if val == '':
                        inq.put(WebSocketDisconnect())
                    else:
                        data = dict((k, v[0]) if len(v) == 1 else (k, v) for k, v in cgi.parse_qs(val).iteritems())
                        inq.put(WebSocketData(data))
                else:
                    try:
                        v = outq.get(waiting=False)
                    except QueueEmpty:
                        pass
                    else:
                        if type(v) is WebSocketDisconnect:
                            send('\x00\xff')
                            break
                        else:
                            data = dumps(dict(v))
                            send('\x00%s\xff' % data)

            except ConnectionClosed:
                inq.put(WebSocketDisconnect())
                raise ConnectionClosed("remote disconnected")
Ejemplo n.º 35
0
 def readline(self, max_size=None):
     evt, line = diesel.first(sleep=self._timeout, until='\n')
     if evt == 'sleep':
         self._timeout = None
         raise requests.exceptions.Timeout
     if max_size:
         line = "".join([self._extra, line])
         nl = line.find('\n') + 1
         if nl > max_size:
             nl = max_size
         line, self._extra = line[:nl], line[nl:]
     return line
Ejemplo n.º 36
0
    def websocket_protocol(self, req):
        """Runs the WebSocket protocol after the handshake is complete.

        Creates two `Queue` instances for incoming and outgoing messages and
        passes them to the `web_socket_handler` that was supplied to the
        `WebSocketServer` constructor.

        """
        inq = Queue()
        outq = Queue()

        if req.rfc_handshake:
            handle_frames = self.handle_rfc_6455_frames
        else:
            # Finish the non-RFC handshake
            key1 = req.headers.get('Sec-WebSocket-Key1')
            key2 = req.headers.get('Sec-WebSocket-Key2')

            # The final key can be in two places. The first is in the
            # `Request.data` attribute if diesel is *not* being proxied
            # to by a smart proxy that parsed HTTP requests. If it is being
            # proxied to, that data will not have been sent until after our
            # initial 101 Switching Protocols response, so we will need to
            # receive it here.

            if req.data:
                key3 = req.data
            else:
                evt, key3 = first(receive=8, sleep=5)
                assert evt == "receive", "timed out while finishing handshake"

            num1 = int(''.join(c for c in key1 if c in '0123456789'))
            num2 = int(''.join(c for c in key2 if c in '0123456789'))
            assert num1 % key1.count(' ') == 0
            assert num2 % key2.count(' ') == 0
            final = pack('!II8s', num1 / key1.count(' '), num2 / key2.count(' '), key3)
            handshake_finish = hashlib.md5(final).digest()
            send(handshake_finish)

            handle_frames = self.handle_non_rfc_frames

        def wrap(req, inq, outq):
            self.web_socket_handler(req, inq, outq)
            outq.put(WebSocketDisconnect())

        handler_loop = fork(wrap, req, inq, outq)

        try:
            handle_frames(inq, outq)
        except ConnectionClosed:
            if handler_loop.running:
                inq.put(WebSocketDisconnect())
            raise
Ejemplo n.º 37
0
def test_basic_fork():
    v = [0]
    done = Event()
    def parent():
        fork(tottering_child, v)
        sleep(0.1)
        done.set()
    runtime.current_app.add_loop(Loop(parent))
    ev, _ = first(sleep=1, waits=[done])
    if ev == 'sleep':
        assert 0, "timed out"
    assert (v[0] == 1)
Ejemplo n.º 38
0
def main():
    usr1 = Signal(SIGUSR1)
    ticks = 0
    log.fields(pid=os.getpid()).info('started')
    while True:
        evt, _ = diesel.first(sleep=1, waits=[usr1])
        if evt == 'sleep':
            ticks += 1
        elif evt == usr1:
            log.fields(ticks=ticks).info('stats')
            # must rearm() to use again
            evt.rearm()
Ejemplo n.º 39
0
 def _readline(self):
     if self.timeout > 0:
         timeout_handler = TimeoutHandler(self.timeout)
         ev, line = diesel.first(until="\n", sleep=timeout_handler.remaining())
         if ev == 'sleep': timeout_handler.timeout()
         else: return line
     else:
         line = diesel.until("\n")
         if line:
             return line
         else:
             raise StompTimeout
Ejemplo n.º 40
0
 def readline(self, max_size=None):
     evt, line = diesel.first(sleep=self._timeout, until='\n')
     if evt == 'sleep':
         self._timeout = None
         raise requests.exceptions.Timeout
     if max_size:
         line = "".join([self._extra, line])
         nl = line.find('\n') + 1
         if nl > max_size:
             nl = max_size
         line, self._extra = line[:nl], line[nl:]
     return line
Ejemplo n.º 41
0
Archivo: chat.py Proyecto: yadra/diesel
def socket_handler(req, inq, outq):
    with f.sub() as group:
        while True:
            q, v = first(waits=[inq, group])
            if q == group:
                outq.put(dict(message=v['message'], nick=v['nick']))
            elif isinstance(v, WebSocketDisconnect):
                return
            elif v.get('nick', '').strip() and v.get('message', '').strip():
                f.pub({
                    'nick': cgi.escape(v['nick'].strip()),
                    'message': cgi.escape(v['message'].strip()),
                })
Ejemplo n.º 42
0
def socket_handler(req, inq, outq):
    with f.sub() as group:
        while True:
            q, v = first(waits=[inq, group])
            if q == group:
                outq.put(dict(message=v['message'], nick=v['nick']))
            elif isinstance(v, WebSocketDisconnect):
                return
            elif v.get('nick', '').strip() and v.get('message', '').strip():
                f.pub({
                    'nick' : cgi.escape(v['nick'].strip()),
                    'message' : cgi.escape(v['message'].strip()),
                    })
Ejemplo n.º 43
0
 def _readline(self):
     if self.timeout > 0:
         timeout_handler = TimeoutHandler(self.timeout)
         ev, line = diesel.first(until="\n",
                                 sleep=timeout_handler.remaining())
         if ev == 'sleep': timeout_handler.timeout()
         else: return line
     else:
         line = diesel.until("\n")
         if line:
             return line
         else:
             raise StompTimeout
Ejemplo n.º 44
0
def get_messages():
    outsock = DieselZMQSocket(zctx.socket(zmq.DEALER),
                              bind="tcp://127.0.0.1:5000")

    for x in xrange(1000):
        t, m = first(sleep=1.0, waits=[outsock])

        if t == 'sleep':
            print "sleep timeout!"
        else:
            print "zmq:", m

    quickstop()
Ejemplo n.º 45
0
def handle_chunks(headers, timeout=None):
    '''Generic chunk handling code, used by both client
    and server.

    Modifies the passed-in HttpHeaders instance.
    '''
    timeout_handler = TimeoutHandler(timeout or 60)

    chunks = []
    while True:
        ev, val = first(until_eol=True, sleep=timeout_handler.remaining())
        if ev == 'sleep': timeout_handler.timeout()

        chunk_head = val

        if ';' in chunk_head:
            # we don't support any chunk extensions
            chunk_head = chunk_head[:chunk_head.find(';')]
        size = int(chunk_head, 16)
        if size == 0:
            break
        else:
            chunks.append(receive(size))
            _ = receive(2)  # ignore trailing CRLF

    while True:
        ev, val = first(until_eol=True, sleep=timeout_handler.remaining())
        if ev == 'sleep': timeout_handler.timeout()

        trailer = val

        if trailer.strip():
            headers.add(*tuple(trailer.split(':', 1)))
        else:
            body = ''.join(chunks)
            headers.set('Content-Length', len(body))
            headers.remove('Transfer-Encoding')
            break
    return body
Ejemplo n.º 46
0
def handle_chunks(headers, timeout=None):
    '''Generic chunk handling code, used by both client
    and server.

    Modifies the passed-in HttpHeaders instance.
    '''
    timeout_handler = TimeoutHandler(timeout or 60)

    chunks = []
    while True:
        ev, val = first(until_eol=True, sleep=timeout_handler.remaining())
        if ev == 'sleep': timeout_handler.timeout()

        chunk_head = val

        if ';' in chunk_head:
            # we don't support any chunk extensions
            chunk_head = chunk_head[:chunk_head.find(';')]
        size = int(chunk_head, 16)
        if size == 0:
            break
        else:
            chunks.append(receive(size))
            _ = receive(2) # ignore trailing CRLF

    while True:
        ev, val = first(until_eol=True, sleep=timeout_handler.remaining())
        if ev == 'sleep': timeout_handler.timeout()

        trailer = val

        if trailer.strip():
            headers.add(*tuple(trailer.split(':', 1)))
        else:
            body = ''.join(chunks)
            headers.set('Content-Length', len(body))
            headers.remove('Transfer-Encoding')
            break
    return body
Ejemplo n.º 47
0
def test_basic_fork():
    v = [0]
    done = Event()

    def parent():
        fork(tottering_child, v)
        sleep(0.1)
        done.set()

    runtime.current_app.add_loop(Loop(parent))
    ev, _ = first(sleep=1, waits=[done])
    if ev == 'sleep':
        assert 0, "timed out"
    assert (v[0] == 1)
Ejemplo n.º 48
0
def test_pending_events_dont_break_ordering_when_handling_early_values():

    # This test confirms that "early values" returned from a Waiter do
    # not give other pending event sources the chance to switch their
    # values into the greenlet while it context switches to give other
    # greenlets a chance to run.

    # First we setup a fake connection. It mimics a connection that does
    # not have data waiting in the buffer, and has to wait for the system
    # to call it back when data is ready on the socket. The delay argument
    # specifies how long the test should wait before simulating that data
    # is ready.

    conn1 = FakeConnection(1, delay=[None, 0.1])

    # Next we setup a Queue instance and prime it with a value, so it will
    # be ready early and return an EarlyValue.

    q = Queue()
    q.put(1)

    # Force our fake connection into the connection stack for the current
    # loop so we can make network calls (like until_eol).

    loop = core.current_loop
    loop.connection_stack.append(conn1)

    try:

        # OK, this first() call does two things.
        # 1) It calls until_eol, finds that no data is ready, and sets up a
        #    callback to be triggered when data is ready (which our
        #    FakeConnection will simulate).
        # 2) Fetches from the 'q' which will result in an EarlyValue.

        source, value = diesel.first(until_eol=True, waits=[q])
        assert source == q, source

        # What must happen is that the callback registered to handle data
        # from the FakeConnection when it arrives MUST BE CANCELED/DISCARDED/
        # FORGOTTEN/NEVER CALLED. If it gets called, it will muck with
        # internal state, and possibly switch back into the running greenlet
        # with an unexpected value, which will throw off the ordering of
        # internal state and basically break everything.

        v = diesel.until_eol()
        assert v == 'expected value 1\r\n', 'actual value == %r !!!' % (v, )

    finally:
        loop.connection_stack = []
Ejemplo n.º 49
0
def test_pending_events_dont_break_ordering_when_handling_early_values():

    # This test confirms that "early values" returned from a Waiter do
    # not give other pending event sources the chance to switch their
    # values into the greenlet while it context switches to give other
    # greenlets a chance to run.

    # First we setup a fake connection. It mimics a connection that does
    # not have data waiting in the buffer, and has to wait for the system
    # to call it back when data is ready on the socket. The delay argument
    # specifies how long the test should wait before simulating that data
    # is ready.

    conn1 = FakeConnection(1, delay=[None, 0.1])

    # Next we setup a Queue instance and prime it with a value, so it will
    # be ready early and return an EarlyValue.

    q = Queue()
    q.put(1)

    # Force our fake connection into the connection stack for the current
    # loop so we can make network calls (like until_eol).

    loop = core.current_loop
    loop.connection_stack.append(conn1)

    try:

        # OK, this first() call does two things.
        # 1) It calls until_eol, finds that no data is ready, and sets up a
        #    callback to be triggered when data is ready (which our
        #    FakeConnection will simulate).
        # 2) Fetches from the 'q' which will result in an EarlyValue.

        source, value = diesel.first(until_eol=True, waits=[q])
        assert source == q, source

        # What must happen is that the callback registered to handle data
        # from the FakeConnection when it arrives MUST BE CANCELED/DISCARDED/
        # FORGOTTEN/NEVER CALLED. If it gets called, it will muck with
        # internal state, and possibly switch back into the running greenlet
        # with an unexpected value, which will throw off the ordering of
        # internal state and basically break everything.

        v = diesel.until_eol()
        assert v == 'expected value 1\r\n', 'actual value == %r !!!' % (v,)

    finally:
        loop.connection_stack = []
    def recv(self, matchid=None):
        evt, frame = first(waits=[self.sock], sleep=self.timeout)
        if evt == 'sleep':
            err = "Timed out after %.2f secs waiting for zmq frame"
            raise MontageRequestTimeout(err % self.timeout)

        env = proto.MontageEnvelope(frame.data)
        if matchid:
            assert env.msgid == matchid.bytes, "request/response id pairs did not match!"

        if env.mtype == proto.MONTAGE_ERROR:
            raise RiakException(proto.MontageError(env.msg).error)

        return id_to_packet[env.mtype](env.msg)
Ejemplo n.º 51
0
def test_multiple_signal_waiters():
    N_WAITERS = 5
    c = Countdown(N_WAITERS)

    def mwaiter():
        diesel.signal(signal.SIGUSR1)
        c.tick()

    for i in xrange(N_WAITERS):
        diesel.fork(mwaiter)
    diesel.sleep()
    os.kill(os.getpid(), signal.SIGUSR1)
    evt, data = diesel.first(sleep=1, waits=[c])
    assert evt is c, "all waiters were not triggered!"
Ejemplo n.º 52
0
    def _handle_all_inbound_and_outbound_traffic(self):
        assert self.zmq_socket
        diesel.fork_child(self._receive_incoming_messages)
        queues = [self.incoming, self.outgoing]
        while True:
            (queue, msg) = diesel.first(waits=queues)

            if queue is self.incoming:
                if msg.remote_identity not in self.clients:
                    self._register_client(msg)
                self.clients[msg.remote_identity].incoming.put(msg)

            elif queue is self.outgoing:
                self.zmq_socket.send(msg.zmq_return, zmq.SNDMORE)
                self.zmq_socket.send(msg.data)
Ejemplo n.º 53
0
    def _handle_all_inbound_and_outbound_traffic(self):
        assert self.zmq_socket
        diesel.fork_child(self._receive_incoming_messages)
        queues = [self.incoming, self.outgoing]
        while True:
            (queue, msg) = diesel.first(waits=queues)

            if queue is self.incoming:
                if msg.remote_identity not in self.clients:
                    self._register_client(msg)
                self.clients[msg.remote_identity].incoming.put(msg)

            elif queue is self.outgoing:
                self.zmq_socket.send(msg.zmq_return, zmq.SNDMORE)
                self.zmq_socket.send(msg.data)
Ejemplo n.º 54
0
def manage_peer_connection(host, port, proposals, saves, gets):
    import traceback
    sleep_time = 0.2
    client_alive_timer = Timer(5.0)
    while True:
        try:
            with PeerClient(host, port) as peer:
                peer.signon()
                peer.sync()
                sleep_time = 0.2
                while True:
                    if client_alive_timer.is_due:
                        peer.keep_clients_alive()
                        client_alive_timer.touch()
                    e, v = first(sleep=client_alive_timer.till_due, waits=[proposals, saves, gets])
                    if e == proposals:
                        id, key, resp = v
                        try:
                            resp.put(PROPOSE_SUCCESS
                                    if peer.propose(id, key)
                                    else PROPOSE_FAIL)
                        except:
                            proposals.put(v) # retry
                            raise
                    elif e == saves:
                        id, key, value, client, rollback, resp = v
                        try:
                            peer.save(id, key, value, client, rollback)
                            resp.put(SAVE_SUCCESS)
                        except:
                            saves.put(v) # retry
                            raise
                    elif e == gets:
                        key, resp = v
                        try:
                            v = peer.get(key)
                            resp.put(v)
                        except:
                            gets.put(v) # retry
                            raise

        except ClientConnectionError, e:
            clog.error("Connection problem to (%s, %s): %s" % (
                host, port, e))
            sleep(sleep_time)
            sleep_time *= 2
            sleep_time = min(sleep_time, 5.0)
        except:
Ejemplo n.º 55
0
def test_signals_are_handled_while_event_loop_is_blocked():
    done = Event()

    def handler():
        diesel.signal(signal.SIGUSR1)
        done.set()

    def killer():
        time.sleep(0.1)
        os.kill(os.getpid(), signal.SIGUSR1)

    diesel.fork(handler)
    diesel.thread(killer)
    diesel.sleep()
    evt, _ = diesel.first(sleep=1, waits=[done])
    assert evt is done
Ejemplo n.º 56
0
    def get(self, waiting=True, timeout=None):
        if self.inp:
            return self.inp.popleft()
        mark = None

        if waiting:
            kw = dict(waits=[self])
            if timeout:
                kw['sleep'] = timeout
            mark, val = first(**kw)
            if mark == self:
                return val
            else:
                raise QueueTimeout()

        raise QueueEmpty()
Ejemplo n.º 57
0
def make_and_wait():
    q1 = Queue()
    q2 = Queue()
    both = [q1, q2]

    fork(fire_random, both)

    while True:
        q, v = first(waits=both)
        assert v is None
        if q == q1:
            print 'q1'
        elif q == q2:
            print 'q2'
        else:
            assert 0
Ejemplo n.º 58
0
def manage_peer_connection(host, port, proposals, saves, gets):
    import traceback
    sleep_time = 0.2
    client_alive_timer = Timer(5.0)
    while True:
        try:
            with PeerClient(host, port) as peer:
                peer.signon()
                peer.sync()
                sleep_time = 0.2
                while True:
                    if client_alive_timer.is_due:
                        peer.keep_clients_alive()
                        client_alive_timer.touch()
                    e, v = first(sleep=client_alive_timer.till_due,
                                 waits=[proposals, saves, gets])
                    if e == proposals:
                        id, key, resp = v
                        try:
                            resp.put(PROPOSE_SUCCESS if peer.
                                     propose(id, key) else PROPOSE_FAIL)
                        except:
                            proposals.put(v)  # retry
                            raise
                    elif e == saves:
                        id, key, value, client, rollback, resp = v
                        try:
                            peer.save(id, key, value, client, rollback)
                            resp.put(SAVE_SUCCESS)
                        except:
                            saves.put(v)  # retry
                            raise
                    elif e == gets:
                        key, resp = v
                        try:
                            v = peer.get(key)
                            resp.put(v)
                        except:
                            gets.put(v)  # retry
                            raise

        except ClientConnectionError, e:
            clog.error("Connection problem to (%s, %s): %s" % (host, port, e))
            sleep(sleep_time)
            sleep_time *= 2
            sleep_time = min(sleep_time, 5.0)
        except:
Ejemplo n.º 59
0
    def _handle_all_inbound_and_outbound_traffic(self):
        assert self.nitro_socket
        queues = [self.nitro_socket, self.outgoing]
        socket = self.nitro_socket
        make_frame = pynitro.NitroFrame
        while self.should_run:
            (queue, msg) = diesel.first(waits=queues)

            if queue is self.outgoing:
                socket.reply(msg.orig_frame, make_frame(msg.data))
            else:
                id, obj = self.parse_message(msg.data)
                msg.clear_data()
                msg = Message(msg, id, obj)
                if msg.identity not in self.clients:
                    self._register_client(msg)
                self.clients[msg.identity].incoming.put(msg)
Ejemplo n.º 60
0
 def whois(self, query):
     """
     Perform a query against the server. Either returns the server's
     response or raises a `Timeout` exception if the downstream server
     took too long.
     """
     diesel.send(query + CRLF)
     result = []
     try:
         while True:
             evt, data = diesel.first(sleep=5, receive=2048)
             if evt == 'sleep':
                 raise Timeout(self.addr)
             result.append(data)
     except diesel.ConnectionClosed, ex:
         if ex.buffer:
             result.append(ex.buffer)