Ë
    êmxi4b  ã                   ó²  — d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZmZmZmZ dd	lmZmZmZmZmZmZmZmZmZmZ  G d
„ dej<                  «      Z G d„ de«      Z  G d„ dejB                  «      Z" G d„ dejB                  «      Z#eedee   eee$df   ef   eee$df   eee$ef   f   eee$df   eee$ef   e$f   f      Z% G d„ de«      Z& G d„ de e&«      Z' G d„ d«      Z( G d„ d«      Z) G d„ de)«      Z* G d„ de)«      Z+ G d„ de)«      Z, G d „ d!e)«      Z- G d"„ d#e(«      Z.ed$e$d%e/fd&„«       Z0ed)d'„«       Z0d$ee$   d%ee/   fd(„Z0y)*ap  Flexible routing implementation.

Tornado routes HTTP requests to appropriate handlers using `Router`
class implementations. The `tornado.web.Application` class is a
`Router` implementation and may be used directly, or the classes in
this module may be used for additional flexibility. The `RuleRouter`
class can match on more criteria than `.Application`, or the `Router`
interface can be subclassed for maximum customization.

`Router` interface extends `~.httputil.HTTPServerConnectionDelegate`
to provide additional routing capabilities. This also means that any
`Router` implementation can be used directly as a ``request_callback``
for `~.httpserver.HTTPServer` constructor.

`Router` subclass must implement a ``find_handler`` method to provide
a suitable `~.httputil.HTTPMessageDelegate` instance to handle the
request:

.. code-block:: python

    class CustomRouter(Router):
        def find_handler(self, request, **kwargs):
            # some routing logic providing a suitable HTTPMessageDelegate instance
            return MessageDelegate(request.connection)

    class MessageDelegate(HTTPMessageDelegate):
        def __init__(self, connection):
            self.connection = connection

        def finish(self):
            self.connection.write_headers(
                ResponseStartLine("HTTP/1.1", 200, "OK"),
                HTTPHeaders({"Content-Length": "2"}),
                b"OK")
            self.connection.finish()

    router = CustomRouter()
    server = HTTPServer(router)

The main responsibility of `Router` implementation is to provide a
mapping from a request to `~.httputil.HTTPMessageDelegate` instance
that will handle this request. In the example above we can see that
routing is possible even without instantiating an `~.web.Application`.

For routing to `~.web.RequestHandler` implementations we need an
`~.web.Application` instance. `~.web.Application.get_handler_delegate`
provides a convenient way to create `~.httputil.HTTPMessageDelegate`
for a given request and `~.web.RequestHandler`.

Here is a simple example of how we can we route to
`~.web.RequestHandler` subclasses by HTTP method:

.. code-block:: python

    resources = {}

    class GetResource(RequestHandler):
        def get(self, path):
            if path not in resources:
                raise HTTPError(404)

            self.finish(resources[path])

    class PostResource(RequestHandler):
        def post(self, path):
            resources[path] = self.request.body

    class HTTPMethodRouter(Router):
        def __init__(self, app):
            self.app = app

        def find_handler(self, request, **kwargs):
            handler = GetResource if request.method == "GET" else PostResource
            return self.app.get_handler_delegate(request, handler, path_args=[request.path])

    router = HTTPMethodRouter(Application())
    server = HTTPServer(router)

`ReversibleRouter` interface adds the ability to distinguish between
the routes and reverse them to the original urls using route's name
and additional arguments. `~.web.Application` is itself an
implementation of `ReversibleRouter` class.

`RuleRouter` and `ReversibleRuleRouter` are implementations of
`Router` and `ReversibleRouter` interfaces and can be used for
creating rule-based routing configurations.

Rules are instances of `Rule` class. They contain a `Matcher`, which
provides the logic for determining whether the rule is a match for a
particular request and a target, which can be one of the following.

1) An instance of `~.httputil.HTTPServerConnectionDelegate`:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/handler"), ConnectionDelegate()),
        # ... more rules
    ])

    class ConnectionDelegate(HTTPServerConnectionDelegate):
        def start_request(self, server_conn, request_conn):
            return MessageDelegate(request_conn)

2) A callable accepting a single argument of `~.httputil.HTTPServerRequest` type:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/callable"), request_callable)
    ])

    def request_callable(request):
        request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
        request.finish()

3) Another `Router` instance:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/router.*"), CustomRouter())
    ])

Of course a nested `RuleRouter` or a `~.web.Application` is allowed:

.. code-block:: python

    router = RuleRouter([
        Rule(HostMatches("example.com"), RuleRouter([
            Rule(PathMatches("/app1/.*"), Application([(r"/app1/handler", Handler)])),
        ]))
    ])

    server = HTTPServer(router)

In the example below `RuleRouter` is used to route between applications:

.. code-block:: python

    app1 = Application([
        (r"/app1/handler", Handler1),
        # other handlers ...
    ])

    app2 = Application([
        (r"/app2/handler", Handler2),
        # other handlers ...
    ])

    router = RuleRouter([
        Rule(PathMatches("/app1.*"), app1),
        Rule(PathMatches("/app2.*"), app2)
    ])

    server = HTTPServer(router)

For more information on application-level routing see docs for `~.web.Application`.

.. versionadded:: 4.5

é    N)Úpartial)Úhttputil)Ú_CallableAdapter)Ú
url_escapeÚurl_unescapeÚutf8)Úapp_log)Úbasestring_typeÚimport_objectÚre_unescapeÚunicode_type)
ÚAnyÚUnionÚOptionalÚ	AwaitableÚListÚDictÚPatternÚTupleÚoverloadÚSequencec                   óŽ   — e Zd ZdZdej
                  dedeej                     fd„Z	de
dej                  dej                  fd„Zy	)
ÚRouterzAbstract router interface.ÚrequestÚkwargsÚreturnc                 ó   — t        «       ‚)aò  Must be implemented to return an appropriate instance of `~.httputil.HTTPMessageDelegate`
        that can serve the request.
        Routing implementations may pass additional kwargs to extend the routing logic.

        :arg httputil.HTTPServerRequest request: current HTTP request.
        :arg kwargs: additional keyword arguments passed by routing implementation.
        :returns: an instance of `~.httputil.HTTPMessageDelegate` that will be used to
            process the request.
        ©ÚNotImplementedError)Úselfr   r   s      úF/home/htdocs/ttos/venv/lib/python3.12/site-packages/tornado/routing.pyÚfind_handlerzRouter.find_handlerÌ   s   € ô "Ó#Ð#ó    Úserver_connÚrequest_connc                 ó   — t        | ||«      S ©N)Ú_RoutingDelegate)r    r$   r%   s      r!   Ústart_requestzRouter.start_requestÚ   s   € ô    k°<Ó@Ð@r#   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚHTTPServerRequestr   r   ÚHTTPMessageDelegater"   ÚobjectÚHTTPConnectionr)   © r#   r!   r   r   É   s`   „ Ù$ð$Ø×1Ñ1ð$Ø=@ð$à	�(×.Ñ.Ñ	/ó$ðAØ!ðAØ19×1HÑ1HðAà	×	%Ñ	%ôAr#   r   c                   ó*   — e Zd ZdZdededee   fd„Zy)ÚReversibleRouterzxAbstract router interface for routers that can handle named routes
    and support reversing them to original urls.
    ÚnameÚargsr   c                 ó   — t        «       ‚)a  Returns url string for a given route name and arguments
        or ``None`` if no match is found.

        :arg str name: route name.
        :arg args: url parameters.
        :returns: parametrized url string for a given route name (or ``None``).
        r   )r    r5   r6   s      r!   Úreverse_urlzReversibleRouter.reverse_urlå   s   € ô "Ó#Ð#r#   N)r*   r+   r,   r-   Ústrr   r   r8   r2   r#   r!   r4   r4   à   s%   „ ñð$ ð $¨Cð $°H¸S±Mô $r#   r4   c                   óÊ   — e Zd Zdededej                  ddfd„Zdeej                  ej                  f   dej                  deed      fd	„Zd
edeed      fd„Zdd„Zdd„Zy)r(   Úrouterr$   r%   r   Nc                 ó<   — || _         || _        d | _        || _        y r'   )r$   r%   Údelegater;   )r    r;   r$   r%   s       r!   Ú__init__z_RoutingDelegate.__init__ñ   s"   € ð 'ˆÔØ(ˆÔØˆŒØˆ�r#   Ú
start_lineÚheadersc                 ó®  — t        |t        j                  «      sJ ‚t        j                  | j                  | j
                  ||¬«      }| j                  j                  |«      | _        | j                  €Et        j                  d|j                  |j                  «       t        | j                  «      | _        | j                  j                  ||«      S )N)Ú
connectionÚserver_connectionr?   r@   z$Delegate for %s %s request not found)Ú
isinstancer   ÚRequestStartLiner.   r%   r$   r;   r"   r=   r	   ÚdebugÚmethodÚpathÚ_DefaultMessageDelegateÚheaders_received)r    r?   r@   r   s       r!   rJ   z!_RoutingDelegate.headers_receivedù   s®   € ô
 ˜*¤h×&?Ñ&?Ô@Ð@Ð@Ü×,Ñ,Ø×(Ñ(Ø"×.Ñ.Ø!Øô	
ˆð Ÿ™×0Ñ0°Ó9ˆŒØ�=‰=Ð Ü�M‰MØ6Ø×!Ñ!Ø—‘ôô
 4°D×4EÑ4EÓFˆDŒMà�}‰}×-Ñ-¨j¸'ÓBÐBr#   Úchunkc                 óT   — | j                   €J ‚| j                   j                  |«      S r'   )r=   Údata_received)r    rK   s     r!   rM   z_RoutingDelegate.data_received  s'   € Ø�}‰}Ð(Ð(Ð(Ø�}‰}×*Ñ*¨5Ó1Ð1r#   c                 óT   — | j                   €J ‚| j                   j                  «        y r'   )r=   Úfinish©r    s    r!   rO   z_RoutingDelegate.finish  s"   € Ø�}‰}Ð(Ð(Ð(Ø�‰×ÑÕr#   c                 óR   — | j                   �| j                   j                  «        y y r'   )r=   Úon_connection_closerP   s    r!   rR   z$_RoutingDelegate.on_connection_close  s!   € Ø�=‰=Ð$Ø�M‰M×-Ñ-Õ/ð %r#   ©r   N)r*   r+   r,   r   r0   r   r1   r>   r   rE   ÚResponseStartLineÚHTTPHeadersr   r   rJ   ÚbytesrM   rO   rR   r2   r#   r!   r(   r(   ð   s�   „ ðØðØ+1ðØAI×AXÑAXðà	óðCà˜(×3Ñ3°X×5OÑ5OÐOÑPðCð ×%Ñ%ðCð 
�)˜D‘/Ñ	"ó	Cð02 5ð 2¨X°iÀ±oÑ-Fó 2óô0r#   r(   c                   ó8   — e Zd Zdej                  ddfd„Zdd„Zy)rI   rB   r   Nc                 ó   — || _         y r'   )rB   )r    rB   s     r!   r>   z _DefaultMessageDelegate.__init__  s	   € Ø$ˆ�r#   c                 ó¾   — | j                   j                  t        j                  ddd«      t        j                  «       «       | j                   j                  «        y )NzHTTP/1.1i”  z	Not Found)rB   Úwrite_headersr   rT   rU   rO   rP   s    r!   rO   z_DefaultMessageDelegate.finish"  sD   € Ø�‰×%Ñ%Ü×&Ñ& z°3¸ÓDÜ× Ñ Ó"ô	
ð 	�‰×ÑÕ r#   rS   )r*   r+   r,   r   r1   r>   rO   r2   r#   r!   rI   rI     s    „ ð% 8×#:Ñ#:ð %¸tó %ô!r#   rI   ÚRuleÚMatcherc            	       óÈ   — e Zd ZdZddee   ddfd„Zdeddfd„Zdd„Zde	j                  d	edee	j                     fd
„Zdede	j                  dedee	j                     fd„Zy)Ú
RuleRouterz!Rule-based router implementation.NÚrulesr   c                 ó:   — g | _         |r| j                  |«       yy)aI  Constructs a router from an ordered list of rules::

            RuleRouter([
                Rule(PathMatches("/handler"), Target),
                # ... more rules
            ])

        You can also omit explicit `Rule` constructor and use tuples of arguments::

            RuleRouter([
                (PathMatches("/handler"), Target),
            ])

        `PathMatches` is a default matcher, so the example above can be simplified::

            RuleRouter([
                ("/handler", Target),
            ])

        In the examples above, ``Target`` can be a nested `Router` instance, an instance of
        `~.httputil.HTTPServerConnectionDelegate` or an old-style callable,
        accepting a request argument.

        :arg rules: a list of `Rule` instances or tuples of `Rule`
            constructor arguments.
        N)r_   Ú	add_rules)r    r_   s     r!   r>   zRuleRouter.__init__:  s   € ð6 ˆŒ
ÙØ�N‰N˜5Õ!ð r#   c                 ó  — |D ]ˆ  }t        |t        t        f«      rFt        |«      dv sJ ‚t        |d   t        «      rt        t        |d   «      g|dd ¢­Ž }nt        |Ž }| j                  j                  | j                  |«      «       ŒŠ y)z£Appends new rules to the router.

        :arg rules: a list of Rule instances (or tuples of arguments, which are
            passed to Rule constructor).
        )é   é   é   r   é   N)
rD   ÚtupleÚlistÚlenr
   r[   ÚPathMatchesr_   ÚappendÚprocess_rule)r    r_   Úrules      r!   ra   zRuleRouter.add_rulesY  s…   € ð ò 	7ˆDÜ˜$¤¬ Ô.Ü˜4“y IÑ-Ð-Ð-Ü˜d 1™g¤Ô7Ü¤¨D°©GÓ 4Ð@°t¸A¸B°xÒ@‘Dä ˜;�Dà�J‰J×Ñ˜d×/Ñ/°Ó5Õ6ñ	7r#   c                 ó   — |S )z¯Override this method for additional preprocessing of each rule.

        :arg Rule rule: a rule to be processed.
        :returns: the same or modified Rule instance.
        r2   )r    rm   s     r!   rl   zRuleRouter.process_rulei  s	   € ð ˆr#   r   r   c                 óà   — | j                   D ]_  }|j                  j                  |«      }|€Œ!|j                  r|j                  |d<    | j                  |j
                  |fi |¤Ž}|€Œ]|c S  y )NÚtarget_kwargs)r_   ÚmatcherÚmatchrp   Úget_target_delegateÚtarget)r    r   r   rm   Útarget_paramsr=   s         r!   r"   zRuleRouter.find_handlerq  s   € ð —J‘Jò 	$ˆDØ ŸL™L×.Ñ.¨wÓ7ˆMØÑ(Ø×%Ò%Ø59×5GÑ5G�M /Ñ2à3˜4×3Ñ3Ø—K‘K ñØ,9ñ�ð Ñ'Ø#’Oð	$ð r#   rt   ru   c                 óX  — t        |t        «      r |j                  |fi |¤ŽS t        |t        j                  «      r4|j
                  €J ‚|j                  |j                  |j
                  «      S t        |«      r.|j
                  €J ‚t        t        |fi |¤Ž|j
                  «      S y)a°  Returns an instance of `~.httputil.HTTPMessageDelegate` for a
        Rule's target. This method is called by `~.find_handler` and can be
        extended to provide additional target types.

        :arg target: a Rule's target.
        :arg httputil.HTTPServerRequest request: current request.
        :arg target_params: additional parameters that can be useful
            for `~.httputil.HTTPMessageDelegate` creation.
        N)rD   r   r"   r   ÚHTTPServerConnectionDelegaterB   r)   rC   Úcallabler   r   )r    rt   r   ru   s       r!   rs   zRuleRouter.get_target_delegateƒ  s¨   € ô �fœfÔ%Ø&�6×&Ñ& wÑ@°-Ñ@Ð@ä˜¤× EÑ EÔFØ×%Ñ%Ð1Ð1Ð1Ø×'Ñ'¨×(AÑ(AÀ7×CUÑCUÓVÐVä�fÔØ×%Ñ%Ð1Ð1Ð1Ü#Ü˜Ñ0 -Ñ0°'×2DÑ2Dóð ð r#   r'   ©rm   r[   r   r[   )r*   r+   r,   r-   r   Ú	_RuleListr>   ra   rl   r   r.   r   r/   r"   rs   r2   r#   r!   r^   r^   7  s™   „ Ù+ñ"˜h yÑ1ð "¸Tó "ð>7˜yð 7¨Tó 7ó ðØ×1Ñ1ðØ=@ðà	�(×.Ñ.Ñ	/óð$ØðØ$,×$>Ñ$>ðØQTðà	�(×.Ñ.Ñ	/ôr#   r^   c                   óZ   ‡ — e Zd ZdZd
dee   ddfˆ fd„Zdˆ fd„Zdede	dee   fd	„Z
ˆ xZS )ÚReversibleRuleRoutera  A rule-based router that implements ``reverse_url`` method.

    Each rule added to this router may have a ``name`` attribute that can be
    used to reconstruct an original uri. The actual reconstruction takes place
    in a rule's matcher (see `Matcher.reverse`).
    Nr_   r   c                 ó2   •— i | _         t        ‰| �	  |«       y r'   )Únamed_rulesÚsuperr>   )r    r_   Ú	__class__s     €r!   r>   zReversibleRuleRouter.__init__§  s   ø€ ØˆÔÜ‰Ñ˜Õr#   c                 óà   •— t         ‰| �  |«      }|j                  rQ|j                  | j                  v r t	        j
                  d|j                  «       || j                  |j                  <   |S )Nz4Multiple handlers named %s; replacing previous value)r   rl   r5   r~   r	   Úwarning)r    rm   r€   s     €r!   rl   z!ReversibleRuleRouter.process_rule«  s[   ø€ Ü‰wÑ# DÓ)ˆà�9Š9Ø�y‰y˜D×,Ñ,Ñ,Ü—‘ØJÈDÏIÉIôð +/ˆD×Ñ˜TŸY™YÑ'àˆr#   r5   r6   c                 ó
  — || j                   v r& | j                   |   j                  j                  |Ž S | j                  D ]@  }t	        |j
                  t        «      sŒ |j
                  j                  |g|¢­Ž }|€Œ>|c S  y r'   )r~   rq   Úreverser_   rD   rt   r4   r8   )r    r5   r6   rm   Úreversed_urls        r!   r8   z ReversibleRuleRouter.reverse_url·  s‚   € Ø�4×#Ñ#Ñ#Ø9�4×#Ñ# DÑ)×1Ñ1×9Ñ9¸4Ð@Ð@à—J‘Jò 	(ˆDÜ˜$Ÿ+™+Ô'7Õ8Ø6˜tŸ{™{×6Ñ6°tÐC¸dÒC�ØÑ+Ø'Ò'ð		(ð r#   r'   ry   )r*   r+   r,   r-   r   rz   r>   rl   r9   r   r8   Ú__classcell__©r€   s   @r!   r|   r|   Ÿ  sC   ø„ ññ ˜h yÑ1ð  ¸Tõ  õ
ð
 ð 
¨Cð 
°H¸S±M÷ 
r#   r|   c                   ój   — e Zd ZdZ	 	 ddddedeeeef      dee   ddf
d	„Zd
edee   fd„Z	defd„Z
y)r[   zA routing rule.Nrq   r\   rt   rp   r5   r   c                 óz   — t        |t        «      rt        |«      }|| _        || _        |r|ni | _        || _        y)ad  Constructs a Rule instance.

        :arg Matcher matcher: a `Matcher` instance used for determining
            whether the rule should be considered a match for a specific
            request.
        :arg target: a Rule's target (typically a ``RequestHandler`` or
            `~.httputil.HTTPServerConnectionDelegate` subclass or even a nested `Router`,
            depending on routing implementation).
        :arg dict target_kwargs: a dict of parameters that can be useful
            at the moment of target instantiation (for example, ``status_code``
            for a ``RequestHandler`` subclass). They end up in
            ``target_params['target_kwargs']`` of `RuleRouter.get_target_delegate`
            method.
        :arg str name: the name of the rule that can be used to find it
            in `ReversibleRouter.reverse_url` implementation.
        N)rD   r9   r   rq   rt   rp   r5   )r    rq   rt   rp   r5   s        r!   r>   zRule.__init__Ç  s;   € ô. �fœcÔ"ô # 6Ó*ˆFàˆŒØˆŒÙ.;™]ÀˆÔØˆ�	r#   r6   c                 ó4   —  | j                   j                  |Ž S r'   )rq   r„   ©r    r6   s     r!   r„   zRule.reverseè  s   € Ø#ˆt�|‰|×#Ñ# TÐ*Ð*r#   c                 ó¤   — dj                  | j                  j                  | j                  | j                  | j
                  | j                  «      S ©Nz${}({!r}, {}, kwargs={!r}, name={!r}))Úformatr€   r*   rq   rt   rp   r5   rP   s    r!   Ú__repr__zRule.__repr__ë  s@   € Ø5×<Ñ<Ø�N‰N×#Ñ#Ø�L‰LØ�K‰KØ×ÑØ�I‰Ió
ð 	
r#   ©NN)r*   r+   r,   r-   r   r   r   r9   r>   r„   r�   r2   r#   r!   r[   r[   Ä  sw   „ Ùð 37Ø"ñàðð ðð    S¨# X¡Ñ/ð	ð
 �s‰mðð 
óðB+˜Sð + X¨c¡]ó +ð
˜#ô 
r#   c                   óZ   — e Zd ZdZdej
                  deeee	f      fd„Z
de	dee   fd„Zy)r\   z*Represents a matcher for request features.r   r   c                 ó   — t        «       ‚)a1  Matches current instance against the request.

        :arg httputil.HTTPServerRequest request: current HTTP request
        :returns: a dict of parameters to be passed to the target handler
            (for example, ``handler_kwargs``, ``path_args``, ``path_kwargs``
            can be passed for proper `~.web.RequestHandler` instantiation).
            An empty dict is a valid (and common) return value to indicate a match
            when the argument-passing features are not used.
            ``None`` must be returned to indicate that there is no match.r   ©r    r   s     r!   rr   zMatcher.matchø  s   € ô "Ó#Ð#r#   r6   c                  ó   — y)zEReconstructs full url from matcher instance and additional arguments.Nr2   r‹   s     r!   r„   zMatcher.reverse  s   € àr#   N)r*   r+   r,   r-   r   r.   r   r   r9   r   rr   r„   r2   r#   r!   r\   r\   õ  sB   „ Ù4ð
$˜X×7Ñ7ð 
$¸HÀTÈ#ÈsÈ(Á^Ñ<Tó 
$ð˜Sð  X¨c¡]ô r#   c                   óD   — e Zd ZdZdej
                  deeee	f      fd„Z
y)Ú
AnyMatcheszMatches any request.r   r   c                 ó   — i S r'   r2   r“   s     r!   rr   zAnyMatches.match  s   € Øˆ	r#   N)r*   r+   r,   r-   r   r.   r   r   r9   r   rr   r2   r#   r!   r–   r–   	  s+   „ Ùð˜X×7Ñ7ð ¸HÀTÈ#ÈsÈ(Á^Ñ<Tô r#   r–   c                   ó^   — e Zd ZdZdeeef   ddfd„Zdej                  de
eeef      fd„Zy)ÚHostMatchesz@Matches requests from hosts specified by ``host_pattern`` regex.Úhost_patternr   Nc                 ó”   — t        |t        «      r1|j                  d«      s|dz  }t        j                  |«      | _        y || _        y )Nú$)rD   r
   ÚendswithÚreÚcompilerš   )r    rš   s     r!   r>   zHostMatches.__init__  s=   € Ü�l¤OÔ4Ø×(Ñ(¨Ô-Ø Ñ#�Ü "§
¡
¨<Ó 8ˆDÕà ,ˆDÕr#   r   c                 óR   — | j                   j                  |j                  «      ri S y r'   )rš   rr   Ú	host_namer“   s     r!   rr   zHostMatches.match  s$   € Ø×Ñ×"Ñ" 7×#4Ñ#4Ô5ØˆIàr#   )r*   r+   r,   r-   r   r9   r   r>   r   r.   r   r   r   rr   r2   r#   r!   r™   r™     sG   „ ÙJð- U¨3°¨<Ñ%8ð -¸Tó -ð˜X×7Ñ7ð ¸HÀTÈ#ÈsÈ(Á^Ñ<Tô r#   r™   c                   óX   — e Zd ZdZdededdfd„Zdej                  de	e
eef      fd„Zy)	ÚDefaultHostMatcheszŒMatches requests from host that is equal to application's default_host.
    Always returns no match if ``X-Real-Ip`` header is present.
    Úapplicationrš   r   Nc                 ó    — || _         || _        y r'   )r¤   rš   )r    r¤   rš   s      r!   r>   zDefaultHostMatches.__init__'  s   € Ø&ˆÔØ(ˆÕr#   r   c                 ó‚   — d|j                   vr1| j                  j                  | j                  j                  «      ri S y )Nz	X-Real-Ip)r@   rš   rr   r¤   Údefault_hostr“   s     r!   rr   zDefaultHostMatches.match+  s6   € à˜gŸo™oÑ-Ø× Ñ ×&Ñ& t×'7Ñ'7×'DÑ'DÔEØ�	Ør#   )r*   r+   r,   r-   r   r   r>   r   r.   r   r   r9   rr   r2   r#   r!   r£   r£   "  sG   „ ñð) Cð )°wð )À4ó )ð˜X×7Ñ7ð ¸HÀTÈ#ÈsÈ(Á^Ñ<Tô r#   r£   c                   ó–   — e Zd ZdZdeeef   ddfd„Zdej                  de
eeef      fd„Zdede
e   fd	„Zdee
e   e
e   f   fd
„Zy)rj   z@Matches requests with paths specified by ``path_pattern`` regex.Úpath_patternr   Nc                 óx  — t        |t        «      r1|j                  d«      s|dz  }t        j                  |«      | _        n|| _        t        | j
                  j                  «      d| j
                  j                  fv sJ d| j
                  j                  z  «       ‚| j                  «       \  | _        | _        y )Nrœ   r   zDgroups in url regexes must either be all named or all positional: %r)rD   r
   r�   rž   rŸ   Úregexri   Ú
groupindexÚgroupsÚpatternÚ_find_groupsÚ_pathÚ_group_count)r    r©   s     r!   r>   zPathMatches.__init__6  sŸ   € Ü�l¤OÔ4Ø×(Ñ(¨Ô-Ø Ñ#�ÜŸ™ LÓ1ˆD�Jà%ˆDŒJä�4—:‘:×(Ñ(Ó)¨a°·±×1BÑ1BÐ-CÑCð 	
ðØ#Ÿz™z×1Ñ1ñ2ó	
ÐCð
 )-×(9Ñ(9Ó(;Ñ%ˆŒ
�DÕ%r#   r   c                 óº  — | j                   j                  |j                  «      }|€y | j                   j                  si S g }i }| j                   j                  rD|j                  «       j                  «       D ��ci c]  \  }}t        |«      t        |«      “Œ }}}n&|j                  «       D �cg c]  }t        |«      ‘Œ }}t        ||¬«      S c c}}w c c}w )N)Ú	path_argsÚpath_kwargs)
r«   rr   rH   r­   r¬   Ú	groupdictÚitemsr9   Ú_unquote_or_noneÚdict)r    r   rr   r³   r´   ÚkÚvÚss           r!   rr   zPathMatches.matchE  sÃ   € Ø—
‘
× Ñ  §¡Ó.ˆØˆ=ØØ�z‰z× Ò ØˆIàˆ	Øˆð �:‰:× Ò à:?¿/¹/Ó:K×:QÑ:QÓ:S÷Ù06°°A”�A“Ô(¨Ó+Ñ+ðˆKò ð 7<·l±l³nÖE°Ô)¨!Õ,ÐEˆIÐEä˜i°[ÔAÐAùóùò Fs   Á<CÂ1Cr6   c                 ó˜  — | j                   €"t        d| j                  j                  z   «      ‚t	        |«      | j
                  k(  sJ d«       ‚t	        |«      s| j                   S g }|D ]H  }t        |t        t        f«      st        |«      }|j                  t        t        |«      d¬«      «       ŒJ | j                   t        |«      z  S )NzCannot reverse url regex z&required number of arguments not foundF)Úplus)r°   Ú
ValueErrorr«   r®   ri   r±   rD   r   rV   r9   rk   r   r   rg   )r    r6   Úconverted_argsÚas       r!   r„   zPathMatches.reverse\  s¹   € Ø�:‰:ÐÜÐ8¸4¿:¹:×;MÑ;MÑMÓNÐNÜ�4‹y˜D×-Ñ-Ò-ð 	
Ø7ó	
Ð-ô �4ŒyØ—:‘:ÐØˆØò 	CˆAÜ˜a¤,´Ð!6Ô7Ü˜“F�Ø×!Ñ!¤*¬T°!«W¸5Ô"AÕBð	Cð �z‰zœE .Ó1Ñ1Ð1r#   c                 óT  — | j                   j                  }|j                  d«      r|dd }|j                  d«      r|dd }| j                   j                  |j                  d«      k7  ryg }|j                  d«      D ]a  }d|v r>|j                  d«      }|d	k\  sŒ	 t        ||dz   d «      }|j                  d
|z   «       ŒE	 t        |«      }|j                  |«       Œc dj                  |«      | j                   j                  fS # t        $ r Y  yw xY w# t        $ r Y  yw xY w)z¶Returns a tuple (reverse string, group count) for a url.

        For example: Given the url pattern /([0-9]{4})/([a-z-]+)/, this method
        would return ('/%s/%s/', 2).
        ú^rf   Nrœ   éÿÿÿÿú(r�   ú)r   z%sÚ )r«   r®   Ú
startswithr�   r­   ÚcountÚsplitÚindexr   r¾   rk   Újoin)r    r®   ÚpiecesÚfragmentÚ	paren_locÚunescaped_fragments         r!   r¯   zPathMatches._find_groupsk  s6  € ð —*‘*×$Ñ$ˆØ×Ñ˜cÔ"Ø˜a˜b�kˆGØ×Ñ˜CÔ Ø˜c˜r�lˆGà�:‰:×Ñ §¡¨cÓ 2Ò2ð àˆØŸ™ cÓ*ò 	2ˆHØ�h‰Ø$ŸN™N¨3Ó/�	Ø “>ð,Ü-8¸À)ÈaÁ-À/Ð9RÓ-SÐ*ð
 —M‘M $Ð);Ñ";Õ<ð(Ü)4°XÓ)>Ð&ð
 —‘Ð0Õ1ð%	2ð( �w‰w�v‹ §
¡
× 1Ñ 1Ð1Ð1øô &ò ,ò  ,ð,ûô "ò (ò (ð(ús$   ÂD
ÃDÄ
	DÄDÄ	D'Ä&D')r*   r+   r,   r-   r   r9   r   r>   r   r.   r   r   r   rr   r„   r   Úintr¯   r2   r#   r!   rj   rj   3  s   „ ÙJð< U¨3°¨<Ñ%8ð <¸Tó <ðB˜X×7Ñ7ð B¸HÀTÈ#ÈsÈ(Á^Ñ<Tó Bð.2˜Sð 2 X¨c¡]ó 2ð&2˜e H¨S¡M°8¸C±=Ð$@ÑAô &2r#   rj   c                   ój   ‡ — e Zd ZdZ	 	 d
deeef   dedee	eef      dee   ddf
ˆ fd„Z
defd	„Zˆ xZS )ÚURLSpeczÍSpecifies mappings between URLs and handlers.

    .. versionchanged: 4.5
       `URLSpec` is now a subclass of a `Rule` with `PathMatches` matcher and is preserved for
       backwards compatibility.
    Nr®   Úhandlerr   r5   r   c                 ó’   •— t        |«      }t        ‰| �	  ||||«       |j                  | _        | j                  | _        || _        y)aƒ  Parameters:

        * ``pattern``: Regular expression to be matched. Any capturing
          groups in the regex will be passed in to the handler's
          get/post/etc methods as arguments (by keyword if named, by
          position if unnamed. Named and unnamed capturing groups
          may not be mixed in the same rule).

        * ``handler``: `~.web.RequestHandler` subclass to be invoked.

        * ``kwargs`` (optional): A dictionary of additional arguments
          to be passed to the handler's constructor.

        * ``name`` (optional): A name for this handler.  Used by
          `~.web.Application.reverse_url`.

        N)rj   r   r>   r«   rt   Úhandler_classr   )r    r®   rÓ   r   r5   rq   r€   s         €r!   r>   zURLSpec.__init__œ  s@   ø€ ô0 ˜gÓ&ˆÜ‰Ñ˜ '¨6°4Ô8à—]‘]ˆŒ
Ø!Ÿ[™[ˆÔØˆ�r#   c                 ó¸   — dj                  | j                  j                  | j                  j                  | j
                  | j                  | j                  «      S r�   )rŽ   r€   r*   r«   r®   rÕ   r   r5   rP   s    r!   r�   zURLSpec.__repr__»  sF   € Ø5×<Ñ<Ø�N‰N×#Ñ#Ø�J‰J×ÑØ×ÑØ�K‰KØ�I‰Ió
ð 	
r#   r�   )r*   r+   r,   r-   r   r9   r   r   r   r   r>   r�   r†   r‡   s   @r!   rÒ   rÒ   ”  sk   ø„ ñð ,0Ø"ñà�s˜G�|Ñ$ðð ðð ˜˜c 3˜h™Ñ(ð	ð
 �s‰mðð 
õð>
˜#÷ 
r#   rÒ   r»   r   c                  ó   — y r'   r2   ©r»   s    r!   r·   r·   Å  ó   € àr#   c                  ó   — y r'   r2   rØ   s    r!   r·   r·   Ê  rÙ   r#   c                 ó&   — | €| S t        | dd¬«      S )z¹None-safe wrapper around url_unescape to handle unmatched optional
    groups correctly.

    Note that args are passed as bytes so the handler can decide what
    encoding to use.
    NF)Úencodingr½   )r   rØ   s    r!   r·   r·   Ï  s   € ð 	€yØˆÜ˜ D¨uÔ5Ð5r#   )r»   Nr   N)1r-   rž   Ú	functoolsr   Útornador   Útornado.httpserverr   Útornado.escaper   r   r   Útornado.logr	   Útornado.utilr
   r   r   r   Útypingr   r   r   r   r   r   r   r   r   r   rw   r   r4   r/   r(   rI   r9   rz   r^   r|   r[   r\   r–   r™   r£   rj   rÒ   rV   r·   r2   r#   r!   ú<module>rä      s¾  ðñaóF 
Ý å Ý /ß 9Ñ 9Ý ß RÓ R÷÷ ÷ ôAˆX×2Ñ2ô Aô.$�vô $ô +0�x×3Ñ3ô +0ô\	!˜h×:Ñ:ô 	!ð Ø	ØØˆS‰	Øˆe�C˜�NÑ# SÐ(Ñ)Øˆe�C˜�NÑ# S¨$¨s°C¨x©.Ð8Ñ9Øˆe�C˜�NÑ# S¨$¨s°C¨x©.¸#Ð=Ñ>ð		@ññ€	ôe�ô eôP"Ð+¨Zô "÷J.
ñ .
÷bñ ô(�ô ô�'ô ô$˜ô ô"^2�'ô ^2ôB.
ˆdô .
ðb 
ð	˜ð 	 ò 	ó 
ð	ð 
ò	ó 
ð	ð	6˜ ™ð 	6¨(°5©/ô 	6r#   