예제 #1
0
def cors_request(req):
    if req.uri.startswith("/p/"):
        return  # enndpoints for printers does not need CORS
    if req.method_number == state.METHOD_OPTIONS:
        res = Response(content_type="text/plain; charset=UTF-8",
                       headers=options_headers,
                       status_code=state.HTTP_NO_CONTENT)
        raise HTTPException(res)
예제 #2
0
def html_form(req, file_callback):
    """Generate upload page for specified callback."""
    stats = ""
    hexdigest = ""
    if req.method == 'POST':
        start = time()
        bytes_read = 0
        hexdigest = ''
        # pylint: disable=comparison-with-callable
        if file_callback == no_factory:
            to_download = min(req.content_length, 65365)
            data = req.read(to_download)
            while data:
                bytes_read += len(data)
                to_download = min(req.content_length - bytes_read, 65365)
                data = req.read(to_download)
        else:
            form = FieldStorage(req,
                                keep_blank_values=app.keep_blank_values,
                                strict_parsing=app.strict_parsing,
                                file_callback=file_callback(req))
            bytes_read = form.bytes_read
            hexdigest = form['file'].file.hexdigest()

        end = time() - start
        args = (hbytes(bytes_read) + (int(end), ) + hbytes(bytes_read / end) +
                (hexdigest, ))
        stats = ("Upload: %.2f%s in %ds -> %.2f%sps SHA256: %s" % args)
        log.info(stats)

        if bytes_read != req.content_length:
            log.error("File uploading not complete")
            raise HTTPException(400, error="File uploading not complete")

    return """
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
        <title>Upload form for %s</title>
        <style>
          body {width:90%%; max-width:900px; margin:auto; padding-top:30px;}
          h1 {text-align: center; color: #707070;}
        </style>
      </head>
      <body>
        <a href="/">/</a>
        <h1>Upload form for %s</h1>
        <form method="post" enctype="multipart/form-data">
          <input type="file" name="file"/>
          <input type="submit" value="Send"/>
        </form>
        <pre>%s</pre>
        <hr>
        <small>Copyright (c) 2021 Ondřej Tůma. See
          <a href="http://poorhttp.zeropage.cz">poorhttp.zeropage.cz</a>
        </small>
      </body>
    </html>""" % (file_callback.__name__, file_callback.__name__, stats)
예제 #3
0
파일: wsgi.py 프로젝트: PoorHttp/PoorWSGI
    def handler_from_default(self, req: SimpleRequest):
        """Internal method, which is called if no handler is found."""
        req.uri_rule = '/*'
        if req.method_number in self.__dhandlers:
            req.uri_handler = self.__dhandlers[req.method_number]
            self.handler_from_before(req)  # call before handlers now
            return self.__dhandlers[req.method_number](req)

        self.handler_from_before(req)  # call before handlers now
        log.error("404 Not Found: %s %s", req.method, req.path)
        raise HTTPException(HTTP_NOT_FOUND)
예제 #4
0
def blackhole_factory(req):
    """Factory for craeting Dummy file instance"""
    if req.content_length <= 0:
        raise HTTPException(400, error="Missing content length or no content")

    def create(filename):
        """Create Blackhole File object"""
        log.debug(create.__doc__)
        return Blackhole(filename)

    return create
예제 #5
0
파일: simple.py 프로젝트: PoorHttp/PoorWSGI
def input_stream(req):
    """Stream request handler"""
    i = 0

    # chunk must be read with extra method, uwsgi has own
    chunk = uwsgi.chunked_read() if uwsgi else req.read_chunk()
    while chunk:
        log.info("chunk: %s", chunk)
        if chunk != b'%d' % i:
            raise HTTPException(state.HTTP_BAD_REQUEST)

        chunk = uwsgi.chunked_read() if uwsgi else req.read_chunk()
        i += 1
    return EmptyResponse(state.HTTP_OK)
예제 #6
0
        def handler(req):
            if 'Authorization' not in req.headers:
                log.info('Digest: Authorization header not found')
                raise HTTPException(state.HTTP_UNAUTHORIZED, realm=realm)

            if req.authorization['type'] != 'Digest':
                log.error('Digest: Bad Authorization type')
                raise HTTPException(state.HTTP_UNAUTHORIZED, realm=realm)

            if not check_token(req.authorization.get('nonce'),
                               req.secret_key,
                               req.user_agent,
                               timeout=req.app.auth_timeout):
                log.info("Digest: nonce value not match")
                raise HTTPException(state.HTTP_UNAUTHORIZED,
                                    realm=realm,
                                    stale=True)

            if not check_credentials(req, realm, username):
                raise HTTPException(state.HTTP_UNAUTHORIZED, realm=realm)

            req.user = req.authorization['username']
            return fun(req)
예제 #7
0
def parse_json_request(raw: bytes, charset: str = "utf-8"):
    """Try to parse request data.

    Returned type could be:

    * JsonDict when dictionary is parsed.
    * JsonList when list is parsed.
    * Other based types from json.loads function like str, int, float, bool
      or None.
    * None when parsing of JSON fails. That is logged with WARNING log level.
    """
    # pylint: disable=inconsistent-return-statements
    try:
        data = json_loads(raw.decode(charset))
        if isinstance(data, dict):
            return JsonDict(data.items())
        if isinstance(data, list):
            return JsonList(data)
        return data
    except BaseException as err:  # pylint: disable=broad-except
        log.error("Invalid request json: %s", str(err))
        raise HTTPException(HTTP_BAD_REQUEST, error=err) from err
예제 #8
0
파일: wsgi.py 프로젝트: PoorHttp/PoorWSGI
    def handler_from_table(self, req: Request):
        """Call right handler from handlers table (fill with route function).

        If no handler is fined, try to find directory or file if Document Root,
        resp. Document Index is set. Then try to call default handler for right
        method or call handler for status code 404 - not found.
        """
        # pylint: disable=too-many-return-statements
        # static routes

        if req.path in self.__handlers:
            if req.method_number in self.__handlers[req.path]:
                handler = self.__handlers[req.path][req.method_number]
                req.uri_rule = req.path  # nice variable for before handlers
                req.uri_handler = handler
                self.handler_from_before(req)  # call before handlers now
                return handler(req)  # call right handler now

            self.handler_from_before(req)  # call before handlers now
            raise HTTPException(HTTP_METHOD_NOT_ALLOWED)

        # regular expression
        for ruri in self.__rhandlers:
            match = ruri.match(req.path)
            if match and req.method_number in self.__rhandlers[ruri]:
                handler, converters, rule = \
                    self.__rhandlers[ruri][req.method_number]
                req.uri_rule = rule or ruri.pattern
                req.uri_handler = handler
                if converters:
                    # create OrderedDict from match inside of dict for
                    # converters applying
                    req.path_args = OrderedDict(
                        (g, c(v))
                        for ((g, c), v) in zip(converters, match.groups()))
                    self.handler_from_before(req)  # call before handlers now
                    return handler(req, *req.path_args.values())

                req.path_args = match.groupdict()
                self.handler_from_before(req)  # call before handlers now
                return handler(req, *match.groups())

        # try file or index
        if req.document_root and \
                req.method_number & (METHOD_HEAD | METHOD_GET):
            rfile = "%s%s" % (req.document_root, path.normpath(
                "%s" % req.path))

            if not path.exists(rfile):
                if req.debug and req.path == '/debug-info':  # work if debug
                    req.uri_rule = '/debug-info'
                    req.uri_handler = debug_info
                    self.handler_from_before(req)  # call before handlers now
                    return debug_info(req, self)
                return self.handler_from_default(req)  # try default

            # return file
            if path.isfile(rfile) and access(rfile, R_OK):
                req.uri_rule = '/*'
                self.handler_from_before(req)  # call before handlers now
                log.info("Return file: %s", req.path)
                return FileResponse(rfile)

            # return directory index
            if req.document_index and path.isdir(rfile) \
                    and access(rfile, R_OK):
                log.info("Return directory: %s", req.path)
                req.uri_rule = '/*'
                req.uri_handler = directory_index
                self.handler_from_before(req)  # call before handlers now
                return directory_index(req, rfile)
            self.handler_from_before(req)  # call before handlers now
            raise HTTPException(HTTP_FORBIDDEN)
        # req.document_root

        if req.debug and req.path == '/debug-info':
            req.uri_rule = '/debug-info'
            req.uri_handler = debug_info
            self.handler_from_before(req)  # call before handlers now
            return debug_info(req, self)

        return self.handler_from_default(req)
예제 #9
0
def directory_index(req, path):
    """Returns directory index as html page."""
    if not isdir(path):
        log.error(
            "Only directory_index can be send with directory_index handler. "
            "`%s' is not directory.", path)
        raise HTTPException(HTTP_INTERNAL_SERVER_ERROR)

    index = os.listdir(path)
    if req.document_root != path[:-1]:
        index.append("..")  # parent directory

    index.sort()

    diruri = req.uri.rstrip('/')
    content = ("<!DOCTYPE html>\n"
               "<html>\n"
               " <head>\n"
               "  <title>Index of %s</title>\n"
               '  <meta http-equiv="content-type" '
               'content="text/html; charset=utf-8"/>\n'
               "  <style>\n"
               "   body { width: 98%%; margin: auto; }\n"
               "   table { font: 90%% monospace; text-align: left; }\n"
               "   td, th { padding: 0 1em 0 1em; }\n"
               "   .size { text-align:right; white-space:pre; }\n"
               "  </style>\n"
               " </head>\n"
               " <body>\n"
               "  <h1>Index of %s</h1>\n"
               "  <hr>\n"
               "  <table>\n"
               "   <tr><th>Name</th><th>Last Modified</th>"
               "<th class=\"size\">Size</th><th>Type</th></tr>\n" %
               (diruri, diruri))

    for item in index:
        # dot files
        if item[0] == "." and item[1] != ".":
            continue
        # bakup files (~)
        if item[-1] == "~":
            continue

        fpath = "%s/%s" % (path, item)
        if not os.access(fpath, os.R_OK):
            continue

        fname = item + ('/' if isdir(fpath) else '')
        ftype = ""

        if isfile(fpath):
            # pylint: disable=unused-variable
            (ftype, encoding) = mimetypes.guess_type(fpath)
            if not ftype:
                ftype = 'application/octet-stream'
            size = "%.1f%s" % hbytes(getsize(fpath))
        elif isdir(fpath):
            ftype = "Directory"
            size = "-"
        else:
            size = ftype = '-'

        content += (
            "   <tr><td><a href=\"%s\">%s</a></td><td>%s</td>"
            "<td class=\"size\">%s</td><td>%s</td></tr>\n" %
            (diruri + '/' + fname, fname,
             strftime("%d-%b-%Y %H:%M", gmtime(getctime(fpath))), size, ftype))

    content += ("  </table>\n" "  <hr>\n")

    if req.debug:
        content += ("  <small><i>%s / Poor WSGI for Python, "
                    "webmaster: %s </i></small>\n" %
                    (req.server_software, req.server_admin))
    else:
        content += ("  <small><i>webmaster: %s </i></small>\n" %
                    req.server_admin)

    content += ("  </body>\n" "</html>")

    return content
예제 #10
0
파일: simple.py 프로젝트: PoorHttp/PoorWSGI
def not_implemented(req):
    raise HTTPException(state.HTTP_NOT_IMPLEMENTED)
예제 #11
0
파일: simple.py 프로젝트: PoorHttp/PoorWSGI
def forbidden(req):
    raise HTTPException(state.HTTP_FORBIDDEN)
예제 #12
0
파일: simple.py 프로젝트: PoorHttp/PoorWSGI
def value_error_handler(req, error):
    """ValueError exception handler example."""
    assert req
    print("ValueError: ", error)
    raise HTTPException(state.HTTP_BAD_REQUEST)
예제 #13
0
def check_api_key(req):
    api_token = req.headers.get("API-Key", None)
    if api_token != XXX:
        raise HTTPException(401)
    return "api-key ok"
예제 #14
0
def check_login(req):
    cookie = PoorSession(req)
    if 'login' not in cookie.data:
        raise HTTPException(401)
    return "login ok"