B
    `$                 @   s   d dl mZ d dlmZ d dlmZmZ ddlmZ ddl	m
Z
mZ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 eeZeedddZdeeedddZG dd deZdS )    )
HTTPStatus)
SSLContext)Tuplecast   )
ProxyError)URLHeadersTimeoutDict)
get_loggerurl_to_origin   )SyncByteStream)SyncHTTPConnection)SyncConnectionPoolResponseByteStream)status_codereturnc             C   s$   y
t | jS  tk
r   dS X d S )N )r   phrase
ValueError)r    r   H/home/dcms/DCMS/lib/python3.7/site-packages/httpcore/_sync/http_proxy.pyget_reason_phrase   s    
r   N)default_headersoverride_headersr   c                sL   | dkrg n| } |dkrg n|}t dd |D   fdd| D } | | S )zj
    Append default_headers and override_headers, de-duplicating if a key existing in
    both cases.
    Nc             S   s   g | ]\}}|  qS r   )lower).0keyvaluer   r   r   
<listcomp>   s    z!merge_headers.<locals>.<listcomp>c                s$   g | ]\}}|   kr||fqS r   )r   )r   r   r   )has_overrider   r   r    !   s   )set)r   r   r   )r!   r   merge_headers   s    
r#   c                   s   e Zd ZdZdeeeeeee	e
eed
 fddZdeeeeeeeeeef d	d
dZdeeeeeeeeeef d	ddZdeeeeeeeeeef d	ddZ  ZS )SyncHTTPProxyaZ  
    A connection pool for making HTTP requests via an HTTP proxy.

    **Parameters:**

    * **proxy_url** - `Tuple[bytes, bytes, Optional[int], bytes]` - The URL of
    the proxy service as a 4-tuple of (scheme, host, port, path).
    * **proxy_headers** - `Optional[List[Tuple[bytes, bytes]]]` - A list of
    proxy headers to include.
    * **proxy_mode** - `str` - A proxy mode to operate in. May be "DEFAULT",
    "FORWARD_ONLY", or "TUNNEL_ONLY".
    * **ssl_context** - `Optional[SSLContext]` - An SSL context to use for
    verifying connections.
    * **max_connections** - `Optional[int]` - The maximum number of concurrent
    connections to allow.
    * **max_keepalive_connections** - `Optional[int]` - The maximum number of
    connections to allow before closing keep-alive connections.
    * **http2** - `bool` - Enable HTTP/2 support.
    NDEFAULTFsync)
	proxy_urlproxy_headers
proxy_modessl_contextmax_connectionsmax_keepalive_connectionskeepalive_expiryhttp2backendmax_keepalivec          	      sL   |dkst t|| _|d kr"g n|| _|| _t j||||||	|
d d S )N)r%   FORWARD_ONLYZTUNNEL_ONLY)r*   r+   r,   r-   r.   r/   r0   )AssertionErrorr   proxy_originr(   r)   super__init__)selfr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   )	__class__r   r   r5   =   s    
zSyncHTTPProxy.__init__)methodurlheadersstreamextr   c             C   s   | j d k	r|   | jdkr(|d dks2| jdkr\td| j| j|| | j|||||dS td| j| j|| | j|||||dS d S )Nr%   r   s   httpr1   zAforward_request proxy_origin=%r proxy_headers=%r method=%r url=%r)r:   r;   r<   z@tunnel_request proxy_origin=%r proxy_headers=%r method=%r url=%r)	Z_keepalive_expiryZ_keepalive_sweepr)   loggertracer3   r(   _forward_request_tunnel_request)r6   r8   r9   r:   r;   r<   r   r   r   requestZ   s(    

zSyncHTTPProxy.requestc             C   s   |dkri n|}t t|di }| j}| |}|dkrXt|| j| jd}| || |\}	}
}}|dkr|d|	|
|f }nd|	|
||f }| j|f }t	| j
|}|j|||||d\}}}}t||| jd}||||fS )zx
        Forwarded proxy requests include the entire URL as the HTTP target,
        rather than just the path.
        Ntimeout)originr.   r*   s	   %b://%b%bs   %b://%b:%d%b)r:   r;   r<   )
connectioncallback)r   r
   getr3   _get_connection_from_poolr   _http2_ssl_context_add_to_poolr#   r(   rA   r   _response_closed)r6   r8   r9   r:   r;   r<   rB   rC   rD   schemehostportpathtargetr   wrapped_streamr   r   r   r?      s&    
zSyncHTTPProxy._forward_requestc             C   s^  |dkri n|}t t|di }t|}| |}|dkr&|\}	}
}t| j| j| jd}d|
|f }| j|f }d|fdg}t	|| j
}|jd|||d\}}}}t|}td	|| x|D ]}qW |d
k s|dkrd||f }t||	dkr||
| t|| j| j|jd}| || |j|||||d\}}}}t||| jd}||||fS )z
        Tunnelled proxy requests require an initial CONNECT request to
        establish the connection, and then send regular requests.
        NrB   )rC   r.   r*   s   %b:%ds   Host)s   Accepts   */*s   CONNECT)r:   r<   z5tunnel_response proxy_status_code=%r proxy_reason=%r    i+  z%d %ss   https)rC   r.   r*   socket)r:   r;   r<   )rD   rE   )r   r
   rF   r   rG   r   r3   rH   rI   r#   r(   rA   r   r=   r>   r   Z	start_tlsrS   rJ   r   rK   )r6   r8   r9   r:   r;   r<   rB   rC   rD   rL   rM   rN   Zproxy_connectionrP   Zconnect_urlZconnect_headersZproxy_status_code_Zproxy_streamZproxy_reasonmsgr   rQ   r   r   r   r@      sV    






zSyncHTTPProxy._tunnel_request)	Nr%   NNNNFr&   N)NNN)NNN)NNN)__name__
__module____qualname____doc__r   r	   strr   intfloatboolr5   bytesr   dictr   rA   r?   r@   __classcell__r   r   )r7   r   r$   (   s,           &  #  ,  r$   )NN)httpr   sslr   typingr   r   _exceptionsr   _typesr   r	   r
   _utilsr   r   baser   rD   r   Zconnection_poolr   r   rV   r=   r[   rZ   r   r#   r$   r   r   r   r   <module>   s   