U
    
W[Ϩ                    @   s  d Z ddlmZmZ eZddlmZ ddlm	Z	 ddl
mZ ddlmZmZ ddlmZmZ ddlmZmZmZ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#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-m.Z. ddl"m/Z/ ddl"m0Z0m1Z1 ddl"m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZDmEZE ddlFmGZG G dd deHZIG dd deHZJe@ddgiZKd d! ZLd"d# ZMd$d% ZNd&d' ZOd(d) ZPG d*d+ d+eZQG d,d- d-eRZSG d.d/ d/eSeZTG d0d1 d1eSeZUG d2d3 d3eZVG d4d5 d5ZWG d6d7 d7ZXG d8d9 d9eZYeeDG d:d; d;ZZG d<d= d=eZ[G d>d? d?eZ\G d@dA dAeZ]G dBdC dCeZ^G dDdE dEeZ_dFS )Gz&
Tests for L{twisted.web._newclient}.
    )divisionabsolute_import)implementer)verifyObject)Failure)	IConsumerIPushProducer)ConnectionDoneConnectionLost)DeferredsucceedfailCancelledError)Protocol)LineReceiver)TestCase)AccumulatingProtocolEventLoggingObserverStringTransport StringTransportWithDisconnection)UNKNOWN_LENGTHSTATUSHEADERBODYDONE)
HTTPParserHTTPClientParser)BadResponseVersion
ParseError)ChunkedEncoder)WrongBodyLengthRequestNotSent)ConnectionAborted)
BadHeadersExcessWrite)TransportProxyProducerLengthEnforcingConsumermakeStatefulDispatcher)	HTTP11ClientProtocolPotentialDataLossRequestRequestGenerationFailedRequestTransmissionFailedResponseResponseDoneResponseFailedResponseNeverReceived)Headers)	_DataLoss)IBodyProducer	IResponse)globalLogPublisherc                   @   s   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.pyr6   6   s   r6   c                   @   s   e Zd ZdZdS )AnotherArbitraryExceptionzI
    Similar to L{ArbitraryException} but with a different identity.
    Nr7   r<   r<   r<   r=   r>   =   s   r>      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                    sF   t | j D ]\}}|| qt| jt d| j f  | S )Nzlen(%s) != len(%s))zipreasonstrapassertEquallen)errreasontypereasonTypesselfr<   r=   cbFailed`   s    z-assertWrapperExceptionTypes.<locals>.cbFailed)assertFailureaddCallback)rK   deferredZmainTyperJ   rL   dr<   rI   r=   assertWrapperExceptionTypesH   s    
rQ   c                 C   s   t | |t|S )zo
    A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
    of L{ResponseFailed}.
    )rQ   r/   rK   rO   rJ   r<   r<   r=   assertResponseFailedl   s    rS   c                 C   s   t | |t|S )zx
    A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
    of L{RequestGenerationFailed}.
    )rQ   r+   rR   r<   r<   r=   assertRequestGenerationFailedu   s    rT   c                 C   s   t | |t|S )zz
    A simple helper to invoke L{assertWrapperExceptionTypes} with a C{mainType}
    of L{RequestTransmissionFailed}.
    )rQ   r,   rR   r<   r<   r=   assertRequestTransmissionFailed~   s    rU   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   rW         OK)r-   _boringHeaders)	transportr<   r<   r=   justTransportResponse   s    r\   c                   @   s   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   s   d S Nr<   rK   r<   r<   r=   bar   s    zGMakeStatefulDispatcherTests.test_functionCalledByState.<locals>.Foo.barZquuxc                 S   s   dS )Nar<   r`   r<   r<   r=   _quux_A   s    zKMakeStatefulDispatcherTests.test_functionCalledByState.<locals>.Foo._quux_Ac                 S   s   dS )Nbr<   r`   r<   r<   r=   _quux_B   s    zKMakeStatefulDispatcherTests.test_functionCalledByState.<locals>.Foo._quux_BN)r8   r9   r:   _statera   r'   rc   re   r<   r<   r<   r=   Foo   s
   
rg   rb   Brd   CN)rD   ra   rf   assertRaisesRuntimeError)rK   rg   Zstatefulr<   r<   r=   test_functionCalledByState   s    z6MakeStatefulDispatcherTests.test_functionCalledByStateN)r8   r9   r:   r;   rl   r<   r<   r<   r=   r]      s   r]   c                   @   sd   e Zd 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S )_HTTPParserTestszt
    Base test class for L{HTTPParser} which is responsible for the bulk of
    the task of parsing HTTP bytes.
    Nc                 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   rD   stater   dataReceivedsepr   )rK   statusprotocolr<   r<   r=   test_statusCallback   s    z$_HTTPParserTests.test_statusCallbackc                 C   s6   i }t  }|j|_|t  |d| j  ||fS )Nrn   )r   __setitem__headerReceivedrq   r   rs   rt   rK   headerrv   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|   rs   rt   rD   rr   r   rz   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   rz   r<   r<   r=   test_continuedHeaderCallback   s    z-_HTTPParserTests.test_continuedHeaderCallbackc                 C   s^   |   \}}| jddddg}|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|   rt   joinrs   rD   )rK   r{   rv   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 r_   )ro   rr   r   r<   Zcalledrv   r<   r=   allHeadersReceived  s    zD_HTTPParserTests.test_allHeadersCallback.<locals>.allHeadersReceivedN)r|   r   rs   rt   rD   r   rr   r   )rK   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   rz   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}.
        rn   r   
   X-Foo: bazr}   r~      bazN)	r   rq   r   rs   rt   rD   listheadersgetAllRawHeaders)rK   rv   expectedr<   r<   r=   test_headersSavedOnResponse  s    z,_HTTPParserTests.test_headersSavedOnResponsec                 C   sR   t  }ddddddddg}|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   
assertTrueZisConnectionControlHeaderassertFalse)rK   rv   ZconnHeaderNamesr{   r<   r<   r=   test_connectionControlHeaders$  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   rq   r   ZswitchToBodyModeobjectrj   rk   rK   rv   r<   r<   r=   test_switchToBodyMode:  s    z&_HTTPParserTests.test_switchToBodyMode)r8   r9   r:   r;   rt   rw   r|   r   r   r   r   r   r   r   r   r<   r<   r<   r=   rm      s   	rm   c                   @   s   e Zd ZdZdZdS )$HTTPParserRFCComplaintDelimeterTestsz<
    L{_HTTPParserTests} using standard CR LF newlines.
       
Nr8   r9   r:   r;   rt   r<   r<   r<   r=   r   F  s   r   c                   @   s   e Zd ZdZdZdS )'HTTPParserNonRFCComplaintDelimeterTestsz5
    L{_HTTPParserTests} using bare LF newlines.
       
Nr   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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: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   rD   parseVersionr   r<   r<   r=   test_parseVersion[  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 r_   )rj   rD   datasexcefrK   r<   r=   checkParsingo  s    z@HTTPClientParserTests.test_parseBadVersion.<locals>.checkParsing   foos   foo/bar/bazs   foo/s   foo/..s   foo/a.bs	   foo/-1.-1)r   r   r   )rK   rv   r   r<   r   r=   test_parseBadVersionf  s    
z*HTTPClientParserTests.test_parseBadVersionc                 C   sb   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
rV   rX   rY   r*   rZ   r   rq   r   rs   rD   responseversioncodephraserK   requestrv   r<   r<   r=   test_responseStatusParsing}  s    

z0HTTPClientParserTests.test_responseStatusParsingc                 C   sb   t ddtd}t|d}|t  |d | |jjd | |jj	d | |jj
d dS )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
rV   rX   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 r_   )rj   r   rp   rD   r   r   rv   rK   r<   r=   r     s    zBHTTPClientParserTests.test_badResponseStatus.<locals>.checkParsingr   s   HTTP/1.1 bar OK)r   )rK   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                      s
     dS NTro   r<   ZbodyDataFinishedr<   r=   <lambda>  r   z3HTTPClientParserTests._noBodyTest.<locals>.<lambda>	producingr   Tr   )r   ro   rx   ry   r   rq   rs   r   _bodyDataReceived_bodyDataFinishedrD   producerStaterr   r   length)	rK   r   ru   r   r{   finishedbodyrv   r[   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*   rZ   r   rD   )rK   r   ru   r   r{   r<   r<   r=   test_headResponse  s    z'HTTPClientParserTests.test_headResponsec                 C   s(   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*   rZ   r   rK   r   ru   r   r<   r<   r=   test_noContentResponse  s    z,HTTPClientParserTests.test_noContentResponsec                 C   s(   t ddtd}d}d}| ||| dS )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  s    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   s   d S r_   r<   restr<   r<   r=   r      r   z<HTTPClientParserTests.test_responseHeaders.<locals>.<lambda>r   s   X-Foo: bar
r      x-foor~   )r   r*   rZ   rq   r   rs   rD   connHeadersr1   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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   s   d S r_   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*   rZ   rq   r   rs   rD   r   r   r1   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   s   d S r_   r<   r   r<   r<   r=   r   ,  r   zRHTTPClientParserTests.test_headResponseContentLengthEntityHeader.<locals>.<lambda>r   r   r   r   r   r   r   r   r<   r<   r=   *test_headResponseContentLengthEntityHeader%  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*   rZ   ro   r   rq   rs   r   r   rD   r   rr   r   r   rK   r   rv   r[   r   r<   r<   r=   test_contentLength:  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*   rZ   ro   rq   r   rs   r   r   rD   rr   r   r   rK   r   rv   r   r<   r<   r=   test_zeroContentLengthZ  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*   rZ   rq   r   rj   
ValueErrorrs   r   r<   r<   r=   !test_multipleContentLengthHeaderst  s    z7HTTPClientParserTests.test_multipleContentLengthHeadersc                 C   sd   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*   rZ   ro   rq   r   rs   rD   rr   r   rK   r   rv   r<   r<   r=   test_extraBytesPassedBack  s    


z/HTTPClientParserTests.test_extraBytesPassedBackc                 C   sd   g }t tddtd|j}|t  |d |d |d | |jt	 | |dg dS )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  s    


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*   rZ   ro   rq   r   rs   r   r   rD   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*   rZ   ro   r   rq   rs   r   r   rD   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*   rZ   ro   r   rq   rs   r   r   rD   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*   rZ   rq   _responseDeferredr   r   r6   rS   )rK   r[   rv   Z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   s
   t  d S r_   r6   )rF   r<   r<   r=   fakeBodyDataFinished1  s    zPHTTPClientParserTests.test_connectionLostWithError.<locals>.fakeBodyDataFinishedrW   log_failure)N)r   createWithCleanupr5   r   r   r*   rZ   rq   r   rN   ro   rs   r   r   assertEqualsrE   assertIsInstancer   r6   flushLoggedErrors)rK   logObserverr[   rv   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   s   d S r_   r<   Zignr<   r<   r=   r   D  r   z<HTTPClientParserTests.test_noResponseAtAll.<locals>.<lambda>)
r   r*   rZ   r   rq   r   r   r
   rM   r0   rK   rv   rP   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   s   d S r_   r<   r   r<   r<   r=   r   T  r   zBHTTPClientParserTests.test_someResponseButNotAll.<locals>.<lambda>   2)r   r*   rZ   r   rq   r   rs   r   r
   rM   r/   rN   r   r   r<   r<   r=   test_someResponseButNotAllL  s    
 z0HTTPClientParserTests.test_someResponseButNotAllc                 C   s   d}t tddtddd }|t  || | t|dddk | |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   s   d S r_   r<   r   r<   r<   r=   r   m  r   zCHTTPClientParserTests.test_1XXResponseIsSwallowed.<locals>.<lambda>r   r   )r   r*   rZ   rq   r   rs   r   getattrrD   rr   r   rE   r   r   r   r   Z_everReceivedData)rK   sample103Responserv   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   s   d S r_   r<   r   r<   r<   r=   r     r   zUHTTPClientParserTests.test_1XXFollowedByFinalResponseOnlyEmitsFinal.<locals>.<lambda>rX   r   r   r   r   r*   rZ   rq   r   rs   rD   r   r   r   r1   r   r   rK   r  Zfollowing200Responserv   r<   r<   r=   -test_1XXFollowedByFinalResponseOnlyEmitsFinalz  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   s   d S r_   r<   r   r<   r<   r=   r     r   zKHTTPClientParserTests.test_multiple1XXResponsesAreIgnored.<locals>.<lambda>rX   r   r   r   r  r  r<   r<   r=   #test_multiple1XXResponsesAreIgnored  s8    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   s   d S r_   r<   r   r<   r<   r=   r     r   zHHTTPClientParserTests.test_ignored1XXResponseCausesLog.<locals>.<lambda>rW   r   
log_formatz#Ignoring unexpected {code} responser   g   )r   r   r5   r   r*   rZ   rq   r   rs   r   rE   )rK   r   r  rv   r   r<   r<   r=    test_ignored1XXResponseCausesLog  s&    
z6HTTPClientParserTests.test_ignored1XXResponseCausesLogN) r8   r9   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<   r<   r<   r=   r   V  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 r_   )r   r   rK   r[   r<   r<   r=   writeTo  s    zSlowRequest.writeToc                 C   s
   d| _ d S r   stoppedr`   r<   r<   r=   stopWriting  s    zSlowRequest.stopWritingN)	r8   r9   r:   r;   methodr  
persistentr  r  r<   r<   r<   r=   r    s   
r  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   r  r<   r<   r=   r    s    
zSimpleRequest.writeToN)r8   r9   r:   r;   r  r  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   r[   r(   rv   rq   r`   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)rv   r   r  rD   r[   r   r`   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                    s      j d d S Nr   rD   r[   r   Zignoredr`   r<   r=   	cbNotSent,  s    z?HTTP11ClientProtocolTests.test_secondRequest.<locals>.cbNotSent)rv   r   r  rM   r  r!   rN   rK   r  rP   r<   r`   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                    s      j d d S r  r  r  r`   r<   r=   r  <  s    zLHTTP11ClientProtocolTests.test_requestAfterConnectionLost.<locals>.cbNotSent)	rv   r   r   r	   rM   r   r  r!   rN   r  r<   r`   r=   test_requestAfterConnectionLost4  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                   @   s   e Zd ZdZdd ZdS )zCHTTP11ClientProtocolTests.test_failedWriteTo.<locals>.BrokenRequestFc                 S   s
   t t S r_   )r   r6   r  r<   r<   r=   r  M  s    zKHTTP11ClientProtocolTests.test_failedWriteTo.<locals>.BrokenRequest.writeToNr8   r9   r:   r  r  r<   r<   r<   r=   BrokenRequestK  s   r"  c                    s&      jj  jttd d S )Nzyou asked for it)r   r[   disconnectingrv   r   r   r	   r  r`   r<   r=   rL   Q  s    
z>HTTP11ClientProtocolTests.test_failedWriteTo.<locals>.cbFailed)rv   r   rT   r6   rN   )rK   r"  rP   rL   r<   r`   r=   test_failedWriteToD  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                   @   s   e Zd ZdZdd ZdS )zMHTTP11ClientProtocolTests.test_synchronousWriteToError.<locals>.BrokenRequestFc                 S   s
   t  d S r_   r   r  r<   r<   r=   r  d  s    zUHTTP11ClientProtocolTests.test_synchronousWriteToError.<locals>.BrokenRequest.writeToNr!  r<   r<   r<   r=   r"  b  s   r"  )rv   r   rT   r6   )rK   r"  rP   r<   r<   r=   test_synchronousWriteToError\  s    z6HTTP11ClientProtocolTests.test_synchronousWriteToErrorNc                 C   s   t  }| j|}t| |tg}| |j | jtt  | 	|j |dkr`|j
d n6|dkr|j
tt  | t}| t|d n |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errbackrW   )r  rv   r   rU   r6   r   r  r   r   r   r   r&  r'  r>   r   rD   rE   )rK   moder   rP   errorsr<   r<   r=   *test_connectionLostDuringRequestGenerationk  s    
zDHTTP11ClientProtocolTests.test_connectionLostDuringRequestGenerationc                 C   s
   |  dS )z
        If the request passed to L{HTTP11ClientProtocol} finishes generation
        successfully after the L{HTTP11ClientProtocol}'s connection has been
        lost, nothing happens.
        r&  r*  r`   r<   r<   r=   +test_connectionLostBeforeGenerationFinished  s    zEHTTP11ClientProtocolTests.test_connectionLostBeforeGenerationFinishedc                 C   s
   |  dS )z
        If the request passed to L{HTTP11ClientProtocol} finished generation
        with an error after the L{HTTP11ClientProtocol}'s connection has been
        lost, nothing happens.
        r'  r+  r`   r<   r<   r=   )test_connectionLostBeforeGenerationFailed  s    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 )NrW   r   r   r	  zJError writing request, but not in valid state to finalize request: {state}rr   CONNECTION_LOST)r   rE   assertInrD   )ignorer   r   rK   r<   r=   check  s    
znHTTP11ClientProtocolTests.test_errorMessageOnConnectionLostBeforeGenerationFailedDoesNotConfuse.<locals>.checkr'  )r   r   r5   r*  rN   )rK   r2  r<   r1  r=   Etest_errorMessageOnConnectionLostBeforeGenerationFailedDoesNotConfuse  s    	z_HTTP11ClientProtocolTests.test_errorMessageOnConnectionLostBeforeGenerationFailedDoesNotConfusec                    s<    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 )NrX   	QUIESCENT)	rD   r   r   r1   r   r[   r#  rv   rr   r   r`   r<   r=   	cbRequest  s    zIHTTP11ClientProtocolTests.test_receiveSimplestResponse.<locals>.cbRequests9   HTTP/1.1 200 OK
Content-Length: 0
Connection: close

rv   r   r*   rZ   rN   rs   rK   rP   r6  r<   r`   r=   test_receiveSimplestResponse  s    
z6HTTP11ClientProtocolTests.test_receiveSimplestResponsec                    s<    j tddtd} fdd}||  j d |S )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   )r1   rD   r   )r   r   r`   r<   r=   r6    s    zHHTTP11ClientProtocolTests.test_receiveResponseHeaders.<locals>.cbRequests+   HTTP/1.1 200 OK
X-Foo: bar
X-Foo: baz

r7  r8  r<   r`   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 )NZ%TRANSMITTING_AFTER_RECEIVING_RESPONSEc                    s
    j fS r_   r   r   pr   r<   r=   r     r   zoHTTP11ClientProtocolTests.test_receiveResponseBeforeRequestGenerationDone.<locals>.cbResponse.<locals>.<lambda>)	r   r   closedDeferreddeliverBodyrD   rr   r   r#  rN   r   whenFinished)rv   quiescentResultrK   r[   r<  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 )NrV   rX   rY   r   r~      foobar)rD   r   r   r   r   r1   r   r&  )resultr   r   r   rK   r<   r=   cbAllResponse   s    z`HTTP11ClientProtocolTests.test_receiveResponseBeforeRequestGenerationDone.<locals>.cbAllResponse)r   r(   ro   rq   r  r   rs   rN   rK   rP   rC  rG  r<   )rv   rB  r   rK   r[   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(   rv   rq   r   Z
MAX_LENGTHr   r*   rZ   rs   rS   r	   )rK   r[   rv   ZlongLinerP   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                    s
    j fS r_   r;  r   r<  r<   r=   r   =  r   zHTTP11ClientProtocolTests.test_connectionLostAfterReceivingResponseBeforeRequestGenerationDone.<locals>.cbResponse.<locals>.<lambda>)r   r   r>  r?  rN   r@  r<   r<  r=   rC  8  s    
zrHTTP11ClientProtocolTests.test_connectionLostAfterReceivingResponseBeforeRequestGenerationDone.<locals>.cbResponsec                    s2    j d  jtt  jjd d S )Nr.  )r   r&  rv   r   r   r6   rD   rf   )r0  rF  r<   r=   rG  ?  s    zuHTTP11ClientProtocolTests.test_connectionLostAfterReceivingResponseBeforeRequestGenerationDone.<locals>.cbAllResponse)r  rv   r   rs   rN   rH  r<   rF  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 )NrD  )rD   r   closedReasonrC   r.   r  r   r<   r=   rG  i  s    zIHTTP11ClientProtocolTests.test_receiveResponseBody.<locals>.cbAllResponse)r   r   r>  rv   r   r*   rZ   rs   rN   ro   rD   r?  )rK   rA  requestDeferredrE  r   rG  r<   r   r=   test_receiveResponseBodyH  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~   rD  z low-level transport disconnected)rv   r   r*   rZ   rs   rN   ro   r   r?  rD   r   r   r   r	   rL  rC   r)   rK   rM  rE  r   rv   r<   r<   r=   Etest_responseBodyFinishedWhenConnectionLostWhenContentLengthIsUnknownp  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
rD  )rv   r   r*   rZ   rs   rN   ro   r   r?  rD   r   r   r   r6   rS   r   rL  r2   rO  r<   r<   r=   4test_chunkedResponseBodyUnfinishedWhenConnectionLost  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   r[   r#  rD   rB   r   r   rv   r   r   r	   r   r`   r<   r=   rL     s     zLHTTP11ClientProtocolTests.test_parserDataReceivedException.<locals>.cbFailed)rv   r   r*   rZ   rs   rS   r   rN   )rK   rM  rP   rL   r<   r`   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)rv   r   r*   rZ   _parserr[   r   	_producerZ_disconnectParserr   r	   rS   )rK   rM  r[   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(   rq   abortrN   ro   rD   r   r#  r   r   r	   )rK   r[   rv   Zr1Z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(   rq   r   r   r	   rX  rN   ro   rD   rf   rK   r[   rv   rE  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(   rq   r   r*   rZ   rX  r   r#  r   r   r	   rS   r"   rZ  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)Z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)rX  r`   )rv   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)r'  rK   rG   )
testResultr<   r=   r   3  s    z`HTTP11ClientProtocolTests.test_abortAfterResponseHeaders.<locals>.BodyDestination.connectionLostN)r8   r9   r:   r;   r]  r   r<   )rv   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)r?  r   r#  r   r   r	   r5  )r`  rv   rK   r[   r<   r=   r?  ;  s    zMHTTP11ClientProtocolTests.test_abortAfterResponseHeaders.<locals>.deliverBodyc                    s     | jt d S r_   )r   r   r-   )errorr`   r<   r=   
checkErrorF  s    zLHTTP11ClientProtocolTests.test_abortAfterResponseHeaders.<locals>.checkError)r   r(   rq   r   r*   rZ   rs   r   r   rN   rS   r"   r2   )rK   rE  r?  rb  rO   r<   )r`  rv   rK   r_  r[   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                    s(    |    | jd |  d S Nr4  rD   rr   ro   r=  rv   rB  rK   r<   r=   r&  ]  s    zHHTTP11ClientProtocolTests.test_quiescentCallbackCalled.<locals>.callbackr   r   NTr  s&   HTTP/1.1 200 OK
Content-length: 3

r   c                    s
     dS )Nresponse doner   r   )rB  r<   r=   r   y  r   zHHTTP11ClientProtocolTests.test_quiescentCallbackCalled.<locals>.<lambda>r   ri  )r   r(   rq   r   r*   rZ   rs   rD   rN   ro   r   r   r>  r?  rL  rC   r.   rU  Z_finishedRequestZ_currentRequestZ_transportProxyr   )rK   r&  r[   rM  rE  r   bodyProtocolr<   rg  r=   test_quiescentCallbackCalledP  s:    



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                    s(    |    | jd |  d S rd  re  rf  rg  r<   r=   r&    s    z]HTTP11ClientProtocolTests.test_transportProducingWhenQuiescentAfterFullBody.<locals>.callbackr   r   NTrh  s)   HTTP/1.1 200 OK
Content-length: 3

BBBZDEFERRED_CLOSErW   r   )r   r(   rq   r   r*   rZ   rs   ZsuccessResultOfrD   rf   rE   r   )rK   r&  r[   rM  r   r<   rg  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                    s(    |    | jd |  d S rd  re  rf  rg  r<   r=   r&    s    zUHTTP11ClientProtocolTests.test_quiescentCallbackCalledEmptyResponse.<locals>.callbackr   r   NTrh  &   HTTP/1.1 200 OK
Content-length: 0

r   r   rW   )r   r(   rq   r   r*   rZ   rN   ro   rs   rD   rE   r   r   r-   )rK   r&  r[   rM  r<   rg  r=   )test_quiescentCallbackCalledEmptyResponse  s    
zCHTTP11ClientProtocolTests.test_quiescentCallbackCalledEmptyResponsec              	   C   s   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   NTrh  s9   HTTP/1.1 200 OK
Content-length: 0
Connection: close

r   r   r(   ro   rq   r   r*   rZ   rs   rN   r   r?  rL  rC   r.   rD   r   r#  rK   rB  r[   rv   rM  rE  r   rj  r<   r<   r=   test_quiescentCallbackNotCalled  s$    


z9HTTP11ClientProtocolTests.test_quiescentCallbackNotCalledc              	   C   s   g }t  }t|j}|| |tddtddd}|d g }||j |d }t	 }|
| |jt | |g  | |j dS )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   NFrh  rm  r   ro  rp  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   s
   t  d S r_   )ZeroDivisionErrorrf  r<   r<   r=   r&    s    zHHTTP11ClientProtocolTests.test_quiescentCallbackThrows.<locals>.callbackr   r   NTrh  rm  r   rW   r   )r   r   r5   r   r(   rq   r   r*   rZ   rs   rN   ro   r   r?  rL  rC   r.   r   rE   r   r   rs  r   r   r#  )rK   r&  r   r[   rv   rM  rE  r   rj  r   r   r<   r<   r=   test_quiescentCallbackThrows  s4    


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(   rq   r   r*   rZ   cancelr   disconnectedrQ   r0   r   rZ  r<   r<   r=   test_cancelBeforeResponse5  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(   rq   r   r*   rZ   rs   ru  r   rv  rS   r   rZ  r<   r<   r=   test_cancelDuringResponseF  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 )NTry  r<   r   )nonLocalr<   r=   ru  d  s    zJHTTP11ClientProtocolTests.assertCancelDuringBodyProduction.<locals>.cancelc                    s   | _ t _jS r_   consumerr   r   )r|  )ru  producerr<   r=   startProducingf  s    
zRHTTP11ClientProtocolTests.assertCancelDuringBodyProduction.<locals>.startProducing   POST   /bars   xxxxx)r   r(   rq   StringProducerr~  r   r*   rZ   r|  r  ru  r   rv  rT   r   )rK   ZproducerLengthr[   rv   r~  rE  r<   )ru  rz  r}  r=    assertCancelDuringBodyProductionW  s     
z:HTTP11ClientProtocolTests.assertCancelDuringBodyProductionc                 C   s
   |  d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 an explicit length has finished producing.
        
   )r  r`   r<   r<   r=   test_cancelDuringBodyProductionu  s    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   r`   r<   r<   r=   &test_cancelDuringChunkedBodyProduction  s    z@HTTP11ClientProtocolTests.test_cancelDuringChunkedBodyProduction)N)'r8   r9   r:   r;   r  r  r  r   r$  r%  r*  r,  r-  r3  r9  r:  rI  rJ  rK  rN  rP  rR  rT  rW  rY  r[  r\  rc  rk  rl  rn  rq  rr  rt  rw  rx  r  r  r  r<   r<   r<   r=   r    sH   		
!		1( @:-(
r  c                   @   s,   e Zd ZdZ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 r_   )r   )rK   r   r<   r<   r=   __init__  s    zStringProducer.__init__c                 C   s   || _ t | _| jS r_   r{  )rK   r|  r<   r<   r=   r~    s    zStringProducer.startProducingc                 C   s
   d| _ d S r   r  r`   r<   r<   r=   stopProducing  s    zStringProducer.stopProducingN)r8   r9   r:   r;   r  r  r~  r  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 d! Zd"d# Zd$d% Zd3d'd(Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd&S )4RequestTestsz
    Tests for L{Request}.
    c                 C   s   t  | _d S r_   )r   r[   r`   r<   r<   r=   r    s    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*   rZ   r  r[   rD   r   r`   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   NTrh  s%   GET / HTTP/1.1
Host: example.com

r  )rK   Z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= |  | |ddddg dS )zf
        L{Request.writeTo} formats header data and writes it to the given
        transport.
        r~   r   r@   )r   r?   r      /fooNr   r   s   GET /foo HTTP/1.1r   s   Connection: closes   Host: example.comr   r   )r1   r*   r  r[   r   splitrD   sort)rK   r   linesr<   r<   r=   test_sendRequestHeaders  s"    z$RequestTests.test_sendRequestHeadersc                 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*   rZ   r  r[   assertNotIdenticalr|  r   r}  r   	streamingrD   r   clearr  r   r&  rK   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 r  )rD   r[   r   r   r}  r  r`   r<   r=   rL     s    zCRequestTests.test_sendChunkedRequestBodyWithError.<locals>.cbFailed)r  r   r*   rZ   r  r[   r  r   r'  r6   rM   rN   )rK   r}  r   writeDeferredrL   rP   r<   r`   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*   rZ   r  r[   r  r|  r   r}  r   r  rD   r   r  r  r   r&  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  )rK   r  r   r<   r<   r=   _sendRequestEmptyBodyWithLength9  s    	z,RequestTests._sendRequestEmptyBodyWithLengthc                 C   s   |  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  r`   r<   r<   r=   test_sendPUTRequestEmptyBodyN  s    z)RequestTests.test_sendPUTRequestEmptyBodyc                 C   s   |  d dS )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  r`   r<   r<   r=   test_sendPOSTRequestEmptyBodyW  s    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*   rZ   r  r[   r|  r  r   r&  r   r}  rM   r    rK   r}  r   r  r<   r<   r=   #test_sendRequestBodyWithTooFewBytes`  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   )rD   r[   r   r  rj   r$   r|  r  rS  finisherr}  rK   r<   r=   rL     s    
zCRequestTests._sendRequestBodyWithTooManyBytesTest.<locals>.cbFailed)r  r*   rZ   r  r[   r|  r  r   r  r   r   r}  rM   r    rN   )rK   r  r   r  rL   rP   r<   r  r=   $_sendRequestBodyWithTooManyBytesTestp  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   s   | j d  d S r_   r   r&  r}  r<   r<   r=   r    s    zCRequestTests.test_sendRequestBodyWithTooManyBytes.<locals>.finisher)r  rK   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   rW   )	r   r'  r6   r/  r   r   r   rD   rE   )r}  r   r   r)  r1  r<   r=   r    s    
zHRequestTests.test_sendRequestBodyErrorWithTooManyBytes.<locals>.finisher)r   r   r5   r  r  r<   r1  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   rW   )r   r   r5   r  r*   rZ   r  r[   r|  Z	_finishedr  r   r&  r'  r6   r/  r   r   rD   rE   r   )rK   r   r}  r   Z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*   rZ   r  r[   r|  r  r   r}  r  rj   r$   rD   r   )rK   r  r}  r   r  r<   r<   r=   -_sendRequestBodyFinishedEarlyThenTooManyBytes  s    
z:RequestTests._sendRequestBodyFinishedEarlyThenTooManyBytesc                 C   s   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   s   | j d  d S r_   r  r  r<   r<   r=   r  	  s    zPRequestTests.test_sendRequestBodyFinishedEarlyThenTooManyBytes.<locals>.finisher)rM   r  r    r  r<   r<   r=   1test_sendRequestBodyFinishedEarlyThenTooManyBytes	  s
    z>RequestTests.test_sendRequestBodyFinishedEarlyThenTooManyBytesc                 C   s   dd }|  | |tS )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 r_   )r   r'  r6   r  r<   r<   r=   r  	  s    zORequestTests.test_sendRequestBodyErroredEarlyThenTooManyBytes.<locals>.finisher)rM   r  r6   r  r<   r<   r=   0test_sendRequestBodyErroredEarlyThenTooManyBytes	  s
    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*   rZ   r  r[   r   r&  r  rj   r$   r|  r  rD   r   )rK   Z_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   r6   rM   )rK   rP   r<   r<   r=   9test_sendChunkedRequestBodyFinishedWithErrorThenWriteMore5	  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*   rZ   r  r[   r   r}  r   r  r|  r  rD   r   r   r#  r   r'  r   r6   rM   r  r<   r<   r=   test_sendRequestBodyWithErrorA	  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   Hostr@   s   example.org)r*   r1   rj   r#   r  r[   rD   r   )rK   r   r<   r<   r=   test_hostHeaderRequiredh	  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*   rZ   r  r[   r   r  r  r   r  r<   r<   r=   test_stopWritingw	  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d S NzstopProducing is bustedr   r<   r<   r<   r=   brokenStopProducing	  s    zBRequestTests.test_brokenStopProducing.<locals>.brokenStopProducingr   r   rW   r   r   N)r   r   r5   r  r  r*   rZ   r  r[   r  rD   rE   r   r6   r   r/  r   r   )rK   r   r}  r  r   r   r   r<   r<   r=   test_brokenStopProducing	  s&     z%RequestTests.test_brokenStopProducing)N)r8   r9   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    s2   %		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   rE  r  r}  r   r[   r&   enforcerr`   r<   r<   r=   r  	  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  rD   r[   r   r  r`   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  rj   r    _noMoreWritesExpectedr`   r<   r<   r=   test_finishedEarly	  s    z/LengthEnforcingConsumerTests.test_finishedEarlyFc                 C   sP   | j d | | jj | j d | | jj |rB| 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}  r  r   r  rM   rE  r    )rK   Z_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}  r  rj   r$   r   r`   r<   r<   r=   test_writeAfterNoMoreExpected	  s
    
z:LengthEnforcingConsumerTests.test_writeAfterNoMoreExpectedc                 C   s
   |  dS )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  r`   r<   r<   r=   test_finishedLate	  s    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  r`   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d S r  )r  r  r}  r6   r<   r`   r<   r=   r  	  s    zRLengthEnforcingConsumerTests.test_stopProducingRaises.<locals>.brokenStopProducingc                    s     t td d S )NrW   )rD   rE   r   r6   r  r`   r<   r=   
cbFinished	  s     zILengthEnforcingConsumerTests.test_stopProducingRaises.<locals>.cbFinished)r}  r  r  rN   )rK   r  r  rP   r<   r`   r=   test_stopProducingRaises	  s    
z5LengthEnforcingConsumerTests.test_stopProducingRaisesN)F)r8   r9   r:   r;   r  r  r  r  r  r  r  r  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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   r`   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   rQ  s   xxxxxxxxxxxxxxxxs   10
xxxxxxxxxxxxxxxx
N)r   r   r  rD   r   r  )rK   r[   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   ZregisterProducerr   r}  r   r  ZunregisterProducerrD   r   )rK   r[   r}  r  r<   r<   r=   test_producerRegistration$
  s    z2RequestBodyConsumerTests.test_producerRegistrationN)r8   r9   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%   r`   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   rV  stopProxyingrK   r[   proxyr<   r<   r=   %test_stopProxyingUnreferencesProducerD
  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   pauseProducingr%   rD   r   resumeProducingr  r  r<   r<   r=   test_resumeProducingP
  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%   rD   r   r  r  r  r  r<   r<   r=   test_pauseProducingg
  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   r  N)r   r%   rD   r   r  r  r  r<   r<   r=   test_stopProducing}
  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   rq   rv   r%   r   	connectedrD   r   loseConnectionr   rK   r[   rv   r  r<   r<   r=    test_loseConnectionWhileProxying
  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   rq   rv   r%   r  r   r  r  r  r<   r<   r=   test_loseConnectionNotProxying
  s    
z:TransportProxyProducerTests.test_loseConnectionNotProxyingN)r8   r9   r:   r;   r  r  r  r  r  r  r  r<   r<   r<   r=   r  7
  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)r\   r   r   r   r4   rK   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                       s   e Zd Z fddZdS )z7ResponseTests.test_makeConnection.<locals>.SomeProtocolc                    s     | d S r_   r   )rK   r}  Z	producersr<   r=   rq   
  s    zFResponseTests.test_makeConnection.<locals>.SomeProtocol.makeConnectionNr8   r9   r:   rq   r<   r  r<   r=   SomeProtocol
  s   r  r   r   N)r   r   r\   r?  r  rD   r   r  )rK   r[   r  r|  r   ZtheProducerr<   r  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                       s   e Zd Z fddZdS )z5ResponseTests.test_dataReceived.<locals>.ListConsumerc                    s     | d S r_   r   rK   r   bytesr<   r=   rs   
  s    zBResponseTests.test_dataReceived.<locals>.ListConsumer.dataReceivedNr8   r9   r:   rs   r<   r  r<   r=   ListConsumer
  s   r  r   N)r   r\   r   r?  r   rD   rK   r  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                       s   e Zd Z fddZdS )z7ResponseTests.test_connectionLost.<locals>.ListConsumerc                    s     | d S r_   r   r^  Zlostr<   r=   r   
  s    zFResponseTests.test_connectionLost.<locals>.ListConsumer.connectionLostN)r8   r9   r:   r   r<   r  r<   r=   r  
  s   r  r   rW   N)r   r\   r   r?  r   rC   r.   rD   rE   r   Z_bodyProtocolr  r<   r  r=   test_connectionLost
  s    

z!ResponseTests.test_connectionLostc                    st   g  G  fdddt }| }tt }|d |d || |d |  dddg | |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                       s   e Zd Z fddZdS )z8ResponseTests.test_bufferEarlyData.<locals>.ListConsumerc                    s     | d S r_   r   r  r  r<   r=   rs     s    zEResponseTests.test_bufferEarlyData.<locals>.ListConsumer.dataReceivedNr  r<   r  r<   r=   r    s   r  r   r~   r   N)r   r\   r   r   r?  rD   r   Z_bodyBuffer)rK   r  rv   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)r\   r   r?  r   rj   rk   r  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)r\   r   r?  r   r   rj   rk   r  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)r\   r   r   rj   rk   r   r  r<   r<   r=   'test_bodyDataReceivedAfterFinishedFails7  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)r\   r   r   r?  r   rj   rk   r   r  r<   r<   r=   'test_bodyDataReceivedAfterDeliveryFailsA  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)r\   r   r   rj   rk   r  r<   r<   r=   'test_bodyDataFinishedAfterFinishedFailsL  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)r\   r   r   r?  r   rj   rk   r  r<   r<   r=   'test_bodyDataFinishedAfterDeliveryFailsV  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                       s   e Zd Z fddZdS )z9ResponseTests.test_transportResumed.<locals>.ListConsumerc                    s     |j d S r_   )ro   r   r  ZtransportStater<   r=   rq   h  s    zHResponseTests.test_transportResumed.<locals>.ListConsumer.makeConnectionNr  r<   r  r<   r=   r  g  s   r  r   r   N)r   r   r  r\   rD   r   r?  )rK   r  r[   rv   r   r<   r  r=   test_transportResumeda  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~   rD  N)r   r\   r   r   r   r?  rD   r   rL  rC   r.   rK   r[   r   rv   r<   r<   r=   )test_bodyDataFinishedBeforeStartProducingu  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.
        Z	CONNECTEDN)r   r\   r   r?  rD   rf   r   r   r6   rL  rC   r  r<   r<   r=   #test_finishedWithErrorWhenConnected  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.
        ZINITIALN)r   r\   rD   rf   r   r   r6   r   r?  rL  rC   r  r<   r<   r=   !test_finishedWithErrorWhenInitial  s    
z/ResponseTests.test_finishedWithErrorWhenInitialN)r8   r9   r:   r;   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r<   r<   r<   r=   r  
  s    


r  N)`r;   Z
__future__r   r   rH   Z__metaclass__Zzope.interfacer   Zzope.interface.verifyr   Ztwisted.python.failurer   Ztwisted.internet.interfacesr   r   Ztwisted.internet.errorr	   r
   Ztwisted.internet.deferr   r   r   r   Ztwisted.internet.protocolr   Ztwisted.protocols.basicr   Ztwisted.trial.unittestr   Ztwisted.test.proto_helpersr   r   r   r   Ztwisted.web._newclientr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   Ztwisted.web.clientr(   r)   r*   r+   r,   r-   r.   r/   r0   Ztwisted.web.http_headersr1   Ztwisted.web.httpr2   Ztwisted.web.iwebr3   r4   Ztwisted.loggerr5   	Exceptionr6   r>   rZ   rQ   rS   rT   rU   r\   r]   r   rm   r   r   r   r  r  r  r  r  r  r  r  r  r<   r<   r<   r=   <module>   s   ,$			                yi/ 