Esempio n. 1
0
    def create_request(self, operation, request, data):
        """ Reimplemented to intercept requests. Stops blacklisted requests

        CFG02

        """

        request.setAttribute(
            QNetworkRequest.HttpPipeliningAllowedAttribute, True)

        request.setAttribute(QNetworkRequest.CacheLoadControlAttribute,
                             QNetworkRequest.PreferCache)

        qurl = request.url()
        url = qurl.toString()

        info = {'notify': self.show_detail,
                'message': None,
                'detail': None,
                'qurl': qurl,
                'color': Fore.GREEN}

        # if keeping a log of the POST data, do it before anything else
        if operation == QNetworkAccessManager.PostOperation:
            notify_post(data, url)

        # stop here if the request is local enough as for not
        # requiring further scrutiny
        if is_local(qurl) and not is_font(qurl):
            info['message'] = "LOCAL"
            return self.__pass(operation, request, data, info=info)

        # make optional the loading of webfonts
        if is_font(qurl):
            if self.load_webfonts:
                return self.__pass(operation, request, data)
            else:
                info['message'] = "TRIMMED WEBFONT"
                return self.__block("about:blank", info=info)

        # If the request is going to be intercepted a custom request is
        # built and returned after optionally reporting the reason

        whitelist = get_options()['sites'][self.__instance]['host_whitelist']

        info['color'] = Fore.RED

        for (stop_case, description, show) in [
                # it may be an un-dns'ed request; careful here
                (is_numerical(qurl.host()), "NUMERICAL", True),
                # whitelist exists, and the requested URL is not in it
                (non_whitelisted(whitelist, qurl),
                 "NON WHITELISTED", self.show_detail)
        ]:
            if stop_case:
                info['notify'] = show
                info['message'] = description
                return self.__block("about:blank", info=info)

        # It's not a local request; it should have a proper URL structure
        # then. 'domain' and 'suffix' must be non-None (and non-empty).

        (subdomain, domain, suffix) = tldextract.extract(url)
        subdomain = subdomain if subdomain != '' else None

        # FIXME this entire block (and maybe the one above) feels half-baked
        for (stop_case, description, detail, show) in [
                # if 'domain' or 'suffix' are not valid, stop;
                # should never happen (even though it does - some providers
                # don't have a proper 'domain' according to tldextract
                (domain == '' or suffix == '',
                 "SHOULD NOT HAPPEN", " {}|{}|{} ".format(subdomain,
                                                          domain,
                                                          suffix), True),

                # site is on a whitelist, but this instance does not use
                # whitelists; this means it belong to another instance,
                # assuming exclusivity
                # TODO 'domain + suffix' is a maybe bad generalization
                (whitelist is None and  # CFG02
                 domain + '.' + suffix in get_options()['all_whitelists'],
                 "WHITELIST^C FILTER", "{} || {} || {} ".format(
                     subdomain,
                     domain,
                     suffix), self.show_detail)
        ]:
            if stop_case:
                info['message'] = description
                info['detail'] = detail
                return self.__block(encode_blocked(description, url),
                                    info=info)

        return self.__pass(operation, request, data)
Esempio n. 2
0
        def reply_complete(reply):
            """ Prints when a request completes, handles the filter that
            chooses between successful and filtered requests

            Replies only - if the request doesn't have to go
            through the network, it will not be reported here

            AB01

            """

            qurl = reply.url()
            s_url = qurl.toString()

            status = reply.attribute(
                QNetworkRequest.HttpStatusCodeAttribute)

            if is_local(qurl) or status is None:
                return

            # 'status' will never be None from here on

            # used only once
            color_status = Fore.GREEN if reply.attribute(
                QNetworkRequest.SourceIsFromCacheAttribute) else Fore.RED

            # was it a filtered reply?
            # used only once
            color = Fore.BLUE if 200 <= status < 400 else Fore.RED

            origin = reply.request().originatingObject()

            if origin:
                # used only once
                not_same = not compare_host(
                    origin.requestedUrl().host(), qurl.host())
            else:
                print("NO ORIGINATING OBJECT", s_url)
                return

            in_iframe = origin != origin.page().mainFrame()

            # this is the response to the original .load(), not a
            # resource loaded by the page itself
            if origin.requestedUrl() == qurl and not in_iframe:
                host = sub("^www.", "", qurl.host())
                path = qurl.path().rstrip("/ ")

                if (  # AB01
                        (host not in DO_NOT_STORE) and
                        (not qurl.hasQuery()) and
                        len(path.split('/')) < 4 and
                        200 <= status < 400):
                    database().store_navigation(host, path, self.prefix)

            if not_same or in_iframe:
                info = {
                    'color_status': color_status,
                    'status': status,
                    'resource': qurl,
                    'source': origin.requestedUrl(),
                    'main_color': color,
                    'iframe': in_iframe}
                show_info(info)