flask-route-match

    def push(self) -> None:
        top = _request_ctx_stack.top
        if top is not None and top.preserved:
            top.pop(top._preserved_exc)
            
        app_ctx = _app_ctx_stack.top
        if app_ctx is None or app_ctx.app != self.app:
            app_ctx = self.app.app_context()
            app_ctx.push()
            self._implicit_app_ctx_stack.append(app_ctx)
        else:
            self._implicit_app_ctx_stack.append(None)

        _request_ctx_stack.push(self)
        
        if self.session is None:
            session_interface = self.app.session_interface
            self.session = session_interface.open_session(self.app, self.request)

            if self.session is None:
                self.session = session_interface.make_null_session(self.app)

        if self.url_adapter is not None:
            self.match_request()
    def match_request(self) -> None:
        try:
            result = self.url_adapter.match(return_rule=True)  # type: ignore
            self.request.url_rule, self.request.view_args = result  # type: ignore
        except HTTPException as e:
            self.request.routing_exception = e
    def match(
        self,
        path_info: t.Optional[str] = None,
        method: t.Optional[str] = None,
        return_rule: bool = False,
        query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None,
        websocket: t.Optional[bool] = None,
    ) -> t.Tuple[t.Union[str, Rule], t.Mapping[str, t.Any]]:
        self.map.update()
        if path_info is None:
            path_info = self.path_info
        else:
            path_info = _to_str(path_info, self.map.charset)
        if query_args is None:
            query_args = self.query_args or {}
        method = (method or self.default_method).upper()

        if websocket is None:
            websocket = self.websocket

        require_redirect = False

        domain_part = self.server_name if self.map.host_matching else self.subdomain
        path_part = f"/{path_info.lstrip('/')}" if path_info else ""
        path = f"{domain_part}|{path_part}"

        have_match_for = set()
        websocket_mismatch = False

        for rule in self.map._rules:
            try:
                rv = rule.match(path, method)
            except RequestPath as e:
                raise RequestRedirect(
                    self.make_redirect_url(
                        url_quote(e.path_info, self.map.charset, safe="/:|+"),
                        query_args,
                    )
                ) from None
            except RequestAliasRedirect as e:
                raise RequestRedirect(
                    self.make_alias_redirect_url(
                        path, rule.endpoint, e.matched_values, method, query_args
                    )
                ) from None
            if rv is None:
                continue
            if rule.methods is not None and method not in rule.methods:
                have_match_for.update(rule.methods)
                continue

            if rule.websocket != websocket:
                websocket_mismatch = True
                continue

            if self.map.redirect_defaults:
                redirect_url = self.get_default_redirect(rule, method, rv, query_args)
                if redirect_url is not None:
                    raise RequestRedirect(redirect_url)

            if rule.redirect_to is not None:
                if isinstance(rule.redirect_to, str):

                    def _handle_match(match: t.Match[str]) -> str:
                        value = rv[match.group(1)]  # type: ignore
                        return rule._converters[match.group(1)].to_url(value)

                    redirect_url = _simple_rule_re.sub(_handle_match, rule.redirect_to)
                else:
                    redirect_url = rule.redirect_to(self, **rv)

                if self.subdomain:
                    netloc = f"{self.subdomain}.{self.server_name}"
                else:
                    netloc = self.server_name

                raise RequestRedirect(
                    url_join(
                        f"{self.url_scheme or 'http'}://{netloc}{self.script_name}",
                        redirect_url,
                    )
                )

            if require_redirect:
                raise RequestRedirect(
                    self.make_redirect_url(
                        url_quote(path_info, self.map.charset, safe="/:|+"), query_args
                    )
                )

            if return_rule:
                return rule, rv
            else:
                return rule.endpoint, rv

        if have_match_for:
            raise MethodNotAllowed(valid_methods=list(have_match_for))

        if websocket_mismatch:
            raise WebsocketMismatch()

        raise NotFound()
    def match(
        self, path: str, method: t.Optional[str] = None
    ) -> t.Optional[t.MutableMapping[str, t.Any]]:
        if not self.build_only:
            require_redirect = False

            m = self._regex.search(path)
            if m is not None:
                groups = m.groupdict()
                if (
                    self.strict_slashes
                    and not self.is_leaf
                    and not groups.pop("__suffix__")
                    and (
                        method is None or self.methods is None or method in self.methods
                    )
                ):
                    path += "/"
                    require_redirect = True
                elif not self.strict_slashes:
                    del groups["__suffix__"]

                result = {}
                for name, value in groups.items():
                    try:
                        value = self._converters[name].to_python(value)
                    except ValidationError:
                        return None
                    result[str(name)] = value
                if self.defaults:
                    result.update(self.defaults)

                if self.merge_slashes:
                    new_path = "|".join(self.build(result, False))  # type: ignore
                    if path.endswith("/") and not new_path.endswith("/"):
                        new_path += "/"
                    if new_path.count("/") < path.count("/"):
                        path = url_unquote(new_path)
                        require_redirect = True

                if require_redirect:
                    path = path.split("|", 1)[1]
                    raise RequestPath(path)

                if self.alias and self.map.redirect_defaults:
                    raise RequestAliasRedirect(result)

                return result

        return None
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值