o
    ¯b;  ã                   @   s:  d Z ddgZddlmZ ddlmZ ddlmZmZ ddl	m
Z
 ddlmZmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZ ddlm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„ dD ƒZ#dZ$dd„ e#D ƒZ%e$ &d¡Z'eeƒG dd„ dƒƒZ(G dd„ dƒZ)G dd„ dƒZ*G dd„ dej+ƒZ,dS )z2
Helpers related to HTTP requests, used by tests.
ÚDummyChannelÚDummyRequesté    )ÚBytesIO)ÚOptional)ÚimplementerÚverify)ÚVersion)ÚIPv4AddressÚIPv6Address)ÚDeferred)ÚIAddressÚISSLTransport)ÚClock)Ú
deprecated)Úunittest)ÚFOUND)ÚHeaders)ÚResource)ÚNOT_DONE_YETÚSessionÚSitec                 C   s   g | ]}d |› d�‘qS )ÚFooÚbar© )Ú.0Úlwr   r   ú@/usr/lib/python3/dist-packages/twisted/web/test/requesthelper.pyÚ
<listcomp>   s    r   )úÚ
z
zFoo barc                 C   s   g | ]}|  d ¡‘qS )Úascii)Úencode)r   Ú	componentr   r   r   r       s    
ÿr    c                   @   s   e Zd ZdZdS )ÚNullAddressz/
    A null implementation of L{IAddress}.
    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r#   &   s    r#   c                   @   sÖ   e Zd ZG dd„ dƒZeeƒG dd„ deƒƒZeeƒ ƒZ	d,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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S )-r   c                   @   sV   e Zd ZdZdZd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S )zDummyChannel.TCPéP   FNc                 C   s,   |d u r
t dddƒ}|| _tƒ | _g | _d S )NÚTCPz192.168.1.1i80  )r	   Ú_peerr   ÚwrittenÚ	producers©ÚselfÚpeerr   r   r   Ú__init__2   s
   
zDummyChannel.TCP.__init__c                 C   ó   | j S ©N)r*   ©r.   r   r   r   ÚgetPeer9   s   zDummyChannel.TCP.getPeerc                 C   s(   t |tƒstd|›�ƒ‚| j |¡ d S )Nz)Can only write bytes to a transport, not )Ú
isinstanceÚbytesÚ	TypeErrorr+   Úwrite©r.   Údatar   r   r   r8   <   s   
zDummyChannel.TCP.writec                 C   s   |D ]}|   |¡ qd S r2   )r8   )r.   Úiovecr:   r   r   r   ÚwriteSequenceA   s   ÿzDummyChannel.TCP.writeSequencec                 C   s   t dd| jƒS )Nr)   z10.0.0.1)r	   Úportr3   r   r   r   ÚgetHostE   ó   zDummyChannel.TCP.getHostc                 C   s   | j  ||f¡ d S r2   )r,   Úappend©r.   ÚproducerÚ	streamingr   r   r   ÚregisterProducerH   s   z!DummyChannel.TCP.registerProducerc                 C   ó   d S r2   r   r3   r   r   r   ÚunregisterProducerK   ó   z#DummyChannel.TCP.unregisterProducerc                 C   ó
   d| _ d S )NT)Údisconnectedr3   r   r   r   ÚloseConnectionN   ó   
zDummyChannel.TCP.loseConnectionr2   )r$   r%   r&   r=   rI   r0   r4   r8   r<   r>   rD   rF   rJ   r   r   r   r   r)   .   s    
r)   c                   @   sD   e 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S )zDummyChannel.SSLc                 C   rE   r2   r   r3   r   r   r   ÚabortConnectionS   ó   z DummyChannel.SSL.abortConnectionc                 C   rE   r2   r   r3   r   r   r   ÚgetTcpKeepAliveW   rM   z DummyChannel.SSL.getTcpKeepAlivec                 C   rE   r2   r   r3   r   r   r   ÚgetTcpNoDelay[   rM   zDummyChannel.SSL.getTcpNoDelayc                 C   rE   r2   r   r3   r   r   r   ÚloseWriteConnection_   rM   z$DummyChannel.SSL.loseWriteConnectionc                 C   rE   r2   r   ©r.   Úenabledr   r   r   ÚsetTcpKeepAlivec   rM   z DummyChannel.SSL.setTcpKeepAlivec                 C   rE   r2   r   rQ   r   r   r   ÚsetTcpNoDelayg   rM   zDummyChannel.SSL.setTcpNoDelayc                 C   rE   r2   r   r3   r   r   r   ÚgetPeerCertificatek   rM   z#DummyChannel.SSL.getPeerCertificateN)
r$   r%   r&   rL   rN   rO   rP   rS   rT   rU   r   r   r   r   ÚSSLQ   s    rV   Nc                 C   s   |   |¡| _d S r2   )r)   Ú	transportr-   r   r   r   r0   q   ó   zDummyChannel.__init__c                 C   rE   r2   r   )r.   Úrequestr   r   r   ÚrequestDonet   rG   zDummyChannel.requestDonec                 C   sL   |d | d | d }|g}|  dd„ |D ƒ¡ | d¡ | j |¡ d S )Nó    ó   
c                 s   s$   � | ]\}}|d  | d V  qdS )s   : r\   Nr   )r   ÚnameÚvaluer   r   r   Ú	<genexpr>z   s   €" z,DummyChannel.writeHeaders.<locals>.<genexpr>)Úextendr@   rW   r<   )r.   ÚversionÚcodeÚreasonÚheadersÚresponse_lineÚheaderSequencer   r   r   ÚwriteHeadersw   s
   
zDummyChannel.writeHeadersc                 C   ó
   | j  ¡ S r2   )rW   r4   r3   r   r   r   r4   ~   rK   zDummyChannel.getPeerc                 C   rh   r2   )rW   r>   r3   r   r   r   r>   �   rK   zDummyChannel.getHostc                 C   s   | j  ||¡ d S r2   )rW   rD   rA   r   r   r   rD   „   s   zDummyChannel.registerProducerc                 C   ó   | j  ¡  d S r2   )rW   rF   r3   r   r   r   rF   ‡   r?   zDummyChannel.unregisterProducerc                 C   ó   | j  |¡ d S r2   )rW   r8   r9   r   r   r   r8   Š   rX   zDummyChannel.writec                 C   rj   r2   )rW   r<   )r.   r;   r   r   r   r<   �   rX   zDummyChannel.writeSequencec                 C   ri   r2   )rW   rJ   r3   r   r   r   rJ   �   r?   zDummyChannel.loseConnectionc                 C   rE   r2   r   r3   r   r   r   Ú
endRequest“   rG   zDummyChannel.endRequestc                 C   s   t | j| jƒS r2   )r5   rW   rV   r3   r   r   r   ÚisSecure–   r?   zDummyChannel.isSecurec                 C   rE   r2   r   r3   r   r   r   rL   ™   rM   zDummyChannel.abortConnectionc                 C   rE   r2   r   r3   r   r   r   rN   �   rM   zDummyChannel.getTcpKeepAlivec                 C   rE   r2   r   r3   r   r   r   rO   ¡   rM   zDummyChannel.getTcpNoDelayc                 C   rE   r2   r   r3   r   r   r   rP   ¥   rM   z DummyChannel.loseWriteConnectionc                 C   rE   r2   r   r3   r   r   r   rS   ©   rM   zDummyChannel.setTcpKeepAlivec                 C   rE   r2   r   r3   r   r   r   rT   ­   rM   zDummyChannel.setTcpNoDelayc                 C   rE   r2   r   r3   r   r   r   rU   ±   rM   zDummyChannel.getPeerCertificater2   )r$   r%   r&   r)   r   r   rV   r   r   Úsiter0   rZ   rg   r4   r>   rD   rF   r8   r<   rJ   rk   rl   rL   rN   rO   rP   rS   rT   rU   r   r   r   r   r   -   s0    #

c                   @   s  e Zd ZU dZdZdZdZee e	d< dd„ Z
dd	„ Zd9d
d„Zdd„ Zdd„ Zdd„ Zd:dd„Zdd„ Zdd„ Zded fdd„Zdd„ Zdd„ Zdd „ Zd:d!d"„Zd#d$„ Zd%d&„ Zeed'd(d)d*ƒd+d,�d-d.„ ƒZd/d0„ Zd1d2„ Zd3d4„ Z d;d5d6„Z!d7d8„ Z"dS )<r   a  
    Represents a dummy or fake request. See L{twisted.web.server.Request}.

    @ivar _finishedDeferreds: L{None} or a C{list} of L{Deferreds} which will
        be called back with L{None} when C{finish} is called or which will be
        errbacked if C{processingFailed} is called.

    @type requestheaders: C{Headers}
    @ivar requestheaders: A Headers instance that stores values for all request
        headers.

    @type responseHeaders: C{Headers}
    @ivar responseHeaders: A Headers instance that stores values for all
        response headers.

    @type responseCode: C{int}
    @ivar responseCode: The response code which was passed to
        C{setResponseCode}.

    @type written: C{list} of C{bytes}
    @ivar written: The bytes which have been written to the request.
    s   http://dummy/s   GETNÚclientc                 C   s"   d| _ | j r| ¡  | j sdS dS )zû
        Call an L{IPullProducer}'s C{resumeProducing} method in a
        loop until it unregisters itself.

        @param prod: The producer.
        @type prod: L{IPullProducer}

        @param s: Whether or not the producer is streaming.
        é   N)ÚgoÚresumeProducing)r.   ÚprodÚsr   r   r   rD   Ò   s   ÿzDummyRequest.registerProducerc                 C   rH   )Nr   )rp   r3   r   r   r   rF   á   rK   zDummyRequest.unregisterProducerc                 C   sl   g | _ g | _d| _|| _g | _d | _|ptd dtƒ d�| _i | _	t
ƒ | _t
ƒ | _d | _g | _d| _d| _d S )Nr   ó   0)rm   ÚuidÚreactors   dummys   HTTP/1.0)Úsitepathr+   ÚfinishedÚpostpathÚprepathÚsessionr   r   ÚprotoSessionÚargsr   ÚrequestHeadersÚresponseHeadersÚresponseCodeÚ_finishedDeferredsÚ_serverNameÚclientproto)r.   ry   r{   rn   r   r   r   r0   ä   s   
zDummyRequest.__init__c                 C   s,   i }| j  ¡ D ]\}}|d || ¡ < q|S )ah  
        Return dictionary mapping the names of all received headers to the last
        value received for each.

        Since this method does not return all header information,
        C{self.requestHeaders.getAllRawHeaders()} may be preferred.

        NOTE: This function is a direct copy of
        C{twisted.web.http.Request.getAllRawHeaders}.
        éÿÿÿÿ)r~   ÚgetAllRawHeadersÚlower)r.   rd   ÚkÚvr   r   r   ÚgetAllHeadersô   s   zDummyRequest.getAllHeadersc                 C   s   | j  | ¡ dg¡d S )aH  
        Retrieve the value of a request header.

        @type name: C{bytes}
        @param name: The name of the request header for which to retrieve the
            value.  Header names are compared case-insensitively.

        @rtype: C{bytes} or L{None}
        @return: The value of the specified request header.
        Nr   )r~   ÚgetRawHeadersr†   )r.   r]   r   r   r   Ú	getHeader  s   zDummyRequest.getHeaderc                 C   s   | j  ||¡ dS )zATODO: make this assert on write() if the header is content-lengthN)r   ÚaddRawHeader©r.   r]   r^   r   r   r   Ú	setHeader  s   zDummyRequest.setHeaderc                 C   s(   | j r| j S | jrJ dƒ‚| j| _ | j S )Nz8Session cannot be requested after data has been written.)r{   r+   r|   )r.   ÚsessionInterfacer   r   r   Ú
getSession  s   ÿþzDummyRequest.getSessionc                 C   s,   |  | ¡}|tu rdS |  |¡ |  ¡  dS )a   
        Render the given resource as a response to this request.

        This implementation only handles a few of the most common behaviors of
        resources.  It can handle a render method that returns a string or
        C{NOT_DONE_YET}.  It doesn't know anything about the semantics of
        request methods (eg HEAD) nor how to set any particular headers.
        Basically, it's largely broken, but sufficient for some tests at least.
        It should B{not} be expanded to do all the same stuff L{Request} does.
        Instead, L{DummyRequest} should be phased out and L{Request} (or some
        other real code factored in a different way) used.
        N)Úrenderr   r8   Úfinish)r.   ÚresourceÚresultr   r   r   r‘     s
   

zDummyRequest.renderc                 C   s"   t |tƒs	tdƒ‚| j |¡ d S )Nzwrite() only accepts bytes)r5   r6   r7   r+   r@   r9   r   r   r   r8   1  s   
zDummyRequest.writeÚreturnc                 C   s   t ƒ }| j |¡ |S )z¹
        Return a L{Deferred} which is called back with L{None} when the request
        is finished.  This will probably only work if you haven't called
        C{finish} yet.
        )r   r�   r@   )r.   rx   r   r   r   ÚnotifyFinish6  s   zDummyRequest.notifyFinishc                 C   s>   | j d | _ | jdur| j}d| _|D ]	}| d¡ qdS dS )z}
        Record that the request is finished and callback and L{Deferred}s
        waiting for notification of this.
        ro   N)rx   r�   Úcallback)r.   Ú	observersÚobsr   r   r   r’   @  s   
üzDummyRequest.finishc                 C   s2   | j dur| j }d| _ |D ]	}| |¡ qdS dS )zK
        Errback and L{Deferreds} waiting for finish notification.
        N)r�   Úerrback)r.   rc   r˜   r™   r   r   r   ÚprocessingFailedL  s   
üzDummyRequest.processingFailedc                 C   s   |g| j |< d S r2   )r}   r�   r   r   r   ÚaddArgV  rX   zDummyRequest.addArgc                 C   s,   | j rJ d d | j ¡¡ƒ‚|| _|| _dS )z{
        Set the HTTP status response code, but takes care that this is called
        before any data is written.
        z;Response code cannot be set after data hasbeen written: {}.ú@@@@N)r+   ÚformatÚjoinr€   ÚresponseMessage)r.   rb   Úmessager   r   r   ÚsetResponseCodeY  s   ÿ
ÿþ
zDummyRequest.setResponseCodec                 C   ó    | j rJ d d | j ¡¡ƒ‚d S )Nz<Last-Modified cannot be set after data has been written: {}.r�   ©r+   rž   rŸ   )r.   Úwhenr   r   r   ÚsetLastModifiedf  ó   ÿ
ÿþzDummyRequest.setLastModifiedc                 C   r£   )Nz3ETag cannot be set after data has been written: {}.r�   r¤   )r.   Útagr   r   r   ÚsetETagm  r§   zDummyRequest.setETagÚTwistedé   é   r   ÚgetClientAddress)Úreplacementc                 C   s   t | jttfƒr| jjS dS )z|
        Return the IPv4 address of the client which made this request, if there
        is one, otherwise L{None}.
        N)r5   rn   r	   r
   Úhostr3   r   r   r   ÚgetClientIPt  s   zDummyRequest.getClientIPc                 C   s   | j du rtƒ S | j S )z•
        Return the L{IAddress} of the client that made this request.

        @return: an address.
        @rtype: an L{IAddress} provider.
        N)rn   r#   r3   r   r   r   r­   ~  s   
zDummyRequest.getClientAddressc                 C   r1   )zƒ
        Get a dummy hostname associated to the HTTP request.

        @rtype: C{bytes}
        @returns: a dummy hostname
        )r‚   r3   r   r   r   ÚgetRequestHostname‰  s   zDummyRequest.getRequestHostnamec                 C   s   t dddƒS )zz
        Get a dummy transport's host.

        @rtype: C{IPv4Address}
        @returns: a dummy transport's host
        r)   ú	127.0.0.1r(   )r	   r3   r   r   r   r>   ’  s   zDummyRequest.getHostc                 C   sD   || _ |  ¡ r
d}nd}||kr|}nd||f }| j d|¡ dS )a_  
        Change the host and port the request thinks it's using.

        @type host: C{bytes}
        @param host: The value to which to change the host header.

        @type ssl: C{bool}
        @param ssl: A flag which, if C{True}, indicates that the request is
            considered secure (if C{True}, L{isSecure} will return C{True}).
        i»  r(   s   %b:%ds   hostN)Ú	_forceSSLrl   r~   rŒ   )r.   r¯   r=   ÚsslÚdefaultÚ
hostHeaderr   r   r   ÚsetHost›  s   zDummyRequest.setHostc                 C   s   |   t¡ |  d|¡ dS )zu
        Utility function that does a redirect.

        The request should have finish() called after this.
        s   locationN)r¢   r   rŽ   )r.   Úurlr   r   r   Úredirect±  s   
zDummyRequest.redirect)NNr2   )r   )#r$   r%   r&   r'   ÚuriÚmethodrn   r   r   Ú__annotations__rD   rF   r0   r‰   r‹   rŽ   r�   r‘   r8   r   r–   r’   r›   rœ   r¢   r¦   r©   r   r   r°   r­   r±   r>   r·   r¹   r   r   r   r   r   ¶   s8   
 

	



		
	c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚDummyRequestTestsz$
    Tests for L{DummyRequest}.
    c                 C   s^   t g ƒ}| ¡  | j| jgd�}|  dt|ƒ¡ |\}|  | d¡t¡ |  | d¡d¡ dS )zp
        L{DummyRequest.getClientIP} is deprecated in favor of
        L{DummyRequest.getClientAddress}
        )ÚoffendingFunctionsro   Úcategoryr¡   z}twisted.web.test.requesthelper.DummyRequest.getClientIP was deprecated in Twisted 18.4.0; please use getClientAddress insteadN)r   r°   ÚflushWarningsÚtest_getClientIPDeprecatedÚassertEqualÚlenÚgetÚDeprecationWarning)r.   rY   ÚwarningsÚwarningr   r   r   rÁ   À  s   ÿýz,DummyRequestTests.test_getClientIPDeprecatedc                 C   s.   t g ƒ}tdddƒ}||_|  d| ¡ ¡ dS )z�
        L{DummyRequest.getClientIP} supports IPv6 addresses, just like
        L{twisted.web.http.Request.getClientIP}.
        r)   z::1é90  N)r   r
   rn   rÂ   r°   )r.   rY   rn   r   r   r   Útest_getClientIPSupportsIPv6Ù  s   z.DummyRequestTests.test_getClientIPSupportsIPv6c                 C   s    t g ƒ}| ¡ }t t|¡ dS )zu
        L{DummyRequest.getClientAddress} returns an L{IAddress}
        provider no C{client} has been set.
        N)r   r­   r   ÚverifyObjectr   )r.   rY   Únullr   r   r   Ú"test_getClientAddressWithoutClientä  s   z4DummyRequestTests.test_getClientAddressWithoutClientc                 C   s2   t g ƒ}tdddƒ}||_| ¡ }|  ||¡ dS )zI
        L{DummyRequest.getClientAddress} returns the C{client}.
        r)   r²   rÈ   N)r   r	   rn   r­   ÚassertIs)r.   rY   rn   Úaddressr   r   r   Útest_getClientAddressí  s
   z'DummyRequestTests.test_getClientAddressN)r$   r%   r&   r'   rÁ   rÉ   rÌ   rÏ   r   r   r   r   r½   »  s    	r½   N)-r'   Ú__all__Úior   Útypingr   Úzope.interfacer   r   Úincrementalr   Útwisted.internet.addressr	   r
   Útwisted.internet.deferr   Útwisted.internet.interfacesr   r   Útwisted.internet.taskr   Útwisted.python.deprecater   Útwisted.trialr   Útwisted.web._responsesr   Útwisted.web.http_headersr   Útwisted.web.resourcer   Útwisted.web.serverr   r   r   ÚtextLinearWhitespaceComponentsÚsanitizedTextÚbytesLinearWhitespaceComponentsr!   ÚsanitizedBytesr#   r   r   ÚSynchronousTestCaser½   r   r   r   r   Ú<module>   s<   ÿ
 
  