
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
;jE                 @   s   d dl Z d dlZd dlZd dlZd dlmZ ddlmZmZmZm	Z	m
Z
 ddlmZmZmZmZmZmZ dd Zdd	d
Zdd Zdd ZdddZdd Zdd Ze Ze
jeddddZdS )    N)SSLError   )config	constantserrors	log_utilsutils)	HTTPErrorRequestURLErrorhttplibstd_urlopenurlparsec       	      O   s  t | dr| j }n| }t| } |jdi }|jtjtjd x |j D ]\}}| j	|| qJW t
jdj|| ydd|krtj|d< tj rttdd rtj }d|_tj|_||d< t| f||S t| f||S  tk
r& } z0|jd	krtj|j|j|j|j|j W Y d d }~X n~ tk
r } z`|j r|t |j d
 dr||j d
 j!t!j"kr|tj| d	t#|d d dj|||_$||_ W Y d d }~X nX d S )Nget_full_urlheaders)z
KC-VersionzKC-Patch-Versionz#Requesting url: `{0}`. Headers: {1}timeoutHAS_SNIFcontexti  r   errnozRequest for `{0}` failed: {1})%hasattrr   r
   popupdater   VERSIONKC_PATCH_VERSIONitems
add_headerr   logdebugformatr   HTTP_TIMEOUTCHECK_SSL_CERTSgetattrsslcreate_default_contextcheck_hostname	CERT_NONEverify_moder   r	   coder   NotFoundurlmsghdrsfpr   argsr   ENOENTstrreason)	r(   r,   kwargsZrequest_urlr   headervaluectxex r5   0/usr/libexec/kcare/python/kcarectl/http_utils.pyurlopen_base   s>    


.r7   Tc                s    fdd}|S )Nc                sb   t | tr o| jdkS t | ttjttjfr2dS t	| dr^t
| jdkr^| jd tjkr^dS d S )Ni  Tr,      r   )
isinstancer	   r&   r   r   HTTPExceptionr   socketr   r   lenr,   r   Z
ECONNRESET)estate)retry_on_500r5   r6   check_functionC   s    
(z3check_urlopen_retry_factory.<locals>.check_functionr5   )r?   r@   r5   )r?   r6   check_urlopen_retry_factoryB   s    	rA   c             C   s   t | dr| j } | jdS )Nr   zfile:)r   r   
startswith)r(   r5   r5   r6   is_local_urlO   s    
rC   c             O   sV   |j dd}|j dtj}t| r2t| f||S tjt|d|dt| f||S )Nr?   Tretry_count)r?   )count)r   r   RETRY_COUNTrC   r7   r   retryrA   )r(   r,   r0   r?   rD   r5   r5   r6   urlopenU   s
    rH   c             C   sH   t | |d}tj r*|r*|jddj| tj rD|rD|jtj| |S )N)methodAuthorizationz	Basic {0})r
   r   UPDATE_FROM_LOCALr   r   r   AUTH_TOKEN_HEADER)r(   auth_string
auth_tokenrI   requestr5   r5   r6   http_request]   s    rP   c             C   s<   | dkrt jdpt jdS | dkr8t jdp6t jdS d S )NhttpZ
http_proxyZ
HTTP_PROXYhttpsZhttps_proxyZHTTPS_PROXY)osgetenv)schemer5   r5   r6   get_proxy_from_envh   s    rV   c               C   s   t tdpt tdS )NrQ   rR   )boolrV   r5   r5   r5   r6   proxy_is_usedo   s    rX   )Zcheck_retryc             C   s  t jj| }|stdj| ttj|}|j}|j	}|jp@d}|dkrRtd|dkrl|j
dkrhdnd}|j
dkr~tj}n|j
dkrtj}ntd	|||tjd
}	i }
|rdj||
d< d|
d< t||
d< tj|
d< z|	jd| x |
j D ]\}}|	j|| qW |	j  t| d}|	j| W dQ R X |	j }|jdkry|j }W n tk
rn   d}Y nX dj|j}|dk	r|dj|7 }tj| t||j|ddW d|	j   X dS )a  Upload a file to the given URL using HTTP PUT with chunked streaming.
    Note: The standard library urllib doesn't support PUT with data
    We need to use httplib directly for this

    This function uses streaming upload to support large files up to 1GB
    without loading the entire file into memory.

    :param file_path: Path to the file to upload
    :param upload_url: Full URL to upload the file to. Query params are ignored.
    :param auth_string: Optional authentication string for Basic Auth
    :return: None if upload succeeded
    :raises HTTPError: If upload fails with HTTP status >= 400
    :raises ValueError: If URL is invalid
    z"Refusing to upload empty file: {0}/NzInvalid URL: missing hostnamerR   i  P   rQ   zInvalid URL: unsupported scheme)r   z	Basic {0}rJ   zapplication/octet-streamzContent-TypezContent-Lengthz
KC-VersionPUTrbi  zFailed to upload file: HTTP {0}z - {0})!rS   pathgetsize
ValueErrorr   r   r   nstrhostnameportrU   r   HTTPConnectionHTTPSConnectionr   HTTP_UPLOAD_TIMEOUTr.   r   r   
putrequestr   	putheader
endheadersopensendgetresponsestatusread	Exceptionr   logerrorr	   close)Z	file_path
upload_urlrM   Z	file_sizeparsedhostrb   Zurl_pathZconn_clsconnr   r1   r2   fresponseZ
error_body	error_msgr5   r5   r6   upload_filev   sT    






rx   )T)NN)N)r   rS   r;   r!   r    r   r   r   r   r   py23r	   r
   r   r   r   r   r7   rA   rC   rH   rP   rV   rX   check_urlopen_retryrG   rx   r5   r5   r5   r6   <module>   s     0


