コード例 #1
0
 def _get_environ(self, request, body, content_length):
     # Resolve the path info.
     path_info = request.match_info["path_info"]
     script_name = request.rel_url.path[:len(request.rel_url.path) -
                                        len(path_info)]
     # Special case: If the app was mounted on the root, then the script name will
     # currently be set to "/", which is illegal in the WSGI spec. The script name
     # could also end with a slash if the WSGIHandler was mounted as a route
     # manually with a trailing slash before the path_info. In either case, we
     # correct this according to the WSGI spec by transferring the trailing slash
     # from script_name to the start of path_info.
     if script_name.endswith("/"):
         script_name = script_name[:-1]
         path_info = "/" + path_info
     # Parse the connection info.
     server_name, server_port = parse_sockname(
         request.transport.get_extra_info("sockname"))
     remote_addr, remote_port = parse_sockname(
         request.transport.get_extra_info("peername"))
     # Detect the URL scheme.
     url_scheme = self._url_scheme
     if url_scheme is None:
         url_scheme = "http" if request.transport.get_extra_info(
             "sslcontext") is None else "https"
     # Create the environ.
     environ = {
         "REQUEST_METHOD": request.method,
         "SCRIPT_NAME": script_name,
         "PATH_INFO": path_info,
         "QUERY_STRING": request.rel_url.query_string,
         "CONTENT_TYPE": request.headers.get("Content-Type", ""),
         "CONTENT_LENGTH": str(content_length),
         "SERVER_NAME": server_name,
         "SERVER_PORT": server_port,
         "REMOTE_ADDR": remote_addr,
         "REMOTE_HOST": remote_addr,
         "REMOTE_PORT": remote_port,
         "SERVER_PROTOCOL": "HTTP/{}.{}".format(*request.version),
         "wsgi.version": (1, 0),
         "wsgi.url_scheme": url_scheme,
         "wsgi.input": body,
         "wsgi.errors": self._stderr,
         "wsgi.multithread": True,
         "wsgi.multiprocess": False,
         "wsgi.run_once": False,
         "asyncio.loop": self._loop,
         "asyncio.executor": self._executor,
         "aiohttp.request": request,
     }
     # Add in additional HTTP headers.
     for header_name in request.headers:
         header_name = header_name.upper()
         if not (is_hop_by_hop(header_name)) and header_name not in (
                 "CONTENT-LENGTH", "CONTENT-TYPE"):
             header_value = ",".join(request.headers.getall(header_name))
             environ["HTTP_" + header_name.replace("-", "_")] = header_value
     # All done!
     return environ
コード例 #2
0
ファイル: wsgi.py プロジェクト: andrefsp/aiohttp-wsgi
 def _get_environ(self, request):
     # Resolve the path info.
     path_info = request.match_info["path_info"]
     script_name = request.path[:len(request.path)-len(path_info)]
     # Special case: If the app was mounted on the root, then the script name will
     # currently be set to "/", which is illegal in the WSGI spec. The script name
     # could also end with a slash if the WSGIHandler was mounted as a route
     # manually with a trailing slash before the path_info. In either case, we
     # correct this according to the WSGI spec by transferring the trailing slash
     # from script_name to the start of path_info.
     if script_name.endswith("/"):
         script_name = script_name[:-1]
         path_info = "/" + path_info
     # Read the body.
     body = (yield from request.read())
     # Parse the connection info.
     server_name, server_port = parse_sockname(request.transport.get_extra_info("sockname"))
     remote_addr, remote_port = parse_sockname(request.transport.get_extra_info("peername"))
     # Detect the URL scheme.
     url_scheme = self._url_scheme
     if url_scheme is None:
         url_scheme = "http" if request.transport.get_extra_info("sslcontext") is None else "https"
     # Create the environ.
     environ = {
         "REQUEST_METHOD": request.method,
         "SCRIPT_NAME": quote(script_name),  # WSGI spec expects URL-quoted path components.
         "PATH_INFO": quote(path_info),  # WSGI spec expects URL-quoted path components.
         "QUERY_STRING": request.query_string,
         "CONTENT_TYPE": request.headers.get("Content-Type", ""),
         "CONTENT_LENGTH": str(len(body)),
         "SERVER_NAME": server_name,
         "SERVER_PORT": server_port,
         "REMOTE_ADDR": remote_addr,
         "REMOTE_HOST": remote_addr,
         "REMOTE_PORT": remote_port,
         "SERVER_PROTOCOL": "HTTP/{}.{}".format(*request.version),
         "wsgi.version": (1, 0),
         "wsgi.url_scheme": url_scheme,
         "wsgi.input": io.BytesIO(body),
         "wsgi.errors": self._stderr,
         "wsgi.multithread": True,
         "wsgi.multiprocess": False,
         "wsgi.run_once": False,
     }
     # Add in additional HTTP headers.
     for header_name in request.headers:
         header_name = header_name.upper()
         if not(is_hop_by_hop(header_name)) and not header_name in ("CONTENT-LENGTH", "CONTENT-TYPE"):
             header_value = ",".join(request.headers.getall(header_name))
             environ["HTTP_" + header_name.replace("-", "_")] = header_value
     # All done!
     return environ
コード例 #3
0
ファイル: wsgi.py プロジェクト: jnurmine/aiohttp-wsgi
 def _get_environ(self, request):
     # Resolve the path info.
     path_info = request.path
     if path_info.startswith(self._script_name):
         path_info = path_info[len(self._script_name):]
     # Read the body.
     body = (yield from request.read())
     # Parse the connection info.
     server_name, server_port = parse_sockname(
         request.transport.get_extra_info("sockname"))
     remote_addr, remote_port = parse_sockname(
         request.transport.get_extra_info("peername"))
     # Detect the URL scheme.
     url_scheme = self._url_scheme
     if url_scheme is None:
         url_scheme = "http" if request.transport.get_extra_info(
             "sslcontext") is None else "https"
     # Create the environ.
     environ = {
         "REQUEST_METHOD": request.method,
         "SCRIPT_NAME": self._script_name,
         "PATH_INFO": path_info,
         "QUERY_STRING": request.query_string,
         "CONTENT_TYPE": request.headers.get("Content-Type", ""),
         "CONTENT_LENGTH": str(len(body)),
         "SERVER_NAME": server_name,
         "SERVER_PORT": server_port,
         "REMOTE_ADDR": remote_addr,
         "REMOTE_HOST": remote_addr,
         "REMOTE_PORT": remote_port,
         "SERVER_PROTOCOL": "HTTP/{}.{}".format(*request.version),
         "wsgi.version": (1, 0),
         "wsgi.url_scheme": url_scheme,
         "wsgi.input": io.BytesIO(body),
         "wsgi.errors": self._stderr,
         "wsgi.multithread": True,
         "wsgi.multiprocess": False,
         "wsgi.run_once": False,
     }
     # Add in additional HTTP headers.
     for header_name in request.headers:
         header_name = header_name.upper()
         if not (is_hop_by_hop(header_name)) and not header_name in (
                 "CONTENT-LENGTH", "CONTENT-TYPE"):
             header_value = ",".join(request.headers.getall(header_name))
             environ["HTTP_" + header_name.replace("-", "_")] = header_value
     # All done!
     return environ
コード例 #4
0
def start_server(
        application,
        loop,
        executor,
        *,
        # Server config.
        host=None,
        port=8080,
        # Unix server config.
        unix_socket=None,
        unix_socket_perms=0o600,
        # Shared server config.
        backlog=1024,
        # aiohttp config.
        static=(),
        # Aiohttp config.
        script_name="",
        **kwargs):
    app = Application()
    # Add static routes.
    for static_item in static:
        assert "=" in static_item, "{!r} should have format 'path=directory'"
        static_item = static_item.split("=", 1)
        path, dirname = static_item
        app.router.add_static(format_path(path), dirname)
    # Add the wsgi application. This has to be last.
    app.router.add_route(
        "*",
        "{}{{path_info:.*}}".format(format_path(script_name)),
        WSGIHandler(application, loop=loop, executor=executor,
                    **kwargs).handle_request,
    )
    # HACK: Access logging is broken in aiohtp for unix sockets.
    handler = app.make_handler(
        access_log=access_logger if unix_socket is None else None)
    # Set up the server.
    shared_server_kwargs = {
        "backlog": backlog,
    }
    if unix_socket is not None:
        server = yield from loop.create_unix_server(handler,
                                                    path=unix_socket,
                                                    **shared_server_kwargs)
    else:
        server = yield from loop.create_server(handler,
                                               host=host,
                                               port=port,
                                               **shared_server_kwargs)
    # Set socket permissions.
    if unix_socket is not None:
        os.chmod(unix_socket, unix_socket_perms)
    # Report.
    server_uri = " ".join(
        "http://{}:{}".format(*parse_sockname(socket.getsockname()))
        for socket in server.sockets)
    logger.info("Serving on %s", server_uri)
    # All done!
    return app, handler, server, server_uri
コード例 #5
0
ファイル: wsgi.py プロジェクト: gogobook/aiohttp-wsgi
 def _get_environ(self, request):
     # Resolve the path info.
     path_info = request.match_info["path_info"]
     script_name = request.path[:len(request.path)-len(path_info)]
     # Read the body.
     body = (yield from request.read())
     # Parse the connection info.
     server_name, server_port = parse_sockname(request.transport.get_extra_info("sockname"))
     remote_addr, remote_port = parse_sockname(request.transport.get_extra_info("peername"))
     # Detect the URL scheme.
     url_scheme = self._url_scheme
     if url_scheme is None:
         url_scheme = "http" if request.transport.get_extra_info("sslcontext") is None else "https"
     # Create the environ.
     environ = {
         "REQUEST_METHOD": request.method,
         "SCRIPT_NAME": script_name,
         "PATH_INFO": path_info,
         "QUERY_STRING": request.query_string,
         "CONTENT_TYPE": request.headers.get("Content-Type", ""),
         "CONTENT_LENGTH": str(len(body)),
         "SERVER_NAME": server_name,
         "SERVER_PORT": server_port,
         "REMOTE_ADDR": remote_addr,
         "REMOTE_HOST": remote_addr,
         "REMOTE_PORT": remote_port,
         "SERVER_PROTOCOL": "HTTP/{}.{}".format(*request.version),
         "wsgi.version": (1, 0),
         "wsgi.url_scheme": url_scheme,
         "wsgi.input": io.BytesIO(body),
         "wsgi.errors": self._stderr,
         "wsgi.multithread": True,
         "wsgi.multiprocess": False,
         "wsgi.run_once": False,
     }
     # Add in additional HTTP headers.
     for header_name in request.headers:
         header_name = header_name.upper()
         if not(is_hop_by_hop(header_name)) and not header_name in ("CONTENT-LENGTH", "CONTENT-TYPE"):
             header_value = ",".join(request.headers.getall(header_name))
             environ["HTTP_" + header_name.replace("-", "_")] = header_value
     # All done!
     return environ
コード例 #6
0
def configure_server(
        application,
        *,

        # Server config.
        host="0.0.0.0",
        port=8080,

        # Unix server config.
        unix_socket=None,
        unix_socket_perms=0o600,

        # aiohttp config.
        static=(),

        # Asyncio config.
        loop=None,

        # Handler config.
        **kwargs):
    loop = loop or asyncio.get_event_loop()
    # Create the WSGI handler.
    wsgi_middleware = middleware.wsgi(application, loop=loop, **kwargs)
    # Wrap the application in an executor.
    app = Application(
        loop=loop,
        middlewares=[wsgi_middleware],
    )
    # Add static routes.
    if isinstance(static, Mapping):
        static = static.items()
    for path, dirname in static:
        app.router.add_static(path, dirname)
    # Set up the server.
    if unix_socket is not None:
        server_future = loop.create_unix_server(
            app.make_handler(),
            path=unix_socket,
        )
    else:
        server_future = loop.create_server(
            app.make_handler(),
            host=host,
            port=port,
        )
    server = loop.run_until_complete(server_future)
    app.logger.info("Serving on http://%s:%s",
                    *parse_sockname(server.sockets[0].getsockname()))
    # Set socket permissions.
    if unix_socket is not None:
        os.chmod(unix_socket, unix_socket_perms)
    # All done!
    return server, app
コード例 #7
0
ファイル: base.py プロジェクト: fscherf/aiohttp-wsgi
 def _serve(self, *args):
     with serve("-q", *args) as (loop, server):
         host, port = parse_sockname(server.sockets[0].getsockname())
         if host == "unix":
             connector = aiohttp.UnixConnector(path=port, loop=loop)
         else:
             connector = aiohttp.TCPConnector(loop=loop)
         session = loop.run_until_complete(create_client_session(connector=connector, loop=loop))
         try:
             yield TestClient(self, loop, host, port, session)
         finally:
             loop.run_until_complete(session.close())
             connector.close()
コード例 #8
0
ファイル: base.py プロジェクト: yaoshiyan/aiohttp-wsgi
 def _run_server(self, *args, **kwargs):
     with run_server(*args, **kwargs) as (loop, site):
         host, port = parse_sockname(site._server.sockets[0].getsockname())
         if host == "unix":
             connector = aiohttp.UnixConnector(path=port, loop=loop)
         else:
             connector = aiohttp.TCPConnector(loop=loop)
         session = aiohttp.ClientSession(connector=connector, loop=loop)
         try:
             yield TestClient(self, loop, host, port, session)
         finally:
             loop.run_until_complete(session.close())
             connector.close()
コード例 #9
0
def close_server(app, handler, server, server_uri, *, shutdown_timeout=60.0):
    # Clean up unix sockets.
    for socket in server.sockets:
        host, port = parse_sockname(socket.getsockname())
        if host == "unix":
            os.unlink(port)
    # Close the server.
    logger.debug("Shutting down server on %s", server_uri)
    server.close()
    yield from server.wait_closed()
    # Shut down app.
    logger.debug("Shutting down app on %s", server_uri)
    yield from app.shutdown()
    yield from handler.shutdown(shutdown_timeout)
    yield from app.cleanup()
コード例 #10
0
def run_server(
        application,
        *,
        # asyncio config.
        threads=4,
        # Server config.
        host=None,
        port=8080,
        # Unix server config.
        unix_socket=None,
        unix_socket_perms=0o600,
        # Shared server config.
        backlog=1024,
        # aiohttp config.
        static=(),
        static_cors=None,
        script_name="",
        shutdown_timeout=60.0,
        **kwargs):
    # Set up async context.
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    assert threads >= 1, "threads should be >= 1"
    executor = ThreadPoolExecutor(threads)
    # Create aiohttp app.
    app = Application()
    # Add static routes.
    static = [(format_path(path), dirname) for path, dirname in static]
    for path, dirname in static:
        app.router.add_static(path, dirname)
    # Add the wsgi application. This has to be last.
    app.router.add_route(
        "*",
        "{}{{path_info:.*}}".format(format_path(script_name)),
        WSGIHandler(application, loop=loop, executor=executor,
                    **kwargs).handle_request,
    )
    # Configure middleware.
    if static_cors:
        app.middlewares.append(
            static_cors_middleware(
                static=static,
                static_cors=static_cors,
            ))
    # Start the app runner.
    runner = AppRunner(app)
    loop.run_until_complete(runner.setup())
    # Set up the server.
    if unix_socket is not None:
        site = UnixSite(runner,
                        path=unix_socket,
                        backlog=backlog,
                        shutdown_timeout=shutdown_timeout)
    else:
        site = TCPSite(runner,
                       host=host,
                       port=port,
                       backlog=backlog,
                       shutdown_timeout=shutdown_timeout)
    loop.run_until_complete(site.start())
    # Set socket permissions.
    if unix_socket is not None:
        os.chmod(unix_socket, unix_socket_perms)
    # Report.
    server_uri = " ".join(
        "http://{}:{}".format(*parse_sockname(socket.getsockname()))
        for socket in site._server.sockets)
    logger.info("Serving on %s", server_uri)
    try:
        yield loop, site
    finally:
        # Clean up unix sockets.
        for socket in site._server.sockets:
            host, port = parse_sockname(socket.getsockname())
            if host == "unix":
                os.unlink(port)
        # Close the server.
        logger.debug("Shutting down server on %s", server_uri)
        loop.run_until_complete(site.stop())
        # Shut down app.
        logger.debug("Shutting down app on %s", server_uri)
        loop.run_until_complete(runner.cleanup())
        # Shut down executor.
        logger.debug("Shutting down executor on %s", server_uri)
        executor.shutdown()
        # Shut down loop.
        logger.debug("Shutting down loop on %s", server_uri)
        loop.close()
        asyncio.set_event_loop(None)
        # All done!
        logger.info("Stopped serving on %s", server_uri)
コード例 #11
0
ファイル: api.py プロジェクト: gogobook/aiohttp-wsgi
def configure_server(application, *,

    # Server config.
    host = "0.0.0.0",
    port = 8080,

    # Unix server config.
    unix_socket = None,
    unix_socket_perms = 0o600,

    # Prexisting socket config.
    socket = None,

    # Shared server config.
    backlog = 1024,

    # aiohttp config.
    routes = (),
    static = (),
    on_finish = (),

    # Asyncio config.
    loop = None,

    # Handler config.
    script_name = "",
    **kwargs

):
    loop = loop or asyncio.get_event_loop()
    app = Application(
        loop = loop,
    )
    # Add routes.
    for method, path, handler in routes:
        app.router.add_route(method, path, handler)
    # Add static routes.
    if isinstance(static, Mapping):
        static = static.items()
    for path, dirname in static:
        app.router.add_static(path, dirname)
    # Add on finish callbacks.
    for on_finish_callback in on_finish:
        app.register_on_finish(on_finish_callback)
    # Add the wsgi application. This has to be last.
    app.router.add_route("*", "{}{{path_info:.*}}".format(script_name), WSGIHandler(application, **kwargs).handle_request)
    # Set up the server.
    shared_server_kwargs = {
        "backlog": backlog,
    }
    if unix_socket is not None:
        server_future = loop.create_unix_server(app.make_handler(),
            path = unix_socket,
            **shared_server_kwargs
        )
    elif socket is not None:
        server_future = loop.create_server(app.make_handler(),
            sock = socket,
            **shared_server_kwargs
        )
    else:
        server_future = loop.create_server(app.make_handler(),
            host = host,
            port = port,
            **shared_server_kwargs
        )
    server = loop.run_until_complete(server_future)
    app.logger.info("Serving on http://%s:%s", *parse_sockname(server.sockets[0].getsockname()))
    # Set socket permissions.
    if unix_socket is not None:
        os.chmod(unix_socket, unix_socket_perms)
    # All done!
    return server, app
コード例 #12
0
ファイル: api.py プロジェクト: youngrok/aiohttp-wsgi
def configure_server(application, *,

    # Server config.
    host = "0.0.0.0",
    port = 8080,

    # Unix server config.
    unix_socket = None,
    unix_socket_perms = 0o600,

    # Prexisting socket config.
    socket = None,

    # Shared server config.
    backlog = 1024,

    # aiohttp config.
    routes = (),
    static = (),
    on_finish = (),

    # Asyncio config.
    loop = None,

    # Handler config.
    script_name = "",
    **kwargs

):
    loop = loop or asyncio.get_event_loop()
    app = Application(
        loop = loop,
    )
    # Add routes.
    for method, path, handler in routes:
        app.router.add_route(method, path, handler)
    # Add static routes.
    if isinstance(static, Mapping):
        static = static.items()
    for path, dirname in static:
        app.router.add_static(path, dirname)
    # Add on finish callbacks.
    for on_finish_callback in on_finish:
        app.on_shutdown.append(on_finish_callback)
    # The WSGI spec says that script name should not end with a slash. However,
    # aiohttp wants all route paths to start with a forward slash. This means
    # we need a special case for mounting on the root.
    if script_name.endswith("/"):  # pragma: no cover
        raise ValueError("Script name should not end with /")
    if script_name == "":
        script_name = "/"
    if not script_name.startswith("/"):  # pragma: no cover
        raise ValueError("Script name should start with /")
    # Add the wsgi application. This has to be last.
    app.router.add_route("*", "{}{{path_info:.*}}".format(script_name), WSGIHandler(application, loop=loop, **kwargs).handle_request)
    # Set up the server.
    shared_server_kwargs = {
        "backlog": backlog,
    }
    if unix_socket is not None:
        server_future = loop.create_unix_server(app.make_handler(),
            path = unix_socket,
            **shared_server_kwargs
        )
    elif socket is not None:
        server_future = loop.create_server(app.make_handler(),
            sock = socket,
            **shared_server_kwargs
        )
    else:
        server_future = loop.create_server(app.make_handler(),
            host = host,
            port = port,
            **shared_server_kwargs
        )
    server = loop.run_until_complete(server_future)
    app.logger.info("Serving on http://%s:%s", *parse_sockname(server.sockets[0].getsockname()))
    # Set socket permissions.
    if unix_socket is not None:
        os.chmod(unix_socket, unix_socket_perms)
    # All done!
    return server, app
コード例 #13
0
def configure_server(
        application,
        *,

        # Server config.
        host="0.0.0.0",
        port=8080,

        # Unix server config.
        unix_socket=None,
        unix_socket_perms=0o600,

        # Prexisting socket config.
        socket=None,

        # Shared server config.
        backlog=1024,

        # aiohttp config.
        routes=(),
        static=(),
        on_finish=(),

        # Asyncio config.
        loop=None,

        # Handler config.
        script_name="",
        **kwargs):
    loop = loop or asyncio.get_event_loop()
    app = Application(loop=loop, )
    # Add routes.
    for method, path, handler in routes:
        app.router.add_route(method, path, handler)
    # Add static routes.
    if isinstance(static, Mapping):
        static = static.items()
    for path, dirname in static:
        app.router.add_static(path, dirname)
    # Add on finish callbacks.
    for on_finish_callback in on_finish:
        app.register_on_finish(on_finish_callback)
    # The WSGI spec says that script name should not end with a slash. However,
    # aiohttp wants all route paths to start with a forward slash. This means
    # we need a special case for mounting on the root.
    if script_name.endswith("/"):  # pragma: no cover
        raise ValueError("Script name should not end with /")
    if script_name == "":
        script_name = "/"
    if not script_name.startswith("/"):  # pragma: no cover
        raise ValueError("Script name should start with /")
    # Add the wsgi application. This has to be last.
    app.router.add_route("*", "{}{{path_info:.*}}".format(script_name),
                         WSGIHandler(application, **kwargs).handle_request)
    # Set up the server.
    shared_server_kwargs = {
        "backlog": backlog,
    }
    if unix_socket is not None:
        server_future = loop.create_unix_server(app.make_handler(),
                                                path=unix_socket,
                                                **shared_server_kwargs)
    elif socket is not None:
        server_future = loop.create_server(app.make_handler(),
                                           sock=socket,
                                           **shared_server_kwargs)
    else:
        server_future = loop.create_server(app.make_handler(),
                                           host=host,
                                           port=port,
                                           **shared_server_kwargs)
    server = loop.run_until_complete(server_future)
    app.logger.info("Serving on http://%s:%s",
                    *parse_sockname(server.sockets[0].getsockname()))
    # Set socket permissions.
    if unix_socket is not None:
        os.chmod(unix_socket, unix_socket_perms)
    # All done!
    return server, app