U
    s@g                     @   s  d Z ddlmZmZ ddlZddlZddlmZ zddlmZm	Z	 W n$ e
k
rh   ddlmZm	Z	 Y nX ddlmZ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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* zddlm+Z+ W n   dZ+Y nX ddl,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6 e$e-j78dZ9e9: j;Z<G dd dej=Z>G dd dej=Z?G dd dej=Z@G dd dej=ZAG dd dej=ZBG dd  d ej=ZCG d!d" d"ej=ZDG d#d$ d$ej=ZEG d%d& d&ej=ZFG d'd( d(ej=ZGG d)d* d*ej=ZHG d+d, d,eZIG d-d. d.ej=ZJG d/d0 d0ejKZLG d1d2 d2ejKZMG d3d4 d4ejKZNG d5d6 d6eNZOG d7d8 d8ejKZPG d9d: d:ejKZQG d;d< d<ejKZRe+dkseSe+d=seOePfD ]ZTd>eT_Uqe Veds6eOePfD ]ZTd?eT_Uq(G d@dA dAZWG dBdC dCeWejKZXG dDdE dEeWejKZYG dFdG dGeWejKZZG dHdI dIejKZ[G dJdK dKe5ej\Z]G dLdM dMe6ej\Z^G dNdO dOe5ej\Z_G dPdQ dQe6ej\Z`dRdS ZaG dTdU dUe5ej\ZbG dVdW dWe6ej\ZcG dXdY dYebZdG dZd[ d[ecZeG d\d] d]e5ej\ZfG d^d_ d_e6ej\ZgG d`da dae6ej\ZhG dbdc dce5ej\ZiG ddde dee6ej\ZjG dfdg dge6ej\ZkdS )hzG
Tests for the old L{twisted.web.client} APIs, C{getPage} and friends.
    )divisionabsolute_importN)ENOSPC)urlparseurljoin)networkStringnativeString
intToBytes)unittestutil)serverclienterrorresource)Data)Redirect)addressreactordefer
interfaces)ClientFactory)FilePath)WrappingFactory)StringTransportwaitUntilAllDisconnectedEventLoggingObserver)ssl)test)globalLogPublisherFilteringLogObserverLogLevelFilterPredicateLogLevelLogger)MethodInjectionTestsMixinURIInjectionTestsMixinz
server.pemc                   @   s8   e Zd ZdZdZdZdd Zdd Zdd	 Zd
d Z	dS )ExtendedRedirectz
    Redirection resource.

    The HTTP status code is set according to the C{code} query parameter.

    @type lastMethod: C{bytes}
    @ivar lastMethod: Last handled HTTP request method
    TNc                 C   s   t j|  || _d S N)r   Resource__init__url)selfr)    r+   A/usr/lib/python3/dist-packages/twisted/web/test/test_webclient.pyr(   @   s    zExtendedRedirect.__init__c                 C   s@   | j r|j| _ dS |j| _ t|jd d }| | j||S d S )Ns   OK Thnx!s   coder   )
lastMethodmethodintargs
redirectTor)   )r*   requestcoder+   r+   r,   renderE   s    zExtendedRedirect.renderc                 C   s   | S r&   r+   )r*   namer2   r+   r+   r,   getChildO   s    zExtendedRedirect.getChildc                 C   s   | | |d| dS )Ns   locations   OK Bye!)setResponseCode	setHeader)r*   r)   r2   r3   r+   r+   r,   r1   S   s    
zExtendedRedirect.redirectTo)
__name__
__module____qualname____doc__ZisLeafr-   r(   r4   r6   r1   r+   r+   r+   r,   r%   3   s   
r%   c                   @   s"   e Zd ZdZdddZdd ZdS )	ForeverTakingResourceza
    L{ForeverTakingResource} is a resource which never finishes responding
    to requests.
    Fc                 C   s   t j|  || _d S r&   )r   r'   r(   _write)r*   writer+   r+   r,   r(   _   s    zForeverTakingResource.__init__c                 C   s   | j r|d tjS Ns
   some bytes)r>   r?   r   NOT_DONE_YETr*   r2   r+   r+   r,   r4   c   s    
zForeverTakingResource.renderN)Fr9   r:   r;   r<   r(   r4   r+   r+   r+   r,   r=   Z   s   
r=   c                   @   s    e Zd ZdZdd Zdd ZdS )ForeverTakingNoReadingResourcez
    L{ForeverTakingNoReadingResource} is a resource that never finishes
    responding and that removes itself from the read loop.
    c                 C   s   t j|  d S r&   )r   r'   r(   r*   r+   r+   r,   r(   n   s    z'ForeverTakingNoReadingResource.__init__c                 C   s   |j   tjS r&   )	transportZpauseProducingr   rA   rB   r+   r+   r,   r4   q   s    
z%ForeverTakingNoReadingResource.renderNrC   r+   r+   r+   r,   rD   i   s   rD   c                   @   s   e Zd Zdd ZdS )CookieMirrorResourcec                 C   sJ   g }t t|j D ]\}}|t|t|f q|  tt|S r&   )	sortedlistZreceived_cookiesitemsappendr   sortr   repr)r*   r2   lkvr+   r+   r,   r4   x   s
    zCookieMirrorResource.renderNr9   r:   r;   r4   r+   r+   r+   r,   rG   w   s   rG   c                   @   s   e Zd Zdd ZdS )RawCookieMirrorResourcec                 C   s&   | d}|d krdS ttt|S )Ns   cookie   None)Z	getHeaderr   rM   r   )r*   r2   headerr+   r+   r,   r4      s    
zRawCookieMirrorResource.renderNrQ   r+   r+   r+   r,   rR      s   rR   c                   @   s   e Zd Zdd ZdS )ErrorResourcec                 C   s&   | d |jdr"|dd dS )Ni  s
   showlength   content-length   0    )r7   r0   getr8   rB   r+   r+   r,   r4      s    
zErrorResource.renderNrQ   r+   r+   r+   r,   rU      s   rU   c                   @   s   e Zd Zdd ZdS )NoLengthResourcec                 C   s   dS )N   nolengthr+   rB   r+   r+   r,   r4      s    zNoLengthResource.renderNrQ   r+   r+   r+   r,   rZ      s   rZ   c                   @   s   e Zd ZdZdd ZdS )HostHeaderResourcezg
    A testing resource which renders itself as the value of the host header
    from the request.
    c                 C   s   |j dd S )N   hostr   )requestHeadersgetRawHeadersrB   r+   r+   r,   r4      s    zHostHeaderResource.renderNr9   r:   r;   r<   r4   r+   r+   r+   r,   r\      s   r\   c                   @   s   e Zd ZdZdd ZdS )PayloadResourcez
    A testing resource which renders itself as the contents of the request body
    as long as the request body is 100 bytes long, otherwise which renders
    itself as C{"ERROR"}.
    c                 C   s:   |j  }|jdd }t|dks2t|dkr6dS |S )NrV   r   d   s   ERROR)Zcontentreadr^   r_   lenr/   )r*   r2   dataZcontentLengthr+   r+   r,   r4      s
    
zPayloadResource.renderNr`   r+   r+   r+   r,   ra      s   ra   c                   @   s   e Zd Zdd Zdd ZdS )DelayResourcec                 C   s
   || _ d S r&   )seconds)r*   rg   r+   r+   r,   r(      s    zDelayResource.__init__c                    s     fdd}t | j| tjS )Nc                      s     d    d S r@   )r?   Zfinishr+   r2   r+   r,   response   s    
z&DelayResource.render.<locals>.response)r   Z	callLaterrg   r   rA   )r*   r2   ri   r+   rh   r,   r4      s    zDelayResource.renderN)r9   r:   r;   r(   r4   r+   r+   r+   r,   rf      s   rf   c                   @   s   e Zd Zdd ZdS )BrokenDownloadResourcec                 C   s   | dd |d dS )NrV      5   abcrX   )r8   r?   rB   r+   r+   r,   r4      s    
zBrokenDownloadResource.renderNrQ   r+   r+   r+   r,   rj      s   rj   c                   @   s    e Zd ZdZdd Zdd ZdS )CountingRedirectzl
    A L{Redirect} resource that keeps track of the number of times the
    resource has been accessed.
    c                 O   s   t j| f|| d| _d S Nr   )r   r(   count)r*   akwr+   r+   r,   r(      s    zCountingRedirect.__init__c                 C   s   |  j d7  _ t| |S N   )ro   r   r4   rB   r+   r+   r,   r4      s    zCountingRedirect.renderNrC   r+   r+   r+   r,   rm      s   rm   c                   @   s    e Zd ZdZdd Zdd ZdS )CountingResourcezR
    A resource that keeps track of the number of times it has been accessed.
    c                 C   s   t j|  d| _d S rn   )r   r'   r(   ro   rE   r+   r+   r,   r(      s    zCountingResource.__init__c                 C   s   |  j d7  _ dS )Nrs   s   Success)ro   rB   r+   r+   r,   r4      s    zCountingResource.renderNrC   r+   r+   r+   r,   rt      s   rt   c                   @   s    e Zd ZdZdd Zdd ZdS )URLJoinTestsz'
    Tests for L{client._urljoin}.
    c                 C   s@   |  tddd |  tddd |  tddd dS )z
        L{client._urljoin} does not include a fragment identifier in the
        resulting URL if neither the base nor the new path include a fragment
        identifier.
           http://foo.com/bar   /quuxs   http://foo.com/quuxs   http://foo.com/bar#s   /quux#NassertEqualr   Z_urljoinrE   r+   r+   r,   test_noFragments   s    


zURLJoinTests.test_noFragmentsc                 C   s@   |  tddd |  tddd |  tddd dS )a  
        L{client._urljoin} preserves the fragment identifier from either the
        new path or the base URL respectively, as specified in the HTTP 1.1 bis
        draft.

        @see: U{https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-22#section-7.1.2}
        s   http://foo.com/bar#fragrw   s   http://foo.com/quux#fragrv   s   /quux#frag2s   http://foo.com/quux#frag2Nrx   rE   r+   r+   r,   test_preserveFragments   s    


z#URLJoinTests.test_preserveFragmentsN)r9   r:   r;   r<   rz   r{   r+   r+   r+   r,   ru      s   ru   c                   @   s&   e Zd ZdZejedgZdd ZdS )HTTPPageGetterTestszq
    Tests for L{HTTPPagerGetter}, the HTTP client protocol implementation
    used to implement L{getPage}.
    categoryc                 C   sd   t jddddiddddd	d
dd}t }t  }||_|| | }dD ]}| || qNdS )a,  
        When a connection is made, L{HTTPPagerGetter} sends the headers from
        its factory's C{headers} dict.  If I{Host} or I{Content-Length} is
        present in this dict, the values are not sent, since they are sent with
        special values before the C{headers} dict is processed.  If
        I{User-Agent} is present in the dict, it overrides the value of the
        C{agent} attribute of the factory.  If I{Cookie} is present in the
        dict, its value is added to the values from the factory's C{cookies}
        attribute.
        s   http://foo/bars   foobar   baz   quuxs	   some datas   example.nets   foobles	   blah blahs   12981s   value)   Hosts
   User-Agents   Cookies   Content-Lengths   Useful)agentcookiespostdataheaders)s   Host: example.net
s   User-Agent: foobar
s   Content-Length: 9
s   Useful: value
s   connection: close
s   Cookie: blah blah; baz=quux
N)r   HTTPClientFactoryr   HTTPPageGetterfactorymakeConnectionvalueassertIn)r*   r   rF   ZprotocolresultZexpectedHeaderr+   r+   r,   test_earlyHeaders  s&    
z%HTTPPageGetterTests.test_earlyHeadersN)r9   r:   r;   r<   r   suppressDeprecationWarningr   r+   r+   r+   r,   r|     s   r|   c                   @   sh  e Zd ZejedgZe Zdd Zdd Z	dd Z
dd	 Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Z d4d5 Z!d6d7 Z"d8d9 Z#d:d; Z$d<d= Z%d>d? Z&d@dA Z'dBdC Z(dDdE Z)dFdG Z*dHdI Z+dJdK Z,dLdM Z-dNdO Z.dPdQ Z/dRdS Z0dTS )UWebClientTestsr}   c                 C   s   t jd|ddS Nr   	127.0.0.1	interfacer   	listenTCPr*   siter+   r+   r,   _listen:  s    zWebClientTests._listenc                 C   s  d | _ d| _t }|dtdd |dtd td| _|d| j |d	t	  |d
t	dd |dt
  |dt  |dt  |dt  |dt  |dt  |dt  |dtd |dtd t | _|d| j |dtd tdd}dd |_|d| td | _|d!| j tj|d d"| _t| j| _| | j| _| j j| _d S )#Nr   s   file
   0123456789z	text/htmls   redirect   /files   /infiniteRedirects   infiniteRedirects   waits   write-then-waitT)r?   s
   never-reads   errorr[   r]   s   payloads   broken   cookiemirrors   delay1rs   s   delay2   s   afterFoundGetCounters   afterFoundGetRedirects   /afterFoundGetCounters"   miscased-head GET response contentzmajor/minorc                 S   s   dS )N   miscased-head contentr+   rh   r+   r+   r,   <lambda>V  rX   z&WebClientTests.setUp.<locals>.<lambda>s   miscased-heads   /extendedRedirects   extendedRedirectZtimeout) r   cleanupServerConnectionsr   r'   putChildr   r   rm   infiniteRedirectResourcer=   rD   rU   rZ   r\   ra   rj   rG   rf   rt   afterFoundGetCounterZrender_Headr%   extendedRedirectr   Siter   r   wrapperr   portgetHostportno)r*   rZmiscasedHeadr+   r+   r,   setUp=  s<    



zWebClientTests.setUpc                 C   s   | j r| j   d | _ t| jj }ttt|| j	D ]&}|
 }| jjd|d |j  q:| j }tttt| jj |gS )NzClosing {proto})proto)r   ZcloseCachedConnectionsrI   r   Z	protocolskeysrangeminrd   r   pop_loginforF   ZabortConnectionr   stopListeningr   DeferredListr   r   )r*   Zconnectionsnr   dr+   r+   r,   tearDown`  s    

 zWebClientTests.tearDownc                 C   s   d| j  }tt|t|S )Nzhttp://127.0.0.1:%d/)r   r   r   r   )r*   pathhostr+   r+   r,   getURLv  s    
zWebClientTests.getURLc                 C   s"   d}t j| d|d| j|S )Nsd   0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789Zpayload)r   r   getPager   addCallbackry   )r*   sr+   r+   r,   testPayloadz  s
     zWebClientTests.testPayloadc                    s4   t  d} |t j}| fdd |S )z
        If the connection is closed before the number of bytes indicated by
        I{Content-Length} have been received, the L{Deferred} returned by
        L{getPage} fails with L{PartialDownloadError}.
        brokenc                    s     | jdS Nrl   )ry   ri   excrE   r+   r,   r     rX   z;WebClientTests.test_getPageBrokenDownload.<locals>.<lambda>)r   r   r   assertFailurePartialDownloadErrorr   r*   r   r+   rE   r,   test_getPageBrokenDownload  s    z)WebClientTests.test_getPageBrokenDownloadc                    s`   t   td j}|tj}fdd}||  fdd}|| |S )z
        If the connection is closed before the number of bytes indicated by
        I{Content-Length} have been received, the L{Deferred} returned by
        L{downloadPage} fails with L{PartialDownloadError}.
        r   c                    s      | jd   | jd | S )z}
            The HTTP status code from the server is propagated through the
            C{PartialDownloadError}.
               200   OK)ry   statusmessage)ri   rE   r+   r,   checkResponse  s    zEWebClientTests.test_downloadPageBrokenDownload.<locals>.checkResponsec                    s      d d S r   )ry   
getContentignoredr   r*   r+   r,   cbFailed  s    z@WebClientTests.test_downloadPageBrokenDownload.<locals>.cbFailed)	r   mktempr   downloadPager   r   r   r   r   )r*   r   r   r   r+   r   r,   test_downloadPageBrokenDownload  s    

z.WebClientTests.test_downloadPageBrokenDownloadc                    s   t td G  fddd}t tttjdgt 	fdd t
d| }|t
j} fdd	}|| |S )
z
        If there is an exception closing the file being written to after the
        connection is prematurely closed, that exception is logged.
        zNo file left on devicec                       s    e Zd Zdd Z fddZdS )zFWebClientTests.test_downloadPageLogsFileCloseError.<locals>.BrokenFilec                 S   s   d S r&   r+   )r*   bytesr+   r+   r,   r?     s    zLWebClientTests.test_downloadPageLogsFileCloseError.<locals>.BrokenFile.writec                    s    d S r&   r+   rE   r   r+   r,   close  s    zLWebClientTests.test_downloadPageLogsFileCloseError.<locals>.BrokenFile.closeNr9   r:   r;   r?   r   r+   r   r+   r,   
BrokenFile  s   r   )ZdefaultLogLevelc                      s
   t  S r&   )r   ZremoveObserverr+   )filteredr+   r,   r     rX   zDWebClientTests.test_downloadPageLogsFileCloseError.<locals>.<lambda>r   c                    sZ    dt d }|d }|jt  |jj j ttd d S )Nrs   r   Zlog_failure)ZassertEqualsrd   assertIsInstancer   IOErrorr0   ry   ZflushLoggedErrors)r   Zeventf)r   logObserverr*   r+   r,   r     s    zDWebClientTests.test_downloadPageLogsFileCloseError.<locals>.cbFailed)r   r   r   r   r    r!   Zcriticalr   ZaddObserver
addCleanupr   r   r   r   r   r   )r*   r   r   r   r+   )r   r   r   r*   r,   #test_downloadPageLogsFileCloseError  s    


z2WebClientTests.test_downloadPageLogsFileCloseErrorc                 C   sL   t t| d| jdt| j tj| dddid| jdgS )Nr   s
   127.0.0.1:r   s   www.example.com)r   )	r   gatherResultsr   r   r   r   ry   r	   r   rE   r+   r+   r,   testHostHeader  s      zWebClientTests.testHostHeaderc                 C   s"   t | d}|| jd |S )z
        L{client.getPage} returns a L{Deferred} which is called back with
        the body of the response if the default method B{GET} is used.
        filer   r   r   r+   r+   r,   test_getPage  s    zWebClientTests.test_getPagec                 C   s&   t j| ddd}|| jd |S )z
        L{client.getPage} returns a L{Deferred} which is called back with
        the empty string if the method is I{HEAD} and there is a successful
        response code.
        r   s   HEADr.   rX   r   r   r+   r+   r,   test_getPageHEAD  s    zWebClientTests.test_getPageHEADc                 C   s&   t j| ddd}|| jd |S )z
        If the request method is a different casing of I{HEAD} (ie, not all
        capitalized) then it is not a I{HEAD} request and the response body
        is returned.
        zmiscased-heads   Headr   r   r   r   r+   r+   r,   test_getPageNotQuiteHEAD  s    z'WebClientTests.test_getPageNotQuiteHEADc                 C   s2   t j| ddd}|| jtd| jf  |S )z
        When a non-zero timeout is passed to L{getPage} and the page is
        retrieved before the timeout period elapses, the L{Deferred} is
        called back with the contents of the page.
        r   rb   r   z127.0.0.1:%s)r   r   r   r   ry   r   r   r   r+   r+   r,   test_timeoutNotTriggering  s
    z(WebClientTests.test_timeoutNotTriggeringc                 C   s$   d| _ | tj| dddtjS )z
        When a non-zero timeout is passed to L{getPage} and that many
        seconds elapse before the server responds to the request. the
        L{Deferred} is errbacked with a L{error.TimeoutError}.
        rs   waitgư>r   )r   r   r   r   r   r   TimeoutErrorrE   r+   r+   r,   test_timeoutTriggering  s
    z%WebClientTests.test_timeoutTriggeringc                 C   sf   g }d|   dfd|   dfg}|D ]6\}}}t| ||}|| j|| || q$t|S )Nr   r   Znolengthr[   )	r   r   r   r   r   _cbDownloadPageTestrK   r   r   )r*   Z	downloadsZdownloadDatar)   r5   re   r   r+   r+   r,   testDownloadPage  s    zWebClientTests.testDownloadPagec              	   C   s.   t |d}| }W 5 Q R X | || d S )Nrb)openrc   ry   )r*   r   re   r5   r   r   r+   r+   r,   r     s    z"WebClientTests._cbDownloadPageTestc                 C   s.   G dd d}| }|  t| d|tS )Nc                   @   s   e Zd Zdd Zdd ZdS )z8WebClientTests.testDownloadPageError1.<locals>.errorfilec                 S   s   t dd S )Nzbadness happened during writer   r*   re   r+   r+   r,   r?   &  s    z>WebClientTests.testDownloadPageError1.<locals>.errorfile.writec                 S   s   d S r&   r+   rE   r+   r+   r,   r   (  s    z>WebClientTests.testDownloadPageError1.<locals>.errorfile.closeNr   r+   r+   r+   r,   	errorfile%  s   r   r   r   r   r   r   r   r*   r   Zefr+   r+   r,   testDownloadPageError1$  s    z%WebClientTests.testDownloadPageError1c                 C   s.   G dd d}| }|  t| d|tS )Nc                   @   s   e Zd Zdd Zdd ZdS )z8WebClientTests.testDownloadPageError2.<locals>.errorfilec                 S   s   d S r&   r+   r   r+   r+   r,   r?   1  s    z>WebClientTests.testDownloadPageError2.<locals>.errorfile.writec                 S   s   t dd S )Nzbadness happened during closer   rE   r+   r+   r,   r   3  s    z>WebClientTests.testDownloadPageError2.<locals>.errorfile.closeNr   r+   r+   r+   r,   r   0  s   r   r   r   r   r+   r+   r,   testDownloadPageError2/  s    z%WebClientTests.testDownloadPageError2c                 C   sD   t dd  tdd | t| ddt}|	| j
 |S )N
unwritablewbr   r   )r   r   oschmodr   r   r   r   r   ZaddBoth_cleanupDownloadPageError3r   r+   r+   r,   testDownloadPageError3:  s    z%WebClientTests.testDownloadPageError3c                 C   s   t dd t d |S )Nr   i  )r   r   unlink)r*   r   r+   r+   r,   r   E  s    
z)WebClientTests._cleanupDownloadPageError3c                    sV   g }dD ]>\}}||}  |tj}||f fdd	 || qtj|ddS )N))Z
nosuchfiles   404)r      401)zerror?showlength=1r   c                    s     | jd |S rn   )ry   r0   )r   r3   rE   r+   r,   r   P  rX   z.WebClientTests._downloadTest.<locals>.<lambda>T)ZfireOnOneErrback)r   r   Errorr   rK   r   r   )r*   r.   Zdlr)   r3   r   r+   rE   r,   _downloadTestJ  s    zWebClientTests._downloadTestc                    s      fddS )Nc                    s   t  | S r&   )r   r   r   r)   rE   r+   r,   r   U  rX   z0WebClientTests.testServerError.<locals>.<lambda>r   rE   r+   rE   r,   testServerErrorT  s    zWebClientTests.testServerErrorc                    s      fddS )Nc                    s   t  | | dd S )N?r   )r   r   r   splitr  rE   r+   r,   r   X  rX   z8WebClientTests.testDownloadServerError.<locals>.<lambda>r  rE   r+   rE   r,   testDownloadServerErrorW  s    z&WebClientTests.testDownloadServerErrorc                 C   sF   |  d}tj|}t|}tt|j|j	| |j
| j|S Nr   )r   r   URI	fromBytesr   r   Z
connectTCPr   r   r   deferredr   _cbFactoryInfor*   r)   urir   r+   r+   r,   testFactoryInfoZ  s
    

zWebClientTests.testFactoryInfoc                 C   sH   |  |jd | |jd |  |jd |  |jd d d d S )Nr   s   HTTP/r   rV   r      10)ry   r   Z
assertTrueversion
startswithr   response_headers)r*   ZignoredResultr   r+   r+   r,   r  a  s    zWebClientTests._cbFactoryInfoc                 C   s"   t | d}|| jd |S )zy
        By default, L{client.getPage} follows redirects and returns the content
        of the target resource.
        redirectr   r   r   r+   r+   r,   test_followRedirecth  s    z"WebClientTests.test_followRedirectc                 C   s.   |  tj| dddtj}|| j |S )z
        If C{followRedirect} is passed a false value, L{client.getPage} does not
        follow redirects and returns a L{Deferred} which fails with
        L{error.PageRedirect} when it encounters one.
        r  FfollowRedirect)r   r   r   r   r   PageRedirectr   _cbCheckLocationr   r+   r+   r,   test_noFollowRedirectr  s    z$WebClientTests.test_noFollowRedirectc                 C   s   |  |jd d S )Nr   )ry   location)r*   r   r+   r+   r,   r    s    zWebClientTests._cbCheckLocationc                    sD    fdd}t jdt jdd  jtj}|| |S )
        When more than C{redirectLimit} HTTP redirects are encountered, the
        page request fails with L{InfiniteRedirection}.
        c                     s"     jd  jjd d S )N   ry   Z_redirectCountr   ro   rp   r   r*   r+   r,   checkRedirectCount  s    zCWebClientTests.test_infiniteRedirection.<locals>.checkRedirectCountinfiniteRedirectr  )redirectLimit)	r   _makeGetterFactoryr   r   r   r
  r   InfiniteRedirectionr   r*   r   r   r+   r  r,   test_infiniteRedirection  s    
z'WebClientTests.test_infiniteRedirectionc                    sH   t j| ddd t j| ddd}| |tj fdd}|S )z
        C{client.HTTPPagerGetter} instances each obey the C{followRedirect}
        value passed to the L{client.getPage} call which created them.
        r  Tr  Fc                    s    S r&   r+   )ZdummyZd1r+   r,   r     rX   z<WebClientTests.test_isolatedFollowRedirect.<locals>.<lambda>)r   r   r   r   r   r  r   )r*   Zd2r   r+   r'  r,   test_isolatedFollowRedirect  s    
z*WebClientTests.test_isolatedFollowRedirectc                    sT     d}tj|ddd} |jd  fdd}tj|dddd}|| |S )	z
        Enabling unsafe redirection behaviour overwrites the method of
        redirected C{POST} requests with C{GET}.
        extendedRedirect?code=302T   POST)r  r.   z*By default, afterFoundGet must be disabledc                    s      jjdd d S N   GETz6With afterFoundGet, the HTTP method must change to GETry   r   r-   ZpagerE   r+   r,   gotPage  s
    z2WebClientTests.test_afterFoundGet.<locals>.gotPager  afterFoundGetr.   )r   r   r   ZassertFalser1  r   r   )r*   r)   r   r/  r   r+   rE   r,   test_afterFoundGet  s    
   
z!WebClientTests.test_afterFoundGetc                    s8     d} fdd}tj|ddddd}|| |S )z
        Passing C{True} for C{afterFoundGet} to L{client.downloadPage} invokes
        the same kind of redirect handling as passing that argument to
        L{client.getPage} invokes.
        r)  c                    s      jjdd d S r+  r-  r.  rE   r+   r,   r/    s
    z:WebClientTests.test_downloadAfterFoundGet.<locals>.gotPageZdownloadTempTr*  r0  )r   r   r   r   )r*   r)   r/  r   r+   rE   r,   test_downloadAfterFoundGet  s    
  
z)WebClientTests.test_downloadAfterFoundGetc                    s6    fdd}  d}tj|dddd}|| |S )z
        When C{afterFoundGet} is C{True}, L{client.getPage} only issues one
        request to the server when following the redirect.  This is a regression
        test, see #4760.
        c                     s      jjd d S rr   )ry   r   ro   r  rE   r+   r,   r     s    zLWebClientTests.test_afterFoundGetMakesOneRequest.<locals>.checkRedirectCountZafterFoundGetRedirectTr*  r0  )r   r   r   r   )r*   r   r)   r   r+   rE   r,   !test_afterFoundGetMakesOneRequest  s    
   
z0WebClientTests.test_afterFoundGetMakesOneRequestc                 C   s\   d| _ tj| d|  dd}tj| d|  dd}t| |tj| |tjgS )a4  
        If the timeout indicated by the C{timeout} parameter to
        L{client.HTTPDownloader.__init__} elapses without the complete response
        being received, the L{defer.Deferred} returned by
        L{client.downloadPage} fires with a L{Failure} wrapping a
        L{defer.TimeoutError}.
        r   r   g{Gz?r   zwrite-then-wait)	r   r   r   r   r   r   r   r   r   )r*   firstsecondr+   r+   r,   test_downloadTimeout  s      z#WebClientTests.test_downloadTimeoutc                 C   s.   d| _ tj| d|  dd}| |tjS )ax  
        If the timeout indicated by the C{timeout} parameter to
        L{client.HTTPDownloader.__init__} elapses without the complete response
        being received, the L{defer.Deferred} returned by
        L{client.downloadPage} fires with a L{Failure} wrapping a
        L{defer.TimeoutError}, even if the remote peer isn't reading data from
        the socket.
        rs   z
never-readg?r   )r   r   r   r   r   r   r   r   r   r+   r+   r,   'test_downloadTimeoutsWorkWithoutReading  s    	 z6WebClientTests.test_downloadTimeoutsWorkWithoutReadingc                    s>   fdd t jdt j dj fddS )z
        After L{client.HTTPDownloader.deferred} fires, the
        L{client.HTTPDownloader} instance's C{status} and C{response_headers}
        attributes are populated with the values from the response.
        c                    sJ     | jd   | jd d d   | jd d d t| j d S )Nr   s   content-typer   s	   text/htmlrV   r  )ry   r   r  r   r   ZfileName)r   rE   r+   r,   checkHeaders  s    z9WebClientTests.test_downloadHeaders.<locals>.checkHeadersr   )
fileOrNamec                    s    S r&   r+   _)r9  r   r+   r,   r     rX   z5WebClientTests.test_downloadHeaders.<locals>.<lambda>)r   r#  r   HTTPDownloaderr   r
  r   rE   r+   )r9  r   r*   r,   test_downloadHeaders	  s    z#WebClientTests.test_downloadHeadersc                    sF      tjdtj ddid} fdd}|j| |jS )z
        The C{cookies} dict passed to the L{client.HTTPDownloader}
        initializer is used to populate the I{Cookie} header included in the
        request sent to the server.
        cookiemirror   foo   bar)r:  r   c                    s    t  d d S )Ns   [('foo', 'bar')])ry   r   r   r   outputr*   r+   r,   
cbFinished'  s    
z7WebClientTests.test_downloadCookies.<locals>.cbFinished)r   r   r#  r   r=  r
  r   )r*   r   rD  r+   rB  r,   test_downloadCookies  s    z#WebClientTests.test_downloadCookiesc                    sJ    fdd}t jdt j dd  jtj}|	| |S )r  c                     s"     jd  jjd d S )N   r  r  r  r+   r,   r   4  s    zEWebClientTests.test_downloadRedirectLimit.<locals>.checkRedirectCountr!  rF  )r:  r"  )
r   r#  r   r=  r   r   r
  r   r$  r   r%  r+   r  r,   test_downloadRedirectLimit/  s    
z)WebClientTests.test_downloadRedirectLimitc                 C   s<   d}t |}| |ddddf|j|j|j|j|jf dS )zv
        L{client.HTTPClientFactory.setURL} alters the scheme, host, port and
        path for absolute URLs.
           http://example.com   http   example.comP      /N)r   r   ry   r)   schemer   r   r   )r*   r)   r   r+   r+   r,   test_setURLB  s    
zWebClientTests.test_setURLc                 C   sF   t d}d}|| | |ddddf|j|j|j|j|jf dS )zu
        L{client.HTTPClientFactory.setURL} removes the fragment identifier from
        the path component.
        rH  s#   https://foo.com:8443/bar;123?a#frags   httpss   foo.comi   s
   /bar;123?aN	r   r   setURLry   r)   rM  r   r   r   r*   r   r)   r+   r+   r,   test_setURLRemovesFragmentN  s    

z)WebClientTests.test_setURLRemovesFragmentc                 C   sF   t d}d}|| | |ddddf|j|j|j|j|jf dS )zW
        L{client.HTTPClientFactory.setURL} alters the path in a relative URL.
        rH  s   /hellorI  rJ  rK  NrO  rQ  r+   r+   r,   test_setURLRelativePath[  s    

z&WebClientTests.test_setURLRelativePathN)1r9   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  r&  r(  r2  r3  r4  r7  r8  r>  rE  rG  rN  rR  rS  r+   r+   r+   r,   r   5  sV   #(


r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )WebClientSSLTestsc                 C   s   t jd|tttddS )Nr   r   ZcontextFactoryr   )r   	listenSSLr   DefaultOpenSSLContextFactoryserverPEMPathr   r+   r+   r,   r   i  s      zWebClientSSLTests._listenc                 C   s   t d| j|f S Nzhttps://127.0.0.1:%d/%sr   r   r*   r   r+   r+   r,   r   p  s    zWebClientSSLTests.getURLc                 C   sL   |  d}tj|}t|}tt|j|j	|t
  |j| j|S r  )r   r   r  r	  r   r   Z
connectSSLr   r   r   r   ZClientContextFactoryr
  r   r  r  r+   r+   r,   r  s  s    

z!WebClientSSLTests.testFactoryInfoN)r9   r:   r;   r   r   r  r+   r+   r+   r,   rT  h  s   rT  c                   @   sB   e Zd ZejedgZdd Zdd Zdd Zdd	 Z	d
d Z
dS ),WebClientRedirectBetweenSSLandPlainTextTestsr}   c                 C   s   t d| j|f S rY  )r   	tlsPortnor[  r+   r+   r,   getHTTPS  s    z5WebClientRedirectBetweenSSLandPlainTextTests.getHTTPSc                 C   s   t d| j|f S Nzhttp://127.0.0.1:%d/%s)r   plainPortnor[  r+   r+   r,   getHTTP  s    z4WebClientRedirectBetweenSSLandPlainTextTests.getHTTPc                 C   s   t dd}t dd}tj|d d}tj|d d}tjd|tttdd| _tj	d|dd| _
| j
 j| _| j j| _|d	t| d
 |dt| d |dt| d |dt dd d S )Ns   not me
text/plains
   me neitherr   r   r   rU  r   s   oneZtwos   twoZthrees   threeZfours   four	   FOUND IT!)r   r   r   r   rV  r   rW  rX  tlsPortr   	plainPortr   r   r`  r]  r   r   r^  ra  )r*   Z	plainRootZtlsRootZ	plainSiteZtlsSiter+   r+   r,   r     s(    

  z2WebClientRedirectBetweenSSLandPlainTextTests.setUpc                 C   s&   t ttj| jj| jjg}t|S r&   )rI   mapr   ZmaybeDeferredre  r   rd  r   )r*   Zdsr+   r+   r,   r     s    z5WebClientRedirectBetweenSSLandPlainTextTests.tearDownc                 C   s   t | d| jdS )NZonerc  r   r   ra  r   ry   rE   r+   r+   r,   testHoppingAround  s     z>WebClientRedirectBetweenSSLandPlainTextTests.testHoppingAroundN)r9   r:   r;   r   r   r   r^  ra  r   r   rh  r+   r+   r+   r,   r\  ~  s   r\  c                   @   sb   e Zd Zejedg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 )CookieTestsr}   c                 C   s   t jd|ddS r   r   r   r+   r+   r,   r     s    zCookieTests._listenc                 C   sR   t dd}|dt  |dt  tj|d d}| || _| j j| _	d S )Ns   El toro!rb  r   s   rawcookiemirrorr   )
r   r   rG   rR   r   r   r   r   r   r   )r*   rootr   r+   r+   r,   r     s    
zCookieTests.setUpc                 C   s
   | j  S r&   )r   r   rE   r+   r+   r,   r     s    zCookieTests.tearDownc                 C   s   t d| j|f S r_  rZ  r[  r+   r+   r,   ra    s    zCookieTests.getHTTPc                 C   s   t | d| jdS )Nr?  s   []rg  rE   r+   r+   r,   testNoCookies  s     zCookieTests.testNoCookiesc                 C   s(   ddd}t j| d|d| jdS )NrA  r   r@  r   r?  r   s!   [('baz', 'quux'), ('foo', 'bar')]rg  r*   r   r+   r+   r,   testSomeCookies  s
    
 zCookieTests.testSomeCookiesc                 C   s   t | d| jdS )NrawcookiemirrorrS   rg  rE   r+   r+   r,   testRawNoCookies  s     zCookieTests.testRawNoCookiesc                 C   s(   ddd}t j| d|d| jdS )NrA  r   rl  rp  rm  )s   'foo=bar; baz=quux's   'baz=quux; foo=bar')r   r   ra  r   r   rn  r+   r+   r,   testRawSomeCookies  s
    
zCookieTests.testRawSomeCookiesc                 C   sf   t d}|d}t }|| dD ]}||d  q(| | d | |jdddd	 d S )
N   http://foo.example.com/127.42.42.42)
s   200 Oks   Squash: yess   Hands: stolensU   Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMTs4   Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/s%   Set-Cookie: SHIPPING=FEDEX; path=/foos   Set-Cookie: HttpOnly;SecurerX   s   bodys	   more body   
sI   GET / HTTP/1.0
Host: foo.example.com
User-Agent: Twisted PageGetter

s   WILE_E_COYOTEs   ROCKET_LAUNCHER_0001s   FEDEX)s   CUSTOMERs   PART_NUMBERs   SHIPPING)	r   r   buildProtocolr   r   ZdataReceivedry   r   r   )r*   r   r   rF   liner+   r+   r,   testCookieHeaderParsing  s    



z#CookieTests.testCookieHeaderParsingN)r9   r:   r;   r   r   r   r   r   r   ra  rk  ro  rq  rr  rx  r+   r+   r+   r,   ri    s   ri  c                   @   sV   e Zd ZdZejedgZdd Zdd Zdd Z	d	d
 Z
dd Zdd Zdd ZdS )HostHeaderTestsz\
    Test that L{HTTPClientFactory} includes the port in the host header
    if needed.
    r}   c              	   C   s\   | dD ]L}z2| dd\}}|  dkr>| W   S W q
 tk
rT   Y q
X q
dS )zq
        Retrieve the value of the I{Host} header from the serialized
        request given by C{bytes}.
        ru     :rs   r]   N)r  striplower
ValueError)r*   r   rw  r5   r   r+   r+   r,   _getHost  s    zHostHeaderTests._getHostc                 C   s<   t d}|d}|t  | | |j d dS )zq
        No port should be included in the host header when connecting to the
        default HTTP port.
        rs  s   127.42.42.42   foo.example.comN	r   r   rv  r   r   ry   r~  rF   r   r*   r   r   r+   r+   r,   test_HTTPDefaultPort  s    

z$HostHeaderTests.test_HTTPDefaultPortc                 C   s<   t d}|d}|t  | | |j d dS )z
        No port should be included in the host header when connecting to the
        default HTTP port even if it is in the URL.
        s   http://foo.example.com:80/rt  r  Nr  r  r+   r+   r,   test_HTTPPort80  s    

zHostHeaderTests.test_HTTPPort80c                 C   s<   t d}|d}|t  | | |j d dS )zx
        The port should be included in the host header when connecting to the
        a non default HTTP port.
           http://foo.example.com:8080/rt     foo.example.com:8080Nr  r  r+   r+   r,   test_HTTPNotPort80$  s    

z"HostHeaderTests.test_HTTPNotPort80c                 C   s<   t d}|d}|t  | | |j d dS )zr
        No port should be included in the host header when connecting to the
        default HTTPS port.
        s   https://foo.example.com/rt  r  Nr  r  r+   r+   r,   test_HTTPSDefaultPort0  s    

z%HostHeaderTests.test_HTTPSDefaultPortc                 C   s<   t d}|d}|t  | | |j d dS )z
        No port should be included in the host header when connecting to the
        default HTTPS port even if it is in the URL.
        s   https://foo.example.com:443/rt  r  Nr  r  r+   r+   r,   test_HTTPSPort443<  s    

z!HostHeaderTests.test_HTTPSPort443c                 C   s<   t d}|d}|t  | | |j d dS )zy
        The port should be included in the host header when connecting to the
        a non default HTTPS port.
        r  rt  r  Nr  r  r+   r+   r,   test_HTTPSNotPort443H  s    

z$HostHeaderTests.test_HTTPSNotPort443N)r9   r:   r;   r<   r   r   r   r~  r  r  r  r  r  r  r+   r+   r+   r,   ry    s   ry  rW  zOpenSSL not presentzReactor doesn't support SSLc                   @   s   e Zd ZdZdd Zd$ddZdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#S )%URITestsa  
    Abstract tests for L{twisted.web.client.URI}.

    Subclass this and L{unittest.TestCase}. Then provide a value for
    C{host} and C{uriHost}.

    @ivar host: A host specification for use in tests, must be L{bytes}.

    @ivar uriHost: The host specification in URI form, must be a L{bytes}. In
        most cases this is identical with C{host}. IPv6 address literals are an
        exception, according to RFC 3986 section 3.2.2, as they need to be
        enclosed in brackets. In this case this variable is different.
    c                 C   sB   |  | jt |  | jt |  |t | d| |d| jS )a  
        Replace the string "HOST" in C{template} with this test's host.

        Byte strings Python between (and including) versions 3.0 and 3.4
        cannot be formatted using C{%} or C{format} so this does a simple
        replace.

        @type template: L{bytes}
        @param template: A string containing "HOST".

        @rtype: L{bytes}
        @return: A string where "HOST" has been replaced by C{self.host}.
        s   HOST)r   r   r   uriHostr   replace)r*   templater+   r+   r,   makeURIStringm  s
    zURITests.makeURIStringrX   c
           
      C   s@   |  ||||||||	f|j|j|j|j|j|j|j|jf dS )aU  
        Assert that all of a L{client.URI}'s components match the expected
        values.

        @param uri: U{client.URI} instance whose attributes will be checked
            for equality.

        @type scheme: L{bytes}
        @param scheme: URI scheme specifier.

        @type netloc: L{bytes}
        @param netloc: Network location component.

        @type host: L{bytes}
        @param host: Host name.

        @type port: L{int}
        @param port: Port number.

        @type path: L{bytes}
        @param path: Hierarchical path.

        @type params: L{bytes}
        @param params: Parameters for last path segment, defaults to C{b''}.

        @type query: L{bytes}
        @param query: Query string, defaults to C{b''}.

        @type fragment: L{bytes}
        @param fragment: Fragment identifier, defaults to C{b''}.
        N)	ry   rM  netlocr   r   r   paramsqueryfragment)
r*   r  rM  r  r   r   r   r  r  r  r+   r+   r,   assertURIEquals  s    ! zURITests.assertURIEqualsc                 C   sd   t j| d}| d|j t j| d}| d|j t j| d}| d|j dS )z
        L{client.URI.fromBytes} by default assumes port 80 for the I{http}
        scheme and 443 for the I{https} scheme.
           http://HOSTrK  s   http://HOST:   https://HOSTi  Nr   r  r	  r  ry   r   r*   r  r+   r+   r,   test_parseDefaultPort  s    zURITests.test_parseDefaultPortc                 C   sL   t jj| ddd}| d|j t jj| ddd}| d|j dS )z
        L{client.URI.fromBytes} accepts a C{defaultPort} parameter that
        overrides the normal default port logic.
        r    )ZdefaultPortr  Nr  r  r+   r+   r,   test_parseCustomDefaultPort  s      z$URITests.test_parseCustomDefaultPortc                 C   sj   t j| d}| d|j | | j|j | | jd |j t j| d}| | j|j dS )zj
        Parsing a I{URI} splits the network location component into I{host} and
        I{port}.
        s   http://HOST:5144r  s   :5144s   http://HOST N)	r   r  r	  r  ry   r   r   r  r  r  r+   r+   r,   test_netlocHostPort  s    zURITests.test_netlocHostPortc                 C   sD   |  d}tj|}| j|d| j| jddd | ||  dS )z/
        Parse the path from a I{URI}.
        s   http://HOST/foo/barrI  rK     /foo/barrM  r  r   r   r   N	r  r   r  r	  r  r  r   ry   toBytesr*   r  Zparsedr+   r+   r,   	test_path  s    
zURITests.test_pathc                 C   sD   |  d}tj|}| j|d| j| jddd | ||  dS )zL
        The path of a I{URI} that has no path is the empty string.
        r  rI  rK  rX   r  Nr  r  r+   r+   r,   test_noPath  s    
zURITests.test_noPathc                 C   s0   |  d}| jtj|d| j| jddd dS )zE
        The path of a I{URI} with an empty path is C{b'/'}.
           http://HOST/rI  rK  rL  r  N)r  r  r   r  r	  r  r   r  r+   r+   r,   test_emptyPath  s    

zURITests.test_emptyPathc              	   C   sF   |  d}tj|}| j|d| j| jdddd | ||  dS )z8
        Parse I{URI} parameters from a I{URI}.
        s   http://HOST/foo/bar;paramrI  rK  r     param)rM  r  r   r   r   r  Nr  r  r+   r+   r,   
test_param  s    
zURITests.test_paramc              
   C   sH   |  d}tj|}| j|d| j| jddddd | ||  dS )	z7
        Parse the query string from a I{URI}.
        s!   http://HOST/foo/bar;param?a=1&b=2rI  rK  r  r     a=1&b=2)rM  r  r   r   r   r  r  Nr  r  r+   r+   r,   
test_query  s    
	zURITests.test_queryc                 C   sJ   |  d}tj|}| j|d| j| jdddddd	 | ||  d	S )
z>
        Parse the fragment identifier from a I{URI}.
        s&   http://HOST/foo/bar;param?a=1&b=2#fragrI  rK  r  r  r  s   frag)rM  r  r   r   r   r  r  r  Nr  r  r+   r+   r,   test_fragment$  s    

zURITests.test_fragmentc                 C   s$   t j| d}| d|j dS )zn
        L{client.URI.originForm} produces an absolute I{URI} path including
        the I{URI} path.
        s   http://HOST/foos   /fooNr   r  r	  r  ry   Z
originFormr  r+   r+   r,   test_originForm7  s    zURITests.test_originFormc                 C   s$   t j| d}| d|j dS )z
        L{client.URI.originForm} produces an absolute I{URI} path including
        the I{URI} path, parameters and query string but excludes the fragment
        identifier.
        s   http://HOST/foo;param?a=1#frags   /foo;param?a=1Nr  r  r+   r+   r,   test_originFormComplexA  s    zURITests.test_originFormComplexc                 C   s$   t j| d}| d|j dS )zp
        L{client.URI.originForm} produces a path of C{b'/'} when the I{URI}
        specifies no path.
        r  rL  Nr  r  r+   r+   r,   test_originFormNoPathL  s    zURITests.test_originFormNoPathc                 C   s$   t j| d}| d|j dS )zv
        L{client.URI.originForm} produces a path of C{b'/'} when the I{URI}
        specifies an empty path.
        r  rL  Nr  r  r+   r+   r,   test_originFormEmptyPathU  s    z!URITests.test_originFormEmptyPathc                 C   sV   |  d}|d}t| tj|}| |jt | |j	t | |j
t dS )z
        L{client.URI.fromBytes} parses the scheme, host, and path elements
        into L{bytes}, even when passed an URL which has previously been passed
        to L{urlparse} as a L{unicode} string.
        s   http://HOST/pathasciiN)r  decoder   r   r  r	  r   rM  r   r   r   )r*   Z	goodInputZbadInputr  r+   r+   r,    test_externalUnicodeInterference_  s    

z)URITests.test_externalUnicodeInterferenceN)rX   rX   rX   )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  ^  s(        
'
	
r  c                   @   s   e Zd ZdZd ZZdS )URITestsForHostnamez>
    Tests for L{twisted.web.client.URI} with host names.
    rJ  Nr9   r:   r;   r<   r  r   r+   r+   r+   r,   r  o  s   r  c                   @   s   e Zd ZdZd ZZdS )URITestsForIPv4zG
    Tests for L{twisted.web.client.URI} with IPv4 host addresses.
    s   192.168.1.67Nr  r+   r+   r+   r,   r  x  s   r  c                   @   s    e Zd ZdZdZdZdd ZdS )URITestsForIPv6z
    Tests for L{twisted.web.client.URI} with IPv6 host addresses.

    IPv6 addresses must always be surrounded by square braces in URIs. No
    attempt is made to test without.
    s   fe80::20c:29ff:fea4:c60s   [fe80::20c:29ff:fea4:c60]c                 C   s<   t jd}| |jd | |jd | | d dS )z
        Brackets around IPv6 addresses are stripped in the host field. The host
        field is then exported with brackets in the output of
        L{client.URI.toBytes}.
        s   http://[::1]:80/index.htmls   ::1s   [::1]:80N)r   r  r	  ry   r   r  r  r  r+   r+   r,   "test_hostBracketIPv6AddressLiteral  s    z2URITestsForIPv6.test_hostBracketIPv6AddressLiteralN)r9   r:   r;   r<   r   r  r  r+   r+   r+   r,   r    s   r  c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )DeprecationTestszB
    Tests that L{client.getPage} and friends are deprecated.
    c                 C   s   t jdttdddd}| j}| |j t	d|f }t
|}| | jg}| t|d | |d d t | |d d	 d
 |dd S )z2
        L{client.getPage} is deprecated.
        r   rX   rb  r   r   http://127.0.0.1:%drs   r~   r   ztwisted.web.client.getPage was deprecated in Twisted 16.7.0; please use https://pypi.org/project/treq/ or twisted.web.client.Agent insteadc                 S   s   d S r&   r+   r;  r+   r+   r,   r     rX   z9DeprecationTests.test_getPageDeprecated.<locals>.<lambda>)r   r   r   r   r   r   r   r   r   r   r   r   flushWarningstest_getPageDeprecatedry   rd   r   
addErrback)r*   r   r   r)   r   warningInfor+   r+   r,   r    s"      


z'DeprecationTests.test_getPageDeprecatedc                 C   s   t jdttdddd}| j}| |j t	d|f }t
|  }t||j}| | jg}| t|d | |d d t | |d d	 d
 |dd S )z7
        L{client.downloadPage} is deprecated.
        r   rX   rb  r   r   r  rs   r~   r   ztwisted.web.client.downloadPage was deprecated in Twisted 16.7.0; please use https://pypi.org/project/treq/ or twisted.web.client.Agent insteadc                 S   s   d S r&   r+   r;  r+   r+   r,   r     rX   z>DeprecationTests.test_downloadPageDeprecated.<locals>.<lambda>)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  test_downloadPageDeprecatedry   rd   r   r  )r*   r   r   r)   r   r   r  r+   r+   r,   r    s$      

z,DeprecationTests.test_downloadPageDeprecatedc                 C   sT   t t| |  }| t|d | |d d t | |d d d| dS )z
        Assert that accessing the given class was deprecated.

        @param klass: The class being deprecated.
        @type klass: L{str}
        rs   r   r~   r   ztwisted.web.client.{} was deprecated in Twisted 16.7.0: please use https://pypi.org/project/treq/ or twisted.web.client.Agent insteadN)getattrr   r  ry   rd   r   format)r*   klassr  r+   r+   r,   _testDeprecatedClass  s    

z%DeprecationTests._testDeprecatedClassc                 C   s   |  d dS )z9
        L{client.HTTPPageGetter} is deprecated.
        r   Nr  rE   r+   r+   r,   test_httpPageGetterDeprecated  s    z.DeprecationTests.test_httpPageGetterDeprecatedc                 C   s   |  d dS )z=
        L{client.HTTPPageDownloader} is deprecated.
        HTTPPageDownloaderNr  rE   r+   r+   r,   !test_httpPageDownloaderDeprecated  s    z2DeprecationTests.test_httpPageDownloaderDeprecatedc                 C   s   |  d dS )z<
        L{client.HTTPClientFactory} is deprecated.
        r   Nr  rE   r+   r+   r,    test_httpClientFactoryDeprecated  s    z1DeprecationTests.test_httpClientFactoryDeprecatedc                 C   s   |  d dS )z9
        L{client.HTTPDownloader} is deprecated.
        r=  Nr  rE   r+   r+   r,   test_httpDownloaderDeprecated  s    z.DeprecationTests.test_httpDownloaderDeprecatedN)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S )GetPageMethodInjectionTests@
    Test L{client.getPage} against HTTP method injections.
    c                 C   s   d}t j||d dS )v
        Attempt a request with the provided method.

        @param method: see L{MethodInjectionTestsMixin}
           http://twisted.invalidr   Nr   r   r*   r.   r  r+   r+   r,   !attemptRequestWithMaliciousMethod  s    z=GetPageMethodInjectionTests.attemptRequestWithMaliciousMethodNr9   r:   r;   r<   r  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZdd ZdS )GetPageURIInjectionTestsz8
    Test L{client.getPage} against URI injections.
    c                 C   s   t | dS )m
        Attempt a request with the provided URI.

        @param uri: see L{URIInjectionTestsMixin}
        Nr  r  r+   r+   r,   attemptRequestWithMaliciousURI  s    z7GetPageURIInjectionTests.attemptRequestWithMaliciousURINr9   r:   r;   r<   r  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZdd ZdS ) DownloadPageMethodInjectionTestsr  c                 C   s   d}t j|t |d dS )r  r  )r   r.   Nr   r   ioBytesIOr  r+   r+   r,   r  *  s    zBDownloadPageMethodInjectionTests.attemptRequestWithMaliciousMethodNr  r+   r+   r+   r,   r  "  s   r  c                   @   s   e Zd ZdZdd ZdS )DownloadPageURIInjectionTestsz=
    Test L{client.downloadPage} against URI injections.
    c                 C   s   t j|t d dS )r  )r   Nr  r  r+   r+   r,   r  =  s    z<DownloadPageURIInjectionTests.attemptRequestWithMaliciousURINr  r+   r+   r+   r,   r  5  s   r  c                 C   s>   t | }||_||_||_d|_d|_i |_d|_i |_	|S )aV  
    Make a L{ClientFactory} that can be used with
    L{client.HTTPPageGetter} and its subclasses.

    @param protocolClass: The protocol class
    @type protocolClass: A subclass of L{client.HTTPPageGetter}

    @param method: the HTTP method

    @param host: the host

    @param path: The URI path

    @return: A L{ClientFactory}.
    rI  r   s
   User/Agent)
r   ZforProtocolr.   r   r   rM  r   r   r   r   )protocolClassr.   r   r   r   r+   r+   r,   makeHTTPPageGetterFactoryG  s    
r  c                   @   s   e Zd ZdZejZdd ZdS )"HTTPPageGetterMethodInjectionTestszG
    Test L{client.HTTPPageGetter} against HTTP method injections.
    c                 C   s:   t  }t| j|ddd}|tddd}|| dS )r
        Attempt a request with the provided method.

        @param method: L{MethodInjectionTestsMixin}
        s   twisted.invalidrL  r.   r   r   TCPr   r   Nr   r  r  rv  r   ZIPv4Addressr   )r*   r.   rF   r   getterr+   r+   r,   r  p  s    zDHTTPPageGetterMethodInjectionTests.attemptRequestWithMaliciousMethodN)r9   r:   r;   r<   r   r   r  r  r+   r+   r+   r,   r  g  s   r  c                   @   s   e Zd ZdZejZdd ZdS )HTTPPageGetterURIInjectionTestszD
    Test L{client.HTTPPageGetter} against HTTP URI injections.
    c                 C   s:   t  }t| jd||d}|tddd}|| dS )i
        Attempt a request with the provided URI.

        @param uri: L{URIInjectionTestsMixin}
        r,  r  r  r   r   Nr  )r*   r  rF   r   r  r+   r+   r,   r    s    z>HTTPPageGetterURIInjectionTests.attemptRequestWithMaliciousURIN)r9   r:   r;   r<   r   r   r  r  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZejZdS )&HTTPPageDownloaderMethodInjectionTestszK
    Test L{client.HTTPPageDownloader} against HTTP method injections.
    Nr9   r:   r;   r<   r   r  r  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZejZdS )#HTTPPageDownloaderURIInjectionTestszH
    Test L{client.HTTPPageDownloader} against HTTP URI injections.
    Nr  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZdd ZdS )%HTTPClientFactoryMethodInjectionTestszK
    Tests L{client.HTTPClientFactory} against HTTP method injections.
    c                 C   s   t d| dS )r     https://twisted.invalidNr   r   r*   r.   r+   r+   r,   r    s    zGHTTPClientFactoryMethodInjectionTests.attemptRequestWithMaliciousMethodNr  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZdd ZdS )"HTTPClientFactoryURIInjectionTestszH
    Tests L{client.HTTPClientFactory} against HTTP URI injections.
    c                 C   s   t | dS r  Nr  r  r+   r+   r,   r    s    zAHTTPClientFactoryURIInjectionTests.attemptRequestWithMaliciousURINr  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZdd ZdS )(HTTPClientFactorySetURLURIInjectionTestszO
    Tests L{client.HTTPClientFactory.setURL} against HTTP URI injections.
    c                 C   s   t d| dS r  r  N)r   r   rP  r  r+   r+   r,   r    s    zGHTTPClientFactorySetURLURIInjectionTests.attemptRequestWithMaliciousURINr  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZdd ZdS )"HTTPDownloaderMethodInjectionTestszH
    Tests L{client.HTTPDownloader} against HTTP method injections.
    c                 C   s   t jdt |d dS )r  r  r   Nr   r=  r  r  r  r+   r+   r,   r    s
    zDHTTPDownloaderMethodInjectionTests.attemptRequestWithMaliciousMethodNr  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZdd ZdS )HTTPDownloaderURIInjectionTestszE
    Tests L{client.HTTPDownloader} against HTTP URI injections.
    c                 C   s   t |t  dS r  r  r  r+   r+   r,   r    s    z>HTTPDownloaderURIInjectionTests.attemptRequestWithMaliciousURINr  r+   r+   r+   r,   r    s   r  c                   @   s   e Zd ZdZdd ZdS )%HTTPDownloaderSetURLURIInjectionTestszL
    Tests L{client.HTTPDownloader.setURL} against HTTP URI injections.
    c                 C   s   t dt }|| dS r  )r   r=  r  r  rP  )r*   r  Z
downloaderr+   r+   r,   r    s
    zDHTTPDownloaderSetURLURIInjectionTests.attemptRequestWithMaliciousURINr  r+   r+   r+   r,   r    s   r  )lr<   Z
__future__r   r   r  r   errnor   r   r   ImportErrorZurllib.parseZtwisted.python.compatr   r   r	   Ztwisted.trialr
   r   Ztwisted.webr   r   r   r   Ztwisted.web.staticr   Ztwisted.web.utilr   Ztwisted.internetr   r   r   r   Ztwisted.internet.protocolr   Ztwisted.python.filepathr   Ztwisted.protocols.policiesr   Ztwisted.test.proto_helpersr   r   r   r   Ztwistedr   Ztwisted.loggerr   r   r    r!   r"   Z!twisted.web.test.injectionhelpersr#   r$   __file__ZsiblingZ	serverPEMZasBytesModer   rX  r'   r%   r=   rD   rG   rR   rU   rZ   r\   ra   rf   rj   rm   rt   ZTestCaseru   r|   r   rT  r\  ri  ry  hasattrZcaseskipZIReactorSSLr  r  r  r  r  ZSynchronousTestCaser  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r+   r+   r+   r,   <module>   s   

'
).    7,L^

  		b



 










