Beispiel #1
0
    def _get_request_response_from_work_unit(self, work_unit):
        """
        In some cases the work unit is a tuple with request / response instances.

        In other cases it is an ID, which needs to be queried from the History DB
        to get the request / response.

        :param work_unit: One of the options explained above
        :return: A request / response tuple
        """
        if not isinstance(work_unit, int):
            request, response = work_unit
        else:
            # Before we sent requests and responses as work units,
            # but since we changed from Queue to CachedQueue for BaseConsumer
            # the database was growing really big (1GB) for storing that traffic
            # and I decided to migrate to using just the response.id and querying
            # the SQLite one extra time.
            history = HistoryItem()
            request, response = history.load_from_file(work_unit)

        # Create a fuzzable request based on the urllib2 request object
        headers_inst = Headers(request.header_items())
        request = FuzzableRequest.from_parts(request.url_object,
                                             request.get_method(),
                                             request.get_data() or '',
                                             headers_inst)

        return request, response
Beispiel #2
0
    def _get_request_response_from_work_unit(self, work_unit):
        """
        In some cases the work unit is a tuple with request / response instances.

        In other cases it is an ID, which needs to be queried from the History DB
        to get the request / response.

        :param work_unit: One of the options explained above
        :return: A request / response tuple
        """
        if not isinstance(work_unit, int):
            request, response = work_unit
        else:
            # Before we sent requests and responses as work units,
            # but since we changed from Queue to CachedQueue for BaseConsumer
            # the database was growing really big (1GB) for storing that traffic
            # and I decided to migrate to using just the response.id and querying
            # the SQLite one extra time.
            history = HistoryItem()
            request, response = history.load_from_file(work_unit)

        # Create a fuzzable request based on the urllib2 request object
        headers_inst = Headers(request.header_items())
        request = FuzzableRequest.from_parts(request.url_object,
                                             request.get_method(),
                                             request.get_data() or '',
                                             headers_inst)

        return request, response
Beispiel #3
0
    def _get_request_response_from_id_impl(self, http_response_id):
        """
        Just reads the request and response from the files. No threading,
        events, caching, etc.

        :param http_response_id: The HTTP response ID
        :return: An HTTP request and response tuple
        """
        history = HistoryItem()
        request, response = history.load_from_file(http_response_id)

        # Create a fuzzable request based on the urllib2 request object
        headers_inst = Headers(request.header_items())
        request = FuzzableRequest.from_parts(request.url_object,
                                             request.get_method(),
                                             request.get_data() or '',
                                             headers_inst)

        return request, response
Beispiel #4
0
    def to_string(self):
        """
        :return: An xml node (as a string) representing the HTTP request / response.

        <http-transaction id="...">
            <http-request>
                <status></status>
                <headers>
                    <header>
                        <field></field>
                        <content></content>
                    </header>
                </headers>
                <body content-encoding="base64"></body>
            </http-request>

            <http-response>
                <status></status>
                <headers>
                    <header>
                        <field></field>
                        <content></content>
                    </header>
                </headers>
                <body content-encoding="base64"></body>
            </http-response>
        </http-transaction>

        One of the differences this class has with the previous implementation is
        that the body is always encoded, no matter the content-type. This helps
        prevent encoding issues.
        """
        # Get the data from the cache
        node = self.get_node_from_cache()
        if node is not None:
            return node

        # HistoryItem to get requests/responses
        req_history = HistoryItem()

        # This might raise a DBException in some cases (which I still
        # need to identify and fix). When an exception is raised here
        # the caller needs to handle it by ignoring this part of the
        # HTTP transaction
        request, response = req_history.load_from_file(self._id)

        data = request.get_data() or ''
        b64_encoded_request_body = base64.encodestring(smart_str_ignore(data))

        body = response.get_body() or ''
        b64_encoded_response_body = base64.encodestring(smart_str_ignore(body))

        context = {
            'id': self._id,
            'request': {
                'status': request.get_request_line().strip(),
                'headers': request.get_headers(),
                'body': b64_encoded_request_body
            },
            'response': {
                'status': response.get_status_line().strip(),
                'headers': response.get_headers(),
                'body': b64_encoded_response_body
            }
        }

        context = dotdict(context)

        template = self.get_template(self.TEMPLATE)
        transaction = template.render(context)
        self.save_node_to_cache(transaction)

        return transaction
Beispiel #5
0
    def to_string(self):
        """
        :return: An xml node (as a string) representing the HTTP request / response.

        <http-transaction id="...">
            <http-request>
                <status></status>
                <headers>
                    <header>
                        <field></field>
                        <content></content>
                    </header>
                </headers>
                <body content-encoding="base64"></body>
            </http-request>

            <http-response>
                <status></status>
                <headers>
                    <header>
                        <field></field>
                        <content></content>
                    </header>
                </headers>
                <body content-encoding="base64"></body>
            </http-response>
        </http-transaction>

        One of the differences this class has with the previous implementation is
        that the body is always encoded, no matter the content-type. This helps
        prevent encoding issues.
        """
        # Get the data from the cache
        node = self.get_node_from_cache()
        if node is not None:
            return node

        # HistoryItem to get requests/responses
        req_history = HistoryItem()

        # This might raise a DBException in some cases (which I still
        # need to identify and fix). When an exception is raised here
        # the caller needs to handle it by ignoring this part of the
        # HTTP transaction
        request, response = req_history.load_from_file(self._id)

        data = request.get_data() or ''
        b64_encoded_request_body = base64.encodestring(smart_str_ignore(data))

        body = response.get_body() or ''
        b64_encoded_response_body = base64.encodestring(smart_str_ignore(body))

        context = {'id': self._id,
                   'request': {'status': request.get_request_line().strip(),
                               'headers': request.get_headers(),
                               'body': b64_encoded_request_body},
                   'response': {'status': response.get_status_line().strip(),
                                'headers': response.get_headers(),
                                'body': b64_encoded_response_body}}

        context = dotdict(context)

        template = self.get_template(self.TEMPLATE)
        transaction = template.render(context)
        self.save_node_to_cache(transaction)

        return transaction