Ë
    "ïàjŠV  ã                   óº   — d Z ddl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mZ ddlmZ dZ ej"                  d	«      Zd
„ Zd„ Zd„ Zd„ Zd„ Z G d„ d«      Zy)a©  
Implements the `LockManager` object that provides the locking functionality.

The LockManager requires a LockStorageDict object to implement persistence.
Two alternative lock storage classes are defined in the lock_storage module:

- wsgidav.lock_man.lock_storage.LockStorageDict
- wsgidav.lock_man.lock_storage.LockStorageShelve


The lock data model is a dictionary with these fields:

    root:
        Resource URL.
    principal:
        Name of the authenticated user that created the lock.
    type:
        Must be 'write'.
    scope:
        Must be 'shared' or 'exclusive'.
    depth:
        Must be '0' or 'infinity'.
    owner:
        String identifying the owner.
    timeout:
        Seconds remaining until lock expiration.
        This value is passed to create() and refresh()
    expire:
        Converted timeout for persistence: expire = time() + timeout.
    token:
        Automatically generated unique token.

é    N)Úcontextmanager)Úpformat)Úutil)ÚHTTP_LOCKEDÚDAVErrorÚDAVErrorConditionÚPRECONDITION_CODE_LockConflict)ÚReadWriteLockÚreStructuredTextzwsgidav.lock_manc                  ój   — dt        j                  t        t        j                  d«      «      «      z   S )Nzopaquelocktoken:é   )r   Úto_strÚhexÚsecretsÚrandbits© ó    úL/srv/dav/.venv/lib/python3.12/site-packages/wsgidav/lock_man/lock_manager.pyÚgenerate_lock_tokenr   ?   s&   € Ø¤§¡¬C´×0@Ñ0@ÀÓ0EÓ,FÓ GÑGÐGr   c                 ó`   — | sJ ‚t        j                  | «      } d| j                  d«      z   } | S )Nú/)r   r   Ústrip)Úpaths    r   Únormalize_lock_rootr   C   s.   € á€Kˆ4Ü�;‰;�tÓ€DØ�—‘˜C“Ñ €DØ€Kr   c                 óZ   — t        | d   «      }|dk\  xr |t        j                  «       k  S )NÚexpirer   )ÚfloatÚtime)Úlockr   s     r   Úis_lock_expiredr    K   s*   € Ü�4˜‘>Ó"€FØ�Q‰;Ò/˜6¤D§I¡I£KÑ/Ð/r   c           	      óŒ  — | sy| d   dk  rdj                  | d   «      }n@dj                  t        j                  | d   «      | d   t        j                  «       z
  «      }dj                  | j	                  dd«      d	d
 | j	                  d«      | j	                  d«      | j	                  d«      | j	                  d«      |«      S )zReturn readable rep.z
Lock: Noner   r   zInfinite ({})z{} (in {} seconds)z-Lock(<{}..>, {!r}, {}, {}, depth-{}, until {}Útokenz??????????????????????????????é   é   ÚrootÚ	principalÚscopeÚdepth)Úformatr   Úget_log_timer   Úget)Ú	lock_dictr   s     r   Úlock_stringr-   P   s¼   € áØà�Ñ˜QÒØ ×'Ñ'¨	°(Ñ(;Ó<‰à%×,Ñ,Ü×Ñ˜i¨Ñ1Ó2°I¸hÑ4GÌ$Ï)É)Ë+Ñ4Uó
ˆð ;×AÑAà�‰�g˜xÓ(¨¨BÐ/Ø�‰�fÓØ�‰�kÓ"Ø�‰�gÓØ�‰�gÓØóð r   c                 óŠ  — t        j                  | d   «      sJ ‚| d   j                  d«      sJ ‚| d   dk(  sJ ‚| d   dv sJ ‚| d   dv sJ ‚t        j                  | d	   «      sJ | «       ‚t	        | d
   «      }|dkD  s|dk(  sJ d«       ‚t        j                  | d   «      sJ ‚d| v rt        j                  | d   «      sJ ‚y y )Nr%   r   ÚtypeÚwriter'   ©ÚsharedÚ	exclusiver(   ©Ú0ÚinfinityÚownerÚtimeoutr   éÿÿÿÿztimeout must be positive or -1r&   r"   )r   Úis_strÚ
startswithÚis_bytesr   )r   r8   s     r   Úvalidate_lockr=   g   sã   € Ü�;‰;�t˜F‘|Ô$Ð$Ð$Ø�‰<×"Ñ" 3Ô'Ð'Ð'Ø�‰<˜7Ò"Ð"Ð"Ø�‰=Ð3Ñ3Ð3Ð3Ø�‰=Ð-Ñ-Ð-Ð-Ü�=‰=˜˜g™Ô'Ð-¨Ó-Ð'ä�D˜‘OÓ$€GØ�QŠ;˜' Rš-ÐIÐ)IÓIÐ'Ü�;‰;�t˜KÑ(Ô)Ð)Ð)Ø�$�Ü�{‰{˜4 ™=Ô)Ð)Ñ)ð r   c                   óÈ   — e Zd ZdZdZd„ Zd„ Zd„ Zd d„Zd„ Z	d„ Z
d	d
œd„Zd„ Zed	d
œd„«       Zddœd„Zddœd„Zd„ Zd„ Zddœd„Zddœd„Zd„ Zd„ Zddœd„Zd„ Zd„ Zd„ Zy)!ÚLockManagerzI
    Implements locking functionality using a custom storage layer.

    i€:	 c                 óŽ   — t        |d«      sJ ‚t        «       | _        || _        | j                  j	                  «        i | _        y)z@
        storage:
            LockManagerStorage object
        Úget_lock_listN)Úhasattrr
   Ú_lockÚstorageÚopenÚ_active_writes)ÚselfrD   s     r   Ú__init__zLockManager.__init__�   s>   € ô
 �w Ô0Ð0Ð0Ü"“_ˆŒ
ØˆŒØ�‰×ÑÔð !ˆÕr   c                 ó8   — | j                   j                  «        y )N)rD   Úclose©rG   s    r   Ú__del__zLockManager.__del__‘   s   € Ø�‰×ÑÕr   c                 óN   — | j                   j                  › d| j                  ›d�S )Nú(ú))Ú	__class__Ú__name__rD   rK   s    r   Ú__repr__zLockManager.__repr__”   s%   € Ø—.‘.×)Ñ)Ð*¨!¨D¯L©LÐ+;¸1Ð=Ð=r   c                 ó´  — i }i }i }i }t         j                  | › d|› �«       | j                  j                  dddd¬«      D ]�  }|d   }t	        |«      ||<   |j                  |d   g «      j                  |«       |j                  |d   g «      j                  |«       |j                  |d	   g «      j                  |«       Œƒ t         j                  d
t        |dd¬«      › �«       |rmt         j                  dt        |dd¬«      › �«       t         j                  dt        |dd¬«      › �«       t         j                  dt        |dd¬«      › �«       y y )Nz: r   TF©Úinclude_rootÚinclude_childrenÚ
token_onlyr"   r&   r7   r%   zLocks:
r   éÿ   )ÚindentÚwidthzLocks by URL:
é   zLocks by principal:
zLocks by owner:
)Ú_loggerÚinforD   rA   r-   Ú
setdefaultÚappendr   )rG   ÚmsgÚurlDictÚ	ownerDictÚuserDictÚ	tokenDictr   Útoks           r   Ú_dumpzLockManager._dump—   sU  € ØˆØˆ	ØˆØˆ	ä�‰˜�v˜R ˜uÐ%Ô&à—L‘L×.Ñ.Ø˜d°TÀeð /ó 
ò 	=ˆDð �w‘-ˆCÜ(¨Ó.ˆI�c‰NØ×Ñ  [Ñ 1°2Ó6×=Ñ=¸cÔBØ× Ñ   g¡°Ó3×:Ñ:¸3Ô?Ø×Ñ˜t F™|¨RÓ0×7Ñ7¸Õ<ð	=ô 	�‰�x¤¨	¸!À3Ô GÐHÐIÔJÙÜ�L‰L˜?¬7°7À1ÈCÔ+PÐ*QÐRÔSÜ�L‰LØ'¬°ÀÈ#Ô(NÐ'OÐPôô �L‰LÐ,¬W°YÀqÐPSÔ-TÐ,UÐVÕWð r   c                 ó†   — |€t         j                  }n|dk  rd}|||||||dœ}| j                  j                  ||«       |S )aå  Acquire lock and return lock_dict.

        principal
            Name of the principal.
        lock_type
            Must be 'write'.
        lock_scope
            Must be 'shared' or 'exclusive'.
        lock_depth
            Must be '0' or 'infinity'.
        lock_owner
            String identifying the owner.
        path
            Resource URL.
        timeout
            Seconds to live

        This function does NOT check, if the new lock creates a conflict!
        r   r9   )r%   r/   r'   r(   r7   r8   r&   )r?   ÚLOCK_TIME_OUT_DEFAULTrD   Úcreate)	rG   r&   Ú	lock_typeÚ
lock_scopeÚ
lock_depthÚ
lock_ownerr   r8   r,   s	            r   Ú_generate_lockzLockManager._generate_lock°   sZ   € ð, ˆ?Ü!×7Ñ7‰GØ�qŠ[ØˆGð ØØØØØØ"ñ
ˆ	ð 	�‰×Ñ˜D )Ô,ØÐr   c          	      ó  — t        |«      }| j                  j                  «        	 | j                  ||||||«       | j	                  |||||||«      | j                  j                  «        S # | j                  j                  «        w xY w)z¨Check for permissions and acquire a lock.

        On success return new lock dictionary.
        On error raise a DAVError with an embedded DAVErrorCondition.
        )r   rC   Úacquire_writeÚ_check_lock_permissionrn   Úrelease)	rG   Úurlrj   rk   rl   rm   r8   r&   Ú
token_lists	            r   ÚacquirezLockManager.acquireØ   s€   € ô" " #Ó&ˆØ�
‰
× Ñ Ô"ð		!à×'Ñ'Ø�Y 
¨J¸
ÀIôð ×&Ñ&Ø˜9 j°*¸jÈ#Èwóð �J‰J×ÑÕ øˆD�J‰J×ÑÕ ús   §,A. Á.B
r5   )r(   c                ó”  — t        |«      }| j                  j                  «        	 | j                  ||||«      }t	        |j
                  «      dkD  rt        t        |¬«      ‚| j                  j                  |d«      dz   | j                  |<   | j                  j                  «        y# | j                  j                  «        w xY w)a  Atomically check write permission and mark <url> as being written.

        Must be paired with a call to end_write_transaction(), typically in
        a try/finally block. This closes the TOCTOU race where a LOCK is
        granted to another principal after the write-permission check but
        before the (potentially slow) request body has been written
        (CWE-367): as long as the transaction is active, acquire() will
        deny new locks on <url>.

        On error (conflicting lock) raise a DAVError(HTTP_LOCKED).
        r   ©Úerr_conditioné   N)r   rC   rp   Ú_get_write_conflictsÚlenÚhrefsr   r   rF   r+   rr   )rG   rs   rt   r&   r(   Úerrconds         r   Ú_begin_write_transactionz$LockManager._begin_write_transactionö   s    € ô " #Ó&ˆØ�
‰
× Ñ Ô"ð	!Ø×/Ñ/°°U¸JÈ	ÓRˆGÜ�7—=‘=Ó! AÒ%Üœ{¸'ÔBÐBØ'+×':Ñ':×'>Ñ'>¸sÀAÓ'FÈÑ'JˆD×Ñ Ñ$à�J‰J×ÑÕ øˆD�J‰J×ÑÕ ús   §A)B+ Â+Cc                 ób  — t        |«      }| j                  j                  «        	 | j                  j	                  |d«      dz
  }|dk  r| j                  j                  |d«       n|| j                  |<   | j                  j                  «        y# | j                  j                  «        w xY w)z3Clear the marker set by _begin_write_transaction().r   ry   N)r   rC   rp   rF   r+   Úpoprr   )rG   rs   Úcounts      r   Ú_end_write_transactionz"LockManager._end_write_transaction  sŒ   € ä! #Ó&ˆØ�
‰
× Ñ Ô"ð	!Ø×'Ñ'×+Ñ+¨C°Ó3°aÑ7ˆEØ˜ŠzØ×#Ñ#×'Ñ'¨¨TÕ2à+0�×#Ñ# CÑ(à�J‰J×ÑÕ øˆD�J‰J×ÑÕ ús   §AB ÂB.c             #   óŽ   K  — | j                  ||||¬«       	 d–— | j                  |«       y# | j                  |«       w xY w­w)zACheck write permission and clear the marker when the block exits.)rs   rt   r&   r(   N)r~   r‚   )rG   rs   rt   r&   r(   s        r   Úwrite_transactionzLockManager.write_transaction  sK   è ø€ ð 	×%Ñ%ØØ!ØØð	 	&ô 	
ð	-Ûà×'Ñ'¨Õ,øˆD×'Ñ'¨Õ,üs   ‚A™/ �A¯AÁAN©r8   c                ó`   — |€t         j                  }| j                  j                  ||¬«      S )z0Set new timeout for lock, if existing and valid.r…   )r?   rh   rD   Úrefresh)rG   r"   r8   s      r   r‡   zLockManager.refresh'  s,   € àˆ?Ü!×7Ñ7ˆGØ�|‰|×#Ñ# E°7Ð#Ó;Ð;r   ©Úkeyc                óZ   — |dv sJ ‚| j                   j                  |«      }|�|€|S ||   S )zîReturn lock_dict, or None, if not found or invalid.

        Side effect: if lock is expired, it will be purged and None is returned.

        key:
            name of lock attribute that will be returned instead of a dictionary.
        )	Nr/   r'   r(   r7   r%   r8   r&   r"   )rD   r+   )rG   r"   r‰   r   s       r   Úget_lockzLockManager.get_lock-  sI   € ð ð 

ñ 

ð 
	
ð 

ð �|‰|×Ñ Ó&ˆØˆ;˜$˜,ØˆKØ�C‰yÐr   c                 ó:   — | j                   j                  |«       y)zDelete lock.N)rD   Údelete)rG   r"   s     r   rr   zLockManager.releaseE  s   € à�‰×Ñ˜EÕ"r   c                 ó.   — | j                  |d¬«      |k(  S )zCReturn True, if <token> exists, is valid, and bound to <principal>.r&   rˆ   )r‹   )rG   r"   r&   s      r   Úis_token_locked_by_userz#LockManager.is_token_locked_by_userI  s   € à�}‰}˜U¨ˆ}Ó4¸	ÑAÐAr   F©Ú	recursivec                óZ   — t        |«      }| j                  j                  |d|d¬«      }|S )z™Return list of lock_dict, if <url> is protected by at least one direct, valid lock.

        Side effect: expired locks for this url are purged.
        TFrT   )r   rD   rA   )rG   rs   r‘   ÚlockLists       r   Úget_url_lock_listzLockManager.get_url_lock_listM  s7   € ô
 " #Ó&ˆØ—<‘<×-Ñ-Ø˜d°YÈ5ð .ó 
ˆð ˆr   )r&   c                óø   — t        |«      }g }|}|rh| j                  j                  |ddd¬«      }|D ],  }||k7  r	|d   dk7  rŒ|�	||d   k(  sŒ|j                  |«       Œ. t	        j
                  |«      }|rŒh|S )zöReturn a list of valid lockDicts, that protect <path> directly or indirectly.

        If a principal is given, only locks owned by this principal are returned.
        Side effect: expired locks for this path and all parents are purged.
        TFrT   r(   r6   r&   )r   rD   rA   r_   r   Úget_uri_parent)rG   rs   r&   r“   ÚuÚ	lock_listr   s          r   Úget_indirect_url_lock_listz&LockManager.get_indirect_url_lock_listX  s¡   € ô " #Ó&ˆØˆØˆÙØŸ™×2Ñ2Ø °uÈð 3ó ˆIð "ò *�Ø˜’8  W¡°Ò ;Øð
 Ð$¨	°T¸+Ñ5FÓ(FØ—O‘O DÕ)ð*ô ×#Ñ# AÓ&ˆAò ð ˆr   c                 ó@   — | j                  |«      }t        |«      dkD  S )z'Return True, if url is directly locked.r   )r”   r{   )rG   rs   r“   s      r   Úis_url_lockedzLockManager.is_url_lockedq  s!   € à×)Ñ)¨#Ó.ˆÜ�8‹}˜qÑ Ð r   c                 ó\   — | j                  |d¬«      }|xr t        j                  ||«      S )z?Check, if url (or any of it's parents) is locked by lock_token.r%   rˆ   )r‹   r   Úis_equal_or_child_uri)rG   rs   Ú
lock_tokenÚlockUrls       r   Úis_url_locked_by_tokenz"LockManager.is_url_locked_by_tokenv  s,   € à—-‘- 
°�-Ó7ˆØÒCœ4×5Ñ5°g¸sÓCÐCr   c                ó
  — | j                   j                  «        	 | j                  ||¬«      }|D ]  }| j                  |d   «       Œ 	 | j                   j                  «        y # | j                   j                  «        w xY w)Nr�   r"   )rC   rp   r”   rr   )rG   rs   r‘   r“   r   s        r   Úremove_all_locks_from_urlz%LockManager.remove_all_locks_from_url{  sn   € Ø�
‰
× Ñ Ô"ð	!Ø×-Ñ-¨c¸YÐ-ÓGˆHØ ò ,�Ø—‘˜T '™]Õ+ñ,ð �J‰J×ÑÕ øˆD�J‰J×ÑÕ ús   œ.A& Á&Bc                 ó   — |dk(  sJ ‚|dv sJ ‚|dv sJ ‚t         j                  d|› d|› d|› d|› d�	«       t        t        «      }| j                  j                  «        	 |}|r¥| j                  |«      }	|	D ]w  }
t         j                  d|› dt        |
«      › �«       ||k7  r	|
d   d	k7  rŒ5|
d
   dk(  r|dk(  rŒCt         j                  dt        |
«      › �«       |j                  |
d   «       Œy t        j                  |«      }|rŒ¥| j                  j                  |«      r)t         j                  d|› �«       |j                  |«       |d	k(  rÛ| j                  j                  |ddd¬«      }|D ]R  }
t        j                   ||
d   «      sJ ‚t         j                  dt        |
«      › �«       |j                  |
d   «       ŒT | j                  j#                  «       D ]H  \  }}|sŒ	t        j                   ||«      sŒ t         j                  d|› �«       |j                  |«       ŒJ | j                  j%                  «        t'        |j(                  «      dkD  rt+        t,        |¬«      ‚y# | j                  j%                  «        w xY w)au  Check, if <principal> can lock <url>, otherwise raise an error.

        If locking <url> would create a conflict, DAVError(HTTP_LOCKED) is
        raised. An embedded DAVErrorCondition contains the conflicting resource.

        @see http://www.webdav.org/specs/rfc4918.html#lock-model

        - Parent locks WILL NOT be conflicting, if they are depth-0.
        - Exclusive depth-infinity parent locks WILL be conflicting, even if
          they are owned by <principal>.
        - Child locks WILL NOT be conflicting, if we request a depth-0 lock.
        - Exclusive child locks WILL be conflicting, even if they are owned by
          <principal>. (7.7)
        - It is not enough to check whether a lock is owned by <principal>, but
          also the token must be passed with the request. (Because <principal>
          may run two different applications on his client.)
        - <principal> cannot lock-exclusive, if he holds a parent shared-lock.
          (This would only make sense, if he was the only shared-lock holder.)
        - TODO: litmus tries to acquire a shared lock on one resource twice
          (locks: 27 'double_sharedlock') and fails, when we return HTTP_LOCKED.
          So we allow multi shared locks on a resource even for the same
          principal.

        @param url: URL that shall be locked
        @param lock_type: "write"
        @param lock_scope: "shared"|"exclusive"
        @param lock_depth: "0"|"infinity"
        @param token_list: list of lock tokens, that the user submitted in If: header
        @param principal: name of the principal requesting a lock

        @return: None (or raise)
        r0   r1   r4   zcheckLockPermission(ú, rO   z    check parent r(   r6   r'   r2   ú  -> DENIED due to locked parent r%   z. -> DENIED due to active write transaction on FTrT   ú -> DENIED due to locked child r   rw   N)r\   Údebugr   r	   rC   Úacquire_readr”   r-   Úadd_hrefr   r–   rF   r+   ÚwarningrD   rA   Úis_child_uriÚitemsrr   r{   r|   r   r   )rG   rs   rj   rk   rl   rt   r&   r}   r—   r˜   r   Ú
child_ocksÚw_urlr�   s                 r   rq   z"LockManager._check_lock_permission„  sš  € ðF ˜GÒ#Ð#Ð#ØÐ4Ñ4Ð4Ð4ØÐ.Ñ.Ð.Ð.ä�‰Ø" 3 % r¨*¨°R¸
°|À2ÀiÀ[ÐPQÐRô	
ô
 $Ô$BÓCˆà�
‰
×ÑÔ!ð0	!àˆAÙØ ×2Ñ2°1Ó5�	Ø%ò 3�DÜ—M‘MÐ$5°a°S¸¼;ÀtÓ;LÐ:MÐ"NÔOØ˜C’x D¨¡M°ZÒ$?à Ø˜g™¨(Ò2°zÀXÒ7Mð !ä—M‘MØ:¼;ÀtÓ;LÐ:MÐNôð ×$Ñ$ T¨&¡\Õ2ð3ô ×'Ñ'¨Ó*�ò! ð, ×"Ñ"×&Ñ& sÔ+Ü—‘Ð"PÐQTÐPUÐ VÔWØ× Ñ  Ô%à˜ZÒ'à!Ÿ\™\×7Ñ7Ø e¸dÈuð 8ó �
ð 'ò 3�DÜ×,Ñ,¨S°$°v±,Ô?Ð?Ð?ä—M‘MÐ$CÄKÐPTÓDUÐCVÐ"WÔXØ×$Ñ$ T¨&¡\Õ2ð	3ð %)×$7Ñ$7×$=Ñ$=Ó$?ò 0‘L�E˜5Ú¤×!2Ñ!2°3¸Õ!>ÜŸ™ØLÈUÈGÐTôð  ×(Ñ(¨Õ/ð0ð �J‰J×ÑÔ ô ˆw�}‰}Ó Ò!Üœ;°gÔ>Ð>Øøð �J‰J×ÑÕ ús    Á B(I1 Ä	C!I1 Ç+I1 È+I1 É1Jc                ó¤  — t        j                  |«      sJ ‚|dv sJ ‚t        j                  d|› d|› d|› d|› d�	«       | j                  j                  «        	 | j                  ||||«      }| j                  j                  «        t        |j                  «      dkD  rt        t        |¬«      ‚y# | j                  j                  «        w xY w)a  Check, if <principal> can modify <url>, otherwise raise HTTP_LOCKED.

        If modifying <url> is prevented by a lock, DAVError(HTTP_LOCKED) is
        raised. An embedded DAVErrorCondition contains the conflicting locks.

        <url> may be modified by <principal>, if it is not currently locked
        directly or indirectly (i.e. by a locked parent).
        For depth-infinity operations, <url> also must not have locked children.

        It is not enough to check whether a lock is owned by <principal>, but
        also the token must be passed with the request. Because <principal> may
        run two different applications.

        See http://www.webdav.org/specs/rfc4918.html#lock-model
            http://www.webdav.org/specs/rfc4918.html#rfc.section.7.4

        TODO: verify assumptions:
        - Parent locks WILL NOT be conflicting, if they are depth-0.
        - Exclusive child locks WILL be conflicting, even if they are owned by <principal>.

        @param url: URL that shall be modified, created, moved, or deleted
        @param depth: "0"|"infinity"
        @param token_list: list of lock tokens, that the principal submitted in If: header
        @param principal: name of the principal requesting a lock

        @return: None or raise error
        r4   zcheck_write_permission(r¤   rO   r   rw   N)r   r:   r\   r§   rC   r¨   rz   rr   r{   r|   r   r   )rG   rs   r(   rt   r&   r}   s         r   Úcheck_write_permissionz"LockManager.check_write_permissionë  sÃ   € ô8 �{‰{˜3ÔÐÐØÐ)Ñ)Ð)Ð)Ü�‰Ø% c U¨"¨U¨G°2°j°\ÀÀIÀ;ÈaÐPô	
ð 	�
‰
×ÑÔ!ð	!Ø×/Ñ/°°U¸JÈ	ÓRˆGà�J‰J×ÑÔ ô ˆw�}‰}Ó Ò!Üœ;°gÔ>Ð>Øøð �J‰J×ÑÕ ús   ÁB3 Â3Cc                 óš  — t        t        «      }|}|r¼| j                  |«      }t        j	                  d|› �«       |D ]v  }t        j	                  dt        |«      › �«       ||k7  r	|d   dk7  rŒ2||d   k(  r|d   |v rŒBt        j	                  dt        |«      › �«       |j                  |d   «       Œx t        j                  |«      }|rŒ¼|dk(  rv| j                  j                  |d	d
d	¬«      }	|	D ]R  }t        j                  ||d   «      sJ ‚t        j	                  dt        |«      › �«       |j                  |d   «       ŒT |S )zŒReturn a DAVErrorCondition listing locks that conflict with a write to <url>.

        Caller must hold self._lock (read or write).
        z  checking z
     lock=r(   r6   r&   r"   r¥   r%   FTrT   r¦   )r   r	   r”   r\   r§   r-   r©   r   r–   rD   rA   r«   )
rG   rs   r(   rt   r&   r}   r—   r˜   r   r­   s
             r   rz   z LockManager._get_write_conflicts  sg  € ô $Ô$BÓCˆð ˆÙØ×.Ñ.¨qÓ1ˆIÜ�M‰M˜K¨ sÐ+Ô,Ø!ò 3�Ü—‘ 
¬;°tÓ+<Ð*=Ð>Ô?Ø˜’8  W¡°Ò ;àØ $ {Ñ"3Ò3¸¸W¹ÈÑ8Sàô —M‘MØ:¼;ÀtÓ;LÐ:MÐNôð ×$Ñ$ T¨&¡\Õ2ð3ô ×#Ñ# AÓ&ˆAò# ð& �JÒàŸ™×3Ñ3Ø %¸$È5ð 4ó ˆJð #ò /�Ü×(Ñ(¨¨d°6©lÔ;Ð;Ð;ä—‘Ð ?ÄÈDÓ@QÐ?RÐSÔTØ× Ñ   f¡Õ.ð	/ð ˆr   )Ú )rQ   Ú
__module__Ú__qualname__Ú__doc__rh   rH   rL   rR   rf   rn   ru   r~   r‚   r   r„   r‡   r‹   rr   r�   r”   r™   r›   r    r¢   rq   r°   rz   r   r   r   r?   r?   y   s³   „ ñð
 #Ðò!ò ò>óXò2&òP!ð< MPô !ò,!ð ØEHó -ó ð-ð )-ô <ð &*ô ò0#òBð 38ô 	ð <@ô ò2!ò
Dð
 ;@ô !òeòN,ó\)r   r?   )rµ   r   r   Ú
contextlibr   Úpprintr   Úwsgidavr   Úwsgidav.dav_errorr   r   r   r	   Úwsgidav.rw_lockr
   Ú__docformat__Úget_module_loggerr\   r   r   r    r-   r=   r?   r   r   r   ú<module>r½      si   ðñ
 óD Û Ý %Ý å ÷ó õ *à"€à
 ˆ$×
 Ñ
 Ð!3Ó
4€òHòò0ò
ò.*÷$Iò Ir   