3
+sY                 @   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jd| j dd d d }t| j |k rRdS | j d| | j |d  }}d| _ | j|}||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   Nr'   )NN)r(   lenr	   structunpackparse)r)   datasizeheaderZ	remaininginfor   r   r   feedN   s    
zV2Parser.feedc             C   s   dj dd tj| 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 jdV  qdS )z%iasciiN)ordencode).0br   r   r   	<genexpr>x   s   z(V2Parser._bytesToIPv4.<locals>.<genexpr>)joinr   Z	iterbytes)
bytestringr   r   r   _bytesToIPv4k   s    zV2Parser._bytesToIPv4c                s*   t j|  dj 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 jdV  qdS )z%x   r   r6   N)intr8   )r9   r:   )	hexStringr   r   r;      s   z(V2Parser._bytesToIPv6.<locals>.<genexpr>r   r   r@   )binasciiZb2a_hexr<   range)r=   r   )rB   r   _bytesToIPv6}   s    

zV2Parser._bytesToIPv6c          #   C   s  |dd }d}t tt& t|dd }t|dd }W dQ R X || jkrVt |t@ |t@  }}|| jks||| jkrt | j| t	krt
j|ddS |t@ |t@  }}	t tt tj|}tj|	}	W dQ R X |tjks|	tjk rt
j|ddS | j| }
|ddtj|
  }|tjkrxt tjt tj|
|\}}W dQ R X t
j|tj|jdtj|jdS d}|	tjkrd}tj}| j}|tjkrtj }| j!}t tjt tj|
|}|\}}}}W dQ R X t
j|||||||||||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IPv6AddressrE   )clslineprefixZaddrInfoZversionCommandZfamilyProtoversionZcommandZfamilyZnetprotoZaddressFormatsourcedestZaddrTypeZaddrClsZ
addrParserr3   ZsPortZdPortr   r   r   r/      sV    



zV2Parser.parseN)r   r   r   r   rJ   rM   rO   _PROXYCOMMANDrN   rQ   r*   r4   staticmethodr>   rE   classmethodr/   r   r   r   r   r    3   s   
r    )r   rC   r-   Z
constantlyr   r   Zzope.interfacer   Ztwisted.internetr   Ztwisted.pythonr   _exceptionsr   r	   r
   r    r   r   r   r   rK   rL   rO   rZ   ZIProxyParserobjectr    r   r   r   r   <module>   s"   	