Exemple #1
0
    def start(self, interval=DEFAULT_SEARCH_TIME,
              search_type=DEFAULT_SEARCH_TYPE, http_version="1.1",
	      man='"ssdp:discover"', mx=1, additionals={}):
        """ Starts the search.

        @param interval: interval between searchs. Default is 600.0 seconds
        @param search_type: type of the search, default is "ssdp:all"
        @param http_version: http version for m-search (default is 1.1)
        @param man: man field for m-search (default is ssdp:discover)
        @param mx: mx field for m-search (default is 1)
        @param additionals: dict containing additional field to be appended
			    in the end of the m-search message (default is
			    a empty dictionary)

        @type interval: float
        @type search_type: string
        @type http_version: string
        @type man: string
        @type mx: int
        @type additionals: dict
        """
        if not self.is_running():
	    self.ssdp.search_type = search_type
            self.listen_udp.start()
            self.loopcall._args = (search_type, http_version, man, mx,
	    			   additionals, )
            self.loopcall.start(interval, now=True)
            log.debug('MSearch started')
        else:
            log.warning(self.msg_already_started)
Exemple #2
0
    def start(self, interval, now=True):
        """ Starts the function calls in the interval specified. If now is
        False, it waits the interval before starting doing calls.

        @param interval: interval between calls
        @param now: whether it will start calling now or not

        @type interval: float
        @type now: boolean
        """
#        print "@@@@@@@@ LoopingCall start: " + str(self)
#        print "@@@@@@@@ LoopingCall start interval: " + str(interval)
#        print "@@@@@@@@ LoopingCall start now: " + str(now)

        if not self.is_running():
            self.interval = interval
            self.running = True
            assert interval != 0, ('(warning) starting LoopingCall with \
                                    interval %f' % self.interval)
            if now:
                self._register()
            else:
                Timer(interval, self._register).start()
        else:
            log.warning(self.msg_already_started)
Exemple #3
0
 def listener_stop(self):
     """ Stops the search.
     """
     if self.listener_is_running():
         log.debug('Multicast event listener stopped')
         self.listen_udp.stop()
     else:
         log.warning(self.msg_already_stopped)
Exemple #4
0
 def stop(self):
     """ Stops the LoopingCall.
     """
     if self.running:
         self.running = False
         self._unregister()
     else:
         log.warning(self.msg_already_stopped)
Exemple #5
0
 def stop(self):
     """ Stops the LoopingCall.
     """
     if self.running:
         self.running = False
         self._unregister()
     else:
         log.warning(self.msg_already_stopped)
Exemple #6
0
 def start(self):
     """ Starts the SSDPServer.
     """
     if not self.is_running():
         self.udp_listener.start()
         self.running = True
     else:
         log.warning(self.msg_already_started)
Exemple #7
0
 def start(self):
     """ Starts the SSDPServer.
     """
     if not self.is_running():
         self.udp_listener.start()
         self.running = True
     else:
         log.warning(self.msg_already_started)
Exemple #8
0
 def listener_start(self):
     """ Starts the listener.
     """
     if not self.listener_is_running():
         self.listen_udp.start()
         log.debug('Multicast event listener started')
     else:
         log.warning(self.msg_already_started)
def get_byte_ranges(r, clen):
    """ Based on a Range header and on the content length of a file, returns a
    list of byte ranges requested. Returns None if the header was invalid and an
    empty list in case of invalid range.

    Based on Cherrypy 3.1 implementation.

    @param r: range header
    @param clen: content length
    """
    # Byte unit supported by us (HTTP1.1) is "bytes". Get the ranges string.
    log.debug('Range: %s, %d' % (r, clen))

    if not r:
        return None

    bunit, branges = r.split('=', 1)

    log.debug('Bunit, branges: %s %s' % (bunit, branges))

    if bunit != 'bytes':
        # Ignore any other kind of units
        log.warning('Received a request with wrong Range header (unit is not'\
                    'bytes')
        return None

    ranges = []

    for br in branges.split(','):
        start, stop = [b.strip() for b in br.split('-', 1)]
        log.debug('%s %s' % (start, stop))

        if not start:
            # If the first number is missing, should return the last n bytes
            # and stop must be present, or else return the whole body.
            if not stop:
                # Invalid! Return None and indicate the whole body
                return None
            # Last n bytes
            ranges.append((clen - int(stop), clen))
            log.debug('Ranges: %s' % ranges)
        else:
            # Start is present
            if not stop:
                # Whole body
                stop = clen - 1
            if int(start) >= clen:
                # If start is equal to or larger than the size of the document
                # minus one, return the whole body
                continue
            if int(stop) < int(start):
                return None
            ranges.append((int(start), int(stop) + 1))
            log.debug('Ranges: %s' % ranges)


    log.debug('Ranges: %s' % ranges)
    return ranges
Exemple #10
0
def get_byte_ranges(r, clen):
    """ Based on a Range header and on the content length of a file, returns a
    list of byte ranges requested. Returns None if the header was invalid and an
    empty list in case of invalid range.

    Based on Cherrypy 3.1 implementation.

    @param r: range header
    @param clen: content length
    """
    # Byte unit supported by us (HTTP1.1) is "bytes". Get the ranges string.
    log.debug('Range: %s, %d' % (r, clen))

    if not r:
        return None

    bunit, branges = r.split('=', 1)

    log.debug('Bunit, branges: %s %s' % (bunit, branges))

    if bunit != 'bytes':
        # Ignore any other kind of units
        log.warning('Received a request with wrong Range header (unit is not'\
                    'bytes')
        return None

    ranges = []

    for br in branges.split(','):
        start, stop = [b.strip() for b in br.split('-', 1)]
        log.debug('%s %s' % (start, stop))

        if not start:
            # If the first number is missing, should return the last n bytes
            # and stop must be present, or else return the whole body.
            if not stop:
                # Invalid! Return None and indicate the whole body
                return None
            # Last n bytes
            ranges.append((clen - int(stop), clen))
            log.debug('Ranges: %s' % ranges)
        else:
            # Start is present
            if not stop:
                # Whole body
                stop = clen - 1
            if int(start) >= clen:
                # If start is equal to or larger than the size of the document
                # minus one, return the whole body
                continue
            if int(stop) < int(start):
                return None
            ranges.append((int(start), int(stop) + 1))
            log.debug('Ranges: %s' % ranges)

    log.debug('Ranges: %s' % ranges)
    return ranges
 def start(self):
     """ Starts the control point.
     """
     if not self.is_running():
         self._ssdp_server.start()
         self._event_listener.start(self.event_host)
         self._multicast_event_listener.start()
     else:
         log.warning(self.msg_already_started)
Exemple #12
0
 def start(self):
     """ Starts the control point.
     """
     if not self.is_running():
         self._ssdp_server.start()
         self._event_listener.start(self.event_host)
         self._multicast_event_listener.start()
     else:
         log.warning(self.msg_already_started)
Exemple #13
0
 def stop(self):
     """ Stops the webserver.
     """
     if self.is_running():
         if not self.adapter:
             raise RuntimeError('Adapter not set')
         self.adapter.stop()
     else:
         log.warning(self.msg_already_stopped)
Exemple #14
0
    def _datagram_received(self, data, address):
        """ Callback for the UDPListener when messages arrive.

        @param data: raw data received
        @param host: host where data came from
        @param port: port where data came from

        @type data: string
        @type host: string
        @type port: integer
        """
        (host, port) = address
        try:
            cmd, headers = parse_http_response(data)
            body = data[data.find("<"):data.rfind(">")+1]
        except Exception as err:
            log.error('Error while receiving datagram packet: %s', str(err))
            return

        # Render notify message
        if not (cmd[0] == 'NOTIFY' and cmd[1] == '*' and cmd[2] == 'HTTP/1.0' and \
           'content-type' in headers and \
           headers['content-type'] == 'text/xml; charset="utf-8"' and \
           'nt' in headers and headers['nt'] == 'upnp:event' and \
           'nts' in headers and headers['nts'] == 'upnp:propchange' and \
           'host' in headers and 'usn' in headers and \
           'svcid' in headers and 'seq' in headers and \
           'lvl' in headers and 'bootid.upnp.org' in headers and \
           'content-length' in headers):

            log.warning('Invalid message')
            return

        addr = headers['host'].split(':')[0]
        port = int(headers['host'].split(':')[1])
        udn = headers['usn'].split('::')[0]
        service_type = headers['usn'].split('::')[1]
        svcid = headers['svcid']
        seq = int(headers['seq'])
        lvl = headers['lvl']
        content_length = int(headers['content-length'])
        bootid = int(headers['bootid.upnp.org'])

        if addr != UPnPDefaults.MULTICAST_EVENT_ADDR or \
           port != UPnPDefaults.MULTICAST_EVENT_PORT:
            log.warning('Invalid address %s:%d' % (addr, port))
            return

        changed_vars = read_notify_message_body(body)

        self.control_point._on_event('', changed_vars)

        for id, dev in list(self.control_point._known_devices.items()):
            service = self._find_service(dev, udn, service_type, svcid)
            if service != None:
                service._on_event(changed_vars)
                log.debug('Multicast event. Event changed vars: %s', changed_vars)
Exemple #15
0
 def stop(self):
     """ Stops the search.
     """
     if self.is_running():
         log.debug('MSearch stopped')
         self.listen_udp.stop()
         self.loopcall.stop()
     else:
         log.warning(self.msg_already_stopped)
Exemple #16
0
 def stop(self):
     """ Stops the search.
     """
     if self.is_running():
         log.debug('MSearch stopped')
         self.listen_udp.stop()
         self.loopcall.stop()
     else:
         log.warning(self.msg_already_stopped)
Exemple #17
0
 def stop(self):
     """ Stops the webserver.
     """
     if self.is_running():
         if not self.adapter:
             raise RuntimeError('Adapter not set')
         self.adapter.stop()
     else:
         log.warning(self.msg_already_stopped)
Exemple #18
0
 def start(self):
     """ Starts the webserver.
     """
     if not self.is_running():
         if not self.adapter:
             raise RuntimeError('Adapter not set.')
         threaded_call.run_async_function(self.adapter.start)
         self.running = True
     else:
         log.warning(self.msg_already_started)
Exemple #19
0
 def __add__(self, obj):
     if issubclass(obj.__class__, Device):
         log.debug("Adding device %s as embedded for %s", obj, self)
         self.add_device(obj)
     elif issubclass(obj.__class__, BaseService):
         log.debug("Adding service %s as service for %s", obj, self)
         self.add_service(obj)
     else:
         log.warning("Ignored invalid addition: %s + %s", self, obj)
     return self
Exemple #20
0
    def __init__(self):
        import brisa.core
        import sys

        if 'brisa.core.reactor' in sys.modules:
            from brisa.core import log
            log.warning('reactor already installed')

        brisa.core.reactor = self
        sys.modules['brisa.core.reactor'] = self
Exemple #21
0
 def start(self):
     """ Starts the webserver.
     """
     if not self.is_running():
         if not self.adapter:
             raise RuntimeError('Adapter not set.')
         threaded_call.run_async_function(self.adapter.start)
         self.running = True
     else:
         log.warning(self.msg_already_started)
Exemple #22
0
 def __add__(self, obj):
     if issubclass(obj.__class__, Device):
         log.debug("Adding device %s as embedded for %s", obj, self)
         self.add_device(obj)
     elif issubclass(obj.__class__, BaseService):
         log.debug("Adding service %s as service for %s", obj, self)
         self.add_service(obj)
     else:
         log.warning("Ignored invalid addition: %s + %s", self, obj)
     return self
Exemple #23
0
 def stop_control_point(self):
     """ Stops the control point.
     """
     if self.is_running():
         if self.is_msearch_running():
             self.stop_search()
         self._ssdp_server.stop()
         self._event_listener.stop()
     else:
         log.warning(self.msg_already_stopped)
    def service_has_been_built(self, built_ok):
        log.debug("Service fetched, %d left, result %s", self.pending_services - 1, built_ok)
        if not built_ok and not brisa.__tolerate_service_parse_failure__:
            log.warning("Device killed")
            self.device = None
        self.pending_services -= 1

        if self.pending_services <= 0:
            log.debug("All services fetched, sending device forward")
            self.callback(self.cargo, self.device)
Exemple #25
0
 def start(self):
     """ Starts the control point.
     """
     print "ControlPoint.start"
     if not self.is_running():
         print "ControlPoint.start _ssdp_server"
         self._ssdp_server.start()
         print "ControlPoint.start _event_listener"
         self._event_listener.start(self.event_host)
     else:
         log.warning(self.msg_already_started)
Exemple #26
0
 def stop_control_point(self):
     """ Stops the control point.
     """
     if self.is_running():
         if self.is_msearch_running():
             self.stop_search()
         self._ssdp_server.stop()
         self._event_listener.stop()
         self._multicast_event_listener.stop()
     else:
         log.warning(self.msg_already_stopped)
Exemple #27
0
    def service_has_been_built(self, built_ok):
        log.debug("Service fetched, %d left, result %s", \
                self.pending_services - 1, built_ok)
        if not built_ok and not brisa.__tolerate_service_parse_failure__:
            log.warning("Device killed")
            self.device = None
        self.pending_services -= 1

        if self.pending_services <= 0:
            log.debug("All services fetched, sending device forward")
            self.callback(self.cargo, self.device)
Exemple #28
0
def url_fetch(url, filename='', attempts=0, interval=0):
    """ Fetches an URL into a file or returns a file descriptor. If attempts
    and interval are not specified, they get their values from
    brisa.url_fetch_attempts and brisa.url_fetch_attempts_interval.

    @param url: URL to be fetched
    @param filename: if specified fetch result gets written on this path
    @param attempts: number of attempts
    @param interval: interval between attempts in seconds

    @type url: string
    @type filename: string
    @type attempts: integer
    @type interval: float
    """
    if not attempts:
        attempts = brisa.url_fetch_attempts
    if not interval:
        interval = brisa.url_fetch_attempts_interval

    handle = None
    last_exception = None
    for k in range(attempts):
        log.debug('Fetching %r (attempt %d)' % (url, k))
        req = urllib.request.Request(url)
        try:
            handle = urllib.request.urlopen(req)
        except IOError as e:
            if hasattr(e, 'reason'):
                log.warning('Attempt %d: failed to reach a server. Reason: %s'%
                            (k, e.reason))
            elif hasattr(e, 'code'):
                log.warning('Attempt %d: the server couldn\'t fulfill the '\
                            'request. Error code: %s' % (k, e.code))
            handle = None
            last_exception = e
        finally:
            if handle != None:
                if not filename:
                    # Return mode
                    log.debug('url %r fetched successfully' % url)
                    return handle
                else:
                    log.debug('writing data to filename %s' % filename)
                    # Writing mode
                    shutil.copyfile(handle, open(filename, 'w'))
                    return None
            sleep(interval)

    if last_exception:
        raise last_exception
    else:
        return None
Exemple #29
0
    def stop(self):
        """ Sends bye bye notifications and stops the SSDPServer.
        """
        if self.is_running():
            # Avoid racing conditions
            own_temp = self.advertised.copy()
            for usn in own_temp:
                self._do_byebye(usn)

            self.renew_loop.stop()
            self.udp_listener.stop()
            self.running = False
        else:
            log.warning(self.msg_already_stopped)
Exemple #30
0
    def stop(self):
        """ Sends bye bye notifications and stops the SSDPServer.
        """
        if self.is_running():
            # Avoid racing conditions
            own_temp = self.advertised.copy()
            for usn in own_temp:
                self._do_byebye(usn)

            self.renew_loop.stop()
            self.udp_listener.stop()
            self.running = False
        else:
            log.warning(self.msg_already_stopped)
Exemple #31
0
    def start(self):
        """ Starts the listener.
        """
        if not self.is_running():
            for name, state_var in list(self.service.get_variables().items()):
                if state_var.send_events and state_var.multicast:
                    state_var.subscribe_for_update(self._update_variable)

            if not self.force_event_reload:
                self.l_call.start(self.event_reload_time)
            self._is_running = True
            log.debug('Multicast event controller started with event reload time: %d'
                      % self.event_reload_time)
        else:
            log.warning(self.msg_already_started)
Exemple #32
0
    def stop(self):
        """ Stops the search.
        """
        if self.is_running():
            log.debug('Multicast event controller stopped')
            for name, state_var in list(self.service.get_variables().items()):
                if state_var.send_events and state_var.multicast:
                    state_var.unsubscribe_for_update(self._update_variable)

            if not self.force_event_reload:
                self.l_call.stop()
                reactor.rem_after_stop_func(self.stop)
            self._is_running = False
        else:
            log.warning(self.msg_already_stopped)
Exemple #33
0
    def stop(self):
        """ Stops the search.
        """
        if self.is_running():
            log.debug('Multicast event controller stopped')
            for name, state_var in self.service.get_variables().items():
                if state_var.send_events and state_var.multicast:
                    state_var.unsubscribe_for_update(self._update_variable)

            if not self.force_event_reload:
                self.l_call.stop()
                reactor.rem_after_stop_func(self.stop)
            self._is_running = False
        else:
            log.warning(self.msg_already_stopped)
Exemple #34
0
    def start(self):
        """ Starts the listener.
        """
        self.listener_start()
        if not self.is_running():
            for name, state_var in self.service.get_variables().items():
                if state_var.send_events and state_var.multicast:
                    state_var.subscribe_for_update(self._update_variable)

            if not self.force_event_reload:
                self.l_call.start(self.event_reload_time)
            self._is_running = True
            log.debug('Multicast event controller started with event reload time: %d'
                      % self.event_reload_time)
        else:
            log.warning(self.msg_already_started)
Exemple #35
0
    def start(self, interval=DEFAULT_SEARCH_TIME,
              search_type=DEFAULT_SEARCH_TYPE):
        """ Starts the search.

        @param interval: interval between searchs. Default is 600.0 seconds
        @param search_type: type of the search, default is "ssdp:all"

        @type interval: float
        @type search_type: string
        """
        if not self.is_running():
            self.listen_udp.start()
            self.loopcall._args = (search_type, )
            self.loopcall.start(interval, now=True)
            log.debug('MSearch started')
        else:
            log.warning(self.msg_already_started)
Exemple #36
0
    def start(self,
              interval=DEFAULT_SEARCH_TIME,
              search_type=DEFAULT_SEARCH_TYPE,
              http_version="1.1",
              man='"ssdp:discover"',
              mx=1,
              additionals={}):
        """ Starts the search.

        @param interval: interval between searchs. Default is 600.0 seconds
        @param search_type: type of the search, default is "ssdp:all"
        @param http_version: http version for m-search (default is 1.1)
        @param man: man field for m-search (default is ssdp:discover)
        @param mx: mx field for m-search (default is 1)
        @param additionals: dict containing additional field to be appended
			    in the end of the m-search message (default is
			    a empty dictionary)

        @type interval: float
        @type search_type: string
        @type http_version: string
        @type man: string
        @type mx: int
        @type additionals: dict
        """
        if not self.is_running():
            self.ssdp.search_type = search_type
            self.listen_udp.start()
            self.loopcall._args = (
                search_type,
                http_version,
                man,
                mx,
                additionals,
            )
            self.loopcall.start(interval, now=True)
            log.debug('MSearch started')
        else:
            log.warning(self.msg_already_started)
Exemple #37
0
def url_fetch(url, filename='', attempts=0, interval=0, silent=False):
    """ Fetches an URL into a file or returns a file descriptor. If attempts
    and interval are not specified, they get their values from
    brisa.url_fetch_attempts and brisa.url_fetch_attempts_interval.

    @param url: URL to be fetched
    @param filename: if specified fetch result gets written on this path
    @param attempts: number of attempts
    @param interval: interval between attempts in seconds#
    @param silent: silently ignore exception and return none

    @type url: string
    @type filename: string
    @type attempts: integer
    @type interval: float
    """
    if not attempts:
        attempts = brisa.url_fetch_attempts
    if not interval:
        interval = brisa.url_fetch_attempts_interval

    handle = None
    last_exception = None
    for k in range(attempts):
        log.debug('Fetching %r (attempt %d)' % (url, k))
        req = urllib2.Request(url)
        try:
            handle = urllib2.urlopen(req)
        except IOError, e:
            if hasattr(e, 'reason'):
                log.warning('Attempt %d: failed to reach a server. Reason: %s'%
                            (k, e.reason))
            elif hasattr(e, 'code'):
                log.warning('Attempt %d: the server couldn\'t fulfill the '\
                            'request. Error code: %s' % (k, e.code))
            handle = None
            last_exception = e
        finally:
Exemple #38
0
def url_fetch(url, filename='', attempts=0, interval=0):
    """ Fetches an URL into a file or returns a file descriptor. If attempts
    and interval are not specified, they get their values from
    brisa.url_fetch_attempts and brisa.url_fetch_attempts_interval.

    @param url: URL to be fetched
    @param filename: if specified fetch result gets written on this path
    @param attempts: number of attempts
    @param interval: interval between attempts in seconds

    @type url: string
    @type filename: string
    @type attempts: integer
    @type interval: float
    """
    if not attempts:
        attempts = brisa.url_fetch_attempts
    if not interval:
        interval = brisa.url_fetch_attempts_interval

    handle = None
    last_exception = None
    for k in range(attempts):
        log.debug('Fetching %r (attempt %d)' % (url, k))
        req = urllib2.Request(url)
        try:
            handle = urllib2.urlopen(req)
        except IOError, e:
            if hasattr(e, 'reason'):
                log.warning(
                    'Attempt %d: failed to reach a server. Reason: %s' %
                    (k, e.reason))
            elif hasattr(e, 'code'):
                log.warning('Attempt %d: the server couldn\'t fulfill the '\
                            'request. Error code: %s' % (k, e.code))
            handle = None
            last_exception = e
        finally:
Exemple #39
0
    def start(self, interval=DEFAULT_SEARCH_TIME,
              search_type=DEFAULT_SEARCH_TYPE):
        """ Starts the search.

        @param interval: interval between searchs. Default is 600.0 seconds
        @param search_type: type of the search, default is "ssdp:all"

        @type interval: float
        @type search_type: string
        """

#        interval = 30.0
        
        if not self.is_running():
            self.search_type = search_type
            self.listen_udp.start()
            
#            print ">>>>>>>>> interval: " + str(interval)
            
            self.loopcall.start(interval, now=True)
            log.debug('MSearch started')
        else:
            log.warning(self.msg_already_started)
Exemple #40
0
        except Exception, err:
            log.error('Error while receiving datagram packet: %s', str(err))
            return

        # Render notify message
        if not (cmd[0] == 'NOTIFY' and cmd[1] == '*' and cmd[2] == 'HTTP/1.0' and \
           headers.has_key('content-type') and \
           headers['content-type'] == 'text/xml; charset="utf-8"' and \
           headers.has_key('nt') and headers['nt'] == 'upnp:event' and \
           headers.has_key('nts') and headers['nts'] == 'upnp:propchange' and \
           headers.has_key('host') and headers.has_key('usn') and \
           headers.has_key('svcid') and headers.has_key('seq') and \
           headers.has_key('lvl') and headers.has_key('bootid.upnp.org') and \
           headers.has_key('content-length')):

            log.warning('Invalid message')
            return

        addr = headers['host'].split(':')[0]
        port = int(headers['host'].split(':')[1])
        udn = headers['usn'].split('::')[0]
        service_type = headers['usn'].split('::')[1]
        svcid = headers['svcid']
        seq = int(headers['seq'])
        lvl = headers['lvl']
        content_length = int(headers['content-length'])
        bootid = int(headers['bootid.upnp.org'])

        if addr != UPnPDefaults.MULTICAST_EVENT_ADDR or \
           port != UPnPDefaults.MULTICAST_EVENT_PORT:
            log.warning('Invalid address %s:%d' % (addr, port))
Exemple #41
0
                        'because of SSDPServer.receive_notify is False)',
                        host, port)
              	return
	    if self.search_type != "upnp:rootdevice" and \
	        self.search_type != "sspd:all" and \
	        self.search_type != headers['nt']:
                # Ignore notify
              	log.debug('Received NOTIFY command from %s:%s (ignored '\
                        'because of SSDPServer.search_type is different'\
			'than headers["nt"])',
                        host, port)
              	return
            # SSDP presence
            self._notify_received(headers, (host, port))
        else:
           log.warning('Received unknown SSDP command %s with headers %s '\
                       'from %s:%s', cmd, str(headers), host, port)

    def _discovery_request(self, headers, (host, port)):
        """ Processes discovery requests and responds accordingly.

        @param headers: discovery headers
        @param host: discovery source host
        @param port: discovery source port

        @type headers: dictionary
        @type host: string
        @type port integer
        """
	for dev_info in self.known_device.values():
	    if (headers['st'] == 'ssdp:all' or dev_info['ST'] == headers['st']):
        	response = []
Exemple #42
0
    def application(self, environ, start_response, response=None):
        """ Application wsgi callback that processes a request. Must not be
        called by the user.

        @param response: used when the request was redirected to this file. If
                         not present, then this file was accessed directly (no
                         redirections) and in this case environ and
                         start_response must be passed accordingly.
        """
        req = Request(environ)

        if response:
            # Redirect mode, see method doc and comments at the end
            r = response
        else:
            # Normal request
            r = Response(200, start_response)

        if not os.path.exists(self.path):
            log.warning('Received request on missing file: %s' % self.path)
            return simple_response(500, r.start_response,
                                   'File not available.')

        try:
            st = os.stat(self.path)
        except OSError:
            return simple_response(404, r.start_response)

        r.body = open(self.path, 'rb')
        content_length = st.st_size

        h = r.headers
        h['Last-modified'] = rfc822.formatdate(st.st_mtime)
        h['Content-type'] = self._content_type

        if self._disposition:
            h['Content-disposition'] = '%s; filename="%s"' % \
                                       (self._disposition, self.name)

        if req.protocol >= (1, 1):
            h['Accept-ranges'] = 'bytes'

            if 'range' not in req.headers:
                # Send the whole response body
                h['Content-length'] = str(content_length)
            else:
                ranges = get_byte_ranges(req.headers['Range'], content_length)

                if ranges == []:
                    # Request range not satisfiable
                    r.status = 416
                    r.headers['Content-range'] = 'bytes */%s' % content_length
                    r.headers['Content-length'] = 0
                    r.body = ['']
                elif ranges:
                    # Partial content status
                    r.status = 206

                    if len(ranges) == 1:
                        # Single part
                        setup_single_part_response(r, ranges[0],
                                                   content_length)

                    else:
                        # Multipart
                        setup_multi_part_response(r, ranges, content_length,
                                                  self._content_type)

                        # Recalculate content length
                        s = 0
                        for ra in ranges:
                            s += ra[1] - ra[0] + 1
                        h['Content-length'] = str(s)

        else:
            # Lower protocols do not support ranges, whole body
            h['Content-length'] = str(content_length)

        if not response:
            # Normal request, not redirected. When redirected, who respond()s is
            # the caller.
            r._respond()

        return r.body
Exemple #43
0
            log.debug("Received M-Search command from %s:%s", host, port)
            self._discovery_request(headers, (host, port))
        elif cmd[0] == "NOTIFY" and cmd[1] == "*":
            log.debug("NOTIFY receive_notify: %s", self.receive_notify)
            if not self.receive_notify:
                # Ignore notify
                log.debug(
                    "Received NOTIFY command from %s:%s (ignored " "because of SSDPServer.receive_notify is False)",
                    host,
                    port,
                )
                return
            # SSDP presence
            self._notify_received(headers, (host, port))
        else:
            log.warning("Received unknown SSDP command %s with headers %s " "from %s:%s", cmd, str(headers), host, port)

    def _discovery_request(self, headers, (host, port)):
        """ Processes discovery requests and responds accordingly.

        @param headers: discovery headers
        @param host: discovery source host
        @param port: discovery source port

        @type headers: dictionary
        @type host: string
        @type port integer
        """
        right_key = 0

        # Do we know about this service?
Exemple #44
0
            and headers.has_key("content-type")
            and headers["content-type"] == 'text/xml; charset="utf-8"'
            and headers.has_key("nt")
            and headers["nt"] == "upnp:event"
            and headers.has_key("nts")
            and headers["nts"] == "upnp:propchange"
            and headers.has_key("host")
            and headers.has_key("usn")
            and headers.has_key("svcid")
            and headers.has_key("seq")
            and headers.has_key("lvl")
            and headers.has_key("bootid.upnp.org")
            and headers.has_key("content-length")
        ):

            log.warning("Invalid message")
            return

        addr = headers["host"].split(":")[0]
        port = int(headers["host"].split(":")[1])
        udn = headers["usn"].split("::")[0]
        service_type = headers["usn"].split("::")[1]
        svcid = headers["svcid"]
        seq = int(headers["seq"])
        lvl = headers["lvl"]
        content_length = int(headers["content-length"])
        bootid = int(headers["bootid.upnp.org"])

        if addr != UPnPDefaults.MULTICAST_EVENT_ADDR or port != UPnPDefaults.MULTICAST_EVENT_PORT:
            log.warning("Invalid address %s:%d" % (addr, port))
            return
Exemple #45
0
            #	        and headers['man'] == '"ssdp:discover"':
            # SSDP discovery
            log.debug('Received M-Search command from %s:%s', host, port)
            self._discovery_request(headers, (host, port))
        elif cmd[0] == 'NOTIFY' and cmd[1] == '*':
            log.debug("NOTIFY receive_notify: %s", self.receive_notify)
            if not self.receive_notify:
                # Ignore notify
                log.debug('Received NOTIFY command from %s:%s (ignored '\
                          'because of SSDPServer.receive_notify is False)',
                          host, port)
                return
            # SSDP presence
            self._notify_received(headers, (host, port))
        else:
            log.warning('Received unknown SSDP command %s with headers %s '\
                        'from %s:%s', cmd, str(headers), host, port)

    def _discovery_request(self, headers, (host, port)):
        """ Processes discovery requests and responds accordingly.

        @param headers: discovery headers
        @param host: discovery source host
        @param port: discovery source port

        @type headers: dictionary
        @type host: string
        @type port integer
        """
        right_key = 0

        # Do we know about this service?
Exemple #46
0
    def application(self, environ, start_response, response=None):
        """ Application wsgi callback that processes a request. Must not be
        called by the user.

        @param response: used when the request was redirected to this file. If
                         not present, then this file was accessed directly (no
                         redirections) and in this case environ and
                         start_response must be passed accordingly.
        """
        req = Request(environ)

        if response:
            # Redirect mode, see method doc and comments at the end
            r = response
        else:
            # Normal request
            r = Response(200, start_response)

        if not os.path.exists(self.path):
            log.warning('Received request on missing file: %s' % self.path)
            return simple_response(500, r.start_response, 'File not available.')

        try:
            st = os.stat(self.path)
        except OSError:
            return simple_response(404, r.start_response)

        r.body = open(self.path, 'rb')
        content_length = st.st_size

        h = r.headers
        h['Last-modified'] = rfc822.formatdate(st.st_mtime)
        h['Content-type'] = self._content_type

        if self._disposition:
            h['Content-disposition'] = '%s; filename="%s"' % \
                                       (self._disposition, self.name)

        if req.protocol >= (1, 1):
            h['Accept-ranges'] = 'bytes'

            if 'range' not in req.headers:
                # Send the whole response body
                h['Content-length'] = str(content_length)
            else:
                ranges = get_byte_ranges(req.headers['Range'], content_length)

                if ranges == []:
                    # Request range not satisfiable
                    r.status = 416
                    r.headers['Content-range'] = 'bytes */%s' % content_length
                    r.headers['Content-length'] = 0
                    r.body = ['']
                elif ranges:
                    # Partial content status
                    r.status = 206

                    if len(ranges) == 1:
                        # Single part
                        setup_single_part_response(r, ranges[0], content_length)

                    else:
                        # Multipart
                        setup_multi_part_response(r, ranges, content_length,
                                                  self._content_type)

                        # Recalculate content length
                        s = 0
                        for ra in ranges:
                            s += ra[1] - ra[0] + 1
                        h['Content-length'] = str(s)

        else:
            # Lower protocols do not support ranges, whole body
            h['Content-length'] = str(content_length)

        if not response:
            # Normal request, not redirected. When redirected, who respond()s is
            # the caller.
            r._respond()

        return r.body