示例#1
0
    def __call__(self, environ, start_response):
        host = environ.get("HTTP_HOST", environ.get("SERVER_NAME")).lower()
        if ":" in host:
            host, port = host.split(":", 1)
        else:
            if environ["wsgi.url_scheme"] == "http":
                port = "80"
            else:
                port = "443"

        path_info = environ["PATH_INFO"]
        path_info = self.normalize_url(path_info, False)[1]

        # The MIME type for the response is determined in one of two ways:
        # 1) URL path suffix (eg /servers/detail.json)
        # 2) Accept header (eg application/json;q=0.8, application/xml;q=0.2)

        # The API version is determined in one of three ways:
        # 1) URL path prefix (eg /v1.1/tenant/servers/detail)
        # 2) Content-Type header (eg application/json;version=1.1)
        # 3) Accept header (eg application/json;q=0.8;version=1.1)

        supported_content_types = list(wsgi.get_supported_content_types())

        mime_type, app, app_url = self._path_strategy(host, port, path_info)

        # Accept application/atom+xml for the index query of each API
        # version mount point as well as the root index
        if (app_url and app_url + "/" == path_info) or path_info == "/":
            supported_content_types.append("application/atom+xml")

        if not app:
            app = self._content_type_strategy(host, port, environ)

        if not mime_type or not app:
            possible_mime_type, possible_app = self._accept_strategy(host, port, environ, supported_content_types)
            if possible_mime_type and not mime_type:
                mime_type = possible_mime_type
            if possible_app and not app:
                app = possible_app

        if not mime_type:
            mime_type = "application/json"

        if not app:
            # Didn't match a particular version, probably matches default
            app, app_url = self._match(host, port, path_info)
            if app:
                app = self._munge_path(app, path_info, app_url)

        if app:
            environ["nova.best_content_type"] = mime_type
            return app(environ, start_response)

        LOG.debug("Could not find application for %s", environ.PATH_INFO)
        environ["paste.urlmap_object"] = self
        return self.not_found_application(environ, start_response)
示例#2
0
    def _path_strategy(self, host, port, path_info):
        """Check path suffix for MIME type and path prefix for API version."""
        mime_type = app = app_url = None

        parts = path_info.rsplit(".", 1)
        if len(parts) > 1:
            possible_type = "application/" + parts[1]
            if possible_type in wsgi.get_supported_content_types():
                mime_type = possible_type

        parts = path_info.split("/")
        if len(parts) > 1:
            possible_app, possible_app_url = self._match(host, port, path_info)
            # Don't use prefix if it ends up matching default
            if possible_app and possible_app_url:
                app_url = possible_app_url
                app = self._munge_path(possible_app, path_info, app_url)

        return mime_type, app, app_url