o
    b6                    @   s  d 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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mZmZmZ ddl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+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z= ddl>m?Z? ddl@mAZA ddlBmCZCmDZD ddlEmFZFmGZG G dd deHZIG dd deHZJeAddgiZKdd ZLdd ZMdd ZNd d! ZOd"d# ZPG d$d% d%e ZQG d&d' d'ZRG d(d) d)eRe ZSG d*d+ d+eRe ZTG d,d- d-e ZUG d.d/ d/ZVG d0d1 d1ZWG d2d3 d3e ZXeeCG d4d5 d5ZYG d6d7 d7e ZZG d8d9 d9e Z[G d:d; d;e Z\G d<d= d=e Z]G d>d? d?e Z^d@S )Az&
Tests for L{twisted.web._newclient}.
    )Optional)implementer)verifyObject)CancelledErrorDeferredfailsucceed)ConnectionDoneConnectionLost)	IConsumerIPushProducer)Protocol)globalLogPublisher)LineReceiver)Failure)AccumulatingProtocolEventLoggingObserverStringTransport StringTransportWithDisconnection)TestCase)BODYDONEHEADERSTATUSUNKNOWN_LENGTH
BadHeadersBadResponseVersionChunkedEncoderConnectionAbortedExcessWriteHTTPClientParser
HTTPParserLengthEnforcingConsumer
ParseErrorRequestNotSentTransportProxyProducerWrongBodyLengthmakeStatefulDispatcher)	HTTP11ClientProtocolPotentialDataLossRequestRequestGenerationFailedRequestTransmissionFailedResponseResponseDoneResponseFailedResponseNeverReceived)	_DataLoss)Headers)IBodyProducer	IResponse)bytesLinearWhitespaceComponentssanitizedBytesc                   @      e Zd ZdZdS )ArbitraryExceptionze
    A unique, arbitrary exception type which L{twisted.web._newclient} knows
    nothing about.
    N__name__
__module____qualname____doc__ r>   r>   A/usr/lib/python3/dist-packages/twisted/web/test/test_newclient.pyr8   C       r8   c                   @   r7   )AnotherArbitraryExceptionzI
    Similar to L{ArbitraryException} but with a different identity.
    Nr9   r>   r>   r>   r?   rA   J   r@   rA      host   example.comc                    s(    fdd} ||}|| |S )a  
    Assert that the given L{Deferred} fails with the exception given by
    C{mainType} and that the exceptions wrapped by the instance of C{mainType}
    it fails with match the list of exception types given by C{reasonTypes}.

    This is a helper for testing failures of exceptions which subclass
    L{_newclient._WrapperException}.

    @param self: A L{TestCase} instance which will be used to make the
        assertions.

    @param deferred: The L{Deferred} which is expected to fail with
        C{mainType}.

    @param mainType: A L{_newclient._WrapperException} subclass which will be
        trapped on C{deferred}.

    @param reasonTypes: A sequence of exception types which will be trapped on
        the resulting C{mainType} exception instance's C{reasons} sequence.

    @return: A L{Deferred} which fires with the C{mainType} instance
        C{deferred} fails with, or which fails somehow.
    c              	      sL   t | j D ]	\}}|| qt| jt d| j d  d | S )Nzlen(z	) != len())zipreasonstrapassertEquallen)errreasontypereasonTypesselfr>   r?   cbFailedn   s   z-assertWrapperExceptionTypes.<locals>.cbFailed)assertFailureaddCallback)rO   deferredmainTyperN   rP   dr>   rM   r?   assertWrapperExceptionTypesU   s   

rV   c                 C      t | |t|S )zo
    A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
    of L{ResponseFailed}.
    )rV   r/   rO   rS   rN   r>   r>   r?   assertResponseFailed}      rY   c                 C   rW   )zx
    A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
    of L{RequestGenerationFailed}.
    )rV   r+   rX   r>   r>   r?   assertRequestGenerationFailed      r[   c                 C   rW   )zz
    A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
    of L{RequestTransmissionFailed}.
    )rV   r,   rX   r>   r>   r?   assertRequestTransmissionFailed   r\   r]   c                 C   s   t dddt| S )z
    Helper function for creating a Response which uses the given transport.
    All of the other parameters to L{Response.__init__} are filled with
    arbitrary values.  Only use this method if you don't care about any of
    them.
    s   HTTP   r_         OK)r-   _boringHeaders)	transportr>   r>   r?   justTransportResponse   s   rd   c                   @      e Zd ZdZdd ZdS )MakeStatefulDispatcherTestsz.
    Tests for L{makeStatefulDispatcher}.
    c                 C   sR   G dd d}| }|  | d d|_|  | d d|_| t|j dS )z
        A method defined with L{makeStatefulDispatcher} invokes a second
        method based on the current state of the object.
        c                   @   s2   e Zd ZdZdd ZedeZdd Zdd Zd	S )
zCMakeStatefulDispatcherTests.test_functionCalledByState.<locals>.FooAc                 S      d S Nr>   rO   r>   r>   r?   bar      zGMakeStatefulDispatcherTests.test_functionCalledByState.<locals>.Foo.barquuxc                 S      dS )Nar>   rj   r>   r>   r?   _quux_A   rl   zKMakeStatefulDispatcherTests.test_functionCalledByState.<locals>.Foo._quux_Ac                 S   rn   )Nbr>   rj   r>   r>   r?   _quux_B   rl   zKMakeStatefulDispatcherTests.test_functionCalledByState.<locals>.Foo._quux_BN)r:   r;   r<   _staterk   r'   rp   rr   r>   r>   r>   r?   Foo   s    
rt   ro   Brq   CN)rH   rk   rs   assertRaisesRuntimeError)rO   rt   statefulr>   r>   r?   test_functionCalledByState   s   z6MakeStatefulDispatcherTests.test_functionCalledByStateN)r:   r;   r<   r=   rz   r>   r>   r>   r?   rf      s    rf   c                   @   sr   e Zd ZU dZdZee e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S )_HTTPParserTestszt
    Base test class for L{HTTPParser} which is responsible for the bulk of
    the task of parsing HTTP bytes.
    Nsepc                 C   s\   g }t  }|j|_|t  | |jt |d| j	  | |dg | |jt
 dS )zj
        L{HTTPParser} calls its C{statusReceived} method when it receives a
        status line.
           HTTP/1.1 200 OKN)r!   appendstatusReceivedmakeConnectionr   rH   stater   dataReceivedr|   r   )rO   statusprotocolr>   r>   r?   test_statusCallback   s   z$_HTTPParserTests.test_statusCallbackc                 C   s6   i }t  }|j|_|t  |d| j  ||fS )Nr}   )r!   __setitem__headerReceivedr   r   r   r|   rO   headerr   r>   r>   r?   _headerTestSetup   s   z!_HTTPParserTests._headerTestSetupc                 C   sJ   |   \}}|d| j  || j | |ddi | |jt dS )ze
        L{HTTPParser} calls its C{headerReceived} method when it receives a
        header.
        s	   X-Foo:bar   X-Foo   barNr   r   r|   rH   r   r   r   r>   r>   r?   test_headerCallback   s
   z$_HTTPParserTests.test_headerCallbackc                 C   sj   |   \}}|d| j  |d| j  |d| j  || j | |ddi | |jt dS )z
        If a header is split over multiple lines, L{HTTPParser} calls
        C{headerReceived} with the entire value once it is received.
        
   X-Foo: bars    bazs   	quuxr   s   bar baz	quuxNr   r   r>   r>   r?   test_continuedHeaderCallback   s   z-_HTTPParserTests.test_continuedHeaderCallbackc                 C   sZ   |   \}}| jg d}|d|  |d|  || j | |ddd dS )z
        Leading and trailing linear whitespace is stripped from the header
        value passed to the C{headerReceived} callback.
        )s    	 s    bar 	s    	    s   X-Bar:s   X-Foo:r   )r   s   X-BarN)r   r|   joinr   rH   )rO   r   r   valuer>   r>   r?   test_fieldContentWhitespace   s   z,_HTTPParserTests.test_fieldContentWhitespacec                    sP   g  |   \} fdd}|_| j |  tg | jt dS )zg
        After the last header is received, L{HTTPParser} calls
        C{allHeadersReceived}.
        c                      s     j t_d S ri   )r~   r   r   r>   calledr   r>   r?   allHeadersReceived  s   
zD_HTTPParserTests.test_allHeadersCallback.<locals>.allHeadersReceivedN)r   r   r   r|   rH   r   r   r   )rO   r   r   r>   r   r?   test_allHeadersCallback  s   z(_HTTPParserTests.test_allHeadersCallbackc                 C   s6   |   \}}|| j | |i  | |jt dS )zp
        If there are no headers in the message, L{HTTPParser} does not call
        C{headerReceived}.
        Nr   r   r>   r>   r?   test_noHeaderCallback  s   z&_HTTPParserTests.test_noHeaderCallbackc                 C   sv   t  }|t  |d| j  |d| j  |d| j  || j dddgfg}| |t|j  dS )zc
        All headers received by L{HTTPParser} are added to
        L{HTTPParser.headers}.
        r}   r   
   X-Foo: bazr   r      bazN)	r!   r   r   r   r|   rH   listheadersgetAllRawHeaders)rO   r   expectedr>   r>   r?   test_headersSavedOnResponse#  s   z,_HTTPParserTests.test_headersSavedOnResponsec                 C   sF   t  }g d}|D ]}| ||d|f  q	| |dd dS )z
        L{HTTPParser.isConnectionControlHeader} returns C{True} for headers
        which are always connection control headers (similar to "hop-by-hop"
        headers from RFC 2616 section 13.5.1) and C{False} for other headers.
        )   content-length
   connections
   keep-alives   tes   trailerss   transfer-encodings   upgrades   proxy-connectionz:Expecting %r to be a connection control header, but wasn'ts   datez`Expecting the arbitrarily selected 'date' header to not be a connection control header, but was.N)r!   
assertTrueisConnectionControlHeaderassertFalse)rO   r   connHeaderNamesr   r>   r>   r?   test_connectionControlHeaders1  s   z._HTTPParserTests.test_connectionControlHeadersc                 C   s4   t  }|t  |t  | t|jt  dS )zi
        L{HTTPParser.switchToBodyMode} raises L{RuntimeError} if called more
        than once.
        N)r!   r   r   switchToBodyModeobjectrw   rx   rO   r   r>   r>   r?   test_switchToBodyModeO  s   z&_HTTPParserTests.test_switchToBodyMode)r:   r;   r<   r=   r|   r   bytes__annotations__r   r   r   r   r   r   r   r   r   r   r>   r>   r>   r?   r{      s   
 
r{   c                   @      e Zd ZdZdZdS )$HTTPParserRFCComplaintDelimeterTestsz<
    L{_HTTPParserTests} using standard CR LF newlines.
       
Nr:   r;   r<   r=   r|   r>   r>   r>   r?   r   Z      r   c                   @   r   )'HTTPParserNonRFCComplaintDelimeterTestsz5
    L{_HTTPParserTests} using bare LF newlines.
       
Nr   r>   r>   r>   r?   r   b  r   r   c                   @   s   e Z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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d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<S )=HTTPClientParserTestszd
    Tests for L{HTTPClientParser} which is responsible for parsing HTTP
    response messages.
    c                 C   s    t dd}| |dd dS )zj
        L{HTTPClientParser.parseVersion} parses a status line into its three
        components.
        Ns	   CANDY/7.2)s   CANDY      )r    rH   parseVersionr   r>   r>   r?   test_parseVersionp  s   
z'HTTPClientParserTests.test_parseVersionc                    sX   t dd}t |j fdd}|d |d |d |d |d |d	 dS )
zr
        L{HTTPClientParser.parseVersion} raises L{ValueError} when passed an
        unparsable version.
        Nc                    s      | }|j|  d S ri   )rw   rH   datasexcefrO   r>   r?   checkParsing  s   z@HTTPClientParserTests.test_parseBadVersion.<locals>.checkParsing   foos   foo/bar/bazs   foo/s   foo/..s   foo/a.bs	   foo/-1.-1)r    r   r   )rO   r   r   r>   r   r?   test_parseBadVersionx  s   
z*HTTPClientParserTests.test_parseBadVersionc                 C   b   t ddtd}t|d}|t  |d | |jjd | |jj	d | |jj
d dS )z
        L{HTTPClientParser.statusReceived} parses the version, code, and phrase
        from the status line and stores them on the response object.
           GET   /N   HTTP/1.1 200 OK
r^   r`   ra   r*   rb   r    r   r   r   rH   responseversioncodephraserO   requestr   r>   r>   r?   test_responseStatusParsing  s   

z0HTTPClientParserTests.test_responseStatusParsingc                 C   r   )z
        L{HTTPClientParser.statusReceived} can parse a status line without a
        phrase (though such lines are a violation of RFC 7230, section 3.1.2;
        nevertheless some broken servers omit the phrase).
        r   r   Ns   HTTP/1.1 200
r^   r`   r   r   r   r>   r>   r?    test_responseStatusWithoutPhrase  s   

z6HTTPClientParserTests.test_responseStatusWithoutPhrasec                    s,   t dd  fdd}|d |d dS )z
        L{HTTPClientParser.statusReceived} raises L{ParseError} if it is called
        with a status line which cannot be parsed.
        Nc                    s"    t j| }|j|  d S ri   )rw   r#   r   rH   r   r   r   rO   r>   r?   r        zBHTTPClientParserTests.test_badResponseStatus.<locals>.checkParsingr   s   HTTP/1.1 bar OK)r    )rO   r   r>   r   r?   test_badResponseStatus  s   
z,HTTPClientParserTests.test_badResponseStatusc           	         s   i }g }g }g  t ||j}|j|_t }|| || |j|j_ fdd|j_	|| | 
|jd | 
|jt | 
|g  | 
|dg | 
 dg | 
|jjd |S )a0  
        Assert that L{HTTPClientParser} parses the given C{response} to
        C{request}, resulting in a response with no body and no extra bytes and
        leaving the transport in the producing state.

        @param request: A L{Request} instance which might have caused a server
            to return the given response.
        @param status: A string giving the status line of the response to be
            parsed.
        @param response: A string giving the response to be parsed.

        @return: A C{dict} of headers from the response.
        c                      
     dS NTr~   r>   bodyDataFinishedr>   r?   <lambda>     
 z3HTTPClientParserTests._noBodyTest.<locals>.<lambda>	producingr   Tr   )r    r~   r   r   r   r   r   r   _bodyDataReceived_bodyDataFinishedrH   producerStater   r   length)	rO   r   r   r   r   finishedbodyr   rc   r>   r   r?   _noBodyTest  s&   



z!HTTPClientParserTests._noBodyTestc                 C   s8   t ddtd}d}d}| |||}| |ddi dS )z
        If the response is to a HEAD request, no body is expected, the body
        callback is not invoked, and the I{Content-Length} header is passed to
        the header callback.
           HEADr   Nr   s   Content-Length: 10

s   Content-Lengths   10)r*   rb   r   rH   )rO   r   r   r   r   r>   r>   r?   test_headResponse  s
   z'HTTPClientParserTests.test_headResponsec                 C   (   t ddtd}d}d}| ||| dS )z
        If the response code is I{NO CONTENT} (204), no body is expected and
        the body callback is not invoked.
        r   r   Ns   HTTP/1.1 204 NO CONTENT
r   r*   rb   r   rO   r   r   r   r>   r>   r?   test_noContentResponse     z,HTTPClientParserTests.test_noContentResponsec                 C   r   )z
        If the response code is I{NOT MODIFIED} (304), no body is expected and
        the body callback is not invoked.
        r   r   Ns   HTTP/1.1 304 NOT MODIFIED
r   r   r   r>   r>   r?   test_notModifiedResponse  r   z.HTTPClientParserTests.test_notModifiedResponsec                 C   s   t tddtddd }|t  |d |d |d | |jti  | |j	j
td	d
gi | |j	jt dS )zq
        The response headers are added to the response object's C{headers}
        L{Headers} instance.
        r   r   Nc                 S   rh   ri   r>   restr>   r>   r?   r         z<HTTPClientParserTests.test_responseHeaders.<locals>.<lambda>r   s   X-Foo: bar
r      x-foor   r    r*   rb   r   r   r   rH   connHeadersr2   r   r   assertIdenticalr   r   r   r>   r>   r?   test_responseHeaders   s   


z*HTTPClientParserTests.test_responseHeadersc                 C   s   t tddtddd }|t  |d |d |d |d	 | |jti  | |j	j
td
dgi | |j	jt dS )z
        The multi-line response headers are folded and added to the response
        object's C{headers} L{Headers} instance.
        r   r   Nc                 S   rh   ri   r>   r   r>   r>   r?   r     r   zEHTTPClientParserTests.test_responseHeadersMultiline.<locals>.<lambda>r   s   X-Multiline: a
s       b
r   s   x-multilines   a    br   r   r>   r>   r?   test_responseHeadersMultiline  s   



z3HTTPClientParserTests.test_responseHeadersMultilinec                 C   s   t tddtddd }|t  |d |d |d |d	 | |jjt	i  | |j
t	d
gdgd | |jjd dS )zv
        The connection control headers are added to the parser's C{connHeaders}
        L{Headers} instance.
        r   r   Nc                 S   rh   ri   r>   r   r>   r>   r?   r   )  r   z>HTTPClientParserTests.test_connectionHeaders.<locals>.<lambda>r      Content-Length: 123
s   Connection: close
r      123s   close)r   r   {   r    r*   rb   r   r   r   rH   r   r   r2   r   r   r   r>   r>   r?   test_connectionHeaders#  s   



z,HTTPClientParserTests.test_connectionHeadersc                 C   s   t tddtddd }|t  |d |d |d | |jjt	d	d
gi | |j
t	i  | |jjd dS )z
        If a HEAD request is made, the I{Content-Length} header in the response
        is added to the response headers, not the connection control headers.
        r   r   Nc                 S   rh   ri   r>   r   r>   r>   r?   r   =  r   zRHTTPClientParserTests.test_headResponseContentLengthEntityHeader.<locals>.<lambda>r   r   r   r   r   r   r   r   r>   r>   r?   *test_headResponseContentLengthEntityHeader7  s   


z@HTTPClientParserTests.test_headResponseContentLengthEntityHeaderc                 C   s   g }t tddtd|j}t }|| |d g }|j|j_|d |d | 	|j
d | 	|jt |d | 	|dg | 	|jt |d	 | 	|dd	g | 	|jt | 	|d
g dS )z
        If a response includes a body with a length given by the
        I{Content-Length} header, the bytes which make up the body are passed
        to the C{_bodyDataReceived} callback on the L{HTTPParser}.
        r   r   Nr   s   Content-Length: 10
r   pauseds   xxxxxxs   yyyyr   )r    r*   rb   r~   r   r   r   r   r   rH   r   r   r   r   rO   r   r   rc   r   r>   r>   r?   test_contentLengthI  s(   






z(HTTPClientParserTests.test_contentLengthc                 C   s   g }t tddtd|j}|t  |d g }|j|j_|d |d | 	|j
t | 	|g  | 	|dg | 	|jjd dS )	z
        If a response includes a I{Content-Length} header indicating zero bytes
        in the response, L{Response.length} is set accordingly and no data is
        delivered to L{Response._bodyDataReceived}.
        r   r   Nr      Content-Length: 0
r   r   r   )r    r*   rb   r~   r   r   r   r   r   rH   r   r   r   rO   r   r   r   r>   r>   r?   test_zeroContentLengthh  s   



z,HTTPClientParserTests.test_zeroContentLengthc                 C   s4   t tddtdd}|t  | t|jd dS )z
        If a response includes multiple I{Content-Length} headers,
        L{HTTPClientParser.dataReceived} raises L{ValueError} to indicate that
        the response is invalid and the transport is now unusable.
        r   r   Ns9   HTTP/1.1 200 OK
Content-Length: 1
Content-Length: 2

)r    r*   rb   r   r   rw   
ValueErrorr   r   r>   r>   r?   !test_multipleContentLengthHeaders  s   z7HTTPClientParserTests.test_multipleContentLengthHeadersc                 C   d   g }t tddtd|j}|t  |d |d |d | |jt	 | |dg dS )zy
        If extra bytes are received past the end of a response, they are passed
        to the finish callback.
        r   r   Nr   r      
Here is another thing!   Here is another thing!
r    r*   rb   r~   r   r   r   rH   r   r   rO   r   r   r>   r>   r?   test_extraBytesPassedBack     


z/HTTPClientParserTests.test_extraBytesPassedBackc                 C   r  )z
        If extra bytes are received past the end of the headers of a response
        to a HEAD request, they are passed to the finish callback.
        r   r   Nr   s   Content-Length: 12
r  r  r  r  r>   r>   r?   test_extraBytesPassedBackHEAD  r  z3HTTPClientParserTests.test_extraBytesPassedBackHEADc                 C   s   g }t tddtd|j}|t  |d g }|j|j_|d |d | 	|g  | 
|jjt |d | 	|dg |d	 | 	|dd
g |d | 	|dg dS )z
        If the response headers indicate the response body is encoded with the
        I{chunked} transfer encoding, the body is decoded according to that
        transfer encoding before being passed to L{Response._bodyDataReceived}.
        r   r   Nr   s   Transfer-Encoding: chunked
r   s   3
a   as   bc
s   bcs
   0

extras   extra)r    r*   rb   r~   r   r   r   r   r   rH   r   r   r   r   r>   r>   r?   test_chunkedResponseBody  s$   






z.HTTPClientParserTests.test_chunkedResponseBodyc                 C   s   g }t tddtd|j}t }|| |d g }|j|j_|d |d |d | 	|ddg |
td | 	|d	g dS )
z
        If a response does not include a I{Transfer-Encoding} or a
        I{Content-Length}, the end of response body is indicated by the
        connection being closed.
        r   r   Nr   r   r   r   zsimulated end of connectionr   )r    r*   rb   r~   r   r   r   r   r   rH   connectionLostr	   r   r>   r>   r?   test_unknownContentLength  s   





z/HTTPClientParserTests.test_unknownContentLengthc                 C   sl   g }t tddtd|j}t }|| |d g }|j|j_|d | 	|dg | 	|dg dS )z
        According to RFC 2616, section 4.4, point 3, if I{Content-Length} and
        I{Transfer-Encoding: chunked} are present, I{Content-Length} MUST be
        ignored
        r   r   Nr   s@   Content-Length: 102
Transfer-Encoding: chunked

3
abc
0

   abcr   )
r    r*   rb   r~   r   r   r   r   r   rH   r   r>   r>   r?   %test_contentLengthAndTransferEncoding  s   



z;HTTPClientParserTests.test_contentLengthAndTransferEncodingc                 C   sH   t  }ttddtdd}|| |j}|tt  t	| |tgS )z
        If L{HTTPClientParser.connectionLost} is called before the headers are
        finished, the C{_responseDeferred} is fired with the L{Failure} passed
        to C{connectionLost}.
        r   r   N)
r   r    r*   rb   r   _responseDeferredr  r   r8   rY   )rO   rc   r   responseDeferredr>   r>   r?   test_connectionLostBeforeBody  s   
z3HTTPClientParserTests.test_connectionLostBeforeBodyc                 C   s   t | t}t }ttddtdd}|| g }|j	|j
 |d |d }d
dd}||_|d | dt| |d }|d	 }| |jt | t dS )z
        If one of the L{Response} methods called by
        L{HTTPClientParser.connectionLost} raises an exception, the exception
        is logged and not re-raised.
        r   r   N&   HTTP/1.1 200 OK
Content-Length: 1

r   c                 S      t  ri   r8   )rJ   r>   r>   r?   fakeBodyDataFinished0     zPHTTPClientParserTests.test_connectionLostWithError.<locals>.fakeBodyDataFinishedr_   log_failureri   )r   createWithCleanupr   r   r    r*   rb   r   r  rR   r~   r   r   r  assertEqualsrI   assertIsInstancer   r8   flushLoggedErrors)rO   logObserverrc   r   r   r  eventr   r>   r>   r?   test_connectionLostWithError  s    



z2HTTPClientParserTests.test_connectionLostWithErrorc                 C   sB   t tddtddd }|j}|t  |t  | |t	S )z
        If no response at all was received and the connection is lost, the
        resulting error is L{ResponseNeverReceived}.
        r   r   Nc                 S   rh   ri   r>   ignr>   r>   r?   r   B  r   z<HTTPClientParserTests.test_noResponseAtAll.<locals>.<lambda>)
r    r*   rb   r  r   r   r  r
   rQ   r0   rO   r   rU   r>   r>   r?   test_noResponseAtAll<  s   z*HTTPClientParserTests.test_noResponseAtAllc                 C   sV   t tddtddd }|j}|t  |d |t  | 	|t
| jt
S )z
        If a partial response was received and the connection is lost, the
        resulting error is L{ResponseFailed}, but not
        L{ResponseNeverReceived}.
        r   r   Nc                 S   rh   ri   r>   r   r>   r>   r?   r   Q  r   zBHTTPClientParserTests.test_someResponseButNotAll.<locals>.<lambda>   2)r    r*   rb   r  r   r   r   r  r
   rQ   r/   rR   r  r"  r>   r>   r?   test_someResponseButNotAllJ  s   
z0HTTPClientParserTests.test_someResponseButNotAllc                 C   s   d}t tddtddd }|t  || | t|dddu  | |j	t
 | tt|j d | tt|j d | |j dS )	zy
        If a response in the 1XX range is received it just gets swallowed and
        the parser resets itself.
           HTTP/1.1 103 Early Hints
Server: socketserver/1.0.0
Link: </other/styles.css>; rel=preload; as=style
Link: </other/action.js>; rel=preload; as=script

r   r   Nc                 S   rh   ri   r>   r   r>   r>   r?   r   j  r   zCHTTPClientParserTests.test_1XXResponseIsSwallowed.<locals>.<lambda>r   r   )r    r*   rb   r   r   r   r   getattrrH   r   r   rI   r   r   r   r   _everReceivedData)rO   sample103Responser   r>   r>   r?   test_1XXResponseIsSwallowed\  s   
z1HTTPClientParserTests.test_1XXResponseIsSwallowedc                 C   s   d}d}t tddtddd }|t  |||  | |jjd | |jj	t
i  | |jt
d	d
gi | |jjd dS )z
        When a 1XX response is swallowed, the final response that follows it is
        the only one that gets sent to the application.
        r&  (   HTTP/1.1 200 OK
Content-Length: 123

r   r   Nc                 S   rh   ri   r>   r   r>   r>   r?   r     r   zUHTTPClientParserTests.test_1XXFollowedByFinalResponseOnlyEmitsFinal.<locals>.<lambda>r`   r   r   r   r    r*   rb   r   r   r   rH   r   r   r   r2   r   r   rO   r)  following200Responser   r>   r>   r?   -test_1XXFollowedByFinalResponseOnlyEmitsFinalv  s   zCHTTPClientParserTests.test_1XXFollowedByFinalResponseOnlyEmitsFinalc                 C   s   d}d}t tddtddd }|t  ||| | |  | |jjd | |jj	t
i  | |jt
d	d
gi | |jjd dS )zp
        It is acceptable for multiple 1XX responses to come through, all of
        which get ignored.
        r&  r+  r   r   Nc                 S   rh   ri   r>   r   r>   r>   r?   r     r   zKHTTPClientParserTests.test_multiple1XXResponsesAreIgnored.<locals>.<lambda>r`   r   r   r   r,  r-  r>   r>   r?   #test_multiple1XXResponsesAreIgnored  s(   z9HTTPClientParserTests.test_multiple1XXResponsesAreIgnoredc                 C   sz   t | t}d}ttddtddd }|t  || | 	dt
| |d }| 	|d	 d
 | 	|d d dS )zF
        When a 1XX response is ignored, Twisted emits a log.
        r&  r   r   Nc                 S   rh   ri   r>   r   r>   r>   r?   r     r   zHHTTPClientParserTests.test_ignored1XXResponseCausesLog.<locals>.<lambda>r_   r   
log_formatz#Ignoring unexpected {code} responser   g   )r   r  r   r    r*   rb   r   r   r   r  rI   )rO   r  r)  r   r  r>   r>   r?    test_ignored1XXResponseCausesLog  s   
z6HTTPClientParserTests.test_ignored1XXResponseCausesLogN)!r:   r;   r<   r=   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r  r  r  r  r  r#  r%  r*  r/  r0  r3  r>   r>   r>   r?   r   j  s>    $

%r   c                   @   s,   e Zd ZdZdZdZdZdd Zdd ZdS )	SlowRequesta  
    L{SlowRequest} is a fake implementation of L{Request} which is easily
    controlled externally (for example, by code in a test method).

    @ivar stopped: A flag indicating whether C{stopWriting} has been called.

    @ivar finished: After C{writeTo} is called, a L{Deferred} which was
        returned by that method.  L{SlowRequest} will never fire this
        L{Deferred}.
    r   Fc                 C   s   t  | _| jS ri   )r   r   rO   rc   r>   r>   r?   writeTo  s   zSlowRequest.writeToc                 C   
   d| _ d S r   stoppedrj   r>   r>   r?   stopWriting     
zSlowRequest.stopWritingN)	r:   r;   r<   r=   methodr9  
persistentr6  r:  r>   r>   r>   r?   r4    s    r4  c                   @   s   e Zd ZdZdZdd ZdS )SimpleRequesta  
    L{SimpleRequest} is a fake implementation of L{Request} which writes a
    short, fixed string to the transport passed to its C{writeTo} method and
    returns a succeeded L{Deferred}.  This vaguely emulates the behavior of a
    L{Request} with no body producer.
    Fc                 C   s   | d td S )N
   SOME BYTES)writer   r5  r>   r>   r?   r6    s   
zSimpleRequest.writeToN)r:   r;   r<   r=   r=  r6  r>   r>   r>   r?   r>    s    r>  c                   @   s*  e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dId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/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z#dCdD Z$dEdF Z%dGdH Z&dS )JHTTP11ClientProtocolTestsz]
    Tests for the HTTP 1.1 client protocol implementation,
    L{HTTP11ClientProtocol}.
    c                 C   s"   t  | _t | _| j| j dS )zR
        Create an L{HTTP11ClientProtocol} connected to a fake transport.
        N)r   rc   r(   r   r   rj   r>   r>   r?   setUp  s   zHTTP11ClientProtocolTests.setUpc                 C   s$   | j t  | | j d dS )z
        L{HTTP11ClientProtocol.request} accepts a L{Request} and calls its
        C{writeTo} method with its own transport.
        r?  N)r   r   r>  rH   rc   r   rj   r>   r>   r?   test_request  s   z&HTTP11ClientProtocolTests.test_requestc                    s>    j t   fdd}  j t t}|| |S )z
        The second time L{HTTP11ClientProtocol.request} is called, it returns a
        L{Deferred} which immediately fires with a L{Failure} wrapping a
        L{RequestNotSent} exception.
        c                          j d d S Nr   rH   rc   r   ignoredrj   r>   r?   	cbNotSent     z?HTTP11ClientProtocolTests.test_secondRequest.<locals>.cbNotSent)r   r   r4  rQ   r>  r$   rR   rO   rI  rU   r>   rj   r?   test_secondRequest  s
   
z,HTTP11ClientProtocolTests.test_secondRequestc                    sD    j ttd  fdd}  j t t}|| |S )z
        L{HTTP11ClientProtocol.request} returns a L{Deferred} which immediately
        fires with a L{Failure} wrapping a L{RequestNotSent} if called after
        the protocol has been disconnected.
        zsad transportc                    rD  rE  rF  rG  rj   r>   r?   rI    rJ  zLHTTP11ClientProtocolTests.test_requestAfterConnectionLost.<locals>.cbNotSent)	r   r  r   r	   rQ   r   r>  r$   rR   rK  r>   rj   r?   test_requestAfterConnectionLost  s
   
z9HTTP11ClientProtocolTests.test_requestAfterConnectionLostc                    sD   G dd d} j | } fdd}t |tg}|| |S )a%  
        If the L{Deferred} returned by L{Request.writeTo} fires with a
        L{Failure}, L{HTTP11ClientProtocol.request} disconnects its transport
        and returns a L{Deferred} which fires with a L{Failure} of
        L{RequestGenerationFailed} wrapping the underlying failure.
        c                   @   re   )zCHTTP11ClientProtocolTests.test_failedWriteTo.<locals>.BrokenRequestFc                 S   s
   t t S ri   )r   r8   r5  r>   r>   r?   r6  ,  r;  zKHTTP11ClientProtocolTests.test_failedWriteTo.<locals>.BrokenRequest.writeToNr:   r;   r<   r=  r6  r>   r>   r>   r?   BrokenRequest)      rO  c                    s&      jj  jttd d S )Nzyou asked for it)r   rc   disconnectingr   r  r   r	   rG  rj   r>   r?   rP   1  s   z>HTTP11ClientProtocolTests.test_failedWriteTo.<locals>.cbFailed)r   r   r[   r8   rR   )rO   rO  rU   rP   r>   rj   r?   test_failedWriteTo!  s   
z,HTTP11ClientProtocolTests.test_failedWriteToc                 C   s*   G dd d}| j | }t| |tgS )z
        If L{Request.writeTo} raises an exception,
        L{HTTP11ClientProtocol.request} returns a L{Deferred} which fires with
        a L{Failure} of L{RequestGenerationFailed} wrapping that exception.
        c                   @   re   )zMHTTP11ClientProtocolTests.test_synchronousWriteToError.<locals>.BrokenRequestFc                 S   r  ri   r  r5  r>   r>   r?   r6  E  r  zUHTTP11ClientProtocolTests.test_synchronousWriteToError.<locals>.BrokenRequest.writeToNrN  r>   r>   r>   r?   rO  B  rP  rO  )r   r   r[   r8   )rO   rO  rU   r>   r>   r?   test_synchronousWriteToError;  s   z6HTTP11ClientProtocolTests.test_synchronousWriteToErrorNc                 C   s   t  }| j|}t| |tg}| |j | jtt  | 	|j |dkr1|j
d |S |dkrM|j
tt  | t}| t|d |S 	 |S )a2  
        If L{HTTP11ClientProtocol}'s transport is disconnected before the
        L{Deferred} returned by L{Request.writeTo} fires, the L{Deferred}
        returned by L{HTTP11ClientProtocol.request} fires with a L{Failure} of
        L{RequestTransmissionFailed} wrapping the underlying failure.
        callbackNerrbackr_   )r4  r   r   r]   r8   r   r9  r  r   r   r   rT  rU  rA   r  rH   rI   )rO   moder   rU   errorsr>   r>   r?   *test_connectionLostDuringRequestGenerationK  s    
zDHTTP11ClientProtocolTests.test_connectionLostDuringRequestGenerationc                 C   
   |  dS )z
        If the request passed to L{HTTP11ClientProtocol} finishes generation
        successfully after the L{HTTP11ClientProtocol}'s connection has been
        lost, nothing happens.
        rT  rX  rj   r>   r>   r?   +test_connectionLostBeforeGenerationFinishedk     
zEHTTP11ClientProtocolTests.test_connectionLostBeforeGenerationFinishedc                 C   rY  )z
        If the request passed to L{HTTP11ClientProtocol} finished generation
        with an error after the L{HTTP11ClientProtocol}'s connection has been
        lost, nothing happens.
        rU  rZ  rj   r>   r>   r?   )test_connectionLostBeforeGenerationFaileds  r\  zCHTTP11ClientProtocolTests.test_connectionLostBeforeGenerationFailedc                    s*   t t  fdd}d|S )a	  
        If the request passed to L{HTTP11ClientProtocol} finished generation
        with an error after the L{HTTP11ClientProtocol}'s connection has been
        lost, an error is logged that gives a non-confusing hint to user on what
        went wrong.
        c                    sH    dt   d }d| |d d |d d d S )Nr_   r   r  r1  zJError writing request, but not in valid state to finalize request: {state}r   CONNECTION_LOST)r  rI   assertInrH   )ignorer  r  rO   r>   r?   check  s   znHTTP11ClientProtocolTests.test_errorMessageOnConnectionLostBeforeGenerationFailedDoesNotConfuse.<locals>.checkrU  )r   r  r   rX  rR   )rO   rb  r>   ra  r?   Etest_errorMessageOnConnectionLostBeforeGenerationFailedDoesNotConfuse{  s
   
z_HTTP11ClientProtocolTests.test_errorMessageOnConnectionLostBeforeGenerationFailedDoesNotConfusec                    <    j tddtd} fdd}||  j d |S )z
        When a response is delivered to L{HTTP11ClientProtocol}, the
        L{Deferred} previously returned by the C{request} method is called back
        with a L{Response} instance and the connection is closed.
        r   r   Nc                    s@     | jd   | jt    jj    jjd d S )Nr`   	QUIESCENT)	rH   r   r   r2   r   rc   rQ  r   r   r   rj   r>   r?   	cbRequest  s   zIHTTP11ClientProtocolTests.test_receiveSimplestResponse.<locals>.cbRequests9   HTTP/1.1 200 OK
Content-Length: 0
Connection: close

r   r   r*   rb   rR   r   rO   rU   rg  r>   rj   r?   test_receiveSimplestResponse  s   
z6HTTP11ClientProtocolTests.test_receiveSimplestResponsec                    rd  )z
        The headers included in a response delivered to L{HTTP11ClientProtocol}
        are included on the L{Response} instance passed to the callback
        returned by the C{request} method.
        r   r   Nc                    s"   t dddgi} | j| d S )Nr   r   r   )r2   rH   r   )r   r   rj   r>   r?   rg    r   zHHTTP11ClientProtocolTests.test_receiveResponseHeaders.<locals>.cbRequests+   HTTP/1.1 200 OK
X-Foo: bar
X-Foo: baz

rh  ri  r>   rj   r?   test_receiveResponseHeaders  s   
z5HTTP11ClientProtocolTests.test_receiveResponseHeadersc                    sp   g t  tj   t  } d  fdd}|| fdd}|| |S )a[  
        If response bytes are delivered to L{HTTP11ClientProtocol} before the
        L{Deferred} returned by L{Request.writeTo} fires, those response bytes
        are parsed as part of the response.

        The connection is also closed, because we're in a confusing state, and
        therefore the C{quiescentCallback} isn't called.
        s8   HTTP/1.1 200 OK
X-Foo: bar
Content-Length: 6

foobarc                    sV   t   t  } _  jd j g  | fddS )N%TRANSMITTING_AFTER_RECEIVING_RESPONSEc                    
    j fS ri   r   r   pr   r>   r?   r     r   zoHTTP11ClientProtocolTests.test_receiveResponseBeforeRequestGenerationDone.<locals>.cbResponse.<locals>.<lambda>)	r   r   closedDeferreddeliverBodyrH   r   r   rQ  rR   r   whenFinished)r   quiescentResultrO   rc   ro  r?   
cbResponse  s   
z]HTTP11ClientProtocolTests.test_receiveResponseBeforeRequestGenerationDone.<locals>.cbResponsec                    sf   | \}} |jd  |jd  |jd  |jtddgi  |d  jd  d S )Nr^   r`   ra   r   r      foobar)rH   r   r   r   r   r2   r   rT  )resultr   r   r   rO   r>   r?   cbAllResponse  s   z`HTTP11ClientProtocolTests.test_receiveResponseBeforeRequestGenerationDone.<locals>.cbAllResponse)r   r(   r~   r   r4  r   r   rR   rO   rU   rv  rz  r>   )r   ru  r   rO   rc   r?   /test_receiveResponseBeforeRequestGenerationDone  s   	



	
zIHTTP11ClientProtocolTests.test_receiveResponseBeforeRequestGenerationDonec                 C   sZ   t  }t }||_|| dtj }|tddtd}|	d| d  t
| |tgS )zy
        The connection is closed when the server respond with a header which
        is above the maximum line.
        r
  r   r   Ns   HTTP/1.1 200 OK
X-Foo: s   
X-Ignored: ignored

)r   r(   r   r   r   
MAX_LENGTHr   r*   rb   r   rY   r	   )rO   rc   r   longLinerU   r>   r>   r?   "test_receiveResponseHeadersTooLong  s   

z<HTTP11ClientProtocolTests.test_receiveResponseHeadersTooLongc                    sL   t   j }jd dd }||  fdd}|| |S )z
        If response bytes are delivered to L{HTTP11ClientProtocol} before the
        request completes, calling C{connectionLost} on the protocol will
        result in protocol being moved to C{'CONNECTION_LOST'} state.
        s8   HTTP/1.1 400 BAD REQUEST
Content-Length: 9

tisk tiskc                    s0   t   t  } _  | fddS )Nc                    rm  ri   rn  r   ro  r>   r?   r     r   zHTTP11ClientProtocolTests.test_connectionLostAfterReceivingResponseBeforeRequestGenerationDone.<locals>.cbResponse.<locals>.<lambda>)r   r   rq  rr  rR   rs  r>   ro  r?   rv    s   
zrHTTP11ClientProtocolTests.test_connectionLostAfterReceivingResponseBeforeRequestGenerationDone.<locals>.cbResponsec                    s2    j d  jtt  jjd d S )Nr^  )r   rT  r   r  r   r8   rH   rs   )r`  ry  r>   r?   rz    s   zuHTTP11ClientProtocolTests.test_connectionLostAfterReceivingResponseBeforeRequestGenerationDone.<locals>.cbAllResponse)r4  r   r   r   rR   r{  r>   ry  r?   Dtest_connectionLostAfterReceivingResponseBeforeRequestGenerationDone  s   

z^HTTP11ClientProtocolTests.test_connectionLostAfterReceivingResponseBeforeRequestGenerationDonec                    s   t   t  } _jtddtd}jd g }||j	 
|g  jd |d }|  jd jd  fd	d
}|| |S )z
        The C{deliverBody} method of the response object with which the
        L{Deferred} returned by L{HTTP11ClientProtocol.request} fires can be
        used to get the body of the response.
        r   r   Ns%   HTTP/1.1 200 OK
Content-Length: 6
r   r   r   r   c                    s     jd  jt d S )Nrw  )rH   r   closedReasonrG   r.   rG  r   r>   r?   rz  J  s   zIHTTP11ClientProtocolTests.test_receiveResponseBody.<locals>.cbAllResponse)r   r   rq  r   r   r*   rb   r   rR   r~   rH   rr  )rO   rt  requestDeferredrx  r   rz  r>   r   r?   test_receiveResponseBody(  s&   

z2HTTP11ClientProtocolTests.test_receiveResponseBodyc                 C   s   | j tddtd}| j d g }||j |d }t }|| | j d | j d | 	|j
d | j ttd	 |jt dS )
z
        If the length of the response body is unknown, the protocol passed to
        the response's C{deliverBody} method has its C{connectionLost}
        method called with a L{Failure} wrapping a L{PotentialDataLoss}
        exception.
        r   r   Ns   HTTP/1.1 200 OK

r   r   r   rw  z low-level transport disconnected)r   r   r*   rb   r   rR   r~   r   rr  rH   r   r  r   r	   r  rG   r)   rO   r  rx  r   r   r>   r>   r?   Etest_responseBodyFinishedWhenConnectionLostWhenContentLengthIsUnknownQ  s    

z_HTTP11ClientProtocolTests.test_responseBodyFinishedWhenConnectionLostWhenContentLengthIsUnknownc                 C   s   | j tddtd}| j d g }||j |d }t }|| | j d | j d | 	|j
d | j tt  t| t|jttgS )	a  
        If the final chunk has not been received when the connection is lost
        (for any reason), the protocol passed to C{deliverBody} has its
        C{connectionLost} method called with a L{Failure} wrapping the
        exception for that reason.
        r   r   Ns/   HTTP/1.1 200 OK
Transfer-Encoding: chunked

r      3
foo
s   3
bar
rw  )r   r   r*   rb   r   rR   r~   r   rr  rH   r   r  r   r8   rY   r   r  r1   r  r>   r>   r?   4test_chunkedResponseBodyUnfinishedWhenConnectionLostn  s$   
zNHTTP11ClientProtocolTests.test_chunkedResponseBodyUnfinishedWhenConnectionLostc                    sJ    j tddtd} j d t |tg} fdd}|| |S )a!  
        If the parser L{HTTP11ClientProtocol} delivers bytes to in
        C{dataReceived} raises an exception, the exception is wrapped in a
        L{Failure} and passed to the parser's C{connectionLost} and then the
        L{HTTP11ClientProtocol}'s transport is disconnected.
        r   r   Ns   unparseable garbage goes here
c                    s<      jj  | jd jjd  jt	t
d d S )Nr   s   unparseable garbage goes herez
it is done)r   rc   rQ  rH   rF   r   r   r   r  r   r	   r   rj   r>   r?   rP     s
   zLHTTP11ClientProtocolTests.test_parserDataReceivedException.<locals>.cbFailed)r   r   r*   rb   r   rY   r#   rR   )rO   r  rU   rP   r>   rj   r?    test_parserDataReceivedException  s   
z:HTTP11ClientProtocolTests.test_parserDataReceivedExceptionc                 C   s`   | j tddtd}| j jj}| |j| j | j t	t
d | |jd t| |t
gS )z
        When the HTTP response parser is disconnected, the
        L{TransportProxyProducer} which was connected to it as a transport is
        stopped.
        r   r   Nzconnection done)r   r   r*   rb   _parserrc   r   	_producer_disconnectParserr   r	   rY   )rO   r  rc   r>   r>   r?   test_proxyStopped  s   
z+HTTP11ClientProtocolTests.test_proxyStoppedc                 C   s   t  }t }|| g }g }| |j | |j | ||fg g f | |j |	t
t  | |dg | |dg dS )z
        L{HTTP11ClientProtocol.abort} will tell the transport to close its
        connection when it is invoked, and returns a C{Deferred} that fires
        when the connection is lost.
        N)r   r(   r   abortrR   r~   rH   r   rQ  r  r   r	   )rO   rc   r   r1r2r>   r>   r?   test_abortClosesConnection  s   
z4HTTP11ClientProtocolTests.test_abortClosesConnectionc                 C   sZ   t  }t }|| |tt  g }| |j | 	|dg | 	|j
d dS )z
        L{HTTP11ClientProtocol.abort} called after the connection is lost
        returns a C{Deferred} that fires immediately.
        Nr^  )r   r(   r   r  r   r	   r  rR   r~   rH   rs   rO   rc   r   rx  r>   r>   r?   test_abortAfterConnectionLost  s   
z7HTTP11ClientProtocolTests.test_abortAfterConnectionLostc                 C   s\   t  }t }|| |tddtd}|  | |j |	t
t  t| |tgS )a  
        The Deferred returned by L{HTTP11ClientProtocol.request} will fire
        with a L{ResponseFailed} failure containing a L{ConnectionAborted}
        exception, if the connection was aborted before all response headers
        have been received.
        r   r   N)r   r(   r   r   r*   rb   r  r   rQ  r  r   r	   rY   r   r  r>   r>   r?   test_abortBeforeResponseBody  s   
z6HTTP11ClientProtocolTests.test_abortBeforeResponseBodyc                    s   t ddt  tddtd}d t G fdddt  fd	d
}fdd}|	| t
ttg}|	|S )aS  
        When the connection is aborted after the response headers have
        been received and the L{Response} has been made available to
        application code, the response body protocol's C{connectionLost}
        method will be invoked with a L{ResponseFailed} failure containing a
        L{ConnectionAborted} exception.
        T)lenientr   r   Nr  c                       s(   e Zd ZdZ fddZfddZdS )zQHTTP11ClientProtocolTests.test_abortAfterResponseHeaders.<locals>.BodyDestinationzl
            A body response protocol which immediately aborts the HTTP
            connection.
            c                    s       dS )z<
                Abort the HTTP connection.
                N)r  rj   )r   r>   r?   connectionMade  s   z`HTTP11ClientProtocolTests.test_abortAfterResponseHeaders.<locals>.BodyDestination.connectionMadec                    s     | dS )z
                Make the reason for the losing of the connection available to
                the unit test via C{testResult}.
                N)rU  rO   rK   )
testResultr>   r?   r    rZ   z`HTTP11ClientProtocolTests.test_abortAfterResponseHeaders.<locals>.BodyDestination.connectionLostN)r:   r;   r<   r=   r  r  r>   )r   r  r>   r?   BodyDestination  s    r  c                    s,   |     j tt  dS )z
            Connect the L{BodyDestination} response body protocol to the
            response, and then simulate connection loss after ensuring that
            the HTTP connection has been aborted.
            N)rr  r   rQ  r  r   r	   rf  )r  r   rO   rc   r>   r?   rr    s   zMHTTP11ClientProtocolTests.test_abortAfterResponseHeaders.<locals>.deliverBodyc                    s     | jt d S ri   )r  r   r-   )errorrj   r>   r?   
checkError     zLHTTP11ClientProtocolTests.test_abortAfterResponseHeaders.<locals>.checkError)r   r(   r   r   r*   rb   r   r   r   rR   rY   r   r1   )rO   rx  rr  r  rS   r>   )r  r   rO   r  rc   r?   test_abortAfterResponseHeaders  s   






z8HTTP11ClientProtocolTests.test_abortAfterResponseHeadersc              	      s  g  fdd}t  }t|  |  tddtddd} d g  g }||j	 |d	 }t
 }t |_|jfd
d ||  d |jt  dg  jd  jd  jd  jd  jd dS )a  
        If after a response is done the {HTTP11ClientProtocol} stays open and
        returns to QUIESCENT state, all per-request state is reset and the
        C{quiescentCallback} is called with the protocol instance.

        This is useful for implementing a persistent connection pool.

        The C{quiescentCallback} is called *before* the response-receiving
        protocol's C{connectionLost}, so that new requests triggered by end of
        first request can re-use a persistent connection.
        c                    (    |    | jd |  d S Nre  rH   r   r~   rp  r   ru  rO   r>   r?   rT  5     zHHTTP11ClientProtocolTests.test_quiescentCallbackCalled.<locals>.callbackr   r   NTr=  s&   HTTP/1.1 200 OK
Content-length: 3

r   c                    r   )Nresponse doner   r   )ru  r>   r?   r   O  r   zHHTTP11ClientProtocolTests.test_quiescentCallbackCalled.<locals>.<lambda>r  r  )r   r(   r   r   r*   rb   r   rH   rR   r~   r   r   rq  rr  r  rG   r.   r  _finishedRequest_currentRequest_transportProxyr  )rO   rT  rc   r  rx  r   bodyProtocolr>   r  r?   test_quiescentCallbackCalled'  s6   




z6HTTP11ClientProtocolTests.test_quiescentCallbackCalledc              	      s   g  fdd}t  }t|  |  tddtddd} d |}|j	d	 t
d
 |jd dS )a  
        The C{quiescentCallback} passed to L{HTTP11ClientProtocol} will only be
        invoked once that protocol is in a state similar to its initial state.
        One of the aspects of this initial state is the producer-state of its
        transport; an L{HTTP11ClientProtocol} begins with a transport that is
        producing, i.e. not C{pauseProducing}'d.

        Therefore, when C{quiescentCallback} is invoked the protocol will still
        be producing.
        c                    r  r  r  r  r  r>   r?   rT  m  r  z]HTTP11ClientProtocolTests.test_transportProducingWhenQuiescentAfterFullBody.<locals>.callbackr   r   NTr  s)   HTTP/1.1 200 OK
Content-length: 3

BBBDEFERRED_CLOSEr_   r   )r   r(   r   r   r*   rb   r   successResultOfrH   rs   rI   r   )rO   rT  rc   r  r   r>   r  r?   1test_transportProducingWhenQuiescentAfterFullBody`  s   

zKHTTP11ClientProtocolTests.test_transportProducingWhenQuiescentAfterFullBodyc              	      s   g  fdd}t  }t|  |  tddtddd}|j  d 	t
d	 d
   d t dS )z
        The quiescentCallback is called before the request C{Deferred} fires,
        in cases where the response has no body.
        c                    r  r  r  r  r  r>   r?   rT    r  zUHTTP11ClientProtocolTests.test_quiescentCallbackCalledEmptyResponse.<locals>.callbackr   r   NTr  &   HTTP/1.1 200 OK
Content-length: 0

r   r   r_   )r   r(   r   r   r*   rb   rR   r~   r   rH   rI   r   r  r-   )rO   rT  rc   r  r>   r  r?   )test_quiescentCallbackCalledEmptyResponse  s   

zCHTTP11ClientProtocolTests.test_quiescentCallbackCalledEmptyResponsec              	   C      g }t  }t|j}|| |tddtddd}|d g }||j |d }t	 }|
| |jt | |g  | |j dS )z
        If after a response is done the {HTTP11ClientProtocol} returns a
        C{Connection: close} header in the response, the C{quiescentCallback}
        is not called and the connection is lost.
        r   r   NTr  s9   HTTP/1.1 200 OK
Content-length: 0
Connection: close

r   r   r(   r~   r   r   r*   rb   r   rR   r   rr  r  rG   r.   rH   r   rQ  rO   ru  rc   r   r  rx  r   r  r>   r>   r?   test_quiescentCallbackNotCalled  s$   


z9HTTP11ClientProtocolTests.test_quiescentCallbackNotCalledc              	   C   r  )z
        If the request was non-persistent (i.e. sent C{Connection: close}),
        the C{quiescentCallback} is not called and the connection is lost.
        r   r   NFr  r  r   r  r  r>   r>   r?   1test_quiescentCallbackNotCalledNonPersistentQuery  s    



zKHTTP11ClientProtocolTests.test_quiescentCallbackNotCalledNonPersistentQueryc              	   C   s   dd }t | t}t }t|}|| |tddtddd}|	d g }|
|j |d	 }t }|| |jt | d
t| |d	 }	|	d }
| |
jt | t | |j dS )zx
        If C{quiescentCallback} throws an exception, the error is logged and
        protocol is disconnected.
        c                 S   r  ri   )ZeroDivisionErrorr  r>   r>   r?   rT    r  zHHTTP11ClientProtocolTests.test_quiescentCallbackThrows.<locals>.callbackr   r   NTr  r  r   r_   r  )r   r  r   r   r(   r   r   r*   rb   r   rR   r~   r   rr  r  rG   r.   r  rI   r  r   r  r  r   rQ  )rO   rT  r  rc   r   r  rx  r   r  r  r   r>   r>   r?   test_quiescentCallbackThrows  s*   



z6HTTP11ClientProtocolTests.test_quiescentCallbackThrowsc                 C   sN   t  }t }|| |tddtd}|  | |j t	| |t
tgS )a  
        The L{Deferred} returned by L{HTTP11ClientProtocol.request} will fire
        with a L{ResponseNeverReceived} failure containing a L{CancelledError}
        exception if the request was cancelled before any response headers were
        received.
        r   r   N)r   r(   r   r   r*   rb   cancelr   disconnectedrV   r0   r   r  r>   r>   r?   test_cancelBeforeResponse  s   

z3HTTP11ClientProtocolTests.test_cancelBeforeResponsec                 C   sV   t  }t }|| |tddtd}|d |  | |j	 t
| |tgS )a  
        The L{Deferred} returned by L{HTTP11ClientProtocol.request} will fire
        with a L{ResponseFailed} failure containing a L{CancelledError}
        exception if the request was cancelled before all response headers were
        received.
        r   r   Nr   )r   r(   r   r   r*   rb   r   r  r   r  rY   r   r  r>   r>   r?   test_cancelDuringResponse  s   

z3HTTP11ClientProtocolTests.test_cancelDuringResponsec                    s   t  }t }|| t|ddifdd  fdd}|_|tddt}j	d	 |
  | |j | d  t| |tgS )
a  
        The L{Deferred} returned by L{HTTP11ClientProtocol.request} will fire
        with a L{RequestGenerationFailed} failure containing a
        L{CancelledError} exception if the request was cancelled before a
        C{bodyProducer} has finished producing.
        	cancelledFc                    s   d d< d S )NTr  r>   r   )nonLocalr>   r?   r  2     zJHTTP11ClientProtocolTests.assertCancelDuringBodyProduction.<locals>.cancelc                    s   | _ t _jS ri   consumerr   r   )r  )r  producerr>   r?   startProducing5  s   
zRHTTP11ClientProtocolTests.assertCancelDuringBodyProduction.<locals>.startProducing   POST   /bars   xxxxx)r   r(   r   StringProducerr  r   r*   rb   r  r@  r  r   r  r[   r   )rO   producerLengthrc   r   r  rx  r>   )r  r  r  r?    assertCancelDuringBodyProduction$  s   
z:HTTP11ClientProtocolTests.assertCancelDuringBodyProductionc                 C   rY  )a(  
        The L{Deferred} returned by L{HTTP11ClientProtocol.request} will fire
        with a L{RequestGenerationFailed} failure containing a
        L{CancelledError} exception if the request was cancelled before a
        C{bodyProducer} with an explicit length has finished producing.
        
   )r  rj   r>   r>   r?   test_cancelDuringBodyProductionC     
z9HTTP11ClientProtocolTests.test_cancelDuringBodyProductionc                 C   s
   |  tS )a'  
        The L{Deferred} returned by L{HTTP11ClientProtocol.request} will fire
        with a L{RequestGenerationFailed} failure containing a
        L{CancelledError} exception if the request was cancelled before a
        C{bodyProducer} with C{UNKNOWN_LENGTH} has finished producing.
        )r  r   rj   r>   r>   r?   &test_cancelDuringChunkedBodyProductionL  r  z@HTTP11ClientProtocolTests.test_cancelDuringChunkedBodyProductionri   )'r:   r;   r<   r=   rB  rC  rL  rM  rR  rS  rX  r[  r]  rc  rj  rk  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r>   r>   r>   r?   rA    sJ    
 2 ) :9.#	rA  c                   @   s<   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dS )r  a  
    L{StringProducer} is a dummy body producer.

    @ivar stopped: A flag which indicates whether or not C{stopProducing} has
        been called.
    @ivar consumer: After C{startProducing} is called, the value of the
        C{consumer} argument to that method.
    @ivar finished: After C{startProducing} is called, a L{Deferred} which was
        returned by that method.  L{StringProducer} will never fire this
        L{Deferred}.
    Fc                 C   s
   || _ d S ri   )r   )rO   r   r>   r>   r?   __init__f  r;  zStringProducer.__init__c                 C   s   || _ t | _| jS ri   r  )rO   r  r>   r>   r?   r  i  s   zStringProducer.startProducingc                 C   r7  r   r8  rj   r>   r>   r?   stopProducingn  r;  zStringProducer.stopProducingc                 C   rh   ri   r>   rj   r>   r>   r?   pauseProducingq     zStringProducer.pauseProducingc                 C   rh   ri   r>   rj   r>   r>   r?   resumeProducingu  r  zStringProducer.resumeProducingN)
r:   r;   r<   r=   r9  r  r  r  r  r  r>   r>   r>   r?   r  V  s    r  c                   @   s   e Z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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d5d)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd(S )6RequestTestsz
    Tests for L{Request}.
    c                 C   s   t  | _d S ri   )r   rc   rj   r>   r>   r?   rB    r  zRequestTests.setUpc                 C   s,   t ddtd| j | | j d dS )zk
        L{Request.writeTo} formats the request data and writes it to the given
        transport.
        r   r   Ns8   GET / HTTP/1.1
Connection: close
Host: example.com

r*   rb   r6  rc   rH   r   rj   r>   r>   r?   test_sendSimplestRequest  s
   z%RequestTests.test_sendSimplestRequestc                 C   s4   t ddtddd}|| j | | j d dS )zO
        A pesistent request does not send 'Connection: close' header.
        r   r   NTr  s%   GET / HTTP/1.1
Host: example.com

r  )rO   reqr>   r>   r?   "test_sendSimplestPersistentRequest  s   z/RequestTests.test_sendSimplestPersistentRequestc                 C   s   t ddgdgd}tdd|d| j | j d}| |d	 d
 | |dd ddg |d	= |dd= |  | |g d dS )zf
        L{Request.writeTo} formats header data and writes it to the given
        transport.
        r   r   rC   )r   rB   r      /fooNr   r      GET /foo HTTP/1.1r   )   Connection: closes   Host: example.comr   r   )r2   r*   r6  rc   r   splitrH   sort)rO   r   linesr>   r>   r?   test_sendRequestHeaders  s   z$RequestTests.test_sendRequestHeadersc                 C   s   t D ]T}t||gddgi}t }tdd|d| | d}| |d d | |d	d d
d
g |d= |d	d= |d |d d	t
t
g}| ||g qdS )z_
        Linear whitespace in request headers is replaced with a single
        space.
        rB   s   example.invalidr   r  Nr   r   r  r  r   r  s   Host: example.invalids   : )r5   r2   r   r*   r6  r   r  rH   remover   r6   )rO   	componentr   rc   r  sanitizedHeaderLiner>   r>   r?   -test_sanitizeLinearWhitespaceInRequestHeaders  s   

z:RequestTests.test_sanitizeLinearWhitespaceInRequestHeadersc                 C   s   t t}tddt|}|| j | |jd | | jj	| | 
| jj | | j d | j  |jd |jd |jd | | jj	d | | j d dS )z
        L{Request.writeTo} uses chunked encoding to write data from the request
        body producer to the given transport.  It registers the request body
        producer with the transport.
        r  r  NsX   POST /bar HTTP/1.1
Connection: close
Transfer-Encoding: chunked
Host: example.com

s   xxxs   yyyyyyyyyyyyyyys!   3
xxx
f
yyyyyyyyyyyyyyy
0

)r  r   r*   rb   r6  rc   assertNotIdenticalr  r   r  r   	streamingrH   r   clearr@  r   rT  rO   r  r   r>   r>   r?   test_sendChunkedRequestBody  s&   
z(RequestTests.test_sendChunkedRequestBodyc                    s`   t t}tddt|}| j} j  |jt	   fdd} 
|t	}|| |S )a  
        If L{Request} is created with a C{bodyProducer} without a known length
        and the L{Deferred} returned from its C{startProducing} method fires
        with a L{Failure}, the L{Deferred} returned by L{Request.writeTo} fires
        with that L{Failure} and the body producer is unregistered from the
        transport.  The final zero-length chunk is not written to the
        transport.
        r  r  c                    s&      j d   jjd  d S rE  )rH   rc   r   r   r  rG  rj   r>   r?   rP     s   zCRequestTests.test_sendChunkedRequestBodyWithError.<locals>.cbFailed)r  r   r*   rb   r6  rc   r  r   rU  r8   rQ   rR   )rO   r  r   writeDeferredrP   rU   r>   rj   r?   $test_sendChunkedRequestBodyWithError  s   	

z1RequestTests.test_sendChunkedRequestBodyWithErrorc                 C   s   t d}tddt|}|| j | |jd | | jj| | 	| jj
 | | j d | j  |jd |jd | | jjd | | j d dS )z
        If L{Request} is created with a C{bodyProducer} with a known length,
        that length is sent as the value for the I{Content-Length} header and
        chunked encoding is not used.
           r  r  NsO   POST /bar HTTP/1.1
Connection: close
Content-Length: 3
Host: example.com

r  )r  r*   rb   r6  rc   r  r  r   r  r   r  rH   r   r  r@  r   rT  r  r>   r>   r?   test_sendRequestBodyWithLength  s   
z+RequestTests.test_sendRequestBodyWithLengthc                 C   s4   t |dtd}|| j | | j |d  dS )a"  
        Verify that the message generated by a L{Request} initialized with
        the given method and C{None} as the C{bodyProducer} includes
        I{Content-Length: 0} in the header.

        @param method: The HTTP method issue in the request.
        @type method: L{bytes}
        r  NsK    /foo HTTP/1.1
Connection: close
Content-Length: 0
Host: example.com

r  )rO   r<  r   r>   r>   r?   _sendRequestEmptyBodyWithLength  s   	z,RequestTests._sendRequestEmptyBodyWithLengthc                 C      |  d dS )z
        If I{PUT} L{Request} is created without a C{bodyProducer},
        I{Content-Length: 0} is included in the header and chunked
        encoding is not used.
        s   PUTNr  rj   r>   r>   r?   test_sendPUTRequestEmptyBody(     z)RequestTests.test_sendPUTRequestEmptyBodyc                 C   r  )z
        If I{POST} L{Request} is created without a C{bodyProducer},
        I{Content-Length: 0} is included in the header and chunked
        encoding is not used.
        r  Nr  rj   r>   r>   r?   test_sendPOSTRequestEmptyBody0  r  z*RequestTests.test_sendPOSTRequestEmptyBodyc                 C   sV   t d}tddt|}|| j}|jd |jd | 	| jj
d | |tS )a  
        If L{Request} is created with a C{bodyProducer} with a known length and
        the producer does not produce that many bytes, the L{Deferred} returned
        by L{Request.writeTo} fires with a L{Failure} wrapping a
        L{WrongBodyLength} exception.
        r  r  r     abN)r  r*   rb   r6  rc   r  r@  r   rT  r   r  rQ   r&   rO   r  r   r  r>   r>   r?   #test_sendRequestBodyWithTooFewBytes8  s   z0RequestTests.test_sendRequestBodyWithTooFewBytesc                    s   t dtddt}|j}jd j jd 	j 
jjd  fdd}|t}|| |S )	a7  
        Verify that when too many bytes have been written by a body producer
        and then the body producer's C{startProducing} L{Deferred} fires that
        the producer is unregistered from the transport and that the
        L{Deferred} returned from L{Request.writeTo} is fired with a L{Failure}
        wrapping a L{WrongBodyLength}.

        @param finisher: A callable which will be invoked with the body
            producer after too many bytes have been written to the transport.
            It should fire the startProducing Deferred somehow.
        r  r  r  r     cdNc                    sL    j d j  tjjd    j d d S )NsQ   POST /bar HTTP/1.1
Connection: close
Content-Length: 3
Host: example.com

abs   efr   )rH   rc   r   r  rw   r   r  r@  r  finisherr  rO   r>   r?   rP   g  s   
	zCRequestTests._sendRequestBodyWithTooManyBytesTest.<locals>.cbFailed)r  r*   rb   r6  rc   r  r@  r   r9  r   r   r  rQ   r&   rR   )rO   r  r   r  rP   rU   r>   r  r?   $_sendRequestBodyWithTooManyBytesTestG  s   
z1RequestTests._sendRequestBodyWithTooManyBytesTestc                 C   s   dd }|  |S )  
        If L{Request} is created with a C{bodyProducer} with a known length and
        the producer tries to produce more than than many bytes, the
        L{Deferred} returned by L{Request.writeTo} fires with a L{Failure}
        wrapping a L{WrongBodyLength} exception.
        c                 S      | j d  d S ri   r   rT  r  r>   r>   r?   r       zCRequestTests.test_sendRequestBodyWithTooManyBytes.<locals>.finisher)r  rO   r  r>   r>   r?   $test_sendRequestBodyWithTooManyBytes  s   
z1RequestTests.test_sendRequestBodyWithTooManyBytesc                    s$   t t  fdd}|S )r  c                    sV   | j t   d }d| |d }|jt t}t|d d S )Nr   r  r_   )	r   rU  r8   r_  r  r   r  rH   rI   )r  r  r   rW  ra  r>   r?   r    s   
zHRequestTests.test_sendRequestBodyErrorWithTooManyBytes.<locals>.finisher)r   r  r   r  r  r>   ra  r?   )test_sendRequestBodyErrorWithTooManyBytes  s   
	z6RequestTests.test_sendRequestBodyErrorWithTooManyBytesc                 C   s   t | t}td}tddt|}|| j |jj	}|j
d |jd |t  |d }| d| |d }| |jt | t| td dS )	a  
        Though there should be no way for the internal C{finishedConsuming}
        L{Deferred} in L{Request._writeToBodyProducerContentLength} to fire a
        L{Failure} after the C{finishedProducing} L{Deferred} has fired, in
        case this does happen, the error should be logged with a message about
        how there's probably a bug in L{Request}.

        This is a whitebox test.
        r  r  r  r  Nr   r  r_   )r   r  r   r  r*   rb   r6  rc   r  	_finishedr@  r   rT  rU  r8   r_  r  r   rH   rI   r  )rO   r  r  r   finishedConsumingr  r   r>   r>   r?   *test_sendRequestBodyErrorWithConsumerError  s   
z7RequestTests.test_sendRequestBodyErrorWithConsumerErrorc                 C   sx   t d}tddt|}|| j}|jd || | | jjd | j	  | 
t|jjd | | j d |S )a  
        Verify that if the body producer fires its Deferred and then keeps
        writing to the consumer that the extra writes are ignored and the
        L{Deferred} returned by L{Request.writeTo} fires with a L{Failure}
        wrapping the most appropriate exception type.
        r  r  r  r  Nr  r   )r  r*   rb   r6  rc   r  r@  r   r  r  rw   r   rH   r   )rO   r  r  r   r  r>   r>   r?   -_sendRequestBodyFinishedEarlyThenTooManyBytes  s   
z:RequestTests._sendRequestBodyFinishedEarlyThenTooManyBytesc                 C      dd }|  | |tS )a-  
        If the request body producer indicates it is done by firing the
        L{Deferred} returned from its C{startProducing} method but then goes on
        to write too many bytes, the L{Deferred} returned by {Request.writeTo}
        fires with a L{Failure} wrapping L{WrongBodyLength}.
        c                 S   r  ri   r  r  r>   r>   r?   r    r  zPRequestTests.test_sendRequestBodyFinishedEarlyThenTooManyBytes.<locals>.finisher)rQ   r  r&   r  r>   r>   r?   1test_sendRequestBodyFinishedEarlyThenTooManyBytes  
   z>RequestTests.test_sendRequestBodyFinishedEarlyThenTooManyBytesc                 C   r  )a3  
        If the request body producer indicates an error by firing the
        L{Deferred} returned from its C{startProducing} method but then goes on
        to write too many bytes, the L{Deferred} returned by {Request.writeTo}
        fires with that L{Failure} and L{WrongBodyLength} is logged.
        c                 S   s   | j t  d S ri   )r   rU  r8   r  r>   r>   r?   r    r  zORequestTests.test_sendRequestBodyErroredEarlyThenTooManyBytes.<locals>.finisher)rQ   r  r8   r  r>   r>   r?   0test_sendRequestBodyErroredEarlyThenTooManyBytes  r  z=RequestTests.test_sendRequestBodyErroredEarlyThenTooManyBytesNc                 C   s`   t t}tddt|}|| j}|j| | j  | 	t
|jjd | | j d |S )a  
        If the request body producer with an unknown length tries to write
        after firing the L{Deferred} returned by its C{startProducing} method,
        the C{write} call raises an exception and does not write anything to
        the underlying transport.
        r  r  r   r   )r  r   r*   rb   r6  rc   r   rT  r  rw   r   r  r@  rH   r   )rO   _withr  r   r  r>   r>   r?   0test_sendChunkedRequestBodyFinishedThenWriteMore  s   
z=RequestTests.test_sendChunkedRequestBodyFinishedThenWriteMorec                 C   s   |  tt }| |tS )a$  
        If the request body producer with an unknown length tries to write
        after firing the L{Deferred} returned by its C{startProducing} method
        with a L{Failure}, the C{write} call raises an exception and does not
        write anything to the underlying transport.
        )r  r   r8   rQ   )rO   rU   r>   r>   r?   9test_sendChunkedRequestBodyFinishedWithErrorThenWriteMore	  s   zFRequestTests.test_sendChunkedRequestBodyFinishedWithErrorThenWriteMorec                 C   s   t d}tddt|}|| j}| | jj| | | jj |j	
d | | j d | | jj |jtt  | | jj | | jjd | |tS )z
        If the L{Deferred} returned from the C{startProducing} method of the
        L{IBodyProducer} passed to L{Request} fires with a L{Failure}, the
        L{Deferred} returned from L{Request.writeTo} fails with that
        L{Failure}.
           r  r  r  sQ   POST /bar HTTP/1.1
Connection: close
Content-Length: 5
Host: example.com

abN)r  r*   rb   r6  rc   r   r  r   r  r  r@  rH   r   r   rQ  r   rU  r   r8   rQ   r  r>   r>   r?   test_sendRequestBodyWithError	  s   
z*RequestTests.test_sendRequestBodyWithErrorc                 C   sx   t ddti d}| t|j| j | | j d t ddtdddgid}| t|j| j | | j d dS )z
        L{Request.writeTo} raises L{BadHeaders} if there is not exactly one
        I{Host} header and writes nothing to the given transport.
        r   r   Nr   s   HostrC   s   example.org)r*   r2   rw   r   r6  rc   rH   r   )rO   r   r>   r>   r?   test_hostHeaderRequired;	  s   z$RequestTests.test_hostHeaderRequiredc                 C   sF   t d}tddt|}|| j | |j |  | |j dS )zc
        L{Request.stopWriting} calls its body producer's C{stopProducing}
        method.
        r  r   r   N)	r  r*   rb   r6  rc   r   r9  r:  r   r  r>   r>   r?   test_stopWritingJ	  s   zRequestTests.test_stopWritingc                 C   s   t | t}td}dd }||_tddt|}|| j |	  | 
t| td | dt| |d }| d| |d }| |jt d	S )
z
        If the body producer's C{stopProducing} method raises an exception,
        L{Request.stopWriting} logs it and does not re-raise it.
        r  c                   S   s   t dNzstopProducing is bustedr  r>   r>   r>   r?   brokenStopProducing^	  s   zBRequestTests.test_brokenStopProducing.<locals>.brokenStopProducingr   r   r_   r   r  N)r   r  r   r  r  r*   rb   r6  rc   r:  rH   rI   r  r8   r  r_  r  r   )rO   r  r  r  r   r  r   r>   r>   r?   test_brokenStopProducingV	  s   z%RequestTests.test_brokenStopProducingri   )r:   r;   r<   r=   rB  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r	  r  r  r  r  r>   r>   r>   r?   r  z  s6    !A
'r  c                   @   sR   e Zd ZdZdd Zdd Zdd Zdd	d
Zdd Zdd Z	dd Z
dd ZdS )LengthEnforcingConsumerTestsz/
    Tests for L{LengthEnforcingConsumer}.
    c                 C   s2   t  | _td| _t | _t| j| j| j| _d S )Nr  )r   rx  r  r  r   rc   r"   enforcerrj   r>   r>   r?   rB  s	  s   

z"LengthEnforcingConsumerTests.setUpc                 C   sJ   | j d | | j d | j  | j d | | j d dS )z
        L{LengthEnforcingConsumer.write} calls the wrapped consumer's C{write}
        method with the bytes it is passed as long as there are fewer of them
        than the C{length} attribute indicates remain to be received.
        r  s   defN)r  r@  rH   rc   r   r  rj   r>   r>   r?   
test_write{	  s
   
z'LengthEnforcingConsumerTests.test_writec                 C   s    | j d | t| j j dS )z
        L{LengthEnforcingConsumer._noMoreWritesExpected} raises
        L{WrongBodyLength} if it is called before the indicated number of bytes
        have been written.
        s	   xxxxxxxxxN)r  r@  rw   r&   _noMoreWritesExpectedrj   r>   r>   r?   test_finishedEarly	  s   z/LengthEnforcingConsumerTests.test_finishedEarlyFc                 C   sP   | j d | | jj | j d | | jj |r!| j   | | jt	S )aN  
        If it is called with a total number of bytes exceeding the indicated
        limit passed to L{LengthEnforcingConsumer.__init__},
        L{LengthEnforcingConsumer.write} fires the L{Deferred} with a
        L{Failure} wrapping a L{WrongBodyLength} and also calls the
        C{stopProducing} method of the producer.
        
   xxxxxxxxxx   x)
r  r@  r   r  r9  r   r  rQ   rx  r&   )rO   _unregisterAfterr>   r>   r?   test_writeTooMany	  s   
z.LengthEnforcingConsumerTests.test_writeTooManyc                 C   sH   | j d | j   | | jj | t| j jd | | jj dS )z
        If L{LengthEnforcingConsumer.write} is called after
        L{LengthEnforcingConsumer._noMoreWritesExpected}, it calls the
        producer's C{stopProducing} method and raises L{ExcessWrite}.
        r  r  N)	r  r@  r  r   r  r9  rw   r   r   rj   r>   r>   r?   test_writeAfterNoMoreExpected	  s
   
z:LengthEnforcingConsumerTests.test_writeAfterNoMoreExpectedc                 C   rY  )z
        L{LengthEnforcingConsumer._noMoreWritesExpected} does nothing (in
        particular, it does not raise any exception) if called after too many
        bytes have been passed to C{write}.
        T)r  rj   r>   r>   r?   test_finishedLate	  r\  z.LengthEnforcingConsumerTests.test_finishedLatec                 C   s"   | j d | | j  d dS )z
        If L{LengthEnforcingConsumer._noMoreWritesExpected} is called after
        the correct number of bytes have been written it returns L{None}.
        r  N)r  r@  r   r  rj   r>   r>   r?   test_finished	  s   z*LengthEnforcingConsumerTests.test_finishedc                    s6    fdd}| j _ fdd}  }|| |S )a8  
        If L{LengthEnforcingConsumer.write} calls the producer's
        C{stopProducing} because too many bytes were written and the
        C{stopProducing} method raises an exception, the exception is logged
        and the L{LengthEnforcingConsumer} still errbacks the finished
        L{Deferred}.
        c                      s   t  j tdr  )r  r  r  r8   r>   rj   r>   r?   r  	  s   zRLengthEnforcingConsumerTests.test_stopProducingRaises.<locals>.brokenStopProducingc                    s     t td d S )Nr_   )rH   rI   r  r8   rG  rj   r>   r?   
cbFinished	  s   zILengthEnforcingConsumerTests.test_stopProducingRaises.<locals>.cbFinished)r  r  r  rR   )rO   r  r  rU   r>   rj   r?   test_stopProducingRaises	  s   	
z5LengthEnforcingConsumerTests.test_stopProducingRaisesN)F)r:   r;   r<   r=   rB  r  r  r  r  r  r  r  r>   r>   r>   r?   r  n	  s    
	r  c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	RequestBodyConsumerTestsz
    Tests for L{ChunkedEncoder} which sits between an L{ITransport} and a
    request/response body producer and chunked encodes everything written to
    it.
    c                 C   s   |  tttt  dS )zC
        L{ChunkedEncoder} instances provide L{IConsumer}.
        N)r   r   r   r   r   rj   r>   r>   r?   test_interface	  s   z'RequestBodyConsumerTests.test_interfacec                 C   sN   t  }t|}|d | | d |  |d | | d dS )z}
        L{ChunkedEncoder.write} writes to the transport the chunked encoded
        form of the bytes passed to it.
        r   r  s   xxxxxxxxxxxxxxxxs   10
xxxxxxxxxxxxxxxx
N)r   r   r@  rH   r   r  )rO   rc   encoderr>   r>   r?   r  	  s   

z#RequestBodyConsumerTests.test_writec                 C   sd   t  }t }t|}||d | |j| | |j |  | |jd | 	|
 d dS )a  
        L{ChunkedEncoder.registerProducer} registers the given streaming
        producer with its transport and L{ChunkedEncoder.unregisterProducer}
        writes a zero-length chunk to its transport and unregisters the
        transport's producer.
        TNs   0

)r   r   r   registerProducerr   r  r   r  unregisterProducerrH   r   )rO   rc   r  r!  r>   r>   r?   test_producerRegistration	  s   z2RequestBodyConsumerTests.test_producerRegistrationN)r:   r;   r<   r=   r   r  r$  r>   r>   r>   r?   r  	  s
    r  c                   @   sH   e Z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S )TransportProxyProducerTestszn
    Tests for L{TransportProxyProducer} which proxies the L{IPushProducer}
    interface of a transport.
    c                 C   s   |  tttd dS )zO
        L{TransportProxyProducer} instances provide L{IPushProducer}.
        N)r   r   r   r%   rj   r>   r>   r?   r   
  s   z*TransportProxyProducerTests.test_interfacec                 C   s6   t  }t|}| |j| |  | |jd dS )z~
        L{TransportProxyProducer.stopProxying} drops the reference to the
        wrapped L{IPushProducer} provider.
        N)r   r%   r   r  stopProxyingrO   rc   proxyr>   r>   r?   %test_stopProxyingUnreferencesProducer
  s
   zATransportProxyProducerTests.test_stopProxyingUnreferencesProducerc                 C   sd   t  }|  t|}| |jd |  | |jd |  |  |  | |jd dS )z
        L{TransportProxyProducer.resumeProducing} calls the wrapped
        transport's C{resumeProducing} method unless told to stop proxying.
        r   r   N)r   r  r%   rH   r   r  r&  r'  r>   r>   r?   test_resumeProducing
  s   z0TransportProxyProducerTests.test_resumeProducingc                 C   s\   t  }t|}| |jd |  | |jd |  |  |  | |jd dS )z
        L{TransportProxyProducer.pauseProducing} calls the wrapped transport's
        C{pauseProducing} method unless told to stop proxying.
        r   r   N)r   r%   rH   r   r  r  r&  r'  r>   r>   r?   test_pauseProducing,
  s   z/TransportProxyProducerTests.test_pauseProducingc                 C   sb   t  }t|}| |jd |  | |jd t  }t|}|  |  | |jd dS )z
        L{TransportProxyProducer.stopProducing} calls the wrapped transport's
        C{stopProducing} method unless told to stop proxying.
        r   r9  N)r   r%   rH   r   r  r&  r'  r>   r>   r?   test_stopProducingA
  s   z.TransportProxyProducerTests.test_stopProducingc                 C   sd   t  }t }|| ||_t|}| |j | |jd |	  | |jd | 
|j dS )zs
        L{TransportProxyProducer.loseConnection} calls the wrapped transport's
        C{loseConnection}.
        r   N)r   r   r   r   r%   r   	connectedrH   r   loseConnectionr   rO   rc   r   r(  r>   r>   r?    test_loseConnectionWhileProxyingU
  s   
z<TransportProxyProducerTests.test_loseConnectionWhileProxyingc                 C   sP   t  }t }|| ||_t|}|  | |j |  | |j dS )zm
        L{TransportProxyProducer.loseConnection} does nothing when the
        proxy is not active.
        N)	r   r   r   r   r%   r&  r   r-  r.  r/  r>   r>   r?   test_loseConnectionNotProxyingj
  s   
z:TransportProxyProducerTests.test_loseConnectionNotProxyingN)r:   r;   r<   r=   r   r)  r*  r+  r,  r0  r1  r>   r>   r>   r?   r%  	  s    r%  c                   @   s   e Z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dd Zdd Zdd Zdd Zdd Zd S )!ResponseTestsz 
    Tests for L{Response}.
    c                 C   s   t t }| tt| dS )z=
        L{Response} instances provide L{IResponse}.
        N)rd   r   r   r   r4   rO   r   r>   r>   r?   test_verifyInterface
  s   
z"ResponseTests.test_verifyInterfacec                    sl   g  t  }G  fdddt}| }t|}||  \}|  | |jd |  | |jd dS )z
        The L{IProtocol} provider passed to L{Response.deliverBody} has its
        C{makeConnection} method called with an L{IPushProducer} provider
        hooked up to the response as an argument.
        c                          e Zd Z fddZdS )z7ResponseTests.test_makeConnection.<locals>.SomeProtocolc                         | d S ri   r   )rO   r  	producersr>   r?   r   
     zFResponseTests.test_makeConnection.<locals>.SomeProtocol.makeConnectionNr:   r;   r<   r   r>   r7  r>   r?   SomeProtocol
      r;  r   r   N)r   r   rd   rr  r  rH   r   r  )rO   rc   r;  r  r   theProducerr>   r7  r?   test_makeConnection
  s   
z!ResponseTests.test_makeConnectionc                    sN   g  G  fdddt }| }tt }|| |d |  dg dS )z
        The L{IProtocol} provider passed to L{Response.deliverBody} has its
        C{dataReceived} method called with bytes received as part of the
        response body.
        c                       r5  )z5ResponseTests.test_dataReceived.<locals>.ListConsumerc                    r6  ri   r   rO   r   r   r>   r?   r   
  r9  zBResponseTests.test_dataReceived.<locals>.ListConsumer.dataReceivedNr:   r;   r<   r   r>   r@  r>   r?   ListConsumer
  r<  rB  r   N)r   rd   r   rr  r   rH   rO   rB  r  r   r>   r@  r?   test_dataReceived
  s   


zResponseTests.test_dataReceivedc                    sj   g  G  fdddt }| }tt }|| |   d t | t d | 	|j
d dS )z
        The L{IProtocol} provider passed to L{Response.deliverBody} has its
        C{connectionLost} method called with a L{Failure} wrapping
        L{ResponseDone} when the response's C{_bodyDataFinished} method is
        called.
        c                       r5  )z7ResponseTests.test_connectionLost.<locals>.ListConsumerc                    r6  ri   r   r  lostr>   r?   r  
  r9  zFResponseTests.test_connectionLost.<locals>.ListConsumer.connectionLostN)r:   r;   r<   r  r>   rE  r>   r?   rB  
  r<  rB  r   r_   N)r   rd   r   rr  r   rG   r.   rH   rI   r   _bodyProtocolrC  r>   rE  r?   test_connectionLost
  s   

z!ResponseTests.test_connectionLostc                    sr   g  G  fdddt }| }tt }|d |d || |d |  g d | |jd dS )z
        If data is delivered to the L{Response} before a protocol is registered
        with C{deliverBody}, that data is buffered until the protocol is
        registered and then is delivered.
        c                       r5  )z8ResponseTests.test_bufferEarlyData.<locals>.ListConsumerc                    r6  ri   r   r?  r@  r>   r?   r   
  r9  zEResponseTests.test_bufferEarlyData.<locals>.ListConsumer.dataReceivedNrA  r>   r@  r>   r?   rB  
  r<  rB  r   r   r   )r   r   r   N)r   rd   r   r   rr  rH   r   _bodyBuffer)rO   rB  r   r   r>   r@  r?   test_bufferEarlyData
  s   




z"ResponseTests.test_bufferEarlyDatac                 C   s,   t t }|t  | t|jt  dS )zb
        L{Response.deliverBody} raises L{RuntimeError} if called more than
        once.
        N)rd   r   rr  r   rw   rx   r3  r>   r>   r?    test_multipleStartProducingFails
  s   
z.ResponseTests.test_multipleStartProducingFailsc                 C   s4   t t }|t  |  | t|jt  dS )zw
        L{Response.deliverBody} raises L{RuntimeError} if called after
        L{Response._bodyDataFinished}.
        N)rd   r   rr  r   r   rw   rx   r3  r>   r>   r?   %test_startProducingAfterFinishedFails
  s   
z3ResponseTests.test_startProducingAfterFinishedFailsc                 C   s&   t t }|  | t|jd dS )z
        L{Response._bodyDataReceived} raises L{RuntimeError} if called after
        L{Response._bodyDataFinished} but before L{Response.deliverBody}.
        r   N)rd   r   r   rw   rx   r   r3  r>   r>   r?   'test_bodyDataReceivedAfterFinishedFails
  s   
z5ResponseTests.test_bodyDataReceivedAfterFinishedFailsc                 C   s2   t t }|  |t  | t|jd dS )z
        L{Response._bodyDataReceived} raises L{RuntimeError} if called after
        L{Response._bodyDataFinished} and after L{Response.deliverBody}.
        r   N)rd   r   r   rr  r   rw   rx   r   r3  r>   r>   r?   'test_bodyDataReceivedAfterDeliveryFails
  s   
z5ResponseTests.test_bodyDataReceivedAfterDeliveryFailsc                 C   s$   t t }|  | t|j dS )zh
        L{Response._bodyDataFinished} raises L{RuntimeError} if called more
        than once.
        N)rd   r   r   rw   rx   r3  r>   r>   r?   'test_bodyDataFinishedAfterFinishedFails  s   
z5ResponseTests.test_bodyDataFinishedAfterFinishedFailsc                 C   s0   t t }|  |t  | t|j dS )z{
        L{Response._bodyDataFinished} raises L{RuntimeError} if called after
        the body has been delivered.
        N)rd   r   r   rr  r   rw   rx   r3  r>   r>   r?   'test_bodyDataFinishedAfterDeliveryFails  s   
z5ResponseTests.test_bodyDataFinishedAfterDeliveryFailsc                    sl   g  G  fdddt }t }|  | }t|}| |jd || |  dg | |jd dS )z
        L{Response.deliverBody} resumes the HTTP connection's transport
        after passing it to the consumer's C{makeConnection} method.
        c                       r5  )z9ResponseTests.test_transportResumed.<locals>.ListConsumerc                    s     |j d S ri   )r~   r   r5  transportStater>   r?   r   #  r  zHResponseTests.test_transportResumed.<locals>.ListConsumer.makeConnectionNr:  r>   rQ  r>   r?   rB  "  r<  rB  r   r   N)r   r   r  rd   rH   r   rr  )rO   rB  rc   r   r   r>   rQ  r?   test_transportResumed  s   
z#ResponseTests.test_transportResumedc                 C   sX   t  }t|}|d |d |  t }|| | |jd |j	t
 dS )z
        If the entire body is delivered to the L{Response} before the
        response's C{deliverBody} method is called, the protocol passed to
        C{deliverBody} is immediately given the body data and then
        disconnected.
        r   r   rw  N)r   rd   r   r   r   rr  rH   r   r  rG   r.   rO   rc   r   r   r>   r>   r?   )test_bodyDataFinishedBeforeStartProducing/  s   


z7ResponseTests.test_bodyDataFinishedBeforeStartProducingc                 C   sL   t  }t|}t }|| | |jd |tt  |j	
t dS )a	  
        The L{Failure} passed to L{Response._bodyDataFinished} when the response
        is in the I{connected} state is passed to the C{connectionLost} method
        of the L{IProtocol} provider passed to the L{Response}'s
        C{deliverBody} method.
        	CONNECTEDN)r   rd   r   rr  rH   rs   r   r   r8   r  rG   rT  r>   r>   r?   #test_finishedWithErrorWhenConnectedA  s   
z1ResponseTests.test_finishedWithErrorWhenConnectedc                 C   sL   t  }t|}| |jd |tt  t }|| |j	
t dS )a  
        The L{Failure} passed to L{Response._bodyDataFinished} when the response
        is in the I{initial} state is passed to the C{connectionLost} method of
        the L{IProtocol} provider passed to the L{Response}'s C{deliverBody}
        method.
        INITIALN)r   rd   rH   rs   r   r   r8   r   rr  r  rG   rT  r>   r>   r?   !test_finishedWithErrorWhenInitialT  s   
z/ResponseTests.test_finishedWithErrorWhenInitialN)r:   r;   r<   r=   r4  r>  rD  rH  rJ  rK  rL  rM  rN  rO  rP  rS  rU  rW  rY  r>   r>   r>   r?   r2  }
  s"    	
	
	
r2  N)_r=   typingr   zope.interfacer   zope.interface.verifyr   twisted.internet.deferr   r   r   r   twisted.internet.errorr	   r
   twisted.internet.interfacesr   r   twisted.internet.protocolr   twisted.loggerr   twisted.protocols.basicr   twisted.python.failurer   twisted.test.proto_helpersr   r   r   r   twisted.trial.unittestr   twisted.web._newclientr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   twisted.web.clientr(   r)   r*   r+   r,   r-   r.   r/   r0   twisted.web.httpr1   twisted.web.http_headersr2   twisted.web.iwebr3   r4   twisted.web.test.requesthelperr5   r6   	Exceptionr8   rA   rb   rV   rY   r[   r]   rd   rf   r{   r   r   r   r4  r>  rA  r  r  r  r  r%  r2  r>   r>   r>   r?   <module>   sp   P,(


!     `      o#   we,~