Ë
    #ïàj›H  ã                   óÀ  — d Z ddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZddlZddlmZ d„ Z	 e
j,                  dd dk(  rd„ ZnddlZd„ Z G d
„ d«      Z G d„ dej:                  «      ZdZd„ Z d„ Z!ddœd„Z"dddddejF                  jH                  ddfd„Z%d„ Z&g Z'dZ( G d„ de)«      Z*dd„Z+y# e$ r ddlZddlZd	„ ZY Œvw xY w)a³  Extensions to unittest for web frameworks.

Use the :py:meth:`WebCase.getPage` method to request a page
from your HTTP server.

Framework Integration
=====================
If you have control over your server process, you can handle errors
in the server-side of the HTTP conversation a bit better. You must run
both the client (your :py:class:`WebCase` tests) and the server in the
same process (but in separate threads, obviously).
When an error occurs in the framework, call server_error. It will print
the traceback to stdout, and keep any assertions you have from running
(the assumption is that, if the server errors, the page output will not
be of further significance to your tests).
é    N)Úalways_iterablec                 ó   — | dk(  ry| dk(  ry| S )zÄReturn an IP address for a client connection given the server host.

    If the server is listening on '0.0.0.0' (INADDR_ANY)
    or '::' (IN6ADDR_ANY), this will return the proper localhost.
    z0.0.0.0ú	127.0.0.1z::z::1© )Úhosts    úC/srv/dav/.venv/lib/python3.12/site-packages/cheroot/test/webtest.pyÚ	interfacer	   %   s   € ð ˆyÒàØˆt‚|àØ€Kó    é   Újavac                  ó@   — t         j                  j                  d«      S ©úGet a key press.é   )ÚsysÚstdinÚreadr   r
   r   Úgetcharr   8   s   € ô —9‘9—>‘> !Ó$Ð$r
   c                  ó*   — t        j                  «       S )r   )ÚmsvcrtÚgetchr   r
   r   r   r   @   s   € ä—<‘<“>Ð!r
   c                  ó¬  — t         j                  j                  «       } t        j                  | «      }	 t        j                  t         j                  j                  «       «       t         j                  j                  d«      }t        j                  | t        j                  |«       |S # t        j                  | t        j                  |«       w xY wr   )
r   r   ÚfilenoÚtermiosÚ	tcgetattrÚttyÚsetrawr   Ú	tcsetattrÚ	TCSADRAIN)ÚfdÚold_settingsÚchs      r   r   r   H   sŽ   € ä�Y‰Y×ÑÓˆÜ×(Ñ(¨Ó,ˆð	CÜ�J‰J”s—y‘y×'Ñ'Ó)Ô*Ü—‘—‘ Ó"ˆBä×Ñ˜b¤'×"3Ñ"3°\ÔBØˆ	øô ×Ñ˜b¤'×"3Ñ"3°\ÕBús   µAB, Â,'Cc                   ó   — e Zd ZdZd„ Zdd„Zy)ÚNonDataPropertyzNon-data property decorator.c                 óH   — |€J d«       ‚t        |«      sJ d«       ‚|| _        y)zInitialize a non-data property.Nzfget cannot be nonezfget must be callable)ÚcallableÚfget)Úselfr'   s     r   Ú__init__zNonDataProperty.__init__X   s-   € àÐÐ6Ð!6Ó6ÐÜ˜Œ~Ð6Ð6Ó6ˆ~Øˆ�	r
   Nc                 ó,   — |€| S | j                  |«      S )zReturn a class property.)r'   )r(   ÚobjÚobjtypes      r   Ú__get__zNonDataProperty.__get__^   s   € àˆ;ØˆKØ�y‰y˜‹~Ðr
   ©N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r)   r-   r   r
   r   r$   r$   U   s   „ Ù&òôr
   r$   c                   óT  — e Zd ZdZdZdZej                  j                  Z	dZ
dZdZdZdZdZdZdZdZed„ «       Zdd	„Zdd
„Zed„ «       Zej0                  d„ «       Zd„ Z	 	 	 	 	 d d„Zed„ «       ZdZd„ Zed„ «       Zd„ Z d!d„Z!d"d„Z"d!d„Z#d!d„Z$d!d„Z%d!d„Z&d!d„Z'd!d„Z(d!d„Z)d#d„Z*y)$ÚWebCasezHelper web test suite base.r   é@  úHTTP/1.1ÚhttpNúutf-8c                 óp   — | j                   j                  «       › d�}t        t        j                  |«      S )zuReturn HTTPConnection or HTTPSConnection based on self.scheme.

        * from :py:mod:`python:http.client`.
        Ú
Connection)ÚschemeÚupperÚgetattrr7   Úclient)r(   Úcls_names     r   Ú_ConnzWebCase._Conny   s/   € ð —k‘k×'Ñ'Ó)Ð*¨*Ð5ˆÜ”t—{‘{ HÓ-Ð-r
   c                 óˆ   — | j                  | j                  «       | j                  «      }||_        |j	                  «        |S )z'Return a connection to our HTTP server.)r@   r	   ÚPORTÚ	auto_openÚconnect)r(   rC   Úconns      r   Úget_connzWebCase.get_conn‚   s2   € à�z‰z˜$Ÿ.™.Ó*¨D¯I©IÓ6ˆà"ˆŒØ�‰ŒØˆr
   c                 óô   — t        j                  t        t        «      5  | j                  j                  «        ddd«       |r| j                  |¬«      | _        y| j                  | _        y# 1 sw Y   Œ5xY w)aY  Make our HTTP_CONN persistent (or not).

        If the 'on' argument is True (the default), then self.HTTP_CONN
        will be set to an instance of HTTP(S)?Connection
        to persist across requests.
        As this class only allows for a single open connection, if
        self already has an open connection, it will be closed.
        N)rC   )Ú
contextlibÚsuppressÚ	TypeErrorÚAttributeErrorÚ	HTTP_CONNÚcloserF   r@   )r(   ÚonrC   s      r   Úset_persistentzWebCase.set_persistentŠ   s`   € ô × Ñ ¤¬NÓ;ñ 	#Ø�N‰N× Ñ Ô"÷	#ñ 35ˆD�M‰M IˆMÓ.ð 	�Ø:>¿*¹*ð 	�÷	#ð 	#ús   ŸA.Á.A7c                 ó.   — t        | j                  d«      S )z+Presence of the persistent HTTP connection.Ú	__class__)ÚhasattrrL   ©r(   s    r   Ú
persistentzWebCase.persistentš   s   € ô �t—~‘~ {Ó3Ð3r
   c                 ó&   — | j                  |«       y r.   )rO   )r(   rN   s     r   rT   zWebCase.persistentŸ   s   € à×Ñ˜BÕr
   c                 ó,   — t        | j                  «      S )zºReturn an IP address for a client connection.

        If the server is listening on '0.0.0.0' (INADDR_ANY)
        or '::' (IN6ADDR_ANY), this will return the proper localhost.
        )r	   ÚHOSTrS   s    r   r	   zWebCase.interface£   s   € ô ˜Ÿ™Ó#Ð#r
   c                 ó”  — dt         _        t        |t        «      r|j	                  d«      }t        |t        «      r|j	                  d«      }|xs d}|| _        d| _        t        j                  «       }t        ||||| j                  | j                  | j                  |xs | j                  || j                  ¬«
      }t        j                  «       |z
  | _        |\  | _        | _        | _        | j                  D �	�
cg c]  \  }	}
|	j!                  «       dk(  sŒd|
f‘Œ c}
}	| _        t         j                  rt         ‚|S c c}
}	w )a;  Open the url with debugging support.

        Return status, headers, body.

        url should be the identifier passed to the server, typically a
        server-absolute path and query string (sent between method and
        protocol), and should only be an absolute URI if proxy support is
        enabled in the server.

        If the application under test generates absolute URIs, be sure
        to wrap them first with :py:func:`strip_netloc`::

            >>> class MyAppWebCase(WebCase):
            ...     def getPage(url, *args, **kwargs):
            ...         super(MyAppWebCase, self).getPage(
            ...             cheroot.test.webtest.strip_netloc(url),
            ...             *args, **kwargs
            ...         )

        ``raise_subcls`` is passed through to :py:func:`openURL`.
        Fr8   r   N)Úraise_subclsÚssl_contextz
set-cookieÚCookie)ÚServerErrorrN   Ú
isinstanceÚstrÚencodeÚurlÚtimeÚopenURLrW   rB   rL   ÚPROTOCOLrZ   ÚstatusÚheadersÚbodyÚlowerÚcookies)r(   r`   re   Úmethodrf   ÚprotocolrY   ÚstartÚresultÚkÚvs              r   ÚgetPagezWebCase.getPage«   s  € ð< ŒŒä�cœ3ÔØ—*‘*˜WÓ%ˆCÜ�dœCÔ Ø—;‘;˜wÓ'ˆDð $Ò) rˆàˆŒØˆŒ	Ü—	‘	“ˆÜØØØØØ�I‰IØ�I‰IØ�N‰NØÒ%˜Ÿ™Ø%Ø×(Ñ(ô
ˆô —I‘I“K %Ñ'ˆŒ	Ø/5Ñ,ˆŒ�T”\ 4¤9ð '+§l¡l÷
Ù"˜a °a·g±g³iÀ<Ó6OˆX�qŠMó
ˆŒô �>Š>ÜÐØˆùó
s   ÄEÄEc                 óÚ   — t         j                  j                  dd«      }t        t	        j
                  |j                  «       «      «      }|rt        j                  dt        d¬«       |S )zÌDetermine whether tests are run in interactive mode.

        Load interactivity setting from environment, where
        the value can be numeric or a string like true or
        False or 1 or 0.
        ÚWEBTEST_INTERACTIVEÚTruezhInteractive test failure interceptor support via WEBTEST_INTERACTIVE environment variable is deprecated.r   )Ú
stacklevel)
ÚosÚenvironÚgetÚboolÚjsonÚloadsrg   ÚwarningsÚwarnÚDeprecationWarning)r(   Úenv_strÚis_interactives      r   ÚinteractivezWebCase.interactiveî   sU   € ô —*‘*—.‘.Ð!6¸Ó?ˆÜœdŸj™j¨¯©«Ó9Ó:ˆÙÜ�M‰MðJä"Øõ	ð Ðr
   é   c                 ó”  — t        «        t        d|z  «       | j                  s| j                  |«      ‚d}t        j                  j                  |«       t        j                  j                  «        	 t        «       j                  «       }t        |t        «      s|j                  d«      }|dvrŒ?t        |j                  «       «       |dk(  r©t        | j                  j                  «       «      D ]‚  \  }}|dz   | j                  z  dk(  r]t        j                  j                  d«       t        «       j!                  «       }t        j                  j                  d	«       |d
k(  r nžt        |«       Œ„ n�|dk(  r t#        j"                  | j$                  «       nk|dk(  rt        | j&                  «       nP|dk(  rt        | j(                  «       n5|dk(  ry |dk(  r| j                  |«      ‚|dk(  rt        j*                  «        t        j                  j                  |«       t        j                  j                  «        �ŒÔ)Nz    ERROR: %szO    Show: [B]ody [H]eaders [S]tatus [U]RL; [I]gnore, [R]aise, or sys.e[X]it >> ÚasciiÚBHSUIRXÚBr   r   z<-- More -->z            ÚqÚHÚSÚUÚIÚRÚX)Úprintr   ÚfailureExceptionr   ÚstdoutÚwriteÚflushr   r<   r]   r^   ÚdecodeÚ	enumeraterf   Ú
splitlinesÚconsole_heightrg   Úpprintre   rd   r`   Úexit)r(   ÚmsgÚpÚiÚxÚlineÚms          r   Ú_handlewebErrorzWebCase._handlewebError  s¾  € ÜŒÜˆo Ñ#Ô$à×ÒØ×'Ñ'¨Ó,Ð,ð3ð 	
ô
 	�
‰
×Ñ˜ÔÜ�
‰
×ÑÔØÜ“	—‘Ó!ˆAÜ˜a¤Ô%Ø—H‘H˜WÓ%�Ø˜	Ñ!ØÜ�!—'‘'“)ÔØ�CŠxÜ(¨¯©×)=Ñ)=Ó)?Ó@ò 	 ‘G�A�tØ˜A™ ×!4Ñ!4Ñ4¸Ò9äŸ
™
×(Ñ(Ð)9Ô:Ü#›IŸO™OÓ-˜äŸ
™
×(Ñ(Ð)9Ô:Ø š8Ù!Ü˜$•Kñ	 ð �c’Ü—‘˜dŸl™lÕ+Ø�c’Ü�d—k‘kÕ"Ø�c’Ü�d—h‘h•Ø�c’àØ�c’Ø×+Ñ+¨CÓ0Ð0Ø�c’Ü—‘”
Ü�J‰J×Ñ˜QÔÜ�J‰J×ÑÔñA r
   c                 ó2   — t        | j                  dd «      S )zInteger HTTP status code.Né   )Úintrd   rS   s    r   Ústatus_codezWebCase.status_code3  s   € ô �4—;‘;˜r �?Ó#Ð#r
   c                 ó\   — t        |t        «      r| j                  n| j                  }||k(  S )z-Check whether actual status matches expected.)r]   r    r¡   rd   )r(   ÚexpectedÚactuals      r   Ústatus_matcheszWebCase.status_matches8  s'   € ä%/°¼#Ô%>�×!Ò!ÀDÇKÁKˆØ˜6Ñ!Ð!r
   c                 ó¤   — t        t        | j                  t        |«      «      «      ryd| j                  › d|› �}| j                  |xs |«       y)z�Fail if self.status != status.

        status may be integer code, exact string status, or
        iterable of allowed possibilities.
        NzStatus z does not match )ÚanyÚmapr¥   r   rd   r�   )r(   rd   r—   Útmpls       r   ÚassertStatuszWebCase.assertStatus=  sJ   € ô Œs�4×&Ñ&¬¸Ó(?Ó@ÔAØà˜Ÿ™˜Ð%5°f°XÐ>ˆØ×Ñ˜Sš[ DÕ)r
   c                 óâ   — |j                  «       }| j                  D ]-  \  }}|j                  «       |k(  sŒ|�t        |«      |k(  sŒ+|c S  |€|€d|z  }n|›d|›d�}| j                  |«       y)z+Fail if (key, [value]) not in self.headers.Nz%r not in headersú:z not in headers)rg   re   r^   r�   )r(   ÚkeyÚvaluer—   Úlowkeyrm   rn   s          r   ÚassertHeaderzWebCase.assertHeaderI  sw   € à—‘“ˆØ—L‘Lò 	‰DˆAˆqØ�w‰w‹y˜FÓ"Ø�=¤C¨£J°!£OØ’Hð	ð
 ˆ;Øˆ}Ø)¨CÑ/‘â03²UÐ;�Ø×Ñ˜SÔ!Ør
   c                 ó  — |j                  «       }| j                  D ]=  \  }}|j                  «       |k(  sŒ|D �cg c]  }t        |«      |k(  sŒ|‘Œ }}|sŒ;|c S  |€dt        «       z  }| j	                  |«       yc c}w )z?Fail if header indicated by key doesn't have one of the values.Nz%(key)r not in %(values)r)rg   re   r^   Úvarsr�   )	r(   r­   Úvaluesr—   r¯   rm   rn   r®   Úmatchess	            r   ÚassertHeaderInzWebCase.assertHeaderInY  s�   € à—‘“ˆØ—L‘Lò 	#‰DˆAˆqØ�w‰w‹y˜FÓ"Ø.4ÖH U¼¸E»
Àa»š5ÐH�ÐHÚØ"’Nð		#ð ˆ;Ø-´³Ñ6ˆCØ×Ñ˜SÔ!Øùò Is   »A>ÁA>c                 ó¼   — | j                  ||¬«      }t        t        j                  |j	                  d«      «      }||v r|S |€|›d|›�}| j                  |«       y)z8Fail if the header does not contain the specified value.)r—   ú,Nz not in )r°   r¨   r^   ÚstripÚsplitr�   )r(   r­   r®   r—   Úactual_valueÚheader_valuess         r   ÚassertHeaderItemValuezWebCase.assertHeaderItemValueg  s_   € à×(Ñ(¨°#Ð(Ó6ˆÜœCŸI™I |×'9Ñ'9¸#Ó'>Ó?ˆØ�MÑ!ØˆLàˆ;Ú$)©=Ð9ˆCØ×Ñ˜SÔ!Ør
   c                 óÊ   — |j                  «       }| j                  D ��cg c]  \  }}|j                  «       |k(  sŒ|‘Œ }}}|r|€d|z  }| j                  |«       yyc c}}w )zFail if key in self.headers.Nz%r in headers©rg   re   r�   )r(   r­   r—   r¯   rm   rn   r´   s          r   ÚassertNoHeaderzWebCase.assertNoHeaders  s`   € à—‘“ˆØ!%§¡×E™˜˜A°·±³¸fÓ1D’1ÐEˆÑEÙØˆ{Ø%¨Ñ+�Ø× Ñ  Õ%ð ùó Fs
    A¼Ac                 óä   — |j                  «       }| j                  }|D ��cg c]!  \  }}|j                  «       |k(  sŒ||k(  sŒ |‘Œ# }}}|r|€
|›d|›d|›�}| j                  |«       yyc c}}w )z0Fail if the header contains the specified value.Nr¬   z in r¾   )	r(   r­   r®   r—   r¯   Úhdrsrm   rn   r´   s	            r   ÚassertNoHeaderItemValuezWebCase.assertNoHeaderItemValue|  sm   € à—‘“ˆØ�|‰|ˆØ!%×L™˜˜A¨¯©«°fÓ)<ÀÀeÃ’1ÐLˆÑLÙØˆ{Ú'*ªE±4Ð8�Ø× Ñ  Õ%ð ùó Ms   ¢A,¾A,ÁA,c                 óÄ   — t        |t        «      r|j                  | j                  «      }|| j                  k7  r&|€d|›d| j                  ›�}| j                  |«       yy)zFail if value != self.body.Nzexpected body:
z

actual body:
©r]   r^   r_   Úencodingrf   r�   ©r(   r®   r—   s      r   Ú
assertBodyzWebCase.assertBody†  sU   € ä�eœSÔ!Ø—L‘L §¡Ó/ˆEØ�D—I‘IÒØ‰{âØ—I’Ið�ð × Ñ  Õ%ð r
   c                 óÀ   — t        |t        «      r|j                  | j                  «      }|| j                  vr%|€|›d| j                  ›�}| j                  |«       yy)zFail if value not in self.body.Nz not in body: rÄ   rÆ   s      r   ÚassertInBodyzWebCase.assertInBody’  sP   € ä�eœSÔ!Ø—L‘L §¡Ó/ˆEØ˜Ÿ	™	Ñ!Øˆ{Ú.3°T·Y²YÐ?�Ø× Ñ  Õ%ð "r
   c                 ó¨   — t        |t        «      r|j                  | j                  «      }|| j                  v r|€d|z  }| j                  |«       yy)zFail if value in self.body.Nz%r found in bodyrÄ   rÆ   s      r   ÚassertNotInBodyzWebCase.assertNotInBody›  sL   € ä�eœSÔ!Ø—L‘L §¡Ó/ˆEØ�D—I‘IÑØˆ{Ø(¨5Ñ0�Ø× Ñ  Õ%ð r
   c                 óÎ   — t        |t        «      r|j                  | j                  «      }t	        j
                  || j                  |«      €|€d|z  }| j                  |«       yy)z4Fail if value (a regex pattern) is not in self.body.NzNo match for %r in body)r]   r^   r_   rÅ   ÚreÚsearchrf   r�   )r(   Úpatternr—   Úflagss       r   ÚassertMatchesBodyzWebCase.assertMatchesBody¤  sW   € ä�gœsÔ#Ø—n‘n T§]¡]Ó3ˆGÜ�9‰9�W˜dŸi™i¨Ó/Ð7Øˆ{Ø/°'Ñ9�Ø× Ñ  Õ%ð 8r
   )F)TF)NÚGETNNr   r.   )NN)Nr   )+r/   r0   r1   r2   rW   rB   r7   r>   ÚHTTPConnectionrL   rc   r;   r`   rZ   rd   re   rf   rÅ   ra   Úpropertyr@   rF   rO   rT   Úsetterr	   ro   r$   r   r”   r�   r¡   r¥   rª   r°   rµ   r¼   r¿   rÂ   rÇ   rÉ   rË   rÑ   r   r
   r   r4   r4   e   s  „ Ù%à€DØ€DØ—‘×*Ñ*€IØ€Hà€FØ
€CØ€Kà€FØ€GØ€Dà€Hà€Dàñ.ó ð.óó
ð  ñ4ó ð4ð ×Ññ ó ð ò$ð ØØØØóAðF ñó ðð$ €Nò.ð` ñ$ó ð$ò"ó

*óó ó
ó&ó&ó
&ó&ó&ô&r
   r4   )ÚPOSTÚPUTÚPATCHc           	      óˆ  — | €g } d}| D ]  \  }}|j                  «       dk(  sŒd} n |s1|dk(  r| j                  d|f«       n| j                  d|›d|›�f«       |t        v r_d}| D ]  \  }}|j                  «       dk(  sŒd} n |s:| j                  d«       | j                  d	t        t	        |xs d
«      «      f«       | S )zAReturn request headers, with required headers added (if missing).Fr   TéP   ÚHostr¬   zcontent-type)zContent-Typez!application/x-www-form-urlencodedzContent-LengthÚ )rg   ÚappendÚmethods_with_bodiesr^   Úlen)re   ri   rf   r   ÚportÚfoundrm   Ú_vs           r   ÚcleanHeadersrã   ±  sß   € à€Øˆð €EØò ‰ˆˆ2Ø�7‰7‹9˜ÓØˆEÙðñ Ø�2Š:Ø�N‰N˜F D˜>Õ*à�N‰N˜Fªt±TÐ$:Ð;Ô<àÔ$Ñ$àˆØò 	‰EˆAˆrØ�w‰w‹y˜NÓ*Ø�Ùð	ñ Ø�N‰NØEôð �N‰NÐ,¬c´#°d²j¸b³/Ó.BÐCÔDà€Nr
   c                 óz   — | j                   ›d| j                  ›�}|| j                  «       | j                  «       fS )z=Return status, headers, body the way we like from a response.ú )rd   ÚreasonÚ
getheadersr   )ÚresponseÚresp_status_lines     r   Úshbrê   Ó  s1   € à"*§/£/°8·?²?ÐCÐà˜X×0Ñ0Ó2°H·M±M³OÐCÐCr
   r   )rY   c                 óª   ‡ — t        j                  t        g|¢­i |¤Ž}ˆ fd„}t        j                   j	                  |d|t
        j                  ¬«      S )z·
    Open a URL, retrying when it fails.

    Specify ``raise_subcls`` (class or tuple of classes) to exclude
    those socket.error subclasses from being suppressed and retried.
    c                  óz   •— t        j                  «       d   } t        | ‰«      r| ‚t        j                  d«       y )Nr   g      à?)r   Úexc_infor]   ra   Úsleep)ÚexcrY   s    €r   Úon_exceptionzopenURL.<locals>.on_exceptionã  s-   ø€ Ü�l‰l‹n˜QÑˆÜ�c˜<Ô(ØˆIÜ�
‰
�3�r
   é	   )ÚretriesÚcleanupÚtrap)Ú	functoolsÚpartialÚ_open_url_onceÚjaracoÚ
retry_callÚsocketÚerror)rY   ÚargsÚkwargsÚopenerrð   s   `    r   rb   rb   Ú  sT   ø€ ô ×Ñœ~Ð?°Ò?¸Ñ?€Fôô ×Ñ×&Ñ&ØØØÜ�\‰\ð	 'ó ð r
   rÒ   r   r5   r6   c	           	      ó¬  — t        |||||«      }t        |d«      r|}	ni }
|r||
d<    |t        |«      |fi |
¤Ž}	||	_        t	        dj                  |D �cg c]  }|j                  «       sŒ|‘Œ c}«      «      |	_        t        | t        «      r| j                  «       } |	j                  |j                  «       | dd¬«       |D ]&  \  }}|	j                  ||j                  d«      «       Œ( |	j                  «        |�|	j!                  |«       |	j#                  «       }t%        |«      \  }}}t        |d«      s|	j'                  «        |||fS c c}w )zBOpen the given HTTP resource and return status, headers, and body.r   ÚcontextrÜ   T)Ú	skip_hostÚskip_accept_encodingzLatin-1)rã   rR   r	   Ú_http_vsn_strr    ÚjoinÚisdigitÚ	_http_vsnr]   Úbytesr‘   Ú
putrequestr<   Ú	putheaderr_   Ú
endheadersÚsendÚgetresponserê   rM   )r`   re   ri   rf   r   rà   Ú	http_connrj   rZ   rE   Úkwrš   r­   r®   rè   ÚsÚhÚbs                     r   r÷   r÷   ò  s=  € ô ˜7 F¨D°$¸Ó=€Gô ˆy˜&Ô!Ø‰àˆÙØ'ˆBˆy‰MÙœ 4›¨$Ñ5°"Ñ5ˆØ!€DÔÜ˜Ÿ™¨XÖ!E¨¸¿¹½¢!Ò!EÓFÓG€D„NÜ�#”uÔØ�j‰j‹lˆØ‡O�OØ�‰‹ØØØ!ð	 ô ð ò 5‰
ˆˆUØ�‰�s˜EŸL™L¨Ó3Õ4ð5à‡O�OÔØÐØ�	‰	�$Œà×ÑÓ!€HÜ�(‹m�G€A€qˆ!Ü�9˜fÔ%à�
‰
ŒØˆa�ˆ7€Nùò) "Fs   ÁEÁ,Ec                 ó    — t         j                  j                  | «      }|\  }}}}}}dd|||df}t         j                  j                  |«      S )a'  Return absolute-URI path from URL.

    Strip the scheme and host from the URL, returning the
    server-absolute portion.

    Useful for wrapping an absolute-URI for which only the
    path is expected (such as in calls to :py:meth:`WebCase.getPage`).

    .. testsetup::

       from cheroot.test.webtest import strip_netloc

    >>> strip_netloc('https://google.com/foo/bar?bing#baz')
    '/foo/bar?bing'

    >>> strip_netloc('//google.com/foo/bar?bing#baz')
    '/foo/bar?bing'

    >>> strip_netloc('/foo/bar?bing#baz')
    '/foo/bar?bing'
    rÜ   )ÚurllibÚparseÚurlparseÚ
urlunparse)	r`   ÚparsedÚ_schemeÚ_netlocÚpathÚparamsÚqueryÚ	_fragmentÚstrippeds	            r   Ústrip_netlocr     sQ   € ô, �\‰\×"Ñ" 3Ó'€FØ7=Ñ4€GˆW�d˜F E¨9Ø�2�t˜V U¨BÐ.€HÜ�<‰<×"Ñ" 8Ó,Ð,r
   Fc                   ó   — e Zd ZdZdZy)r\   z&Exception for signalling server error.FN)r/   r0   r1   r2   rN   r   r
   r   r\   r\   F  s
   „ Ù0à	�Br
   r\   c                 óÒ   — | €t        j                  «       } t        s| d   t        v rydt        _        t        «        t        dj                  t        j                  | Ž «      «       y)zÁServer debug hook.

    Return True if exception handled, False if ignored.
    You probably want to wrap this, so you can still handle an error using
    your framework when it's ignored.
    r   FTrÜ   )
r   rí   Ú
ignore_allÚignored_exceptionsr\   rN   rŒ   r  Ú	tracebackÚformat_exception)rï   s    r   Úserver_errorr&  L  sQ   € ð €{Ü�l‰l‹nˆå�S˜‘VÔ1Ñ1ØØ„K„NÜ	„GÜ	ˆ"�'‰'”)×,Ñ,¨cÐ2Ó
3Ô4Ør
   r.   ),r2   rH   rõ   Úhttp.clientr7   rx   rt   r•   rÍ   rú   r   ra   r$  ÚunittestÚurllib.parser  rz   Újaraco.functoolsrø   Úmore_itertools.morer   r	   Úplatformr   r   ÚImportErrorr   r   r$   ÚTestCaser4   rÞ   rã   rê   rb   r>   rÓ   r÷   r  r#  r"  Ú	Exceptionr\   r&  r   r
   r   ú<module>r0     s  ðñó" Û Û Û Û 	Û Û 	Û Û 
Û Û Û Û Û ã Ý /òðà
‡|�|�B�QÐ˜6Ò!ó	%ó 	ò	"÷*ñ ô F&ˆh×Ñô F&ðR
 /Ð òòDDð !#ô ð4 ØØ	Ø	Ø	Ø�k‰k×(Ñ(ØØó+ò\-ð< Ð ð
 €
ô�)ô ôøðS ò ãÛô	ðús   Á	C
 Ã
CÃC