Example #1
0
    def _echo_request_line(self, flow):
        if flow.request.stickycookie:
            stickycookie = click.style("[stickycookie] ", fg="yellow", bold=True)
        else:
            stickycookie = ""

        if flow.client_conn:
            client = click.style(strutils.escape_control_characters(flow.client_conn.address.host), bold=True)
        else:
            client = click.style("[replay]", fg="yellow", bold=True)

        method = flow.request.method
        method_color = dict(
            GET="green",
            DELETE="red"
        ).get(method.upper(), "magenta")
        method = click.style(strutils.escape_control_characters(method), fg=method_color, bold=True)
        if self.showhost:
            url = flow.request.pretty_url
        else:
            url = flow.request.url
        url = click.style(strutils.escape_control_characters(url), bold=True)

        httpversion = ""
        if flow.request.http_version not in ("HTTP/1.1", "HTTP/1.0"):
            httpversion = " " + flow.request.http_version  # We hide "normal" HTTP 1.

        line = "{stickycookie}{client} {method} {url}{httpversion}".format(
            stickycookie=stickycookie,
            client=client,
            method=method,
            url=url,
            httpversion=httpversion
        )
        self.echo(line)
Example #2
0
    def _echo_request_line(self, flow):
        if flow.request.stickycookie:
            stickycookie = click.style(
                "[stickycookie] ", fg="yellow", bold=True
            )
        else:
            stickycookie = ""

        if flow.client_conn:
            client = click.style(
                strutils.escape_control_characters(
                    repr(flow.client_conn.address)
                )
            )
        elif flow.request.is_replay:
            client = click.style("[replay]", fg="yellow", bold=True)
        else:
            client = ""

        method = flow.request.method
        method_color = dict(
            GET="green",
            DELETE="red"
        ).get(method.upper(), "magenta")
        method = click.style(
            strutils.escape_control_characters(method),
            fg=method_color,
            bold=True
        )
        if self.showhost:
            url = flow.request.pretty_url
        else:
            url = flow.request.url
        url = click.style(strutils.escape_control_characters(url), bold=True)

        http_version = ""
        if flow.request.http_version not in ("HTTP/1.1", "HTTP/1.0"):
            # We hide "normal" HTTP 1.
            http_version = " " + flow.request.http_version

        if self.flow_detail >= 2:
            linebreak = "\n    "
        else:
            linebreak = ""

        line = "{client}: {linebreak}{stickycookie}{method} {url}{http_version}".format(
            client=client,
            stickycookie=stickycookie,
            linebreak=linebreak,
            method=method,
            url=url,
            http_version=http_version
        )
        self.echo(line)
Example #3
0
    def _echo_response_line(self, flow):
        if flow.response.is_replay:
            replay = click.style("[replay] ", fg="yellow", bold=True)
        else:
            replay = ""

        code = flow.response.status_code
        code_color = None
        if 200 <= code < 300:
            code_color = "green"
        elif 300 <= code < 400:
            code_color = "magenta"
        elif 400 <= code < 600:
            code_color = "red"
        code = click.style(str(code), fg=code_color, bold=True, blink=(code == 418))
        reason = click.style(strutils.escape_control_characters(flow.response.reason), fg=code_color, bold=True)

        if flow.response.content is None:
            size = "(content missing)"
        else:
            size = human.pretty_size(len(flow.response.content))
        size = click.style(size, bold=True)

        arrows = click.style("<<", bold=True)

        line = "{replay} {arrows} {code} {reason} {size}".format(
            replay=replay,
            arrows=arrows,
            code=code,
            reason=reason,
            size=size
        )
        self.echo(line)
Example #4
0
 def dump(self, data, hexdump):
     if hexdump:
         for line in strutils.hexdump(data):
             self("\t%s %s %s" % line)
     else:
         data = data.decode("ascii", "replace").replace(u"\ufffd", u".")
         for i in strutils.escape_control_characters(data).split(u"\n"):
             self(u"\t%s" % i)
Example #5
0
 def dump(self, data, hexdump):
     if hexdump:
         for line in strutils.hexdump(data):
             self("\t%s %s %s" % line)
     else:
         data = strutils.native(
             strutils.escape_control_characters(
                 data.decode("ascii", "replace").replace(u"\ufffd", u".")))
         for i in data.split("\n"):
             self("\t%s" % i)
Example #6
0
def safe_to_print(lines, encoding="utf8"):
    """
    Wraps a content generator so that each text portion is a *safe to print* unicode string.
    """
    for line in lines:
        clean_line = []
        for (style, text) in line:
            if isinstance(text, bytes):
                text = text.decode(encoding, "replace")
            text = strutils.escape_control_characters(text)
            clean_line.append((style, text))
        yield clean_line
Example #7
0
def safe_to_print(lines, encoding="utf8"):
    """
    Wraps a content generator so that each text portion is a *safe to print* unicode string.
    """
    for line in lines:
        clean_line = []
        for (style, text) in line:
            if isinstance(text, bytes):
                text = text.decode(encoding, "replace")
            text = strutils.escape_control_characters(text)
            clean_line.append((style, text))
        yield clean_line
Example #8
0
    def echo_flow(self, f):
        if f.request:
            self._echo_request_line(f)
            self._echo_message(f.request)

        if f.response:
            self._echo_response_line(f)
            self._echo_message(f.response)

        if f.error:
            msg = strutils.escape_control_characters(f.error.msg)
            self.echo(" << {}".format(msg), bold=True, fg="red")
Example #9
0
    def echo_flow(self, f):
        if f.request:
            self._echo_request_line(f)
            self._echo_message(f.request)

        if f.response:
            self._echo_response_line(f)
            self._echo_message(f.response)

        if f.error:
            msg = strutils.escape_control_characters(f.error.msg)
            self.echo(" << {}".format(msg), bold=True, fg="red")
Example #10
0
def test_escape_control_characters():
    assert strutils.escape_control_characters(u"one") == u"one"
    assert strutils.escape_control_characters(u"\00ne") == u".ne"
    assert strutils.escape_control_characters(u"\nne") == u"\nne"
    assert strutils.escape_control_characters(u"\nne", False) == u".ne"
    assert strutils.escape_control_characters(u"\u2605") == u"\u2605"
    assert (
        strutils.escape_control_characters(bytes(bytearray(range(128))).decode()) ==
        u'.........\t\n..\r.................. !"#$%&\'()*+,-./0123456789:;<'
        u'=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.'
    )
    assert (
        strutils.escape_control_characters(bytes(bytearray(range(128))).decode(), False) ==
        u'................................ !"#$%&\'()*+,-./0123456789:;<'
        u'=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.'
    )

    if not six.PY2:
        with tutils.raises(ValueError):
            strutils.escape_control_characters(b"foo")
Example #11
0
    def http(self, r):
        """
            Performs a single request.

            r: A language.http.Request object, or a string representing one
            request.

            Returns Response if we have a non-ignored response.

            May raise a exceptions.NetlibException
        """
        logger = log.ConnectionLogger(
            self.fp,
            self.hexdump,
            False,
            self.rfile if self.showresp else None,
            self.wfile if self.showreq else None,
        )
        with logger.ctx() as lg:
            try:
                lg(">> %s" % r)
            except AttributeError as e:
                lg("error logging..")

            resp, req = None, None
            try:
                req = language.serve(r, self.wfile, self.settings)
                self.wfile.flush()

                resp = self.protocol.read_response(self.rfile, treq(method=req["method"].encode()))
                resp.sslinfo = self.sslinfo
            except exceptions.HttpException as v:
                lg("Invalid server response: %s" % v)
                raise
            except exceptions.TcpTimeout:
                if self.ignoretimeout:
                    lg("Timeout (ignored)")
                    return None
                lg("Timeout")
                raise
            finally:
                if resp:
                    lg("<< %s %s: %s bytes" % (
                        resp.status_code, strutils.escape_control_characters(resp.reason) if resp.reason else "", len(resp.content)
                    ))
                    if resp.status_code in self.ignorecodes:
                        lg.suppress()
            return resp
Example #12
0
def test_escape_control_characters():
    assert strutils.escape_control_characters(u"one") == u"one"
    assert strutils.escape_control_characters(u"\00ne") == u".ne"
    assert strutils.escape_control_characters(u"\nne") == u"\nne"
    assert strutils.escape_control_characters(u"\nne", False) == u".ne"
    assert strutils.escape_control_characters(u"\u2605") == u"\u2605"
    assert (
        strutils.escape_control_characters(
            bytes(bytearray(range(128))).decode()) ==
        u'.........\t\n..\r.................. !"#$%&\'()*+,-./0123456789:;<'
        u'=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.'
    )
    assert (
        strutils.escape_control_characters(
            bytes(bytearray(range(128))).decode(), False) ==
        u'................................ !"#$%&\'()*+,-./0123456789:;<'
        u'=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.'
    )

    with tutils.raises(ValueError):
        strutils.escape_control_characters(b"foo")
Example #13
0
    def _echo_response_line(self, flow):
        if flow.response.is_replay:
            replay = click.style("[replay] ", fg="yellow", bold=True)
        else:
            replay = ""

        code = flow.response.status_code
        code_color = None
        if 200 <= code < 300:
            code_color = "green"
        elif 300 <= code < 400:
            code_color = "magenta"
        elif 400 <= code < 600:
            code_color = "red"
        code = click.style(
            str(code),
            fg=code_color,
            bold=True,
            blink=(code == 418)
        )
        reason = click.style(
            strutils.escape_control_characters(flow.response.reason),
            fg=code_color,
            bold=True
        )

        if flow.response.raw_content is None:
            size = "(content missing)"
        else:
            size = human.pretty_size(len(flow.response.raw_content))
        size = click.style(size, bold=True)

        arrows = click.style(" <<", bold=True)
        if self.flow_detail == 1:
            # This aligns the HTTP response code with the HTTP request method:
            # 127.0.0.1:59519: GET http://example.com/
            #               << 304 Not Modified 0b
            arrows = " " * (len(repr(flow.client_conn.address)) - 2) + arrows

        line = "{replay}{arrows} {code} {reason} {size}".format(
            replay=replay,
            arrows=arrows,
            code=code,
            reason=reason,
            size=size
        )
        self.echo(line)
Example #14
0
    def _echo_response_line(self, flow):
        if flow.response.is_replay:
            replay = click.style("[replay] ", fg="yellow", bold=True)
        else:
            replay = ""

        code = flow.response.status_code
        code_color = None
        if 200 <= code < 300:
            code_color = "green"
        elif 300 <= code < 400:
            code_color = "magenta"
        elif 400 <= code < 600:
            code_color = "red"
        code = click.style(
            str(code),
            fg=code_color,
            bold=True,
            blink=(code == 418)
        )
        reason = click.style(
            strutils.escape_control_characters(flow.response.reason),
            fg=code_color,
            bold=True
        )

        if flow.response.raw_content is None:
            size = "(content missing)"
        else:
            size = human.pretty_size(len(flow.response.raw_content))
        size = click.style(size, bold=True)

        arrows = click.style(" <<", bold=True)
        if self.flow_detail == 1:
            # This aligns the HTTP response code with the HTTP request method:
            # 127.0.0.1:59519: GET http://example.com/
            #               << 304 Not Modified 0b
            arrows = " " * (len(repr(flow.client_conn.address)) - 2) + arrows

        line = "{replay}{arrows} {code} {reason} {size}".format(
            replay=replay,
            arrows=arrows,
            code=code,
            reason=reason,
            size=size
        )
        self.echo(line)
Example #15
0
    def http(self, r):
        """
            Performs a single request.

            r: A language.http.Request object, or a string representing one
            request.

            Returns Response if we have a non-ignored response.

            May raise a exceptions.NetlibException
        """
        logger = log.ConnectionLogger(
            self.fp,
            self.hexdump,
            False,
            self.rfile if self.showresp else None,
            self.wfile if self.showreq else None,
        )
        with logger.ctx() as lg:
            lg(">> %s" % r)
            resp, req = None, None
            try:
                req = language.serve(r, self.wfile, self.settings)
                self.wfile.flush()

                resp = self.protocol.read_response(
                    self.rfile, treq(method=req["method"].encode()))
                resp.sslinfo = self.sslinfo
            except exceptions.HttpException as v:
                lg("Invalid server response: %s" % v)
                raise
            except exceptions.TcpTimeout:
                if self.ignoretimeout:
                    lg("Timeout (ignored)")
                    return None
                lg("Timeout")
                raise
            finally:
                if resp:
                    lg("<< %s %s: %s bytes" %
                       (resp.status_code,
                        strutils.escape_control_characters(resp.reason)
                        if resp.reason else "", len(resp.content)))
                    if resp.status_code in self.ignorecodes:
                        lg.suppress()
            return resp