+
    ]f*y  c            	       sD   R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIHt ^ RIHt ^ RIt^ RIHt ^ RIHt ^ RIHtHt  ! R R]P0                  4      t ! R	 R
]P4                  4      tR tR]
P:                  R]
P<                  ]
P>                  ,          ]
P@                  ,          ]
PB                  ,          R]
P<                  ]
P>                  ,          ]
P@                  ,          ]
PB                  ,          ]
PD                  ,          R]
P<                  ]
P>                  ,          ]
P@                  ,          ]
PB                  ,          ]
PD                  ,          ]
PF                  ,          /t$R t%R t& ! R R]]4      t'](R8X  d
   ]&! 4        R# R# )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                   sL   a  ] tR t^t o RtRtR tR tR tR t	R t
R tR	tV tR
# )ProxyRequestHandler   z
Traffic Legend:
    }  - Client receive
    }. - Client receive partial
    {  - Target receive

    >  - Target send
    >. - Target send partial
    <  - Client send
    <. - Client send partial
c                s    V P                  VP                  VP                  4       V P                  R R4       VP                  P                  4        F  w  r#V P                  W#4       K  	  V P                  4        R# )zContent-Typez	text/htmlN)Zsend_responsecodemsgZsend_headerheadersZitemsZend_headers)selfexZnameZvals   &&  >/usr/lib/python3.14/site-packages/websockify/websocketproxy.pysend_auth_errorZ#ProxyRequestHandler.send_auth_error'   s_    277BFF+5))+IDT' , 	    c                s   V P                   P                  '       g   R # V P                  V P                   P                  4      w  rVR8X  d   W P                   n        R # WP                   n        W P                   n        R # )Nunix_socket)servertoken_plugin
get_targetunix_targettarget_hosttarget_port)r   ZhostZports   &  r   validate_connectionZ'ProxyRequestHandler.validate_connection/   sW    {{'''__T[[%=%=>
= &*KK# '+KK#&*KK#r   c                s~   V P                   P                  '       g   R #  V P                  P                  4       pVR,          p\	        V Uu. uF  q3^ ,          NK  	  up4      pVR,          V P
                  R&    V P                   P                  P                  V P
                  V P                   P                  V P                   P                  R7       R # u upi   \        \        \        3 d     Lzi ; i  \        P                   d0    \        P                  ! 4       ^,          pT P!                  T4       h i ; i)NZsubjectZ
commonNameZSSL_CLIENT_S_DN_CN)r
   r   r   )r   auth_pluginrequestZgetpeercertZdictr
   Z	TypeErrorZAttributeErrorZKeyErrorZauthenticater   r   authZAuthenticationErrorsysexc_infor   )r   Zclient_cert_dataZclient_cert_subjectZxr   s   &    r   auth_connectionZ#ProxyRequestHandler.auth_connection;   s   {{&&&	#||779"29"="&6I'J6I!6I'J"K1D\1RDLL-.
	KK##00$++2I2I KK33 1 5 (K >84 		 '' 	"B  $	s1   ,C CC ;AC8 C C54C58AD<c                s   V P                   P                  '       dD   RRP                  V P                   P                  4      : RV P                   P                  : R2pMlV P                   P                  '       d   RV P                   P                  ,          pM2RV P                   P
                  : RV P                   P                  : 2pV P                   P                  '       d
   VR,          pV P                  V4        \        P                  P                  V P                   P
                  V P                   P                  R	V P                   P                  V P                   P                  R
7      pT P                   P                  '       g:   T P                  P                  \        P                   \        P"                  ^4       T P                   P                  '       gL   T P                   P                  '       g0   TP                  \        P                   \        P"                  ^4       T P%                  T P&                  4        T P)                  T4       T'       d   TP+                  \        P,                  4       TP/                  4        T P0                  '       d>   T P                  RT P                   P
                  T P                   P                  4       R# R# R#   \         dT   pT P                  RT P                   P
                  T P                   P                  T4       T P                  RR4      hRp?ii ; i  T'       d   TP+                  \        P,                  4       TP/                  4        T P0                  '       d=   T P                  RT P                   P
                  T P                   P                  4       i i i ; i)z?
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)ZconnectZuse_sslr   zFailed to connect to %s:%s: %si  z&Failed to connect to downstream serverNz%s:%s: Closed target)r   wrap_cmdjoinr   r   r   
ssl_targetlog_messager   WebSockifyServersocket	ExceptionCCloseunix_listenr   Z
setsockoptZSOL_TCPZTCP_NODELAYprint_traffictraffic_legenddo_proxyZshutdownZ	SHUT_RDWRcloseverbose)r   r	   ZtsockZe   &   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 {{&&&LL##FNNF4F4FJ{{###DKK,C,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-   A4K* M *M5AMMA	O>Oc                s   V P                   '       d=   V P                  P                  R4      pV'       d   VP                  R4      ^ ,          pMf\	        \        V P                  4      ^,          4      pRV9   d9   \        VR,          4      '       d!   VR,          ^ ,          P                  R4      pMRpVf   V P                  P                  R4      hVP                  V4      pVe   V# V P                  P                  RV,          4      h)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.
ZHostr!   tokenZ
NzToken not presentzToken '%s' not found)
host_tokenr
   getZ	partitionr   r   pathlenZrstripr   ZECloseZlookup)r   Ztarget_pluginr3   argsZresult_pairs   &&   r   r   ZProxyRequestHandler.get_target   s     ???LL$$V,E
 ,Q/ HTYY/23D$3tG}#5#5Wa(//5=++$$%899#**51"++$$%;e%CDDr   c                s   . p^ p. pV P                   V.pV P                  P                  '       d8   \        P                  ! 4       pW`P                  P                  ,           V n        MRV n         . pV P                  eW   \        P                  ! 4       pW`P                  8  d2   W`P                  P                  ,           V n        V P	                  4        V'       d   VP                  V4       V'       g	   V'       d   VP                  V P                   4        \        P                  ! WW. ^4      w  rp
T
'       d   \        R4      hT P                   T	9   d   T P                  T4      p. pT P                   T9   Ed   T P!                  4       w  rTP#                  T4       T'       d   \%        T4      ^ 8w  dn   TP'                  ^ 4      pTP)                  T4      pT\%        T4      8X  d   T P+                  R4       KU  TP-                  ^ TTR 4       T P+                  R4       K}  T P.                  '       d<   T P1                  RT P                  P2                  T P                  P4                  4       T P7                  TR,          TR	,          4      hY9   dk   TP'                  ^ 4      pTP)                  T4      pT\%        T4      8X  d   T P+                  R4       M&TP-                  ^ TTR 4       T P+                  R4       Y9   g   EK  TP9                  T P:                  4      p\%        T4      ^ 8X  d   \%        T4      ^ 8w  d    RpT'       d   T P                  T4      pK  . pT P.                  '       d<   T P1                  R
T P                  P2                  T P                  P4                  4       T P7                  RR4      hTP                  T4       T P+                  R4       EK|    \        P                  \        3 d`    \        P                  ! 4       ^,          p\        TR4      '       d   TP                  pM	T^ ,          pT\        P                  8w  d   h  EK  i ; i)z1
Proxy client WebSocket to normal target socket.
NTerrnozSocket exceptionZ>z.>z%s:%s: Client closed connectionr   Zreasonz%s:%s: Target closed connectioni  zTarget closedZ{)r   r   	heartbeattimeZ	send_pingappendselecterrorZOSErrorr   r   Zhasattrr9   ZEINTRr)   Zsend_framesZrecv_framesZextendr7   popZsendr,   Zinsertr0   r&   r   r   r*   Zrecvbuffer_size)r   ZtargetZcqueueZc_pendZtqueueZrlistnowZwlistZinsZoutsZexceptsZexcZerrZbufsZclosedZdatZsentZbufs   &&                r   r.   ZProxyRequestHandler.do_proxy   sW    v&;;   ))+C ;;#8#88DN!DNE~~)iik'%(;;+@+@%@DNNN$u||F+dll!;%+]]5Q%G"7 i(:;;||t#))&1||s"#//1d#v;!+$jjm%{{3/3s8+ ..s3 #MM!SZ8 ..t4 |||(()J $ 7 79P9PR++fVnfX6FGG ~jjm{{3'3s8#&&s+ MM!SZ0&&t, }kk$"2"23s8q= 6{a'!%$%)%5%5f%=F!#|||(()J $ 7 79P9PR++dO<<c"""3'[ LL'* 
llnQ'3(())Ca&C%++%
s   O+ +A5Q%$Q%)r:   N)__name__
__module____qualname____firstlineno__r@   r-   r   r   r   r2   r   r.   __static_attributes____classdictcell__)__classdict__s   @r   r   r      s:     K
N
+4/Nb%ENi( i(r   r   c                   sR   a a ] tR tRt oRtRt]3V 3R lltR tR t	R t
RtVtV ;t# )	WebSocketProxyi  zU
Proxy traffic to and from a WebSockets client to a normal TCP
socket server target.
r   c           
     s  < VP                  R R4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  R	R4      V n	        VP                  R
R4      V n
        . ROV n        V P                  '       EdR   \        P                  P                  \        P                   ^ ,          4      p\        P                  P#                  VRR4      \        P                  P#                  VRRR4      \        P                  P#                  VR4      V.pRV n        V FP  p\        P                  P#                  VR4      p\        P                  P'                  V4      '       g   KJ  Wpn         M	  V P$                  '       g   \)        R4      h\        P                  P+                  V P$                  4      V n        RV n        \,        P,                  ! \,        P.                  \,        P0                  4      pVP3                  R4       VP5                  4       ^,          V n        VP7                  4        \9        RV P$                  \        P:                  P=                  RR4      .4      p	\        P:                  P?                  R\        P@                  P#                  V	4      R\C        VR,          4      R\C        V P                  4      /4       \D        S
V `  ! V.VO5/ VB  R# )r   Nr   r#   	wrap_moder   r%   r:   r   r4   r   z..Zlib
websockifyz	rebind.soz1rebind.so not found, perhaps you need to run makez	127.0.0.1Z
LD_PRELOADZREBIND_OLD_PORTlisten_portZREBIND_NEW_PORT)    rM   rM   ) rM   )$r?   r   r   r#   rJ   r   r%   r:   r   r4   r   
wrap_timesosr6   Zdirnamer   argvr$   rebinderexistsr)   abspathr(   ZAF_INETZSOCK_STREAMZbindZgetsocknamer/   Zfilterenvironr5   ZupdateZpathsepZstrsuper__init__)r   RequestHandlerClassr8   kwargsZwsdirZrebinder_pathZrdirZrpathZsockZld_preloads	__class__s   &&*,      r   rW   ZWebSocketProxy.__init__   su   $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>>%(($)M	 & === STTGGOODMM:DM*D==1C1CDDIIg#//1!4DJJL !

|UY8Z'\]KJJbjjook:!3vm'<#=!3t'7'7#8: ;
 	,>t>v>r   c                sp   V P                  R RP                  V P                  4      4       V P                  P	                  \
        P
                  ! 4       4       V P                  P                  ^ 4       \        P                  ! V P                  \        P                  \        R7      V n        RV n        R# )zStarting '%s'r   )ZenvZ
preexec_fnTN)r	   r$   r#   rO   r<   r;   r?   
subprocessZPopenrP   rU   _subprocess_setupcmdspawn_message)r   s   &r   run_wrap_cmdZWebSocketProxy.run_wrap_cmdT  sr    #((4=="9:tyy{+A##2:::KM!r   c                s   V P                   '       d0   RRP                  V P                   4      : RV P                  : R2pM<V P                  '       d   V P                  pMV P                  : RV P                  : 2pV P
                  R8w  d   RpMV P                  : RV P                  : 2pV P                  '       d)   RV: R	\        V P                  4      P                  : 2pM
RV: R
V: 2pV P                  '       d
   VR,          pV P                  RV4       V P                   '       d   V P                  4        R# R# )z?
Called after Websockets server startup (i.e. after daemonize)
Z'r   r   r    r!   Ninetdz  - proxying from z to targets generated by z to r"   z%s)r#   r$   r   r   r   	listen_fdlisten_hostrL   r   typerB   r%   r	   r_   )r   Z
dst_stringZ
src_stringr	   r1   r   startedZWebSocketProxy.started\  s     ===-0XXdmm-DdFVFVWJ))J$($4$4d6F6FGJ>>T! J$($4$4d6F6FGJD!2!23<<>C 
 J(C ???>!Cs=== r   c                s   V P                   '       dS   V P                  '       dA   V P                  P                  4       pVR 8w  d    V P                  RV,          4       R V n        V P                   '       d   V P                  R 8X  d   V P                  R8X  d   R # V P                  R8X  d   \
        P                  ! X4       R # V P                  R8X  d   \        P                  ! 4       p\        V P                  4      \        V P                  4      ,          pW#,
          ^
8  d/   V P                  '       d   V P                  R4       RV n        R # R # V P                  4        R # R # R # R # )Nz/Wrapped command exited (or daemon). Returned %signoreexitrespawnzCommand respawning too fastF)r#   r]   pollZvmsgrJ   r   rf   r;   ZsumrO   r7   r^   warnr_   )r   ZretrA   Zavgr1   r   rh   ZWebSocketProxy.poll}  s     ===TXXX((--/Cd{		KcQR===TXX-~~)6)9,iik$//*3t+??I#)))		"?@-2* * %%' - .=r   )r   r]   r:   r4   rR   r^   r%   r   r   r   r   r#   rJ   rO   )rB   rC   rD   rE   __doc__r@   r   rW   r_   rd   rh   rF   rG   __classcell__rZ   rH      @@r   rI   rI     s/     
 K+> 2?h" B( (r   rI   c                  sl    \         P                   ! \         P                  \         P                  4       R # )N)signalZSIGPIPEZSIG_DFL r   r   r\   r\     s     MM&..&..1r   defaulttlsv1_1tlsv1_2tlsv1_3c                s$   V \         9   d   \         V ,          # \        \         P                  4       4      pVP                  4        VR,          p\        P
                  ! \        P                  4      pVP                  RW4       \         V,          # )zTReturns SSL options for the most secure TSL version available on this
Python versionz.TLS version %s unsupported. Falling back to %si)	SSL_OPTIONSZlistkeysZsortlogging	getLoggerrI   Z
log_prefixri   )Zversionru   ZfallbackZloggerr1   r   select_ssl_versionrx     ss     +7## K$$&'		8"">#<#<=D	' 8$$r   c            	      s   \         P                  ! 4       p V P                  \         P                  4       \         P                  ! R 4      pV P                  V4       \         P                  ! 4       pVP                  V 4       VP                  \         P                  4       RpVR,          pVR,          pVR,          pVR,          pVR,          pVR,          pVR,          p\        P                  ! VR7      pVP                  RRR	R
R7       VP                  RR	RR7       VP                  RRRR7       VP                  RRRR	RR7       VP                  RR	RR7       VP                  R\        ^ RR7       VP                  R\        ^ RR7       VP                  RRR R!7       VP                  R"R#R$R!7       VP                  R%R#R&R!7       VP                  R'R	R(R7       VP                  R)R	R*R7       VP                  R+R	R,R7       VP                  R-RR.R/7       VP                  R0R1R2. ROR3R4R57       VP                  R6R3R7R7       VP                  R8R9RR#R:7       VP                  R;R#R<R!7       VP                  R=R>RR7       VP                  R?R@R	RA7       VP                  RBR#RCRDRE7       VP                  RFR	RGR7       VP                  RHRIRJ. RORKRL7       VP                  RMRNR	RORPRQ7       VP                  RRR	RSR7       VP                  RTRRURVRW7       VP                  RXR#RYRZRE7       VP                  R[R#R\R]RE7       VP                  R^R	R_R7       VP                  R`R#RYRaRE7       VP                  RbR#R\RcRE7       VP                  Rd\        ^ ReRfRg7       VP                  RhRRiRjRW7       VP                  RkR#RlRmRE7       VP                  RnR	RoR7       VP                  RpR	RqR7       VP                  4       w  rVVP                  '       d$   VP                  '       g   VP!                  Rr4       VP"                  '       d$   VP                  '       g   VP!                  Rs4       VP$                  '       d$   VP&                  '       g   VP!                  Rt4       VP(                  '       d$   VP&                  '       g   VP!                  Ru4       VP(                  '       d$   VP*                  '       g   VP!                  Rv4       VP,                  '       d$   VP.                  '       g   VP!                  Rw4       \1        VP2                  4      Vn        V=VP6                  '       d   \8        P:                  P=                  VP6                  4      Vn        \         P>                  ! VP6                  4      pVP                  \         P                  4       VP                  V4       \         P                  ! 4       pVP                  V4       V=VP.                  '       Ed   VP.                  PA                  Rx4      '       d/   VP.                  PC                  Rx^4      w  r \        V	4      p	W3p
M)\8        P:                  P=                  VP.                  4      p
^ RzI#H$p VPJ                  '       d   VPL                  pMVPN                  pV! V
VR{VP,                  R|7      pVP                  \         P                  4       VP                  V4       \         P                  ! 4       pVP                  V4       V=V=VPP                  '       d5   \         P                  ! 4       pVP                  \         P                  4       VPR                  '       d/   \8        P:                  P=                  VPR                  4      Vn)        VPR                  '       d   R}Vn        VPR                  Vn        V=)\T        PV                  PA                  R~4      '       d   VR,          Vn,        MR#Vn,        \Z        P\                  '       g$   VP^                  '       d   VP!                  R4       VP`                  '       dR   \8        P:                  Pc                  VPd                  4      '       g#   VP!                  RVPd                  ,          4       VPf                  '       d&   \T        Ph                  Pk                  4       Vn6        EMVPn                  '       d[   VPp                  '       d    \        VPp                  ^4      Vn8        M\r        Pt                  \r        Pv                  ,          Vn8        M\y        V4      ^8  d   VP!                  R4       VP{                  ^ 4      pVPA                  Rx4      ^ 8  dA   VPC                  Rx^4      w  Vn>        Vn?        VP|                  P                  R4      Vn>        MRVuVn>        Vn?         \        VP~                  4      Vn?        V=3VPX                  '       g%   VP                  '       g   VP                  '       d   R#VnB        R#VnC        M\y        V4      ^8  d   VP!                  R4       VP{                  ^ 4      pVPA                  Rx4      ^ 8  dA   VPC                  Rx^4      w  VnB        VnC        VP                  P                  R4      VnB        MVP!                  R4        \        VP                  4      VnC        \y        V4      ^ 8  d#   VPX                  R#8X  d   VP!                  R4       VP                  e   RVP                  9  d   RVP                  ,          Vn        VP                  PC                  R^4      w  pp\        V4       \        \T        P                  V,          V4      pV! VP                  4      Vn        V=VP&                  e   RVP&                  9  d   RVP&                  ,          Vn        VP&                  PC                  R^4      w  pp\        V4       \        \T        P                  V,          V4      pV! VP$                  4      Vn        V=VP                  pV=GV'       d(   \        R/ VP                  B pVP                  4        R## \        R/ VP                  B pVP                  4        R##   \D         d    TP!                  Ry4        ELi ; i  \D         d    TP!                  R4        EL	i ; i  \D         d    TP!                  R4        EL,i ; i  \D         d    TP!                  R4        ELTi ; i)z%(message)sz
    %prog [options]z2 [source_addr:]source_port target_addr:target_portz/ --token-plugin=CLASS [source_addr:]source_portz- --unix-target=FILE [source_addr:]source_portz/ [source_addr:]source_port -- WRAP_COMMAND_LINE)usagez	--verbosez-vZ
store_truezverbose messages)actionhelpz	--trafficzper frame trafficz--recordz(record sessions to FILE.[session_number]ZFILE)r{   metavarz--daemonz-Ddaemonz$become a daemon (background process))destrz   r{   z
--run-oncez-handle a single WebSocket connection and exitz	--timeoutz-after TIMEOUT seconds exit when not connected)rc   rp   r{   z--idle-timeoutzEserver exits after TIMEOUT seconds if there are no active connectionsz--certzself.pemzSSL certificate file)rp   r{   z--keyNz$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-versionZchoicerp   Zstorez?minimum TLS version to use (default, tlsv1_1, tlsv1_2, tlsv1_3))rc   rp   choicesrz   r{   z--ssl-ciphersz]list of ciphers allowed for connection. For a list of supported ciphers run `openssl ciphers`z--unix-listenzlisten to unix socket)r{   r|   rp   z--unix-listen-modez/specify mode for unix socket (defaults to 0600)z--unix-targetzconnect to unix socket targetz--inetdz/inetd mode, receive listening socket from stdin)r{   rz   z--webZDIRz1run webserver on same port. Serve files from DIR.)rp   r|   r{   z
--web-authz+require authentication to access webserver.z--wrap-moderf   ZMODEz\action to take when the wrapped program exits or daemonizes: exit (default), ignore, respawn)rp   r|   r   r{   z--prefer-ipv6z-6Zsource_is_ipv6z&prefer IPv6 when resolving source_addr)rz   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-pluginZCLASSzxuse a Python class, usually one from websockify.token_plugins, such as TokenFile, to process tokens into host:port pairsz--token-sourceZ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--heartbeatZINTERVALz0send a ping to the client every INTERVAL seconds)rc   rp   r|   r{   z
--log-filelog_filezFile where logs will be savedz--syslogZ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.z--file-onlyz5use this to disable directory listings in web server.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!   zError parsing syslog port)WebsockifySysLogHandlerrK   )ZaddressZfacilityZidentZlegacyZ	TokenFilez--:i   NNz6SSL target requested and Python SSL module not loaded.zSSL only and %s not foundz%Error parsing listen unix socket modezToo few argumentsz[]rN   zError parsing listen portzError parsing targetzError parsing target portzToo many argumentsZ.zwebsockify.token_plugins.%szwebsockify.auth_plugins.%s)rp   rq   rr   rs   )rf   re   rg   ro   )Mrv   ZStreamHandlerZsetLevelZDEBUGZ	FormatterZsetFormatterrw   Z
addHandlerZINFOoptparseZOptionParserZ
add_optionZintZ
parse_argsZtoken_sourcer   r>   r4   Zauth_sourcer   Zweb_authwebZlegacy_syslogZsyslogrx   Zssl_versionZssl_optionsr   rP   r6   rT   ZFileHandlerZcountZrsplitZ
ValueErrorZwebsockify.sysloghandlerr   r}   Z
LOG_DAEMONZLOG_USERr0   r   r   rQ   r#   r   sslr%   Zssl_onlyrS   Zcertr`   ZstdinZfilenora   r+   Zunix_listen_modestatZS_IREADZS_IWRITEr7   r?   rb   rL   Zstripr   r   r   Z
__import__ZgetattrZmodules	libserverLibProxyServerZ__dict__Zserve_foreverrI   Zstart_server)Zstderr_handlerZlog_formatterZrootry   ZparserZoptsr8   Zlog_file_handlerZsyslog_hostZsyslog_portZsyslog_destr   Zsyslog_facilityZsyslog_handlerargZtoken_plugin_moduleZtoken_plugin_clsZauth_plugin_moduleZauth_plugin_clsr   r   s                        r   websockify_initr     s   **,NGMM*%%m4M.DOON#MM',, $E	AAE	$$E	>>E	$$E	<<E	$$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(&$  H
*DB  D
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$>  ? '\  ] mLR  T $$&LT
 !2!2!2HIt000FG 0 0 0FG}}}T---CD}}}TXXX;<$+++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  "'|||  "gmm$ ''//$//:' OO
xx~~dRDOOOMN}}}RWW^^DII660499<=zzz))+				   F(+D,A,A1(E%
 %)LL4==$@D!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]  :89:z  FDEF$  	6LL45	6(  	6LL45	6sH   's% %t t+ ?u %ttt('t(+u
uu.-u.c                   sH   a a ] tR tRt oRt]3V 3R lltV 3R ltRtVt	V ;t
# )r   i  zL
Just like WebSocketProxy, but uses standard Python SocketServer
framework.
c                s  < VP                  R R4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  RR4      V n        VP                  R	R4      V n	        RV n        RV n        R
V n
        VP                  RR4      pVP                  RR4      pVP                  RR4      pV'       * V n        VP                  RR
4      V n        VP                  RR4      pV'       d%   \        P                  P                  V4      V n        VP                  RR
4      V n        ^ V n        VP'                  4        F  p\)        RV,          4       K  	  V'       d   \        P*                  ! V4       \,        SV `]  W43V4       R# )r   Nr   r#   rJ   r   r%   r   r   r:   Frb   rN   rL   r   r0   recordrun_oncez1warning: option %s ignored when using --libserver)r?   r   r   r#   rJ   r   r%   r   r   r:   r}   only_upgrader0   rP   r6   rT   r   r   
handler_idru   ZprintZchdirrV   rW   )	r   rX   rY   rb   rL   r   r   r   rZ   s	   &&,     r   rW   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;;=CEKL ! HHSM+35HIr   c                sX   < V ;P                   ^,          un         \        SV `	  W4       R# )z/Override process_request to implement a counterN)r   rV   process_request)r   r   Zclient_addressrZ   s   &&&r   r   ZLibProxyServer.process_request  s    18r   )r   r}   r   r:   r   r   r   r%   r   r   r   r   r0   r#   rJ   )rB   rC   rD   rE   rj   r   rW   r   rF   rG   rk   rl   rm   r   r   r     s      
 ,? $JN9 9r   r   Z__main__))rj   rn   r(   r   r;   rP   r   r[   rv   r9   r   r   Zsocketserverr    Zhttp.serverr   r=   rK   r   r   r   Zurllib.parser   r   ZWebSockifyRequestHandlerr   r'   rI   r\   ZOP_ALLZPROTOCOL_SSLv23ZOP_NO_SSLv2ZOP_NO_SSLv3ZOP_NO_TLSv1ZOP_NO_TLSv1_1ZOP_NO_TLSv1_2rt   rx   r   r   rB   ro   r   r   <module>r      sI  	 V U U U U U ' "  ' + +(*CC (B}(%66 }(@2 szzs""S__4sFOOs""S__4sFOO''(s""S__4sFOO''(*-*;*;<%"pf	09^Z 09f z r   