Beispiel #1
0
    def __init__(self, req):
	self.req = req
	self.response_started = 0

	# reqpb
	self.reqpb = apache.make_table()
	self.reqpb["clf-request"] = self.req.the_request
	self.reqpb["method"] = self.req.method
	self.reqpb["protocol"] = self.req.subprocess_env["SERVER_PROTOCOL"]
	self.reqpb["uri"] = self.req.uri
	self.reqpb["query"] = self.req.subprocess_env["QUERY_STRING"]

	# headers
	self.headers = self.req.headers_in

	# srvhdrs
	self.srvhdrs = self.req.headers_out

        # vars
        self.vars = apache.make_table()
        pw = self.req.get_basic_auth_pw()
        if pw:
            self.vars["auth-password"] = pw
        if self.req.connection.ap_auth_type:
            self.vars["auth-type"] = self.req.connection.ap_auth_type
        if self.req.connection.user:
            self.vars["auth-user"] = self.req.connection.user
        if self.req.path_info:
            self.vars["path-info"] = self.req.path_info
        if self.req.subprocess_env.has_key("PATH_TRANSLATED"):
            self.vars["path-translated"] = self.req.subprocess_env["PATH_TRANSLATED"]
        if self.req.filename:
            self.vars["path"] = self.req.filename
Beispiel #2
0
def NSAPI_ParameterBlock(req):

    pb = apache.make_table()
    conf = req.get_config()
    opt = req.get_options()

    for k in conf.keys():
        pb[k] = conf[k]
    for k in opt.keys():
        pb[k] = opt[k]
    pb["fn"] = "python_request_handler"
    pb["method"] = "GET|HEAD|POST"
    pb["server-software"] = "Apache"
    pb["type"] = req.content_type
    pw = req.get_basic_auth_pw()
    pb["auth-password"] = pw
    pb["auth-type"] = req.connection.ap_auth_type
    pb["auth-user"] = req.connection.user

    return NSAPI_Pblock(pb)
Beispiel #3
0
    def __init__(self,
                 req,
                 keep_blank_values=0,
                 strict_parsing=0,
                 file_callback=None,
                 field_callback=None):
        #
        # Whenever readline is called ALWAYS use the max size EVEN when
        # not expecting a long line. - this helps protect against
        # malformed content from exhausting memory.
        #

        self.list = FieldList()

        # always process GET-style parameters
        if req.args:
            pairs = parse_qsl(req.args, keep_blank_values)
            for pair in pairs:
                self.add_field(pair[0], pair[1])

        if req.method != "POST":
            return

        try:
            clen = int(req.headers_in["content-length"])
        except (KeyError, ValueError):
            # absent content-length is not acceptable
            raise apache.SERVER_RETURN(apache.HTTP_LENGTH_REQUIRED)

        if "content-type" not in req.headers_in:
            ctype = b"application/x-www-form-urlencoded"
        else:
            ctype = req.headers_in["content-type"].encode("latin1")

        if not isinstance(ctype, bytes):
            raise TypeError("ctype must be of type bytes")

        if ctype.startswith(b"application/x-www-form-urlencoded"):
            v = req.read(clen)
            if not isinstance(v, bytes):
                raise TypeError("req.read() must return bytes")
            pairs = parse_qsl(v, keep_blank_values)
            for pair in pairs:
                self.add_field(pair[0], pair[1])
            return

        if not ctype.startswith(b"multipart/"):
            # we don't understand this content-type
            raise apache.SERVER_RETURN(apache.HTTP_NOT_IMPLEMENTED)

        # figure out boundary
        try:
            i = ctype.lower().rindex(b"boundary=")
            boundary = ctype[i + 9:]
            if len(boundary) >= 2 and boundary[:1] == boundary[-1:] == b'"':
                boundary = boundary[1:-1]
            boundary = re.compile(b"--" + re.escape(boundary) + b"(--)?\r?\n")

        except ValueError:
            raise apache.SERVER_RETURN(apache.HTTP_BAD_REQUEST)

        # read until boundary
        self.read_to_boundary(req, boundary, None)

        end_of_stream = False
        while not end_of_stream:
            ## parse headers

            ctype, type_options = b"text/plain", {}
            disp, disp_options = None, {}
            headers = apache.make_table()

            line = req.readline(readBlockSize)
            if not isinstance(line, bytes):
                raise TypeError("req.readline() must return bytes")
            match = boundary.match(line)
            if (not line) or match:
                # we stop if we reached the end of the stream or a stop
                # boundary (which means '--' after the boundary) we
                # continue to the next part if we reached a simple
                # boundary in either case this would mean the entity is
                # malformed, but we're tolerating it anyway.
                end_of_stream = (not line) or (match.group(1) is not None)
                continue

            skip_this_part = False
            while line not in (b'\r', b'\r\n'):
                nextline = req.readline(readBlockSize)
                while nextline and nextline[:1] in [b' ', b'\t']:
                    line = line + nextline
                    nextline = req.readline(readBlockSize)
                # we read the headers until we reach an empty line
                # NOTE : a single \n would mean the entity is malformed, but
                # we're tolerating it anyway
                h, v = line.split(b":", 1)
                headers.add(
                    h, v)  # mp_table accepts bytes, but always returns str
                h = h.lower()
                if h == b"content-disposition":
                    disp, disp_options = parse_header(v)
                elif h == b"content-type":
                    ctype, type_options = parse_header(v)
                    #
                    # NOTE: FIX up binary rubbish sent as content type
                    # from Microsoft IE 6.0 when sending a file which
                    # does not have a suffix.
                    #
                    if ctype.find(b'/') == -1:
                        ctype = b'application/octet-stream'

                line = nextline
                match = boundary.match(line)
                if (not line) or match:
                    # we stop if we reached the end of the stream or a
                    # stop boundary (which means '--' after the
                    # boundary) we continue to the next part if we
                    # reached a simple boundary in either case this
                    # would mean the entity is malformed, but we're
                    # tolerating it anyway.
                    skip_this_part = True
                    end_of_stream = (not line) or (match.group(1) is not None)
                    break

            if skip_this_part:
                continue

            if b"name" in disp_options:
                name = disp_options[b"name"]
            else:
                name = None

            # create a file object
            # is this a file?
            filename = None
            if b"filename" in disp_options:
                filename = disp_options[b"filename"]
                if file_callback and isinstance(file_callback,
                                                collections.Callable):
                    file = file_callback(filename)
                else:
                    file = tempfile.TemporaryFile("w+b")
            else:
                if field_callback and isinstance(field_callback,
                                                 collections.Callable):
                    file = field_callback()
                else:
                    file = BytesIO()

            # read it in
            self.read_to_boundary(req, boundary, file)
            file.seek(0)

            # make a Field
            if filename:
                field = Field(name)
                field.filename = filename
            else:
                field = StringField(file.read())
                field.name = name
            field.file = file
            field.type = PY2 and ctype or ctype.decode('latin1')
            field.type_options = type_options
            field.disposition = PY2 and disp or disp.decode('latin1')
            field.disposition_options = disp_options
            field.headers = headers
            self.list.append(field)
Beispiel #4
0
    def __init__(self, req, keep_blank_values=0, strict_parsing=0, file_callback=None, field_callback=None):
        #
        # Whenever readline is called ALWAYS use the max size EVEN when
        # not expecting a long line. - this helps protect against
        # malformed content from exhausting memory.
        #

        self.list = FieldList()

        # always process GET-style parameters
        if req.args:
            pairs = parse_qsl(req.args, keep_blank_values)
            for pair in pairs:
                self.add_field(pair[0], pair[1])

        if req.method != "POST":
            return

        try:
            clen = int(req.headers_in["content-length"])
        except (KeyError, ValueError):
            # absent content-length is not acceptable
            raise apache.SERVER_RETURN(apache.HTTP_LENGTH_REQUIRED)

        if "content-type" not in req.headers_in:
            ctype = b"application/x-www-form-urlencoded"
        else:
            ctype = req.headers_in["content-type"].encode("latin1")

        if not isinstance(ctype, bytes):
            raise TypeError("ctype must be of type bytes")

        if ctype.startswith(b"application/x-www-form-urlencoded"):
            v = req.read(clen)
            if not isinstance(v, bytes):
                raise TypeError("req.read() must return bytes")
            pairs = parse_qsl(v, keep_blank_values)
            for pair in pairs:
                self.add_field(pair[0], pair[1])
            return

        if not ctype.startswith(b"multipart/"):
            # we don't understand this content-type
            raise apache.SERVER_RETURN(apache.HTTP_NOT_IMPLEMENTED)

        # figure out boundary
        try:
            i = ctype.lower().rindex(b"boundary=")
            boundary = ctype[i+9:]
            if len(boundary) >= 2 and boundary[:1] == boundary[-1:] == b'"':
                boundary = boundary[1:-1]
            boundary = re.compile(b"--" + re.escape(boundary) + b"(--)?\r?\n")

        except ValueError:
            raise apache.SERVER_RETURN(apache.HTTP_BAD_REQUEST)

        # read until boundary
        self.read_to_boundary(req, boundary, None)

        end_of_stream = False
        while not end_of_stream:
            ## parse headers

            ctype, type_options = b"text/plain", {}
            disp, disp_options = None, {}
            headers = apache.make_table()

            line = req.readline(readBlockSize)
            if not isinstance(line, bytes):
                raise TypeError("req.readline() must return bytes")
            match = boundary.match(line)
            if (not line) or match:
                # we stop if we reached the end of the stream or a stop
                # boundary (which means '--' after the boundary) we
                # continue to the next part if we reached a simple
                # boundary in either case this would mean the entity is
                # malformed, but we're tolerating it anyway.
                end_of_stream = (not line) or (match.group(1) is not None)
                continue

            skip_this_part = False
            while line not in (b'\r',b'\r\n'):
                nextline = req.readline(readBlockSize)
                while nextline and nextline[:1] in [ b' ', b'\t']:
                    line = line + nextline
                    nextline = req.readline(readBlockSize)
                # we read the headers until we reach an empty line
                # NOTE : a single \n would mean the entity is malformed, but
                # we're tolerating it anyway
                h, v = line.split(b":", 1)
                headers.add(h, v)  # mp_table accepts bytes, but always returns str
                h = h.lower()
                if h == b"content-disposition":
                    disp, disp_options = parse_header(v)
                elif h == b"content-type":
                    ctype, type_options = parse_header(v)
                    #
                    # NOTE: FIX up binary rubbish sent as content type
                    # from Microsoft IE 6.0 when sending a file which
                    # does not have a suffix.
                    #
                    if ctype.find(b'/') == -1:
                        ctype = b'application/octet-stream'

                line = nextline
                match = boundary.match(line)
                if (not line) or match:
                    # we stop if we reached the end of the stream or a
                    # stop boundary (which means '--' after the
                    # boundary) we continue to the next part if we
                    # reached a simple boundary in either case this
                    # would mean the entity is malformed, but we're
                    # tolerating it anyway.
                    skip_this_part = True
                    end_of_stream = (not line) or (match.group(1) is not None)
                    break

            if skip_this_part:
                continue

            if b"name" in disp_options:
                name = disp_options[b"name"]
            else:
                name = None

            # create a file object
            # is this a file?
            filename = None
            if b"filename" in disp_options:
                filename = disp_options[b"filename"]
                if file_callback and isinstance(file_callback, collections.Callable):
                    file = file_callback(filename)
                else:
                    file = tempfile.TemporaryFile("w+b")
            else:
                if field_callback and isinstance(field_callback, collections.Callable):
                    file = field_callback()
                else:
                    file = BytesIO()

            # read it in
            self.read_to_boundary(req, boundary, file)
            file.seek(0)

            # make a Field
            if filename:
                field = Field(name)
                field.filename = filename
            else:
                field = StringField(file.read())
                field.name = name
            field.file = file
            field.type = PY2 and ctype or ctype.decode('latin1')
            field.type_options = type_options
            field.disposition = PY2 and disp or disp.decode('latin1')
            field.disposition_options = disp_options
            field.headers = headers
            self.list.append(field)
Beispiel #5
0
    def __init__(self, req, keep_blank_values=0, strict_parsing=0):

        self._req =_req = req._req

        self.list = []

        # always process GET-style parameters
        if _req.args:
            pairs = parse_qsl(req.args, keep_blank_values)
            for pair in pairs:
                file = StringIO.StringIO(pair[1])
                self.list.append(Field(pair[0], file, "text/plain", {},
                                       None, {}))

        if _req.method == "POST":

            try:
                clen = int(_req.headers_in["content-length"])
            except (KeyError, ValueError):
                # absent content-length is not acceptable
                raise apache.SERVER_RETURN, apache.HTTP_LENGTH_REQUIRED

            if not _req.headers_in.has_key("content-type"):
                ctype = "application/x-www-form-urlencoded"
            else:
                ctype = _req.headers_in["content-type"]

            if ctype == "application/x-www-form-urlencoded":
                
                pairs = parse_qsl(req.read(clen), keep_blank_values)
                for pair in pairs:
                    file = StringIO.StringIO(pair[1])
                    self.list.append(Field(pair[0], file, "text/plain",
                                     {}, None, {}))

            elif ctype[:10] == "multipart/":

                # figure out boundary
                # XXX what about req.boundary?
                try:
                    i = string.rindex(string.lower(ctype), "boundary=")
                    boundary = ctype[i+9:]
                    if len(boundary) >= 2 and boundary[0] == boundary[-1] == '"':
                        boundary = boundary[1:-1]
                    boundary = "--" + boundary
                except ValueError:
                    raise apache.SERVER_RETURN, apache.HTTP_BAD_REQUEST

                #read until boundary
                line = _req.readline()
                sline = string.strip(line)
                while line and sline != boundary:
                    line = _req.readline()

                while 1:

                    ## parse headers
                    
                    ctype, type_options = "text/plain", {}
                    disp, disp_options = None, {}
                    headers = apache.make_table()
                    line = _req.readline()
                    while line and line not in ["\n", "\r\n"]:
                        h, v = string.split(line, ":", 1)
                        headers.add(h, v)
                        h = string.lower(h)
                        if h == "content-disposition":
                            disp, disp_options = parse_header(v)
                        elif h == "content-type":
                            ctype, type_options = parse_header(v)
                        line = _req.readline()

                    if disp_options.has_key("name"):
                        name = disp_options["name"]
                    else:
                        name = None

                    # is this a file?
                    if disp_options.has_key("filename"):
                        file = self.make_file()
                    else:
                        file = StringIO.StringIO()

                    # read it in
                    self.read_to_boundary(_req, boundary, file)
                    file.seek(0)

                    # make a Field
                    field = Field(name, file, ctype, type_options,
                                  disp, disp_options)
                    field.headers = headers
                    if disp_options.has_key("filename"):
                        field.filename = disp_options["filename"]

                    self.list.append(field)

                    if not line or sline == (boundary + "--"):
                        break

            else:
                # we don't understand this content-type
                raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED
Beispiel #6
0
 def client(self):
     client = apache.make_table()
     client["ip"] = self.req.connection.remote_ip
     client["dns"] = self.req.connection.remote_host
     return client