Esempio n. 1
0
File: main.py Progetto: qwdm/scp
def authorized_sfk(appid, token):
    """ Request Userbase by API """

    import base64
    import requests

    # authorize scp in userbase
    b64_uid = base64.standard_b64encode(CONFIG['scp_userbase']['uid'])
    b64_token = base64.standard_b64encode(CONFIG['scp_userbase']['token'])
    headers = {
        'Authorization': 'Nptv %s:%s' % (b64_uid, b64_token),
        'Content-Type': 'application/json'
    }

    userbase_host = CONFIG['scp_userbase']['host'] if CONFIG['scp_userbase'][
        'host'] else 'userbase.staging.nptv.home'
    url = 'http://%s/v2/applications/%s/auth.json' % (userbase_host, appid)

    data = json.dumps({'token': token})
    try:
        resp = requests.post(url, data=data, headers=headers)
    except Exception as e:
        LOGGER.error('Authorization request fails: %s; appid %s; token %s' %
                     (str(e), appid, token))
        return False

    if int(resp.status_code) == 204:
        LOGGER.info('Authorization passed')
        return True
    else:
        LOGGER.info('Authorization rejected: appid %s; token %s' %
                    (appid, token))
        return False
Esempio n. 2
0
    def start_client(self,
                     sock=None,
                     guid=None,
                     addr=None,
                     first_packet=None,
                     death_event=None):
        if self.alive == False:
            return

        sockwrap = ClientSockWrap(sock=sock, addr=addr, guid=guid)
        docker = ClientDocker(client=sockwrap,
                              sfk=self.sfk.sockwrap,
                              guid=guid,
                              addr=addr)
        sender = eventlet.spawn(sockwrap.sender,
                                callback=lambda: self.drop_client(guid))
        recver = eventlet.spawn(sockwrap.recver,
                                callback=lambda: self.drop_client(guid))
        docker_thread = eventlet.spawn(docker.mainloop,
                                       callback=lambda: self.drop_client(guid))

        self.clients[guid] = ClientSubsystem(sockwrap,
                                             docker,
                                             death_event,
                                             threads=(sender, recver,
                                                      docker_thread))

        self.sfk.docker.add_session(guid, sockwrap)
        if first_packet:
            try:
                docker.send_first(first_packet)
            except Exception as e:
                LOGGER.error("First packet sending fails: " + str(e))
Esempio n. 3
0
 def close_socket(self):
     try:
         self.sock.shutdown(socket.SHUT_RDWR)
         self.sock.close()
         LOGGER.info("{0} sockwrapper close socket".format(str(self)))
     except Exception as e:
         LOGGER.error("Fails socket close: %s" % str(e))
Esempio n. 4
0
    def recver(self, callback=lambda: None):
        """ recieve packets from sock, 
            check packet's type, 
            put packet to recv queue
        """
        f = self.sock.makefile()
        try:
            while True:
                try:
                    packet_class = determine_packet_type(f)
                except Disconnection as e:
                    raise Disconnection

                if packet_class == self.NATIVE_PACKET:
                    packet = packet_class()
                    packet.read_fields(f)
                    self.queue_recv.put(packet)
                else:
                    LOGGER.error("{0} recver: unexpected magic".format(
                        str(self)))
                    raise UnexpectedProtocol

        except Disconnection as e:
            LOGGER.info("Disconnection: {0}".format(str(self)))
        except Exception as e:
            LOGGER.error("recver error: {0} {1}".format(str(self), str(e)))
        LOGGER.info(str(self) + " recver terminate")
        eventlet.spawn_n(callback)
Esempio n. 5
0
 def recved_packets_processor(self):
     try:
         while True:
             packet = self.queue_recv.get()
             LOGGER.info("recved: %s" % packet.bindata)
     except Exception as e:
         LOGGER.error("recved_packets_processor: %s" % str(e))
Esempio n. 6
0
 def close_socket(self):
     try:
         self.sock.shutdown(socket.SHUT_RDWR)
         self.sock.close()
         LOGGER.info("{0} sockwrapper close socket".format(str(self)))
     except Exception as e:
         LOGGER.error("Fails socket close: %s" % str(e))
Esempio n. 7
0
def authorized_sfk(appid, token):
    """ Request Userbase by API """

    import base64
    import requests

    # authorize scp in userbase
    b64_uid = base64.standard_b64encode(CONFIG['scp_userbase']['uid'])
    b64_token = base64.standard_b64encode(CONFIG['scp_userbase']['token'])
    headers = {
               'Authorization' : 'Nptv %s:%s' % (b64_uid, b64_token),
               'Content-Type'  : 'application/json'
              }

    userbase_host = CONFIG['scp_userbase']['host'] if CONFIG['scp_userbase']['host'] else 'userbase.staging.nptv.home'
    url = 'http://%s/v2/applications/%s/auth.json' % (userbase_host, appid)
    
    data = json.dumps({'token' : token})
    try:
        resp = requests.post(url, data=data, headers=headers)
    except Exception as e:
        LOGGER.error('Authorization request fails: %s; appid %s; token %s' % (str(e), appid, token))
        return False


    if int(resp.status_code) == 204:
        LOGGER.info('Authorization passed')
        return True
    else:
        LOGGER.info('Authorization rejected: appid %s; token %s' % (appid, token))
        return False
Esempio n. 8
0
    def recver(self, callback=lambda: None):
        """ recieve packets from sock, 
            check packet's type, 
            put packet to recv queue
        """
        f = self.sock.makefile()
        try:
            while True:
                try:
                    packet_class = determine_packet_type(f)
                except Disconnection as e:
                    raise Disconnection

                if packet_class == self.NATIVE_PACKET:
                    packet = packet_class()
                    packet.read_fields(f)  
                    self.queue_recv.put(packet)
                else:
                    LOGGER.error(
                        "{0} recver: unexpected magic".format(str(self)))
                    raise UnexpectedProtocol
                
        except Disconnection as e:
            LOGGER.info("Disconnection: {0}".format(str(self)))
        except Exception as e:
            LOGGER.error("recver error: {0} {1}".format(str(self), str(e)))
        LOGGER.info(str(self) + " recver terminate")
        eventlet.spawn_n(callback)
Esempio n. 9
0
 def recved_packets_processor(self):
     try:
         while True:
             packet = self.queue_recv.get()
             LOGGER.info("recved: %s" % packet.bindata)
     except Exception as e:
         LOGGER.error("recved_packets_processor: %s" % str(e))
Esempio n. 10
0
File: sfkmodel.py Progetto: qwdm/scp
 def send_packet(self, packet):
     data = packet.assemble()
     try:
         self.sock.sendall(data)
     except Exception as e:
         LOGGER.error("Sending auth packet fails: " + str(e))
     else:
         LOGGER.info("Auth packet sent successfully.")
Esempio n. 11
0
 def send_packet(self, packet):
     data = packet.assemble() 
     try:
         self.sock.sendall(data)
     except Exception as e:
         LOGGER.error("Sending auth packet fails: " + str(e))
     else:
         LOGGER.info("Auth packet sent successfully.")
Esempio n. 12
0
File: dockers.py Progetto: qwdm/scp
 def mainloop(self, callback=lambda: None):
     try:
         while True:
             packet = self.client_sockwrap.get_packet()
             new_packet = self._pack_spif2_to_scp(packet)
             self.sfk_sockwrap.put_packet(new_packet)
     except Exception as e:
         LOGGER.error("ClientDocker {0} {1}".format(str_uuid(self.guid),
                                                    str(e)))
         callback()
Esempio n. 13
0
 def _read_int(fileobj):
     try:
         data = fileobj.read(4)
         if not data:
             LOGGER.info("disconnection")   # хотелось бы таки знать, что именно отвалилось
             return None
         return struct.unpack('!I', data)[0]
     except Exception as e:
         LOGGER.error(
             "cannot read int field from socket: {0}".format(str(e)))
         return None
Esempio n. 14
0
    def get_appid(self):  # from client
        try:
            pb = sfk_pb2.Msg()
            pb.ParseFromString(self.protobuf)
            sfk_url = json.loads(pb.session.params)['sfk-url']
            parsed_url = urlparse(sfk_url)
            appid = parsed_url.path[1:]  # drop '/' symbol
            return appid
        except Exception as e:
            LOGGER.error('in get_appid: ' + str(e))

        raise FieldExtractionError("cannot extract appid")
Esempio n. 15
0
 def get_auth_info(self):  # from sfk in very first packet
     """ extract appid, token from very first (auth) packet from sfk.
         return (None, None) if any errors happened
     """
     pb = scp_pb2.Msg()
     try:
         pb.ParseFromString(self.protobuf)
     except Exception as e:
         LOGGER.error(str(e))
         return None, None
     else:
         return pb.auth.appid, pb.auth.token
Esempio n. 16
0
    def get_appid(self): # from client
        try:
            pb = sfk_pb2.Msg()
            pb.ParseFromString(self.protobuf)
            sfk_url = json.loads(pb.session.params)['sfk-url']
            parsed_url = urlparse(sfk_url)
            appid = parsed_url.path[1:] # drop '/' symbol
            return appid
        except Exception as e:
            LOGGER.error('in get_appid: ' + str(e))

        raise FieldExtractionError("cannot extract appid")
Esempio n. 17
0
 def _read_int(fileobj):
     try:
         data = fileobj.read(4)
         if not data:
             LOGGER.info("disconnection"
                         )  # хотелось бы таки знать, что именно отвалилось
             return None
         return struct.unpack('!I', data)[0]
     except Exception as e:
         LOGGER.error("cannot read int field from socket: {0}".format(
             str(e)))
         return None
Esempio n. 18
0
 def get_auth_info(self): # from sfk in very first packet
     """ extract appid, token from very first (auth) packet from sfk.
         return (None, None) if any errors happened
     """
     pb = scp_pb2.Msg()
     try:
         pb.ParseFromString(self.protobuf)
     except Exception as e:
         LOGGER.error(str(e))
         return None, None
     else:
         return pb.auth.appid, pb.auth.token
Esempio n. 19
0
    def _make_reply_packet(self, payload='', guid=None):
        if guid not in self.guids:
            LOGGER.error("No session with guid %s" % str_uuid(guid))

        pb = sfk_pb2.Msg()
        pb.mtype = pb.DATA
        pb.data.content_type = "simple"
        pb.data.payload = "test"
        protobuf = pb.SerializeToString()
        data = "%s %s %s" % (self.appid, payload, str_uuid(guid))
        spif = prot.Spif2Packet(protobuf=protobuf, data=data)
        return prot.ScpPacket(guid=guid, data=spif.assemble())
Esempio n. 20
0
File: sfkmodel.py Progetto: qwdm/scp
    def _make_reply_packet(self, payload='', guid=None):
        if guid not in self.guids:
            LOGGER.error("No session with guid %s" % str_uuid(guid))

        pb = sfk_pb2.Msg()
        pb.mtype = pb.DATA
        pb.data.content_type = "simple"
        pb.data.payload = "test"
        protobuf = pb.SerializeToString()
        data = "%s %s %s" % (self.appid, payload, str_uuid(guid))
        spif = prot.Spif2Packet(protobuf=protobuf, data=data)
        return prot.ScpPacket(guid=guid, data=spif.assemble())
Esempio n. 21
0
    def sender(self, callback=lambda: None): 
        """get packet from sending queue, send it via sock. 
           By convention, packet type checking performed 
           before putting in queue
        """
        try:
            while True:
                packet = self.queue_send.get()
                data = packet.assemble()
                self.sock.sendall(data)
                # TODO if DEBUG
                try:
                    if packet.get_msg_type() == 'pong':
                        LOGGER.debug('pong sent %s' % self)
                except AttributeError:
                    pass

        except Exception:
            LOGGER.error(str(self) + " sender error")
        eventlet.spawn_n(callback)
Esempio n. 22
0
    def get_msg_type(self):
        pb = scp_pb2.Msg()
        try:
            pb.ParseFromString(self.protobuf)
        except Exception as e:
            LOGGER.error("Cannot parse protobuf")
            return None

        msg_type = {
            pb.AUTH: 'auth',
            pb.PING: 'ping',
            pb.MESSAGE: 'msg',
            pb.PONG: 'pong',
            pb.SFKCONTENT: 'sfkcontent',
            pb.SESSION_DROPPED: 'session_dropped',
        }.get(pb.mtype, None)
#        if msg_type is None:
#            raise ProtocolError("bad mtype")
#        else:   # no one catch this exception!!!
        return msg_type
Esempio n. 23
0
    def get_msg_type(self):
        pb = scp_pb2.Msg()
        try:
            pb.ParseFromString(self.protobuf)
        except Exception as e:
            LOGGER.error("Cannot parse protobuf")
            return None

        msg_type = {
            pb.AUTH: 'auth',
            pb.PING: 'ping',
            pb.MESSAGE: 'msg',
            pb.PONG: 'pong',
            pb.SFKCONTENT: 'sfkcontent',
            pb.SESSION_DROPPED: 'session_dropped',
        }.get(pb.mtype, None)
        #        if msg_type is None:
        #            raise ProtocolError("bad mtype")
        #        else:   # no one catch this exception!!!
        return msg_type
Esempio n. 24
0
    def sender(self, callback=lambda: None):
        """get packet from sending queue, send it via sock. 
           By convention, packet type checking performed 
           before putting in queue
        """
        try:
            while True:
                packet = self.queue_send.get()
                data = packet.assemble()
                self.sock.sendall(data)
                # TODO if DEBUG
                try:
                    if packet.get_msg_type() == 'pong':
                        LOGGER.debug('pong sent %s' % self)
                except AttributeError:
                    pass

        except Exception:
            LOGGER.error(str(self) + " sender error")
        eventlet.spawn_n(callback)
Esempio n. 25
0
File: main.py Progetto: qwdm/scp
    def register_rengine(self, sock, addr):
        packet = self._recv_packet(Spif2Packet, sock)
        if packet == None:
            sock.close()
            return

        try:
            appid = packet.get_appid()
        except ProtocolError:
            LOGGER.error(
                "cannot extract appid needed for just connected client")
            sock.close()
            return

        if not self._is_sfk_connectable(appid):
            LOGGER.error(
                "attempt connecting to non-connected sfk with appid " \
                + str(appid))
            sock.close()
            return

        sfk, sfk_id = self._get_sfk(appid)  # after _is_connectable check
        # always correct
        guid = self._generate_guid()
        self.info.add_client(appid, sfk_id, guid, addr)

        LOGGER.info(
            'Register: Client connected to appid {0} with guid {1}'.format(
                appid, str_uuid(guid)))
        # waiting for death_event prevents eventlet.serve from closing socket
        death_event = eventlet.event.Event()
        sfk.start_client(sock=sock,
                         guid=guid,
                         addr=addr,
                         first_packet=packet,
                         death_event=death_event)
        death_event.wait()
        LOGGER.info('Register: death_event from rengine guid {0}'.format(
            str_uuid(guid)))
Esempio n. 26
0
    def read_fields(self, fileobj):
        timeout = Timeout(SCP_TIMEOUT,
                          TimeoutError('Timeout while recv scp packet'))
        try:

            s = fileobj

            self.flags = s.read(1)
            self.guid = s.read(16)
            pb_len = self._read_int(s)
            data_len = self._read_int(s)

            if pb_len == None or data_len == None:
                raise ProtocolError('Protobuf or data length not supplied')

            # protobuf len issues
            if pb_len > SCP_MAX_PROTOBUF_LEN:
                raise ProtocolError('Protobuf lenght too large')
            elif pb_len > 0:
                self.protobuf = s.read(pb_len)
            else:
                raise ProtocolError('Protobuf lenght 0')

            # data len issues
            if data_len != 0:
                self.data = s.read(data_len)
            else:
                self.data = ''

        except TimeoutError as e:
            LOGGER.error("Timeout fired while recv field of packet")
            raise ProtocolError(str(e))
        finally:
            timeout.cancel()

        # clean alternative representation of packet
        self.set_raw_packet(None)
Esempio n. 27
0
 def recved_packets_processor(self):
     try:
         while True:
             packet = self.queue_recv.get()
             self.guids.add(packet.guid)
             mtype = packet.get_msg_type()    
             payload = None
             if mtype == 'msg':
                 buf = StringIO.StringIO(packet.data)
                 pack_class = prot.determine_packet_type(buf)
                 client_pack = pack_class()
                 client_pack.read_fields(buf)
                 payload = client_pack.bindata
             elif mtype == 'sfkcontent':
                 SfkModel.sfkcontent_handler(packet)
                 continue
             elif mtype == 'session_dropped':
                 self.guids.remove(packet.guid)
                 LOGGER.info('session dropped guid {0}'.format(
                     str_uuid(packet.guid)))
                 continue
             elif mtype == 'pong':
                 LOGGER.info('Pong recieved')
             else:
                 LOGGER.error("Unknown message type: {0}".format(mtype))
                         
             LOGGER.info('recved packet guid {0}; mtype {1}'.format(
                                               str_uuid(packet.guid),
                                               mtype))
             if payload:
                 LOGGER.info('message: %s' % payload)
                 reply = self._make_reply_packet(payload=payload, 
                                                 guid=packet.guid)
                 self.queue_send.put(reply)
                 LOGGER.info('reply is sent')
     except Exception as e:
         LOGGER.exception("recved_packets_processor: " + str(e))
Esempio n. 28
0
    def register_rengine(self, sock, addr):
        packet = self._recv_packet(Spif2Packet, sock) 
        if packet == None:
            sock.close()
            return

        try:
            appid  = packet.get_appid()
        except ProtocolError:
            LOGGER.error(
                "cannot extract appid needed for just connected client")
            sock.close()
            return

        if not self._is_sfk_connectable(appid):
            LOGGER.error(
                "attempt connecting to non-connected sfk with appid " \
                + str(appid))
            sock.close()
            return 
       
        sfk, sfk_id = self._get_sfk(appid) # after _is_connectable check
                                           # always correct
        guid = self._generate_guid()
        self.info.add_client(appid, sfk_id, guid, addr)

        LOGGER.info(
            'Register: Client connected to appid {0} with guid {1}'.format(
                                                 appid, str_uuid(guid)))
        # waiting for death_event prevents eventlet.serve from closing socket
        death_event = eventlet.event.Event()
        sfk.start_client(sock=sock, guid=guid, addr=addr, 
                         first_packet=packet, death_event=death_event)
        death_event.wait()
        LOGGER.info(
            'Register: death_event from rengine guid {0}'.format(
                                                 str_uuid(guid)))
Esempio n. 29
0
    def sfkcontent_handler(packet):
        LOGGER.info("Got SfkContent protobuf")
        uri, request_id, headers = packet.get_sfkcontent() 
        LOGGER.info("uri: %s" % uri)
        LOGGER.info("request_id: %s" % request_id)

        url = '/'.join([STATIC_SERV_URL, request_id, uri])
        LOGGER.info("URL: %s" % url)

#        time.sleep(2)

        if uri in URI_PATH:
            data=open(URI_PATH[uri], 'rb').read()
            headers={'Content-Type': 'image/jpg',
                     'X-SCP-Status': '200 OK'}
        else:
            LOGGER.error("Chpoken uri: %s" % uri)
            data='No way!'
            headers={'Content-Type': 'text/plain', 
                     'X-SCP-Status': '404 Not Found'}

        r = requests.post(url, 
                          data=data, 
                          headers=headers)
        LOGGER.info("Uri %s sent, with response code %s" % (uri, r.status_code))
        if int(r.status_code) != 200:
            LOGGER.error(r.text)

        LOGGER.info("request headers")
        for header in headers:
            LOGGER.info(header)

        LOGGER.info("response headers")
        for header, val in r.headers.items():
            LOGGER.info("%s: %s" % (header, val))

        return None
Esempio n. 30
0
File: sfkmodel.py Progetto: qwdm/scp
    def sfkcontent_handler(packet):
        LOGGER.info("Got SfkContent protobuf")
        uri, request_id, headers = packet.get_sfkcontent()
        LOGGER.info("uri: %s" % uri)
        LOGGER.info("request_id: %s" % request_id)

        url = '/'.join([STATIC_SERV_URL, request_id, uri])
        LOGGER.info("URL: %s" % url)

        #        time.sleep(2)

        if uri in URI_PATH:
            data = open(URI_PATH[uri], 'rb').read()
            headers = {'Content-Type': 'image/jpg', 'X-SCP-Status': '200 OK'}
        else:
            LOGGER.error("Chpoken uri: %s" % uri)
            data = 'No way!'
            headers = {
                'Content-Type': 'text/plain',
                'X-SCP-Status': '404 Not Found'
            }

        r = requests.post(url, data=data, headers=headers)
        LOGGER.info("Uri %s sent, with response code %s" %
                    (uri, r.status_code))
        if int(r.status_code) != 200:
            LOGGER.error(r.text)

        LOGGER.info("request headers")
        for header in headers:
            LOGGER.info(header)

        LOGGER.info("response headers")
        for header, val in r.headers.items():
            LOGGER.info("%s: %s" % (header, val))

        return None
Esempio n. 31
0
File: sfkmodel.py Progetto: qwdm/scp
    def recved_packets_processor(self):
        try:
            while True:
                packet = self.queue_recv.get()
                self.guids.add(packet.guid)
                mtype = packet.get_msg_type()
                payload = None
                if mtype == 'msg':
                    buf = StringIO.StringIO(packet.data)
                    pack_class = prot.determine_packet_type(buf)
                    client_pack = pack_class()
                    client_pack.read_fields(buf)
                    payload = client_pack.bindata
                elif mtype == 'sfkcontent':
                    SfkModel.sfkcontent_handler(packet)
                    continue
                elif mtype == 'session_dropped':
                    self.guids.remove(packet.guid)
                    LOGGER.info('session dropped guid {0}'.format(
                        str_uuid(packet.guid)))
                    continue
                elif mtype == 'pong':
                    LOGGER.info('Pong recieved')
                else:
                    LOGGER.error("Unknown message type: {0}".format(mtype))

                LOGGER.info('recved packet guid {0}; mtype {1}'.format(
                    str_uuid(packet.guid), mtype))
                if payload:
                    LOGGER.info('message: %s' % payload)
                    reply = self._make_reply_packet(payload=payload,
                                                    guid=packet.guid)
                    self.queue_send.put(reply)
                    LOGGER.info('reply is sent')
        except Exception as e:
            LOGGER.exception("recved_packets_processor: " + str(e))
Esempio n. 32
0
    def read_fields(self, fileobj):
        timeout = Timeout(SCP_TIMEOUT, TimeoutError('Timeout while recv scp packet'))
        try:

            s = fileobj

            self.flags = s.read(1)
            self.guid = s.read(16)
            pb_len = self._read_int(s)
            data_len = self._read_int(s)

            if pb_len == None or data_len == None:
                raise ProtocolError('Protobuf or data length not supplied')
            
            # protobuf len issues
            if pb_len > SCP_MAX_PROTOBUF_LEN:
                raise ProtocolError('Protobuf lenght too large')
            elif pb_len > 0:
                self.protobuf = s.read(pb_len)
            else:
                raise ProtocolError('Protobuf lenght 0')
            
            # data len issues
            if data_len != 0:
                self.data = s.read(data_len)
            else:
                self.data = ''

        except TimeoutError as e:
            LOGGER.error("Timeout fired while recv field of packet")
            raise ProtocolError(str(e))
        finally:
            timeout.cancel()

        # clean alternative representation of packet
        self.set_raw_packet(None)
Esempio n. 33
0
    def sfk_side(self, request_id, uri):
        """ Handle POST requests from sfk """
        if not self.sfk_authorization_ok(request_id):
            LOGGER.info('Sfk POST bad request_id')
            abort(401, "Bad request_id")

        body = request.body
        headers = request.headers
        # cut custom headers for scp
        if 'X-SCP-Status' in headers:  # headers case-insensitive
            status = headers['X-SCP-Status']
            passed_headers = dict((k, v) for (k, v) in headers.items()
                                  if not k.startswith(_hkey('X-SCP')))
            status_supplied = True
        else:
            status = '500 Internal Server Error'
            body = ''
            passed_headers = {}
            status_supplied = False
            LOGGER.error("X-SCP-Status was not supplied")

        resp = HTTPResponse(body, status, **passed_headers)

        evt = self.request_id_events.get(request_id, None)

        if evt is None:
            # если нет такого ожидаемого события, то уже прошел таймаут
            abort(408, '')  # Request Timeout
        else:
            evt.send(resp)
            del self.request_id_events[request_id]

        if status_supplied:
            return ''  # пустой ответ с кодом 200
        else:
            abort(400, 'X-Scp-Status not supplied')
Esempio n. 34
0
    def sfk_side(self, request_id, uri):
        """ Handle POST requests from sfk """
        if not self.sfk_authorization_ok(request_id):
            LOGGER.info('Sfk POST bad request_id')
            abort(401, "Bad request_id")

        body = request.body
        headers = request.headers
        # cut custom headers for scp
        if 'X-SCP-Status' in headers: # headers case-insensitive
            status = headers['X-SCP-Status']
            passed_headers = dict((k, v) for (k, v) in headers.items()
                                         if not k.startswith(_hkey('X-SCP')))
            status_supplied = True
        else:
            status = '500 Internal Server Error'
            body = ''
            passed_headers = {}
            status_supplied = False
            LOGGER.error("X-SCP-Status was not supplied")
            
        resp = HTTPResponse(body, status, **passed_headers)

        evt = self.request_id_events.get(request_id, None)

        if evt is None:
            # если нет такого ожидаемого события, то уже прошел таймаут
            abort(408, '') # Request Timeout
        else:
            evt.send(resp)
            del self.request_id_events[request_id]

        if status_supplied:
            return '' # пустой ответ с кодом 200
        else:
            abort(400, 'X-Scp-Status not supplied')
Esempio n. 35
0
    def start_client(self, sock=None, guid=None, 
                           addr=None, first_packet=None, death_event=None):
        if self.alive == False:
            return

        sockwrap = ClientSockWrap(sock=sock, addr=addr, guid=guid)
        docker = ClientDocker(client=sockwrap, 
                              sfk=self.sfk.sockwrap, guid=guid, addr=addr)
        sender = eventlet.spawn(sockwrap.sender, 
                                callback=lambda: self.drop_client(guid)) 
        recver = eventlet.spawn(sockwrap.recver, 
                                callback=lambda: self.drop_client(guid))
        docker_thread = eventlet.spawn(docker.mainloop,
                                       callback=lambda: self.drop_client(guid))
        
        self.clients[guid] = ClientSubsystem(sockwrap, docker, death_event,
                                 threads=(sender, recver, docker_thread))
                                            
        self.sfk.docker.add_session(guid, sockwrap)
        if first_packet:
            try:
                docker.send_first(first_packet)
            except Exception as e:
                LOGGER.error("First packet sending fails: " +  str(e))
Esempio n. 36
0
File: main.py Progetto: qwdm/scp
    def register_sfk(self, sfk_sock, sfk_addr):
        auth_packet = self._recv_packet(ScpPacket, sfk_sock)

        # basic auth packet check
        basic_test_passed = False  # just init value
        error_msg = ""

        if auth_packet == None:
            error_msg = "Error when auth packed recved"
        elif auth_packet.get_msg_type() != 'auth':
            error_msg = "Unexpected message type while auth attempt"
        elif len(auth_packet.data) != 0:
            error_msg = "Auth packet contains unexpected data"
        else:
            basic_test_passed = True

        if not basic_test_passed:
            LOGGER.error(error_msg)
            sfk_sock.close()
            return

        appid, token = auth_packet.get_auth_info()
        # check authorization
        auth_check_passed = False
        if not appid or not token:
            LOGGER.error("Appid or Token not supplied")
        elif NEED_AUTH and not authorized_sfk(appid, token):
            LOGGER.error(
                "Bad appid/token pair from just connected sfk: %s %s" %
                (appid, token))
        else:
            auth_check_passed = True

        if not auth_check_passed:
            sfk_sock.close()
            return

        sfk_id = str(uuid.uuid4())
        LOGGER.info("Sfk with appid %s, sfk_id %s connected" %
                    (str_uuid(appid), sfk_id))
        # waiting for death_event prevents eventlet.serve from closing socket
        death_event = eventlet.event.Event()
        sfk_supervizor = SfkSupervizor(sfk_sock=sfk_sock,
                                       registrar=self,
                                       appid=appid,
                                       sfk_id=sfk_id,
                                       sfk_addr=sfk_addr,
                                       death_event=death_event)
        self.remember_sfk(sfk_supervizor, appid, sfk_id)
        self.info.add_sfk_instance(appid, sfk_id, sfk_addr)

        death_event.wait()
        LOGGER.info(
            'Register: death_event from sfk appid {0}; sfk_id {1}'.format(
                appid, sfk_id))
Esempio n. 37
0
    def register_sfk(self, sfk_sock, sfk_addr):
        auth_packet = self._recv_packet(ScpPacket, sfk_sock)

        # basic auth packet check
        basic_test_passed = False # just init value
        error_msg = ""

        if auth_packet == None:
            error_msg = "Error when auth packed recved"
        elif auth_packet.get_msg_type() != 'auth':
            error_msg = "Unexpected message type while auth attempt"
        elif len(auth_packet.data) != 0:
            error_msg = "Auth packet contains unexpected data"
        else:
            basic_test_passed = True

        if not basic_test_passed:
            LOGGER.error(error_msg)
            sfk_sock.close()
            return

        appid, token = auth_packet.get_auth_info()
        # check authorization
        auth_check_passed = False
        if not appid or not token:
            LOGGER.error("Appid or Token not supplied")
        elif NEED_AUTH and not authorized_sfk(appid, token):
            LOGGER.error("Bad appid/token pair from just connected sfk: %s %s" % (appid, token))
        else:
            auth_check_passed = True

        if not auth_check_passed:
            sfk_sock.close()
            return

        sfk_id = str(uuid.uuid4())
        LOGGER.info("Sfk with appid %s, sfk_id %s connected" % (str_uuid(appid), sfk_id))
        # waiting for death_event prevents eventlet.serve from closing socket
        death_event = eventlet.event.Event()
        sfk_supervizor = SfkSupervizor(sfk_sock=sfk_sock, 
                                       registrar=self, 
                                       appid=appid,
                                       sfk_id=sfk_id,
                                       sfk_addr=sfk_addr,
                                       death_event=death_event)
        self.remember_sfk(sfk_supervizor, appid, sfk_id)
        self.info.add_sfk_instance(appid, sfk_id, sfk_addr)

        death_event.wait()
        LOGGER.info('Register: death_event from sfk appid {0}; sfk_id {1}'.format(appid, sfk_id))
Esempio n. 38
0
File: main.py Progetto: qwdm/scp
    def _recv_packet(self, expected_packet_class, sock):
        f = sock.makefile()
        timeout = Timeout(CONFIG['scp_protocol']['scp_timeout'])
        try:
            packet_class = determine_packet_type(f)
        except Timeout as t:
            if t is not timeout:
                LOGGER.error("Accidently catch wrong timeout!")
            else:
                LOGGER.error("Timeout fired when try to recieve magic")
            return None
        except (UnexpectedProtocol, Disconnection) as e:
            LOGGER.error(e)
            return None
        finally:
            timeout.cancel()

        if packet_class != expected_packet_class:
            LOGGER.error("Authorization fails: unexpected packet type")
            return None

        packet = packet_class()
        # TODO timeout
        try:
            packet.read_fields(f)
        except socket.error as e:
            LOGGER.error("Cannot recieve packet correctly, %s" % e)
            return None
        except ProtocolError as e:
            LOGGER.error("Cannot recieve packet correctly, %s" % e)
            return None
        except Exception as e:
            LOGGER.error("Cannot recieve packet correctly, %s" % e)
            return None

        return packet
Esempio n. 39
0
    def _recv_packet(self, expected_packet_class, sock):
        f = sock.makefile()
        timeout = Timeout(CONFIG['scp_protocol']['scp_timeout'])
        try:
            packet_class = determine_packet_type(f)
        except Timeout as t:
            if t is not timeout:
                LOGGER.error("Accidently catch wrong timeout!")
            else:
                LOGGER.error("Timeout fired when try to recieve magic")
            return None
        except (UnexpectedProtocol, Disconnection) as e:
            LOGGER.error(e)
            return None
        finally:
            timeout.cancel()


        if packet_class != expected_packet_class: 
            LOGGER.error("Authorization fails: unexpected packet type")
            return None

        packet = packet_class()
        # TODO timeout
        try: 
            packet.read_fields(f)
        except socket.error as e:
            LOGGER.error("Cannot recieve packet correctly, %s" % e)
            return None 
        except ProtocolError as e:
            LOGGER.error("Cannot recieve packet correctly, %s" % e)
            return None
        except Exception as e:
            LOGGER.error("Cannot recieve packet correctly, %s" % e)
            return None

        return packet