Esempio n. 1
0
    async def get(self, request: Request) -> None:
        try:
            if self.data is None:
                await asyncio.wait_for(self.read_task, timeout=30)
                if self.data is None:
                    request.setResponseCode(503)
                    request.write(b'Service temporarily unavailable')
                    return

            raw_query = urlparse(request.uri).query
            query = parse_qs(raw_query)

            # Check for etag matching
            if self.etag_base:
                hasher = hashlib.sha256()
                hasher.update(self.etag_base)
                hasher.update(raw_query)
                if request.setETag(hasher.hexdigest().encode('utf-8')):
                    # Etag matched; do not send a body
                    return

            # decode query parameter
            releases = None
            if b'releases' in query:
                releases = set(
                    self.release_aliases.get(release)
                    for release in sanitize_query_list(query[b'releases']))
                releases &= self.releases

            components = None
            if b'components' in query:
                components = sanitize_query_list(query[b'components'])
                components &= self.components

            architectures = None
            if b'architectures' in query:
                architectures = sanitize_query_list(query[b'architectures'])
                architectures.add('all')
                architectures &= self.architectures

            # generate filtered results
            def transform(item):
                result = item.copy()
                if releases is not None:
                    result['packages'] = [
                        package for package in result['packages']
                        if package['release'] in releases
                    ]
                if components is not None:
                    result['packages'] = [
                        package for package in result['packages']
                        if package['component'] in components
                    ]
                if architectures is not None:
                    result['packages'] = [
                        package for package in result['packages']
                        if package['architecture'] in architectures
                    ]
                return result, bool(result['packages'])

            result = [
                value for value, pred in map(transform, self.data) if pred
            ]

            # deliver results
            request.setHeader(b'content-type',
                              b'application/json; charset=utf-8')
            request.write(simplejson.dumps(result).encode('utf-8'))
        except Exception as e:
            log.err(
                "An exception occurred while handling request ({})".format(e))
            request.setResponseCode(400)
            request.write('Bad request'.encode('utf-8'))
        finally:
            request.finish()