o
    f                     @   s   d Z ddlZddlZddlmZmZmZmZmZ ddl	m
Z
 ddlmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZmZmZmZ G dd deZG dd deZdZdZdZdZe
ej G dd dZ!dS )zD
IProxyParser implementation for version two of the PROXY protocol.
    N)CallableLiteralTupleTypeUnion)implementer)ValueConstantValues)address)compat   )_info_interfaces)InvalidNetworkProtocolInvalidProxyHeaderMissingAddressDataconvertErrorc                   @   s0   e Zd ZdZedZedZedZedZdS )	NetFamilyz(
    Values for the 'family' field.
    r          0   N)	__name__
__module____qualname____doc__r   UNSPECINETINET6UNIX r   r   E/usr/lib/python3/dist-packages/twisted/protocols/haproxy/_v2parser.pyr      s    r   c                   @   s(   e Zd ZdZedZedZedZdS )NetProtocolz&
    Values for 'protocol' field.
    r   r      N)r   r   r   r   r   r   STREAMDGRAMr   r   r   r    r!   (   s
    r!         LOCALPROXYc                   @   s   e Zd ZdZdZdgZeedZdddddddZ	dddZ
ded	eeejef ed f fddZeded	efddZeded	efddZeded	ejfddZd
S )V2Parserzn
    PROXY protocol version two header parser.

    Version two of the PROXY protocol is a binary format.
    s   

 
QUIT
r   )r   r   z!4s4s2Hz	!16s16s2Hz	!108s108s)      !   "   1   2   returnNc                 C   s
   d| _ d S )N    )buffer)selfr   r   r    __init__O   s   
zV2Parser.__init__dataNNc                 C   s   |  j |7  _ t| j dk rt td| j dd d d }t| j |k r)dS | j d| | j |d }}d| _ | |}||fS )a  
        Consume a chunk of data and attempt to parse it.

        @param data: A bytestring.
        @type data: bytes

        @return: A two-tuple containing, in order, a L{_interfaces.IProxyInfo}
            and any bytes fed to the parser that followed the end of the
            header.  Both of these values are None until a complete header is
            parsed.

        @raises InvalidProxyHeader: If the bytes fed to the parser create an
            invalid PROXY header.
        r   z!H   r   r6   Nr1   )r2   lenr   structunpackparse)r3   r5   sizeheader	remaininginfor   r   r    feedR   s   
zV2Parser.feed
bytestringc                 C   s   d dd t| D S )a7  
        Convert packed 32-bit IPv4 address bytes into a dotted-quad ASCII bytes
        representation of that address.

        @param bytestring: 4 octets representing an IPv4 address.
        @type bytestring: L{bytes}

        @return: a dotted-quad notation IPv4 address.
        @rtype: L{bytes}
           .c                 s   s$    | ]}d t |f dV  qdS )z%iasciiN)ordencode.0br   r   r    	<genexpr>|   s    
z(V2Parser._bytesToIPv4.<locals>.<genexpr>)joinr   	iterbytesrA   r   r   r    _bytesToIPv4p   s   
zV2Parser._bytesToIPv4c                    s*   t |  d fddtdddD S )a=  
        Convert packed 128-bit IPv6 address bytes into a colon-separated ASCII
        bytes representation of that address.

        @param bytestring: 16 octets representing an IPv6 address.
        @type bytestring: L{bytes}

        @return: a dotted-quad notation IPv6 address.
        @rtype: L{bytes}
           :c                 3   s0    | ]}t  ||d   dddV  qdS )   r   xrC   N)intrE   rF   	hexStringr   r    rI      s
    
z(V2Parser._bytesToIPv6.<locals>.<genexpr>r   r   rO   )binasciib2a_hexrJ   rangerL   r   rR   r    _bytesToIPv6   s   

zV2Parser._bytesToIPv6linec              	   C   sX  |dd }d}t tt t|dd }t|dd }W d   n1 s(w   Y  || jkr5t |t@ |t@ }}|| jvsH|| jvrKt | j| t	krYt
|ddS |t@ |t@ }}	t tt t|}t|	}	W d   n1 s|w   Y  |tju s|	tju rt
|ddS | j| }
|ddt|
  }|tju rt tjt t|
|\}}W d   n1 sw   Y  t
|t|dt|dS d}|	tju rd}tj}| j}|tju rtj }| j!}t tjt t|
|}|\}}}}W d   n	1 sw   Y  t
|||||" |||||" |S )	a  
        Parse a bytestring as a full PROXY protocol header.

        @param line: A bytestring that represents a valid HAProxy PROXY
            protocol version 2 header.
        @type line: bytes

        @return: A L{_interfaces.IProxyInfo} containing the
            parsed data.

        @raises InvalidProxyHeader: If the bytestring does not represent a
            valid PROXY header.
        N      r7   r       TCPUDP)#r   
IndexErrorr   rD   PREFIX_HIGH_LOWVERSIONSCOMMANDS_LOCALCOMMANDr   	ProxyInfo
ValueErrorr   r   lookupByValuer!   r   ADDRESSFORMATSr9   calcsizer   errorr   r:   r
   UNIXAddressrstripr$   IPv4AddressrM   r   IPv6AddressrW   decode)clsrX   prefixaddrInfoversionCommandfamilyProtoversioncommandfamilynetprotoaddressFormatsourcedestaddrTypeaddrCls
addrParserr?   sPortdPortr   r   r    r;      sb   





zV2Parser.parse)r0   N)r   r   r   r   r_   rb   rd   _PROXYCOMMANDrc   rh   r4   bytesr   r   r   re   r@   staticmethodrM   rW   classmethodr;   r   r   r   r    r)   8   s0    


r)   )"r   rT   r9   typingr   r   r   r   r   zope.interfacer   
constantlyr   r	   twisted.internetr
   twisted.pythonr    r   r   _exceptionsr   r   r   r   r   r!   r`   ra   rd   r   IProxyParserr)   r   r   r   r    <module>   s$   
