U
    
W[                     @   s   d Z ddlZddlZddlmZmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZmZmZmZ dd	lmZ dd
l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eZdS )zD
IProxyParser implementation for version two of the PROXY protocol.
    N)ValuesValueConstant)implementer)address)compat   )convertErrorInvalidProxyHeaderInvalidNetworkProtocolMissingAddressData)_info)_interfacesc                   @   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   UNSPECZ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   ZSTREAMDGRAMr   r   r   r   r   %   s   r         ZLOCALZPROXYc                   @   sj   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
 Z
dd Zedd Zedd Ze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   c                 C   s
   d| _ d S )N    )buffer)selfr   r   r   __init__J   s    zV2Parser.__init__c                 C   s   |  j |7  _ t| j dk r"t td| j dd d d }t| j |k rRd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   )NNNr'   )r(   lenr	   structunpackparse)r)   datasizeheaderZ	remaininginfor   r   r   feedN   s    
zV2Parser.feedc                 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>w   s   z(V2Parser._bytesToIPv4.<locals>.<genexpr>)joinr   Z	iterbytesZ
bytestringr   r   r   _bytesToIPv4k   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   | ](}d t  ||d  df dV  qdS )z%x   r   r6   N)intr8   r9   Z	hexStringr   r   r<      s   z(V2Parser._bytesToIPv6.<locals>.<genexpr>r   r   rA   )binasciiZb2a_hexr=   ranger>   r   rC   r   _bytesToIPv6}   s    

zV2Parser._bytesToIPv6c              	   C   s  |dd }d}t tt& t|dd }t|dd }W 5 Q R X || jkrVt |t@ |t@  }}|| jks||| jkrt | j| t	krt
|ddS |t@ |t@  }}	t tt t|}t|	}	W 5 Q R X |tjks|	tjk rt
|ddS | j| }
|ddt|
  }|tjkrxt tjt t|
|\}}W 5 Q R X t
|t|dt|dS d}|	tjkrd}tj}| j}|tjkrtj }| j!}t tjt t|
|}|\}}}}W 5 Q R X 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      r+   r       ZTCPZUDP)"r   
IndexErrorr	   r7   PREFIX_HIGH_LOWVERSIONSCOMMANDS_LOCALCOMMANDr   Z	ProxyInfo
ValueErrorr
   r   ZlookupByValuer   r   ADDRESSFORMATSr-   Zcalcsizer   errorr   r.   r   ZUNIXAddressrstripr   ZIPv4Addressr?   r   ZIPv6AddressrF   )clslineprefixZaddrInfoZversionCommandZfamilyProtoversionZcommandZfamilyZnetprotoZaddressFormatsourcedestZaddrTypeZaddrClsZ
addrParserr3   ZsPortZdPortr   r   r   r/      s^    


zV2Parser.parseN)r   r   r   r   rK   rN   rP   _PROXYCOMMANDrO   rR   r*   r4   staticmethodr?   rF   classmethodr/   r   r   r   r   r    3   s&   


r    )r   rD   r-   Z
constantlyr   r   Zzope.interfacer   Ztwisted.internetr   Ztwisted.pythonr   _exceptionsr   r	   r
   r    r   r   r   r   rL   rM   rP   r[   ZIProxyParserobjectr    r   r   r   r   <module>   s"   	