
    #&ap                        d Z 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ZddlZddl	Z	ddl
Z
ddlmZ ddlmZ ddlZddlmZ ddlmZ ddlmZmZ  G d d	ej.                        Z G d
 dej2                        Zd Ze
j8                  e
j:                  e
j<                  z  e
j>                  z  e
j@                  z  e
j:                  e
j<                  z  e
j>                  z  e
j@                  z  e
jB                  z  e
j:                  e
j<                  z  e
j>                  z  e
j@                  z  e
jB                  z  e
jD                  z  dZ#d Z$d Z% G d dee      Z&e'dk(  r e%        yy)aV  
A WebSocket to TCP socket proxy with support for "wss://" encryption.
Copyright 2011 Joel Martin
Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)

You can make a cert/key with openssl using:
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
as taken from http://docs.python.org/dev/library/ssl.html#certificates

    N)ThreadingMixIn)
HTTPServer)websockifyserver)auth_plugins)parse_qsurlparsec                   8    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
y	)
ProxyRequestHandler   z
Traffic Legend:
    }  - Client receive
    }. - Client receive partial
    {  - Target receive

    >  - Target send
    >. - Target send partial
    <  - Client send
    <. - Client send partial
c                     | j                  |j                  |j                         | j                  dd       |j                  j                         D ]  \  }}| j                  ||        | j                          y )NzContent-Typez	text/html)send_responsecodemsgsend_headerheadersitemsend_headers)selfexnamevals       ;/usr/lib/python3/dist-packages/websockify/websocketproxy.pysend_auth_errorz#ProxyRequestHandler.send_auth_error'   sh    277BFF+5))+ 	(ID#T3'	( 	    c                     | j                   j                  sy | j                  | j                   j                        \  }}|dk(  r|| j                   _        y || j                   _        || j                   _        y )Nunix_socket)servertoken_plugin
get_targetunix_targettarget_hosttarget_port)r   hostports      r   validate_connectionz'ProxyRequestHandler.validate_connection/   s\    {{''__T[[%=%=>
d= &*DKK# '+DKK#&*DKK#r   c                 B   | j                   j                  sy 	 | j                  j                         }|d   }t	        |D cg c]  }|d   	 c}      }|d   | j
                  d<   	 | j                   j                  j                  | j
                  | j                   j                  | j                   j                         y c c}w # t        t        t        f$ r Y ww xY w# t        j                  $ r* t        j                         d   }| j!                  |        w xY w)Nsubjectr   
commonNameSSL_CLIENT_S_DN_CN)r   r!   r"      )r   auth_pluginrequestgetpeercertdictr   	TypeErrorAttributeErrorKeyErrorauthenticater!   r"   authAuthenticationErrorsysexc_infor   )r   client_cert_dataclient_cert_subjectxr   s        r   auth_connectionz#ProxyRequestHandler.auth_connection;   s    {{&&	#||779"29"="&6I'J!'J"K1D\1RDLL-.
	KK##00$++2I2I KK33 1 5 (K >84 		 '' 	"B  $	s0   (C CC 'AC! C CC!=Dc                    | j                   j                  rAddj                  | j                   j                        d| j                   j                  d}n`| j                   j                  rd| j                   j                  z  }n0d| j                   j
                  d| j                   j                  }| j                   j                  r|dz  }| j                  |       	 t        j                  j                  | j                   j
                  | j                   j                  d	| j                   j                  | j                   j                  
      }| j                  j                  t        j                  t        j                   d       | j                   j                  sE| j                   j                  s/|j                  t        j                  t        j                   d       | j#                  | j$                         	 | j'                  |       |rx|j)                  t        j*                         |j-                          | j.                  r<| j                  d| j                   j
                  | j                   j                         yyy# t        $ rS}| j                  d| j                   j
                  | j                   j                  |       | j                  dd      d}~ww xY w# |rx|j)                  t        j*                         |j-                          | j.                  r<| j                  d| j                   j
                  | j                   j                         w w w xY w)zO
        Called after a new WebSocket connection has been established.
        zconnecting to command: ' ' (port )zconnecting to unix socket: %szconnecting to: : (using SSL)T)connectuse_sslr   zFailed to connect to %s:%s: %si  z&Failed to connect to downstream serverNr*   z%s:%s: Closed target)r   wrap_cmdjoinr"   r    r!   
ssl_targetlog_messager   WebSockifyServersocket	ExceptionCCloser,   
setsockoptSOL_TCPTCP_NODELAYprint_traffictraffic_legenddo_proxyshutdown	SHUT_RDWRcloseverbose)r   r   tsockes       r   new_websocket_clientz(ProxyRequestHandler.new_websocket_clientU   s    ;;=@XXdkkFZFZ=[]a]h]h]t]tuC[[$$1DKK4K4KKC % %)KK$;$;T[[=T=TVC ;;!!>!C		N$55<<T[[=T=T;?;;;R;RCGCG;;CYCYGK{{G^G^	 = `E 	0B0BAF{{##DKK,C,CV^^V-?-?C4../	NMM% v//0<<$$%; KK33T[[5L5LN     	N=![[44dkk6M6MqR++d$LMM	N v//0<<$$%; KK33T[[5L5LN   s'   %A4J 	K4 	K1AK,,K14A<M0c                    | j                   r2| j                  j                  d      }|rb|j                  d      d   }nMt	        t        | j                        d         }d|v r&t        |d         r|d   d   j                  d      }nd}|| j                  j                  d      |j                  |      }||S | j                  j                  d	|z        )
z
        Gets a token from either the path or the host,
        depending on --host-token, and looks up a target
        for that token using the token plugin. Used by
        validate_connection() to set target_host and target_port.
        Hostr?   r      token
NzToken not presentzToken '%s' not found)
host_tokenr   get	partitionr   r   pathlenrstripr   ECloselookup)r   target_pluginr[   argsresult_pairs        r   r   zProxyRequestHandler.get_target   s     ??LL$$V,E
 ,Q/ HTYY/23D$3tG}#5Wa(//5=++$$%899#**51"++$$%;e%CDDr   c                    g }d}g }| j                   |g}| j                  j                  r3t        j                         }|| j                  j                  z   | _        nd| _        	 g }| j                  Qt        j                         }|| j                  kD  r.|| j                  j                  z   | _        | j	                          |r|j                  |       |s|r|j                  | j                          	 t        j                  ||g d      \  }}	}
|
rt        d      | j                   |	v r| j                  |      }g }| j                   |v r| j!                         \  }}|j#                  |       |r_| j$                  r;| j'                  d| j                  j(                  | j                  j*                         | j-                  |d   |d         ||	v rh|j/                  d      }|j1                  |      }|t3        |      k(  r| j5                  d	       n&|j7                  d||d        | j5                  d
       ||v r|j9                  | j:                        }t3        |      dk(  rY| j$                  r;| j'                  d| j                  j(                  | j                  j*                         | j-                  dd      |j                  |       | j5                  d       # t        j                  t        f$ rM t        j                         d   }t        |d      r|j                  }n|d   }|t        j                  k7  r Y w xY w)zA
        Proxy client WebSocket to normal target socket.
        r   Nr*   errnozSocket exceptionz%s:%s: Client closed connectionr   reason>z.>z%s:%s: Target closed connectioni  zTarget closed{)r,   r   	heartbeattime	send_pingappendselecterrorOSErrorr5   r6   hasattrri   EINTRrI   send_framesrecv_framesextendrT   rF   r!   r"   rJ   popsendra   rN   insertrecvbuffer_size)r   targetcqueuec_pendtqueuerlistnowwlistinsoutsexceptsexcerrbufscloseddatsentbufs                     r   rP   zProxyRequestHandler.do_proxy   s    v&;;  ))+C 4;;#8#88DN!DNE~~)iik'%(4;;+@+@%@DNNN$u||F+dll!;%+]]5%Q%G"T7 i(:;;||t#))&1||s"#//1fd#||(()J $ 7 79P9PR++fVnfX6FGG ~jjm{{3'3s8#&&s+ MM!SZ0&&t, }kk$"2"23s8q=||(()J $ 7 79P9PR++dO<<c"""3'I  LL'* 
llnQ'3())Ca&C%++%
s   8K+ +A"MMN)__name__
__module____qualname__r}   rO   r   r%   r:   rW   r   rP    r   r   r
   r
      s1    K
N
+4-N^%ENS(r   r
   c                   <     e Zd ZdZdZef fd	Zd Zd Zd Z	 xZ
S )WebSocketProxyza
    Proxy traffic to and from a WebSockets client to a normal TCP
    socket server target.
    r   c                    |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  d	d       | _	        |j                  d
d       | _
        g d| _        | j                  rt        j                  j                  t        j                   d         }t        j                  j#                  |dd      t        j                  j#                  |ddd      t        j                  j#                  |d      |g}d | _        |D ]J  }t        j                  j#                  |d      }t        j                  j'                  |      sC|| _         n | j$                  st)        d      t        j                  j+                  | j$                        | _        d| _        t-        j,                  t,        j.                  t,        j0                        }|j3                  d       |j5                         d   | _        |j7                          t        j8                  j;                  | j$                  t=        |d         t=        | j                        d       t?        	|   |g|i | y )Nr!   r"   rC   	wrap_moder    rE   rm   r   r]   r+   )r   r   r   r   z..lib
websockifyz	rebind.soz1rebind.so not found, perhaps you need to run makez	127.0.0.1) r   r*   listen_port)
LD_PRELOADREBIND_OLD_PORTREBIND_NEW_PORT)!ry   r!   r"   rC   r   r    rE   rm   r   r]   r+   
wrap_timesosr`   dirnamer5   argvrD   rebinderexistsrI   abspathrH   AF_INETSOCK_STREAMbindgetsocknamerS   environupdatestrsuper__init__)
r   RequestHandlerClassrf   kwargswsdirrebinder_pathrdirrpathsock	__class__s
            r   r   zWebSocketProxy.__init__  s?   $jj=$jj=$jjT:$jjd;$jj=$jjt<$jjd;"JJ~t< **\48!::mT: '==GGOOCHHQK0EWW\\%u=WW\\%ulKWW\\%6"$M !DM% T;777>>%($)DM	 == STTGGOODMM:DM*D==1C1CDDIIg#//1!4DJJLJJ"mm#&vm'<#=#&t'7'7#8: ;
 	,>t>v>r   c                 j   | j                  ddj                  | j                               | j                  j	                  t        j
                                | j                  j                  d       t        j                  | j                  t        j                  t              | _        d| _        y )NzStarting '%s'r<   r   )env
preexec_fnT)r   rD   rC   r   rp   rn   ry   
subprocessPopenr   r   _subprocess_setupcmdspawn_message)r   s    r   run_wrap_cmdzWebSocketProxy.run_wrap_cmd9  sr    #((4=="9:tyy{+A##2:::KM!r   c                 ,   | j                   r-ddj                  | j                         d| j                  d}n4| j                  r| j                  }n| j                  d| j                  }| j
                  dk7  rd}n| j                  d| j                  }| j                  r&d|d	t        | j                        j                  }nd|d
|}| j                  r|dz  }| j                  d|       | j                   r| j                          yy)zO
        Called after Websockets server startup (i.e. after daemonize)
        'r<   r=   r>   r?   Ninetdz  - proxying from z to targets generated by z to r@   z%s)rC   rD   r"   r    r!   	listen_fdlisten_hostr   r   typer   rE   r   r   )r   
dst_string
src_stringr   s       r   startedzWebSocketProxy.startedA  s     ==-0XXdmm-DdFVFVWJ))J$($4$4d6F6FGJ>>T! J$($4$4d6F6FGJD!2!23<<>C 
 J(C ??>!Cs== r   c                 f   | j                   rF| j                  r:| j                  j                         }|d k7  r| j                  d|z         d | _        | j                   r| j                  d k(  r| j                  dk(  ry | j                  dk(  rt        j                         y | j                  dk(  r~t        j                         }t        | j                        t        | j                        z  }||z
  dk  r&| j                  r| j                  d       d| _        y y | j                          y y y y )Nz/Wrapped command exited (or daemon). Returned %signoreexitrespawn
   zCommand respawning too fastF)rC   r   pollvmsgr   r5   r   rn   sumr   ra   r   warnr   )r   retr   avgs       r   r   zWebSocketProxy.pollb  s     ==TXX((--/Cd{		KcQR==TXX-~~)6)9,iik$//*3t+??#I#))		"?@-2* * %%' - .=r   )r   r   r   __doc__r}   r
   r   r   r   r   __classcell__r   s   @r   r   r      s(    
 K+> /?b" B(r   r   c                  h    t        j                   t         j                  t         j                         y )N)signalSIGPIPESIG_DFLr   r   r   r   r   }  s     MM&..&..1r   defaulttlsv1_1tlsv1_2tlsv1_3c                    | t         v r	t         |    S t        t         j                               }|j                          |d   }t	        j
                  t        j                        }|j                  d| |       t         |   S )zXReturns SSL options for the most secure TSL version available on this
    Python versionz.TLS version %s unsupported. Falling back to %s)	SSL_OPTIONSlistkeyssortlogging	getLoggerr   
log_prefixr   )versionr   fallbackloggers       r   select_ssl_versionr     su     +7## K$$&'		8"">#<#<=DX	' 8$$r   c                     t        j                  t        j                        } d| _        | j                  t         j                         t        j                         }|j                  t         j                         t        j                  d      }|j                  |       | j                  |       d}|dz  }|dz  }|dz  }t        j                  |      }|j                  ddd	d
       |j                  dd	d       |j                  ddd       |j                  dddd	d       |j                  dd	d       |j                  dt        dd       |j                  dt        dd       |j                  dd d!"       |j                  d#d d$"       |j                  d%d d&"       |j                  d'd	d(       |j                  d)d	d*       |j                  d+d	d,       |j                  d-dd./       |j                  d0d1d2g d3d4d56       |j                  d7d4d8       |j                  d9d:d       |j                  d;d<d	=       |j                  d>d d?d@A       |j                  dBd	dC       |j                  dDdEdFg dGdHI       |j                  dJdKd	dLdMN       |j                  dOd	dP       |j                  dQddRdST       |j                  dUd dVdWA       |j                  dXd dYdZA       |j                  d[d	d\       |j                  d]d dVd^A       |j                  d_d dYd`A       |j                  dat        ddbdcd       |j                  deddfdgT       |j                  dhd didjA       |j                  dkd	dl       |j!                         \  }}|j"                  r|j$                  s|j'                  dm       |j(                  r|j$                  s|j'                  dn       |j*                  r|j,                  s|j'                  do       |j.                  r|j,                  s|j'                  dp       |j.                  r|j0                  s|j'                  dq       |j2                  r|j4                  s|j'                  dr       t7        |j8                        |_        |`|j<                  rt>        j@                  jC                  |j<                        |_        t        jD                  |j<                        }|j                  t         j                         |j                  |       | j                  |       |`|j4                  r|j4                  jG                  ds      r0|j4                  jI                  dsdt      \  }}		 t        |	      }	||	f}
n)t>        j@                  jC                  |j4                        }
ddvl&m'} |jP                  r|jR                  }n|jT                  } ||
|dw|j2                  x      }|j                  t         j                         |j                  |       | j                  |       |`|`|jV                  r| j                  t         j                         |jX                  r.t>        j@                  jC                  |jX                        |_,        |jX                  rdy|_        |jX                  |_        |`,tZ        j\                  jG                  dz      r|dtd  |_/        nd |_/        t`        jb                  s|jd                  r|j'                  d{       |jf                  rGt>        j@                  ji                  |jj                        s|j'                  d||jj                  z         |jl                  r$tZ        jn                  jq                         |_9        ntu        |      dtk  r|j'                  d}       |jw                  d      }|jG                  ds      dkD  r@|jI                  dsdt      \  |_<        |_=        |jx                  j}                  d~      |_<        nd|c|_<        |_=        	 t        |jz                        |_=        |`6|j^                  s|j~                  s|j$                  rd |_@        d |_A        ntu        |      dtk  r|j'                  d}       |jw                  d      }|jG                  ds      dkD  r@|jI                  dsdt      \  |_@        |_A        |j                  j}                  d~      |_@        n|j'                  d       	 t        |j                        |_A        tu        |      dkD  r |j^                  d k(  r|j'                  d       |j$                  d|j$                  vrd|j$                  z  |_        |j$                  jI                  ddt      \  }}t        |       t        tZ        j                  |   |      } ||j"                        |_        |`|j,                  d|j,                  vrd|j,                  z  |_        |j,                  jI                  ddt      \  }}t        |       t        tZ        j                  |   |      } ||j*                        |_        |`|j                  }|`E|r&t        di |j                  }|j                          y t        di |j                  }|j                          y # tJ        $ r |j'                  du       Y vw xY w# tJ        $ r |j'                  d       Y w xY w# tJ        $ r |j'                  d       Y w xY w)NFz%(message)sz
    %prog [options]z4 [source_addr:]source_port [target_addr:target_port]z/ [source_addr:]source_port -- WRAP_COMMAND_LINE)usagez	--verbosez-v
store_truezverbose messages)actionhelpz	--trafficzper frame trafficz--recordz(record sessions to FILE.[session_number]FILE)r   metavarz--daemonz-Ddaemonz$become a daemon (background process))destr   r   z
--run-oncez-handle a single WebSocket connection and exitz	--timeoutr   z-after TIMEOUT seconds exit when not connected)r   r   r   z--idle-timeoutzEserver exits after TIMEOUT seconds if there are no active connectionsz--certzself.pemzSSL certificate file)r   r   z--keyz$SSL key file (if separate from cert)z--key-passwordzSSL key passwordz
--ssl-onlyz)disallow non-encrypted client connectionsz--ssl-targetz#connect to SSL target as SSL clientz--verify-clientzlrequire encrypted client to present a valid certificate (needs Python 2.7.9 or newer or Python 3.4 or newer)z--cafilezfile of concatenated certificates of authorities trusted for validating clients (only effective with --verify-client). If omitted, system default list of CAs is used.)r   r   z--ssl-versionchoicer   r   storez?minimum TLS version to use (default, tlsv1_1, tlsv1_2, tlsv1_3))r   r   choicesr   r   z--ssl-ciphersz]list of ciphers allowed for connection. For a list of supported ciphers run `openssl ciphers`z--unix-targetzconnect to unix socket targetz--inetdz/inetd mode, receive listening socket from stdin)r   r   z--webDIRz1run webserver on same port. Serve files from DIR.)r   r   r   z
--web-authz+require authentication to access webserver.z--wrap-moder   MODE)r   r   r   z\action to take when the wrapped program exits or daemonizes: exit (default), ignore, respawn)r   r   r   r   z--prefer-ipv6z-6source_is_ipv6z&prefer IPv6 when resolving source_addr)r   r   r   z--libserverz&use Python library SocketServer enginez--target-config
target_cfgzConfiguration file containing valid targets in the form 'token: host:port' or, alternatively, a directory containing configuration files of this form (DEPRECATED: use `--token-plugin TokenFile --token-source  path/to/token/file` instead))r   r   r   z--token-pluginCLASSzxuse a Python class, usually one from websockify.token_plugins, such as TokenFile, to process tokens into host:port pairsz--token-sourceARGz=an argument to be passed to the token plugin on instantiationz--host-tokenzJuse the host HTTP header as token instead of the token URL query parameterz--auth-pluginz|use a Python class, usually one from websockify.auth_plugins, such as BasicHTTPAuth, to determine if a connection is allowedz--auth-sourcez<an argument to be passed to the auth plugin on instantiationz--heartbeatINTERVALz0send a ping to the client every INTERVAL seconds)r   r   r   r   z
--log-filelog_filezFile where logs will be savedz--syslogSERVERz\Log to syslog server. SERVER can be local socket, such as /dev/log, or a UDP host:port pair.z--legacy-syslogzoUse the old syslog protocol instead of RFC 5424. Use this if the messages produced by websockify seem abnormal.z1You must use --token-plugin to use --token-sourcez/You must use --token-plugin to use --host-tokenz/You must use --auth-plugin to use --auth-sourcez,You must use --auth-plugin to use --web-authz$You must use --web to use --web-authz,You must use --syslog to use --legacy-syslogr?   r*   zError parsing syslog port)WebsockifySysLogHandlerr   )addressfacilityidentlegacy	TokenFilez--z6SSL target requested and Python SSL module not loaded.zSSL only and %s not foundzToo few argumentsz[]r   zError parsing listen portzError parsing targetzError parsing target portzToo many arguments.zwebsockify.token_plugins.%szwebsockify.auth_plugins.%sr   )Jr   r   r   r   	propagatesetLevelINFOStreamHandlerDEBUG	FormattersetFormatter
addHandleroptparseOptionParser
add_optionint
parse_argstoken_sourcer   rr   r]   auth_sourcer+   web_authweblegacy_syslogsyslogr   ssl_versionssl_optionsr   r   r`   r   FileHandlercountrsplit
ValueErrorwebsockify.sysloghandlerr  r   
LOG_DAEMONLOG_USERrT   r   r5   r   rC   r   sslrE   ssl_onlyr   certr   stdinfilenor   ra   ry   r   r   stripr    r!   r"   
__import__getattrmodules	libserverLibProxyServer__dict__serve_foreverstart_server)r   stderr_handlerlog_formatterr   parseroptsrf   log_file_handlersyslog_hostsyslog_portsyslog_destr  syslog_facilitysyslog_handlerargtoken_plugin_moduletoken_plugin_clsauth_plugin_moduleauth_plugin_clsr-  r   s                        r   websockify_initrA    s
   ~889FF
OOGLL!**,NGMM*%%m4M.
n% $E	CCE	$$E	>>E""/F
k4#  %
k,$  &
j;V  M
j$,7  9 l<@  B
kQ@  B
&S!&  ' h
'  )
gt7  9
&#  %
l<<  >
n\6  8
'C  D j&>  ? oHi@R  T og6  7 o0&  B
iB<  Y
gtUD  F
l<>  @
mVV1=  > ot&69  ; mL9  ;
',  - &gW  X &e.  / n\7  8 otW\  ] otU.  / m#q*C  E
lF0  2 j$>  ? '\  ] $$&LT4
 !2!2HIt00FG 0 0FG}}T--CD}}TXX;<$++CD *$*:*:;D }}6"..t}}=!!'--0%%m4*+{{;;S!'+{{'9'9#q'A$K:!+. '4K ''//$++6KD ;;5@@O5>>O 1:I7C8<8J8JL 	.##M2.)||& ''//$//:' OO
xx~~dQRDOOMN}}RWW^^DII60499<=zz))+t9q=LL,-hhqk99S>A14C1C.Dd.#//55d;D13S.Dd.	6"4#3#34D 	
}}((D,=,=t9q=LL,-hhqk99S>A14C1C.Dd.#//55d;DLL/0	6"4#3#34D 4y1}$.)*$d'''-0A0AA  150A0A0H0Ha0P--&'"3;;/B#CEUV,T->->?#d&&&;d>N>NND.2.>.>.E.Ec1.M+O%&!#++.@"A?S*4+;+;< I0$--0  0$--0E  :89:F  	6LL45	6(  	6LL45	6s6   l l" m ll"m ?m m! m!c                   0     e Zd ZdZef fd	Z fdZ xZS )r.  zX
    Just like WebSocketProxy, but uses standard Python SocketServer
    framework.
    c                    |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  dd       | _        |j                  d	d       | _	        d | _        d | _        d
| _
        |j                  dd      }|j                  dd       }|j                  dd      }| | _        |j                  dd
      | _        |j                  dd      }|r$t        j                  j                  |      | _        |j                  dd
      | _        d| _        |j'                         D ]  }t)        d|z          |rt        j*                  |       t,        | ]  ||f|       y )Nr!   r"   rC   r   r    rE   r   r+   rm   Fr   r   r   r  rT   recordrun_oncer   z1warning: option %s ignored when using --libserver)ry   r!   r"   rC   r   r    rE   r   r+   rm   r   only_upgraderT   r   r`   r   rD  rE  
handler_idr   printchdirr   r   )	r   r   r   r   r   r  rD  r<  r   s	           r   r   zLibProxyServer.__init__  s   $jj=$jj=$jjT:$jjd;$jj=$jjt<$jj>$jj=$jjd;   M26M48E2. #&gIu5Hb)''//&1DKJ6;;= 	MCEKL	M HHSM+{35HIr   c                 P    | xj                   dz  c_         t        | 	  ||       y)z/Override process_request to implement a counterr*   N)rG  r   process_request)r   r,   client_addressr   s      r   rK  zLibProxyServer.process_request  s     18r   )r   r   r   r   r
   r   rK  r   r   s   @r   r.  r.    s    
 ,? $JN9 9r   r.  __main__)(r   r   rH   r  rn   r   r5   r   r   ri   r$  socketserverr   http.serverr   rq   r   r   r   r3   urllib.parser   r   WebSockifyRequestHandlerr
   rG   r   r   OP_ALLPROTOCOL_SSLv23OP_NO_SSLv2OP_NO_SSLv3OP_NO_TLSv1OP_NO_TLSv1_1OP_NO_TLSv1_2r   r   rA  r.  r   r   r   r   <module>rY     s>  	 P O O O O ' "  ' + +g(*CC g(Rz(%66 z(z2 zz""S__4sFOO""S__4sFOO''(""S__4sFOO''(*-*;*;<%"Zz09^Z 09f z r   