Example #1
0
def _preview(is_request):
    if is_request:
        template = "request_preview.html"
    else:
        template = "response_preview.html"

    spec = request.args["spec"]

    args = dict(
        spec = spec,
        section = "main",
        syntaxerror = None,
        error = None,
        pauses = None
    )
    if not spec.strip():
        args["error"] = "Can't parse an empty spec."
        return render(template, False, **args)

    try:
        if is_request:
            r = rparse.parse_request(app.config["pathod"].request_settings, spec)
        else:
            r = rparse.parse_response(app.config["pathod"].request_settings, spec)
    except rparse.ParseException, v:
        args["syntaxerror"] = str(v)
        args["marked"] = v.marked()
        return render(template, False, **args)
Example #2
0
File: app.py Project: emidln/pathod
def _preview(is_request):
    if is_request:
        template = "request_preview.html"
    else:
        template = "response_preview.html"

    spec = request.args["spec"]

    args = dict(
        spec = spec,
        section = "main",
        syntaxerror = None,
        error = None,
        pauses = None
    )
    if not spec.strip():
        args["error"] = "Can't parse an empty spec."
        return render(template, False, **args)

    try:
        if is_request:
            r = rparse.parse_request(app.config["pathod"].request_settings, spec)
        else:
            r = rparse.parse_response(app.config["pathod"].request_settings, spec)
    except rparse.ParseException, v:
        args["syntaxerror"] = str(v)
        args["marked"] = v.marked()
        return render(template, False, **args)
Example #3
0
    def __init__(self,
                 addr,
                 ssloptions=None,
                 craftanchor="/p/",
                 staticdir=None,
                 anchors=None,
                 sizelimit=None,
                 noweb=False,
                 nocraft=False,
                 noapi=False,
                 nohang=False,
                 timeout=None,
                 logreq=False,
                 logresp=False,
                 hexdump=False):
        """
            addr: (address, port) tuple. If port is 0, a free port will be
            automatically chosen.
            ssloptions: a dictionary containing certfile and keyfile specifications.
            craftanchor: string specifying the path under which to anchor response generation.
            staticdir: path to a directory of static resources, or None.
            anchors: A list of (regex, spec) tuples, or None.
            sizelimit: Limit size of served data.
            nocraft: Disable response crafting.
            noapi: Disable the API.
            nohang: Disable pauses.
        """
        tcp.TCPServer.__init__(self, addr)
        self.ssloptions = ssloptions
        self.staticdir = staticdir
        self.craftanchor = craftanchor
        self.sizelimit = sizelimit
        self.noweb, self.nocraft, self.noapi, self.nohang = noweb, nocraft, noapi, nohang
        self.timeout, self.logreq, self.logresp, self.hexdump = timeout, logreq, logresp, hexdump

        if not noapi:
            app.api()
        self.app = app.app
        self.app.config["pathod"] = self
        self.log = []
        self.logid = 0
        self.anchors = []
        if anchors:
            for i in anchors:
                try:
                    arex = re.compile(i[0])
                except re.error:
                    raise PathodError("Invalid regex in anchor: %s" % i[0])
                try:
                    aresp = rparse.parse_response(self.request_settings, i[1])
                except rparse.ParseException, v:
                    raise PathodError("Invalid page spec in anchor: '%s', %s" %
                                      (i[1], str(v)))
                self.anchors.append((arex, i[1]))
Example #4
0
    def __init__(   self,
                    addr, ssloptions=None, craftanchor="/p/", staticdir=None, anchors=None,
                    sizelimit=None, noweb=False, nocraft=False, noapi=False, nohang=False,
                    timeout=None, logreq=False, logresp=False, hexdump=False
                ):
        """
            addr: (address, port) tuple. If port is 0, a free port will be
            automatically chosen.
            ssloptions: a dictionary containing certfile and keyfile specifications.
            craftanchor: string specifying the path under which to anchor response generation.
            staticdir: path to a directory of static resources, or None.
            anchors: A list of (regex, spec) tuples, or None.
            sizelimit: Limit size of served data.
            nocraft: Disable response crafting.
            noapi: Disable the API.
            nohang: Disable pauses.
        """
        tcp.TCPServer.__init__(self, addr)
        self.ssloptions = ssloptions
        self.staticdir = staticdir
        self.craftanchor = craftanchor
        self.sizelimit = sizelimit
        self.noweb, self.nocraft, self.noapi, self.nohang = noweb, nocraft, noapi, nohang
        self.timeout, self.logreq, self.logresp, self.hexdump = timeout, logreq, logresp, hexdump

        if not noapi:
            app.api()
        self.app = app.app
        self.app.config["pathod"] = self
        self.log = []
        self.logid = 0
        self.anchors = []
        if anchors:
            for i in anchors:
                try:
                    arex = re.compile(i[0])
                except re.error:
                    raise PathodError("Invalid regex in anchor: %s"%i[0])
                try:
                    aresp = rparse.parse_response(self.request_settings, i[1])
                except rparse.ParseException, v:
                    raise PathodError("Invalid page spec in anchor: '%s', %s"%(i[1], str(v)))
                self.anchors.append((arex, i[1]))
Example #5
0
class PathodHandler(tcp.BaseHandler):
    wbufsize = 0
    sni = None

    def info(self, s):
        logger.info("%s:%s: %s" %
                    (self.client_address[0], self.client_address[1], str(s)))

    def handle_sni(self, connection):
        self.sni = connection.get_servername()

    def serve_crafted(self, crafted, request_log):
        response_log = crafted.serve(self.wfile, self.server.check_policy)
        log = dict(type="crafted", request=request_log, response=response_log)
        if response_log["disconnect"]:
            return False, log
        return True, log

    def handle_request(self):
        """
            Returns a (again, log) tuple. 

            again: True if request handling should continue.
            log: A dictionary, or None
        """
        line = self.rfile.readline()
        if line == "\r\n" or line == "\n":  # Possible leftover from previous message
            line = self.rfile.readline()
        if line == "":
            # Normal termination
            return False, None

        parts = http.parse_init_http(line)
        if not parts:
            s = "Invalid first line: %s" % repr(line)
            self.info(s)
            return False, dict(type="error", msg=s)

        method, path, httpversion = parts
        headers = http.read_headers(self.rfile)
        if headers is None:
            s = "Invalid headers"
            self.info(s)
            return False, dict(type="error", msg=s)

        request_log = dict(
            path=path,
            method=method,
            headers=headers.lst,
            httpversion=httpversion,
            sni=self.sni,
            remote_address=self.client_address,
        )

        try:
            content = http.read_http_body_request(self.rfile, self.wfile,
                                                  headers, httpversion, None)
        except http.HttpError, s:
            s = str(s)
            self.info(s)
            return False, dict(type="error", msg=s)

        for i in self.server.anchors:
            if i[0].match(path):
                self.info("crafting anchor: %s" % path)
                aresp = rparse.parse_response(self.server.request_settings,
                                              i[1])
                return self.serve_crafted(aresp, request_log)

        if not self.server.nocraft and path.startswith(
                self.server.craftanchor):
            spec = urllib.unquote(path)[len(self.server.craftanchor):]
            self.info("crafting spec: %s" % spec)
            try:
                crafted = rparse.parse_response(self.server.request_settings,
                                                spec)
            except rparse.ParseException, v:
                self.info("Parse error: %s" % v.msg)
                crafted = rparse.PathodErrorResponse(
                    "Parse Error",
                    "Error parsing response spec: %s\n" % v.msg + v.marked())
            except rparse.FileAccessDenied:
                self.info("File access denied")
                crafted = rparse.PathodErrorResponse("Access Denied")