B
    u9a+  ã               @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ	m
Z
mZ d dlmZ e j e¡ZejZe j ed¡ZG dd„ de	ƒZG dd„ de
ƒZG d	d
„ d
eƒZG dd„ dejƒZdeeddœdd„Zedkrd dlZejddZejdde ddd ejddddddd ejdd d!d"d#d$d ejd%d&e!d'd(d) ejd*d+e!d,d- ejd.d/e!d'd0d) e "¡ Z#e#j$e_$e#j%r|eZ&neZ&e  '¡ e&_(e )ej*j+¡Z,e, -e¡ e#j.r¶e, /e#j.¡ e#j0rÊe, 1e#j0¡ e#j2rÞe, 3e#j2¡ ed1e#j4fe&e,ƒZ5e#j$re6d2 7e#¡ƒ e5 8d3¡ dS )4é    N)Ú
HTTPServerÚSimpleHTTPRequestHandlerÚBaseHTTPRequestHandler)Úsupportzkeycert.pemc               @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚHTTPSServerc             C   s   t  | ||¡ || _d S )N)Ú_HTTPServerÚ__init__Úcontext)ÚselfÚserver_addressÚhandler_classr	   © r   ú!/usr/lib/python3.7/ssl_servers.pyr      s    zHTTPSServer.__init__c             C   s   d| j j| j| jf S )Nz
<%s %s:%s>)Ú	__class__Ú__name__Zserver_nameÚserver_port)r
   r   r   r   Ú__str__   s    zHTTPSServer.__str__c          
   C   sf   y"| j  ¡ \}}| jj|dd}W n: tk
r\ } ztjrJtj 	d| ¡ ‚ W d d }~X Y nX ||fS )NT)Zserver_sidezGot an error:
%s
)
ZsocketZacceptr	   Zwrap_socketÚOSErrorr   ÚverboseÚsysÚstderrÚwrite)r
   ÚsockZaddrZsslconnÚer   r   r   Úget_request    s    zHTTPSServer.get_requestN)r   Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r      s   r   c               @   s(   e Zd ZdZeZdZdd„ Zdd„ ZdS )ÚRootedHTTPRequestHandlerzTestHTTPS/1.0é   c             C   s~   t j |¡d }tj t j |¡¡}| d¡}td|ƒ}| j	}x:|D ]2}tj 
|¡\}}tj |¡\}}tj ||¡}qDW |S )zñTranslate a /-separated PATH to the local filename syntax.

        Components that mean special things to the local file system
        (e.g. drive or directory names) are ignored.  (XXX They should
        probably be diagnosed.)

        é   ú/N)ÚurllibÚparseZurlparseÚosÚpathÚnormpathZunquoteÚsplitÚfilterÚrootÚ
splitdriveÚjoin)r
   r$   ZwordsZwordZdriveÚheadr   r   r   Útranslate_path6   s    	


z'RootedHTTPRequestHandler.translate_pathc          	   G   s:   t jr6tj d| jj| jj| j 	¡ |  
¡ || f ¡ d S )Nz server (%s:%d %s):
   [%s] %s
)r   r   r   Ústdoutr   Úserverr   r   ZrequestÚcipherZlog_date_time_string)r
   ÚformatÚargsr   r   r   Úlog_messageJ   s    z$RootedHTTPRequestHandler.log_messageN)	r   r   r   Úserver_versionÚherer(   Ztimeoutr,   r2   r   r   r   r   r   ,   s
   r   c               @   s.   e Zd ZdZdZddd„Zdd„ Zdd	„ Zd
S )ÚStatsRequestHandlerzSExample HTTP request handler which returns SSL statistics on GET
    requests.
    zStatsHTTPS/1.0Tc             C   s‚   | j jj}|j}| ¡ | ¡ | ¡ dœ}t |¡}| 	d¡}|  
d¡ |  dd¡ |  dtt|ƒƒ¡ |  ¡  |r~| j |¡ dS )zServe a GET request.)Zsession_cacher/   Úcompressionzutf-8éÈ   zContent-typeztext/plain; charset=utf-8zContent-LengthN)ZrfileÚrawZ_sockr	   Zsession_statsr/   r6   ÚpprintZpformatÚencodeZsend_responseZsend_headerÚstrÚlenZend_headersZwfiler   )r
   Ú	send_bodyr   r	   ZstatsZbodyr   r   r   Údo_GET\   s    



zStatsRequestHandler.do_GETc             C   s   | j dd dS )zServe a HEAD request.F)r=   N)r>   )r
   r   r   r   Údo_HEADn   s    zStatsRequestHandler.do_HEADc             G   s   t jrtj| |f|žŽ  d S )N)r   r   r   Úlog_request)r
   r0   r1   r   r   r   r@   r   s    zStatsRequestHandler.log_requestN)T)r   r   r   Ú__doc__r3   r>   r?   r@   r   r   r   r   r5   U   s
   
r5   c               @   s<   e Zd Zedfdd„Zdd„ Zddd„Zdd	„ Zd
d„ ZdS )ÚHTTPSServerThreadNc             C   s<   d | _ t|df|pt|ƒ| _| jj| _tj | ¡ d| _	d S )Nr   T)
Úflagr   r   r.   r   ÚportÚ	threadingÚThreadr   Zdaemon)r
   r	   Úhostr   r   r   r   r   y   s    
zHTTPSServerThread.__init__c             C   s   d| j j| jf S )Nz<%s %s>)r   r   r.   )r
   r   r   r   r   ‚   s    zHTTPSServerThread.__str__c             C   s   || _ tj | ¡ d S )N)rC   rE   rF   Ústart)r
   rC   r   r   r   rH   …   s    zHTTPSServerThread.startc             C   s2   | j r| j  ¡  z| j d¡ W d | j ¡  X d S )Ngš™™™™™©?)rC   Úsetr.   Úserve_foreverZserver_close)r
   r   r   r   Úrun‰   s
    
zHTTPSServerThread.runc             C   s   | j  ¡  d S )N)r.   Zshutdown)r
   r   r   r   Ústop‘   s    zHTTPSServerThread.stop)N)	r   r   r   ÚHOSTr   r   rH   rK   rL   r   r   r   r   rB   w   s
   	
rB   )r	   ÚcertfilerG   r   c               s`   |d krt  t jj¡}| |¡ t|||ƒ‰ t ¡ }ˆ  |¡ | 	¡  ‡ fdd„}|  
|¡ ˆ S )Nc                  s8   t jrtj d¡ ˆ  ¡  t jr,tj d¡ ˆ  ¡  d S )Nzstopping HTTPS server
zjoining HTTPS thread
)r   r   r   r-   r   rL   r*   r   )r.   r   r   ÚcleanupŸ   s    z"make_https_server.<locals>.cleanup)ÚsslÚcreate_default_contextÚPurposeÚCLIENT_AUTHÚload_cert_chainrB   rE   ZEventrH   ÚwaitZ
addCleanup)Zcaser	   rN   rG   r   rC   rO   r   )r.   r   Úmake_https_server•   s    


rV   Ú__main__zERun a test HTTPS server. By default, the current directory is served.)Údescriptionz-pz--portiQ  z(port to listen on (default: %(default)s))ÚtypeÚdefaultÚhelpz-qz--quietr   TÚstore_falsezbe less verbose)ÚdestrZ   Úactionr[   z-sz--statsÚuse_stats_handlerFÚ
store_truezalways return stats pagez--curve-nameÚ
curve_nameÚstorez&curve name for EC-based Diffie-Hellman)r]   rY   r^   r[   z	--ciphersÚcipherszallowed cipher list)r]   rY   r[   z--dhÚdh_filez!PEM file containing DH parametersÚ z'Listening on https://localhost:{0.port}gš™™™™™¹?)9r#   r   rP   r9   rE   Zurllib.parser!   Zhttp.serverr   r   r   r   Ztestr   r$   ÚdirnameÚ__file__r4   rM   r*   ZCERTFILEr   r   r5   rF   rB   rV   r   ÚargparseÚArgumentParserÚparserÚadd_argumentÚintr;   Ú
parse_argsr1   r   r_   r   Úgetcwdr(   rQ   rR   rS   r	   rT   ra   Zset_ecdh_curverd   Zload_dh_paramsrc   Zset_ciphersrD   r.   Úprintr0   rJ   r   r   r   r   Ú<module>   sf   )"






