示例#1
0
文件: sipapi.py 项目: ikatson/p2p-sip
 def _tcpreceiver(self, stack, sock, remote, maxsize=16386): # handle the messages on the given TCP connection.
     self.conn[remote] = sock
     pending = ''
     while True:
         data = yield multitask.recv(sock, maxsize)
         logger.debug('%r=>%r on type=%r\n%s', remote, sock.getsockname(), stack.transport.type, data)
         if data: 
             pending += data
             while True:
                 msg = pending
                 index1, index2 = msg.find('\n\n'), msg.find('\n\r\n')
                 if index2 > 0 and index1 > 0:
                     if index1 < index2:
                         index = index1 + 2
                     else: 
                         index = index2 + 3
                 elif index1 > 0: 
                     index = index1 + 2
                 elif index2 > 0:
                     index = index2 + 3
                 else:
                     logger.debug('no CRLF found'); break # no header part yet
                 
                 match = re.search(r'content-length\s*:\s*(\d+)\r?\n', msg.lower())
                 if not match: logger.debug('no content-length found'); break # no content length yet
                 length = int(match.group(1))
                 if len(msg) < index+length: logger.debug('has more content %d < %d (%d+%d)', len(msg), index+length, index, length); break # pending further content.
                 total, pending = msg[:index+length], msg[index+length:]
                 try: stack.received(total, remote)
                 except: logger.exception('receiving')
         else: # socket closed
             break
     try: del self.conn[remote]
     except: pass
示例#2
0
def client_handler(sock):
    with closing(sock):
        while True:
            data = (yield multitask.recv(sock, 1024))
            if not data:
                break
    yield multitask.send(sock, data)
示例#3
0
文件: agent.py 项目: ikatson/p2p-sip
 def tcpreceiver(sock,
                 remote): # handle the messages on the given TCP connection.
     while True:
         data = yield multitask.recv(sock, maxsize)
         if _debug: print '%r=>%r on type=%r\n%s' % (
             remote, sock.getsockname(), sock.type, data)
         if data: stack.received(data, remote)
示例#4
0
def client_handler(sock):
    while True:
        request = (yield multitask.recv(sock, 1024))
        if not request:
            break
        response = handle_request(request)
        yield multitask.send(sock, response)
示例#5
0
def handle_connection(sock, address):
    with closing(sock):
        while True:
            data = (yield multitask.recv(sock, 1024))
            if not data:
                break
            yield multitask.send(sock, data)
示例#6
0
def client_handler(sock):
    while True:
        request = (yield multitask.recv(sock, 1024))
        if not request:
            break
        response = handle_request(request)
        yield multitask.send(sock, response)
示例#7
0
文件: p2p.py 项目: ATOM49/django-voip
 def tcphandler(self, sock, addr, maxsize=16386, timeout=60):
     '''Handle an established TCP connection, and close it if no activity for timeout.'''
     remotes = []
     try:
         buffer = '' # buffer of data
         while True:
             try: data = yield multitask.recv(sock, maxsize, timeout=timeout)
             except multitask.Timeout: break # no activity for the timeout
             if not data: continue
             buffer = buffer + data
             if len(buffer) < 2: continue # wait for length atleast
             size = struct.unpack('!H', buffer[:2])
             if size>maxsize: buffer=''; print 'Network.tcphandler() something wrong, ignoring'; continue # TODO: something wrong happened, the protocol went out of sync?
             if len(buffer)<(2+size): continue # we need more data.
             data, buffer = buffer[2:2+size], buffer[2+size:]
             msg, remote = self.parse(data, addr, sock.type)
             if not msg: continue # TODO: handle non-p2p message
             if _debug: print self.name, 'tcp-received %s=>%s: %r'%(remote.hostport, self.nodetcp.hostport, msg)
             if remote not in self.tcpc: 
                 self.tcpc[remote] = sock # update the table, indicating we have a connection to this node.
                 remotes.append(remote)   # store the remote node so that we can clear tcpc on exit
             if 'ack' in msg: del msg['ack'] # just remove the ack attribute. No need to ack on tcp.
             msg['remote'] = remote # put remote as an attribute in msg before putting on queue.
             yield self.put(msg)    # put the parsed msg so that other interested party may get it.
     finally: 
         toremove = map(lambda y: y[0], filter(lambda x: x[1] == sock, self.tcpc.items()))
         for node in toremove: del self.tcpc[node]
示例#8
0
def client_handler(sock):
    with closing(sock):
        while True:
            data = (yield multitask.recv(sock, 1024))
            if not data:
                break
            yield multitask.send(sock, data)
示例#9
0
def handle_connection(sock, address):
    with closing(sock):
        while True:
            data = (yield multitask.recv(sock, 1024))
            if not data:
                break
            yield multitask.send(sock, data)
示例#10
0
 def waitExit():
     import socket
     sock = socket.socket(type=socket.SOCK_DGRAM)
     while True:
         try:
             yield multitask.recv(sock, 2)
         except multitask.Timeout:
             pass
示例#11
0
 def tcpreceiver(
         sock,
         remote):  # handle the messages on the given TCP connection.
     while True:
         data = yield multitask.recv(sock, maxsize)
         if _debug:
             print '%r=>%r on type=%r\n%s' % (
                 remote, sock.getsockname(), sock.type, data)
         if data: stack.received(data, remote)
示例#12
0
 def tcpreceiver(sock, remote): # handle a new incoming TCP connection
     while True:
         data = (yield multitask.recv(sock, maxsize))
         if not data: break # socket closed
         type, length, magic = struct.unpack('!HHL', data[:8])
         valid = (type & 0xC000 == 0) and magic == Message.MAGIC and length<=(maxsize-8) # valid
         if valid: 
             yield datahandler(sock, data, remote)
             if _debug: print 'tcpreceiver() finished data handler'
         else: 
             handler(sock, data, remote)
示例#13
0
 def read(self, count):
     try:
         while True:
             if len(self.buffer) >= count: # do not have data in buffer
                 data, self.buffer = self.buffer[:count], self.buffer[count:]
                 raise StopIteration(data)
             data = (yield multitask.recv(self.sock, 4096)) # read more from socket
             if not data: raise ConnectionClosed
             #if _debug: print 'socket.read[%d] %r'%(len(data), data)
             self.bytesRead += len(data)
             self.buffer += data
     except StopIteration: raise
     except: raise ConnectionClosed # anything else is treated as connection closed.
示例#14
0
    def _tcpreceiver(
            self,
            stack,
            sock,
            remote,
            maxsize=16386):  # handle the messages on the given TCP connection.
        self.conn[remote] = sock
        pending = ''
        while True:
            data = yield multitask.recv(sock, maxsize)
            logger.debug('%r=>%r on type=%r\n%s', remote, sock.getsockname(),
                         stack.transport.type, data)
            if data:
                pending += data
                while True:
                    msg = pending
                    index1, index2 = msg.find('\n\n'), msg.find('\n\r\n')
                    if index2 > 0 and index1 > 0:
                        if index1 < index2:
                            index = index1 + 2
                        else:
                            index = index2 + 3
                    elif index1 > 0:
                        index = index1 + 2
                    elif index2 > 0:
                        index = index2 + 3
                    else:
                        logger.debug('no CRLF found')
                        break  # no header part yet

                    match = re.search(r'content-length\s*:\s*(\d+)\r?\n',
                                      msg.lower())
                    if not match:
                        logger.debug('no content-length found')
                        break  # no content length yet
                    length = int(match.group(1))
                    if len(msg) < index + length:
                        logger.debug('has more content %d < %d (%d+%d)',
                                     len(msg), index + length, index, length)
                        break  # pending further content.
                    total, pending = msg[:index + length], msg[index + length:]
                    try:
                        stack.received(total, remote)
                    except:
                        logger.exception('receiving')
            else:  # socket closed
                break
        try:
            del self.conn[remote]
        except:
            pass
示例#15
0
def client_handler(sock):
	with closing(sock):
		while 1:
			try:
				data = (yield multitask.recv(sock,1024))
			except socket.error,e:
				print "****",e
				raise
			print "recv:",data
			if not data:
				break
			data += "...OK"
			yield multitask.send(sock,data)
			print "send:",data
示例#16
0
 def tcphandler(self, sock, addr, maxsize=16386, timeout=60):
     '''Handle an established TCP connection, and close it if no activity for timeout.'''
     remotes = []
     try:
         buffer = ''  # buffer of data
         while True:
             try:
                 data = yield multitask.recv(sock, maxsize, timeout=timeout)
             except multitask.Timeout:
                 break  # no activity for the timeout
             if not data: continue
             buffer = buffer + data
             if len(buffer) < 2: continue  # wait for length atleast
             size = struct.unpack('!H', buffer[:2])
             if size > maxsize:
                 buffer = ''
                 print 'Network.tcphandler() something wrong, ignoring'
                 continue  # TODO: something wrong happened, the protocol went out of sync?
             if len(buffer) < (2 + size): continue  # we need more data.
             data, buffer = buffer[2:2 + size], buffer[2 + size:]
             msg, remote = self.parse(data, addr, sock.type)
             if not msg: continue  # TODO: handle non-p2p message
             if _debug:
                 print self.name, 'tcp-received %s=>%s: %r' % (
                     remote.hostport, self.nodetcp.hostport, msg)
             if remote not in self.tcpc:
                 self.tcpc[
                     remote] = sock  # update the table, indicating we have a connection to this node.
                 remotes.append(
                     remote
                 )  # store the remote node so that we can clear tcpc on exit
             if 'ack' in msg:
                 del msg[
                     'ack']  # just remove the ack attribute. No need to ack on tcp.
             msg['remote'] = remote  # put remote as an attribute in msg before putting on queue.
             yield self.put(
                 msg
             )  # put the parsed msg so that other interested party may get it.
     finally:
         toremove = map(lambda y: y[0],
                        filter(lambda x: x[1] == sock, self.tcpc.items()))
         for node in toremove:
             del self.tcpc[node]
示例#17
0
def echo_client(hostname, port):
    addrinfo = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC,
                                  socket.SOCK_STREAM)
    family, socktype, proto, canonname, sockaddr = addrinfo[0]

    with closing(socket.socket(family, socktype, proto)) as sock:
        sock.connect(sockaddr)

        while True:
            if sys.platform == 'win32':
                input = sys.stdin.readline()
            else:
                input = (yield multitask.read(STDIN_FILENO, 1024))

            yield multitask.send(sock, input)
            output = (yield multitask.recv(sock, 1024))

            if sys.platform == 'win32':
                sys.stdout.write(output)
            else:
                yield multitask.write(STDOUT_FILENO, output)
示例#18
0
def request(sock, server=None, **kwargs):
    '''Send a STUN client request with retransmissions and return the response.
    This is a generator function, and can be called as
        response, external = yield request(sock, ('stun.iptel.org', 3478))

    It raises ValueError in case of failure and multitask.Timeout in case of timeout
    or failure to connect TCP or invalid response received. For TCP, the sock remains
    connected after successful return or exception from this function.
    
    Arguments are as follows:
        sock: the socket to use for sending request and receiving response.
        server: optional server (ip, port), defaults to defaultServers[0]. For TCP if sock
          is already connected, then server argument is ignored.
        method: optional STUN method, defaults to Message.BINDING.
        tid: optional transaction id, by default generates a new.
        attrs: optional attributes, by default empty list [].
        rto: optional RTO, defaults to 0.1 for UDP and 9.3 for TCP.
        retry: optional retry count, defaults to 7 for UDP and 1 for TCP.
        maxsize: optional maximum packet size, defaults to 1500. 
        handler: optional handler function, that receives any message that was received
          but not handled by the request method. 
    The handler argument allows demultiplexing other types of received messages on the 
    same socket. Note that raising an exception is not good, because we still want to 
    wait for response instead of exiting. The handler is invoked as 
    handler(sock, remote, data) where data is raw data string and remote is usually 
    server (ip, port). If no handler is specified, then invalid data raises a ValueError.
    '''
    
    server = server or defaultServers[0] # use first server if missing
    handler = kwargs.get('handler', None)
    maxsize = kwargs.get('maxsize', 1500)
    
    m = Message()
    m.method = kwargs.get('method', Message.BINDING)
    m.type = Message.REQUEST
    m.tid = kwargs.get('tid', urandom(12))
    m.attrs = kwargs.get('attrs', [])
    mstr = str(m) # formatted message bytes to send
    
    if len(mstr) >= maxsize: raise ValueError, 'Cannot send packet of length>%d'%(maxsize)
    
    if sock.type == socket.SOCK_STREAM:
        remote = None
        try: remote = sock.getpeername()
        except: pass
        if not remote: 
            try: 
                sock.connect(server)
                remote = server # connect if not already connected.
            except: 
                raise multitask.Timeout() # can't connect, then raise a timeout error.
        tcp, rto, retry = True, kwargs.get('rto', 9.3), kwargs.get('retry', 1)
    else:
        tcp, rto, retry = False, kwargs.get('rto', 0.100), kwargs.get('retry', 7) 
    
    while retry>0:
        retry = retry - 1
        if _debug: print 'sending STUN request method=%d, len=%d, remaining-retry=%d'%(m.method, len(mstr), retry)
        if tcp: 
            yield multitask.send(sock, mstr) # send the request
        else: 
            yield multitask.sendto(sock, mstr, server)
        try:
            if tcp: # receiving a TCP packet is complicated. remote is already set
                data = (yield multitask.recv(sock, maxsize, timeout=rto))
                if not data: break
                if _debug: print 'request() received data'
                type, length, magic = struct.unpack('!HHL', data[:8])
                if type & 0xC000 != 0 or magic != Message.MAGIC:
                    raise ValueError, 'invalid STUN response from server type=0x%x, magic=0x%x'%(type, magic)
                if length > (maxsize-8):
                    raise ValueError, 'very large response length[%d]>%d'%(length+8, maxsize)
            else: # receive a UDP datagram
                data, remote = (yield multitask.recvfrom(sock, maxsize, timeout=rto))
                
            if data:
                try:
                    response = Message(data) # parse the message if any
                    if _debug: print 'received STUN message method=%d, type=%d'%(response.method, response.type)
                except:
                    if _debug: print 'received invalid STUN message len=%d'%(len(response))
                    if handler: 
                        handler(sock, remote, data) # allow app to demultiplex
                        continue # retry next
                    else:
                        raise ValueError, 'Invalid response from server'
                    
                if response.tid != m.tid: 
                    if _debug: print 'The tid does not match. ignoring'
                    if handler: handler(sock, remote, data)
                    continue # probably a old response, don't raise exception.
                
                external = None
                for attr in response.attrs:
                    if not attr.optional and attr.type not in Attribute.knownTypes:
                        raise ValueError, 'Attribute 0x%04x not understood in response'%attr.type
                if response.type == Message.RESPONSE: # success response
                    for attr in response.attrs:
                        if m.method == Message.BINDING:
                            if attr.type == Attribute.XOR_MAPPED_ADDRESS:
                                external = attr.xorAddress # (family, ip, port)
                            elif attr.type == Attribute.MAPPED_ADDRESS: # for backward compatibility with RFC 3489
                                external = attr.address 
                elif response.type == Message.ERROR: # error response
                    error = None
                    for attr in response.attrs:
                        if attrs.type == Attribute.ERROR_CODE:
                            error = attrs.error  # (code, reason)
                            break
                    raise ValueError, 'Request failed with error %r'%error
                if external:
                    external = external[1:] # ignore the address family
                    raise StopIteration(response, external) # result to the caller
                # TODO: else do we continue or raise an error?
        except multitask.Timeout:
            rto = rto * 2 # double the rto
        except StopIteration:
            if _debug: print 'request() returning external=' + str(external)
            raise
        except: # any other exception, fall back to Timeout exception
            if _debug: print 'Some ValueError exception', sys.exc_info()
            break
        
    raise multitask.Timeout  # no response after all retransmissions
示例#19
0
    def _wsreceiver(
            self,
            stack,
            sock,
            remote,
            maxsize=16386):  # handle the messages on the given TCP connection.
        handshake = False
        pending = ''
        while True:
            data = yield multitask.recv(sock, maxsize)
            logger.debug('%r=>%r on type=%r length %d', sock.getpeername(),
                         sock.getsockname(), stack.transport.type, len(data))
            if data:
                pending += data
                if not handshake:
                    # do handshake first
                    logger.debug('handshake\n%s', data)
                    if pending.startswith('<policy-file-request/>'):
                        logger.debug(
                            'received policy-file-request, responding for port %r'
                            % (stack.transport.port, ))
                        sock.sendall(
                            '''<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy><allow-access-from domain="*" to-ports="%d"/></cross-domain-policy>'''
                            % (stack.transport.port, ))
                        sock.close()
                        break
                    else:
                        msg = pending
                        index1, index2 = msg.find('\n\n'), msg.find('\n\r\n')
                        if index2 > 0 and index1 > 0:
                            if index1 < index2:
                                index = index1 + 2
                            else:
                                index = index2 + 3
                        elif index1 > 0:
                            index = index1 + 2
                        elif index2 > 0:
                            index = index2 + 3
                        else:
                            logger.debug('no CRLF found')
                            break  # no header part yet, wait for more
                        match = re.search(r'content-length\s*:\s*(\d+)\r?\n',
                                          msg[:index].lower())
                        length = int(match.group(1)) if match else 0
                        if len(msg) < index + length:
                            logger.debug('has more content %d < %d (%d+%d)',
                                         len(msg), index + length, index,
                                         length)
                            break  # pending further content.
                        total, pending = pending[:index +
                                                 length], pending[index +
                                                                  length:]
                        try:
                            lines = total.split('\n')
                            headers = dict([(h.strip().lower(), value.strip())
                                            for h, sep, value in [
                                                line.strip().partition(':')
                                                for line in lines[1:]
                                                if line.strip()
                                            ]])
                            method, path, protocol = lines[0].split(' ')
                            headers.update(method=method,
                                           path=path,
                                           protocol=protocol)
                            if method != 'GET' or headers.get(
                                    'upgrade',
                                    '').lower() != 'websocket' or headers.get(
                                        'connection',
                                        '') != 'Upgrade' or headers.get(
                                            'sec-websocket-protocol',
                                            '').lower() != 'sip':
                                raise ValueError, 'Invalid WS request with invalid method, upgrade, connection or protocol'
                            if int(headers.get(
                                    'sec-websocket-version',
                                    '0')) < 13:  # version is too old
                                raise ValueError, 'Old or missing websocket version. Must be >= 13'
                            stack.websocket = headers  # store the handshake parameters
                            key = headers.get('sec-websocket-key', '')
                            # key = 'dGhlIHNhbXBsZSBub25jZQ==' # used for testing, generates accept = s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
                            accept = base64.b64encode(
                                hashlib.sha1(
                                    key +
                                    "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").
                                digest())
                            response = '\r\n'.join([
                                'HTTP/1.1 101 Switching Protocols',
                                'Upgrade: websocket', 'Connection: Upgrade',
                                'Sec-WebSocket-Accept: %s' %
                                (accept, ), 'Sec-WebSocket-Protocol: sip'
                            ]) + '\r\n\r\n'
                            logger.debug('%r=>%r\n%s', sock.getsockname(),
                                         sock.getpeername(), response)

                            sock.sendall(response)
                            handshake = True
                            self.conn[remote] = sock
                        except:
                            logger.exception('parsing websocket request')
                            sock.close()
                            break
                else:
                    # process request
                    while pending:
                        m = pending
                        opcode, length = ord(m[0]) & 0x0f, ord(m[1]) & 0x7f
                        if opcode != 0x01:
                            logger.warning('only text opcode is supported')
                        if length == 126:
                            length = struct.unpack('>H', m[2:4])[0]
                            masks = m[4:8]
                            offset = 8
                        elif length == 127:
                            lengths = struct.unpack('>II', m[2:10])
                            length = lengths[0] * 2**32 + lengths[1]
                            masks = m[10:14]
                            offset = 14
                        else:
                            masks = m[2:6]
                            offset = 6
                        logger.debug('offset=%r length=%r', offset, length)
                        if len(m) < offset + length:
                            logger.debug('incomplete message')
                            break
                        decoded, encoded, pending = [], m[offset:offset +
                                                          length], m[offset +
                                                                     length:]
                        for i, ch in enumerate(encoded):
                            decoded.append(chr(ord(ch) ^ ord(masks[i % 4])))
                        decoded = ''.join(decoded)
                        logger.debug('websocket received\n%s', decoded)
                        try:
                            stack.received(decoded, remote)
                        except:
                            logger.exception('receiving')
            else:  # socket closed
                break
        try:
            del self.conn[remote]
        except:
            pass
示例#20
0
def client_handler(sock):
    with closing(sock):
        while True:
            buf = (yield multitask.recv(sock, 1024))
            if not buf:
                break

            data = buf.strip()

            t = time.strftime('%Y%m', time.localtime(time.time()))
            #h = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
            # self.request is the TCP socket connected to the client
            file_object = open(path + '/log%s.txt' % t, 'a+')
            #file_object.writelines("Received Data:[ip:%s]%s:%s" % (sock, h, data,))

            if not data.startswith("$"):
                break

            datas = data.split(",")
            if not len(datas) == 4:
                break

            channel = datas[1]
            device_code = datas[2]
            parking_state = datas[3][0]
            sql_device = "select * from t_device where f_channel = $channel and f_code = $code"
            device = list(pg.db.query(sql_device, vars={"channel": channel, "code": device_code}))

            if device:
                device = device[0]

            sql_record = "select * from t_monitor_record where f_device_id = $device_id"
            last_record = list(pg.db.query(sql_record, vars={"device_id": device.f_id}))

            sql_command = "select * from t_command where f_is_executed=0 and f_device_id in (select f_id from t_device where f_channel = $channel) limit 1"
            commands = list(pg.db.query(sql_command, vars={"channel": channel}))

            now = datetime.datetime.now()

            # 收费管理时段, 记录地磁设备数据
            if now.hour < 23 or now.hour >= 7:

                # 判断状态变化是否在60秒,忽略60秒内地磁变化
                last_state = parking_state
                if last_record:
                    last_record = last_record[0]
                    if int((now - last_record.f_stamp).total_seconds()) >= 60:  # 忽略状态变化在60妙以内的数据
                        last_state = last_record.f_state
                        last_record.f_data = data
                        last_record.f_stamp = datetime.datetime.now()
                        if parking_state is not None:
                            last_record.f_state = parking_state

                        # 状态变更时,记录数据
                        if str(last_state) != str(parking_state):
                            if parking_state == "0":  # 更新车辆离开时间
                                last_record.f_leave_stamp = now
                            else:
                                last_record.f_parking_stamp = now
                                last_record.f_leave_stamp = None

                            pg.db.update("t_monitor_record", where="f_device_id=%s" % device.f_id, **last_record)

                            pg.his("t_monitor_record", **last_record)

                else:
                    if parking_state is not None and parking_state == "1":
                        last_record = {"f_device_id": device.f_id, "f_device_code": device.f_code, "f_data": data, "f_parking_stamp": now, "f_stamp": now, "f_parking_id": device.f_parking_id, "f_parking_code": device.f_parking_code, "f_leave_stamp": None, "f_state": parking_state, "f_street_id": device.f_street_id}
                        pg.db.insert("t_monitor_record", **last_record)
                        pg.his("t_monitor_record", **last_record)

                # create message
                message = {"f_content": None, "f_device_id": device.f_id, "f_device_code": device_code, "f_create_time": datetime.datetime.now(), "f_done_time": None, "f_parking_id": device.f_parking_id, "f_parking_code": device.f_parking_code, "f_is_done": 0, "f_done_user_id": None, "f_state": parking_state, "f_street_id": device.f_street_id}
                if str(last_state) != str(parking_state):
                    if parking_state == "0":
                        message["f_content"] = U"车位[%s]有车离开" % device.f_parking_code
                    else:
                        message["f_content"] = U"车位[%s]有车进入" % device.f_parking_code

                    pg.db.insert("t_message", **message)

            # send reset command
            if commands:
                for c in commands:
                    c.f_is_executed = 1
                    c.f_executed_time = datetime.datetime.now()
                    pg.db.update("t_command", where="f_id=%d" % c.f_id, ** c)
                    file_object.writelines("Execute Command :%s" % c.f_command)

                    yield multitask.send(sock, c.f_command)

            file_object.close()
            yield multitask.send(sock, "successful")
示例#21
0
            yield multitask.connect(sock, sockaddr)
            break
        except socket.error, err:
            sock.close()
    else:
        raise socket.error(err)

    with closing(sock):
        while True:
            if sys.platform == 'win32':
                input = sys.stdin.readline()
            else:
                input = (yield multitask.read(sys.stdin.fileno(), 1024))

            yield multitask.send(sock, input)
            output = (yield multitask.recv(sock, 1024))

            if sys.platform == 'win32':
                sys.stdout.write(output)
            else:
                yield multitask.write(sys.stdout.fileno(), output)


if __name__ == '__main__':
    hostname = None
    port = 1111

    if len(sys.argv) > 1:
        hostname = sys.argv[1]
    if len(sys.argv) > 2:
        port = int(sys.argv[2])
示例#22
0
文件: sipapi.py 项目: ikatson/p2p-sip
    def _wsreceiver(self, stack, sock, remote, maxsize=16386): # handle the messages on the given TCP connection.
        handshake = False
        pending = ''
        while True:
            data = yield multitask.recv(sock, maxsize)
            logger.debug('%r=>%r on type=%r length %d', sock.getpeername(), sock.getsockname(), stack.transport.type, len(data))
            if data: 
                pending += data
                if not handshake:
                    # do handshake first
                    logger.debug('handshake\n%s', data)
                    if pending.startswith('<policy-file-request/>'):
                        logger.debug('received policy-file-request, responding for port %r'%(stack.transport.port,))
                        sock.sendall('''<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy><allow-access-from domain="*" to-ports="%d"/></cross-domain-policy>'''%(stack.transport.port,))
                        sock.close()
                        break
                    else:
                        msg = pending
                        index1, index2 = msg.find('\n\n'), msg.find('\n\r\n')
                        if index2 > 0 and index1 > 0:
                            if index1 < index2:
                                index = index1 + 2
                            else: 
                                index = index2 + 3
                        elif index1 > 0: 
                            index = index1 + 2
                        elif index2 > 0:
                            index = index2 + 3
                        else:
                            logger.debug('no CRLF found'); break # no header part yet, wait for more
                        match = re.search(r'content-length\s*:\s*(\d+)\r?\n', msg[:index].lower())
                        length = int(match.group(1)) if match else 0
                        if len(msg) < index+length: logger.debug('has more content %d < %d (%d+%d)', len(msg), index+length, index, length); break # pending further content.
                        total, pending = pending[:index+length], pending[index+length:]
                        try:
                            lines = total.split('\n')
                            headers = dict([(h.strip().lower(), value.strip()) for h,sep,value in [line.strip().partition(':') for line in lines[1:] if line.strip()]])
                            method, path, protocol = lines[0].split(' ')
                            headers.update(method=method, path=path, protocol=protocol)
                            if method != 'GET' or headers.get('upgrade', '').lower() != 'websocket' or headers.get('connection', '') != 'Upgrade' or headers.get('sec-websocket-protocol', '').lower() != 'sip':
                                raise ValueError, 'Invalid WS request with invalid method, upgrade, connection or protocol'
                            if int(headers.get('sec-websocket-version', '0')) < 13: # version is too old
                                raise ValueError, 'Old or missing websocket version. Must be >= 13'
                            stack.websocket = headers # store the handshake parameters
                            key = headers.get('sec-websocket-key','')
                            # key = 'dGhlIHNhbXBsZSBub25jZQ==' # used for testing, generates accept = s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
                            accept = base64.b64encode(hashlib.sha1(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest())
                            response = '\r\n'.join([
                                        'HTTP/1.1 101 Switching Protocols', 'Upgrade: websocket', 'Connection: Upgrade',
                                        'Sec-WebSocket-Accept: %s'%(accept,), 'Sec-WebSocket-Protocol: sip']) + '\r\n\r\n'
                            logger.debug('%r=>%r\n%s', sock.getsockname(), sock.getpeername(), response)
                            
                            sock.sendall(response)
                            handshake = True
                            self.conn[remote] = sock
                        except: 
                            logger.exception('parsing websocket request')
                            sock.close()
                            break
                else:
                    # process request
                    while pending:
                        m = pending
                        opcode, length = ord(m[0]) & 0x0f, ord(m[1]) & 0x7f
                        if opcode != 0x01:
                            logger.warning('only text opcode is supported')
                        if length == 126:
                            length = struct.unpack('>H', m[2:4])[0]
                            masks = m[4:8]
                            offset = 8
                        elif length == 127:
                            lengths = struct.unpack('>II', m[2:10])
                            length = lengths[0] * 2**32 + lengths[1]
                            masks = m[10:14]
                            offset = 14
                        else:
                            masks = m[2:6]
                            offset = 6
                        logger.debug('offset=%r length=%r', offset, length)
                        if len(m) < offset + length:
                            logger.debug('incomplete message')
                            break
                        decoded, encoded, pending = [], m[offset:offset+length], m[offset+length:]
                        for i, ch in enumerate(encoded):
                            decoded.append(chr(ord(ch) ^ ord(masks[i % 4])))
                        decoded = ''.join(decoded)
                        logger.debug('websocket received\n%s', decoded)
                        try: stack.received(decoded, remote)
                        except: logger.exception('receiving')
            else: # socket closed
                break
        try: del self.conn[remote]
        except: pass
示例#23
0
            yield multitask.connect(sock, sockaddr)
            break
        except socket.error, err:
            sock.close()
    else:
        raise socket.error(err)

    with closing(sock):
        while True:
            if sys.platform == "win32":
                input = sys.stdin.readline()
            else:
                input = (yield multitask.read(sys.stdin.fileno(), 1024))

            yield multitask.send(sock, input)
            output = (yield multitask.recv(sock, 1024))

            if sys.platform == "win32":
                sys.stdout.write(output)
            else:
                yield multitask.write(sys.stdout.fileno(), output)


if __name__ == "__main__":
    hostname = None
    port = 1111

    if len(sys.argv) > 1:
        hostname = sys.argv[1]
    if len(sys.argv) > 2:
        port = int(sys.argv[2])