U
    ˆjñ  ã                   @   sà   d Z ddlZddlZddl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 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ÚTupleÚTypeÚUnion)Úimplementer)ÚValueConstantÚValues)ÚLiteral)Ú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   ÚUNSPECZINETÚINET6ÚUNIX© r   r   úG/tmp/pip-unpacked-wheel-j5h_c8_q/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                   @   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d„Z
eeeejef ed f dœdd„Zeeedœdd„ƒZeeedœdd„ƒZeeejdœ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   N)Úreturnc                 C   s
   d| _ d S )Nó    )Úbuffer)Úselfr   r   r   Ú__init__P   s    zV2Parser.__init__©NN)Údatar,   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   r1   Nr-   )r.   Úlenr   ÚstructÚunpackÚparse)r/   r2   ÚsizeÚheaderÚ	remainingÚinfor   r   r   ÚfeedS   s    
zV2Parser.feed)Ú
bytestringr,   c                 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©r=   r   r   r   Ú_bytesToIPv4q   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   s.   | ]&}t ˆ ||d  … dƒd› d¡V  qdS )é   r   Úxr?   N)ÚintrA   rB   ©Z	hexStringr   r   rE   Ž   s   ÿz(V2Parser._bytesToIPv6.<locals>.<genexpr>r   r   rK   )ÚbinasciiÚb2a_hexrF   ÚrangerH   r   rN   r   Ú_bytesToIPv6�   s    

þzV2Parser._bytesToIPv6)Úliner,   c              	   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r‚tƒ ‚| j| t	kržt
 |dd¡S |t@ |t@  }}	t ttƒ� t |¡}t |	¡}	W 5 Q R X |tjksð|	tjk� rþt
 |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�rŒd}tj}| j}|tjk�r°t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é   é   r3   r   ó    ZTCPZUDP)#r   Ú
IndexErrorr   r@   ÚPREFIXÚ_HIGHÚ_LOWÚVERSIONSÚCOMMANDSÚ_LOCALCOMMANDr   Ú	ProxyInfoÚ
ValueErrorr   r   ZlookupByValuer    r   ÚADDRESSFORMATSr5   Úcalcsizer   Úerrorr   r6   r
   ZUNIXAddressÚrstripr"   ÚIPv4AddressrI   r   ÚIPv6AddressrR   Údecode)ÚclsrS   ÚprefixZaddrInfoZversionCommandZfamilyProtoÚversionÚcommandÚfamilyZnetprotoZaddressFormatÚsourceÚdestZaddrTypeZaddrClsZ
addrParserr;   ZsPortZdPortr   r   r   r7   “   sZ    


ýþýzV2Parser.parse)r   r   r   r   rX   r[   r]   Ú_PROXYCOMMANDr\   r`   r0   Úbytesr   r   r   r^   r<   ÚstaticmethodrI   rR   Úclassmethodr7   r   r   r   r   r%   9   s*   
÷þr%   )#r   rO   r5   Útypingr   r   r   r   Zzope.interfacer   Z
constantlyr   r   Ztyping_extensionsr	   Ztwisted.internetr
   Ztwisted.pythonr   Ú r   r   Ú_exceptionsr   r   r   r   r   r    rY   rZ   r]   rn   ZIProxyParserr%   r   r   r   r   Ú<module>   s$   
