
    hI                        d dl mZm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mZmZmZmZmZmZmZ 	 eZ	 d dlZddlmZ ddl m!Z! dd	l"m#Z# dd
l$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7 erddl8m9Z9 ddl:m;Z; ddl<m=Z= ere>Z? e@ed      s
 eAedd       d ZB G d deC      ZDy#  eZY xY w# e$ r9 er  edj5                  ej6                                ej8                  d       Y e$ r9 er  edj5                  ej6                                ej8                  d       Y w xY w)    )print_functionunicode_literalsN   )ANYWINCORESEXEMACOSPY2TYPE_CHECKING	EnvParamsunicodez[1;31m
  you do not have jinja2 installed,[33m
  choose one of these:[0m
   * apt install python-jinja2
   * {} -m pip install --user jinja2
   * (try another python version, if you have one)
   * (try copyparty.sfx instead)
a  [1;31m
  your jinja2 version is incompatible with your python version;[33m
  please try to replace it with an older version:[0m
   * {} -m pip install --user jinja2==2.11.3
   * (try another python version, if you have one)
   * (try copyparty.sfx instead)
)HttpConn)Metrics)U2idx)E_SCKFHC
CachedDictDaemonGardaMagicianNetdevNetMapbuild_netmaphas_resourceipnormload_ipuload_resourcemin_exshut_socketspackstart_log_thrsstart_stackmonub64enc)VFS)	BrokerCliSSDPrAF_UNIXic                 n    t        | d|z   d      5 }|j                         cd d d        S # 1 sw Y   y xY w)Nzweb/r)r   read)Enamefs      F/jellyfin/media/venv/lib/python3.12/site-packages/copyparty/httpsrv.pyload_jinja2_resourcer0   _   s2    	q&4-	- vvx  s   +4c                   v    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zy)HttpSrvz
    handles incoming connections using HttpConn to process http,
    relying on MpSrv for performance (HttpSrv is just plain threads)
    c                 v    | _         | _        |j                   _         j                  j                   _        |j                   _        |j
                   _        t        j                  d       t        j                          _	        |r$dj                  |t        j                               nd}t                _        t        g g        _        d  _        t%         j                  j&                         _        t%         j                  j*                         _        t%         j                  j.                         _        t%         j                  j2                         _        t%         j                  j6                  d       _        t%         j                  j6                         _        t%         j                  j<                         _        i  _         i  _!        i }i }|x _"         _#        |x _$         _%        d j                  jL                  d _'        tQ                _)        d|z    _*        tW        jX                          _-        tW        jX                          _.        d _/        d _0        d _1        d	 _2         j                  jf                  rd nti        jj                          _6        d  _7        tq                _9        i  _:        tw        d
       _<        t{                _>        d _?        d _@        d _A        g  _B        d _C        tQ                _D        d _E        d	 _F        d _G        i  _H        d _I        t        j                         }t        j                   fd      |_M        g d}|D ci c]  }||j                  |dz          c} _O        t         j                  d       _Q         j                  j                  r8t         j                   j                  j                        \   _T         _U        nd x _T         _U        t         j                  j                         _X        t         j                  j                         _Z        t        d       _[        dj                          _]         j                  j                  s%d}	 xj                  |	j                         z  c_]         j                  j                  rddlm`}
  |
|       _         jl                  r j                  d       |ri  _#        i  _%         j                  j                  r t         j                  j                  |        j                  j                  r+t         j                   j                  j                  |       i  _f        t         j                  d       y c c}w )Nx   z
-n{}-i{:x} Fz
<img src="z.cpr/iiam.gif?cache=i" />hsrvr   g        g?c                 0    t        j                  |       S N)r0   r,   )r.   selfs    r/   <lambda>z"HttpSrv.__init__.<locals>.<lambda>   s    5I$&&RS5T     )browserbrowser2cfidpmdmdemsgrupssharessplashsvcsz.htmlzweb/deps/prism.js.gzlanz GET HEAD POST PUT DELETE OPTIONSz.PROPFIND PROPPATCH LOCK UNLOCK MKCOL COPY MOVEr   r&      z
hsrv-init2)ibrokernidargsr,   logasrvsocketsetdefaulttimeouttimet0formatosgetpidr   magicianr   nmssdpr   ban_pwgpwdban_pwcgpwcban_404g404ban_403g403ban_422g422gmalban_urlgurlbansaclosedlitdlidlstdlsSRSiiamsetboundr-   	threadingLockmutexu2mutexstoppingtp_nthrtp_nclitp_timeno_htpqueue	LifoQueuetp_q
t_periodicr   u2fhu2scr   pipesr   metricsnreqnsusnbansrvsncliclientsnclimaxcb_tscb_v
u2idx_freeu2idx_njinja2EnvironmentFunctionLoaderloaderget_templatej2r   prismipur   ipu_iuipu_nmr   ipaipa_nmxff_srcxff_nmxff_lansplitmallowno_davzsr'   start_threadsstackmonr"   log_thrsr!   th_cfgr   	post_init)r9   rI   rJ   nsufrg   ri   envjnxr   r'   s   `          r/   __init__zHttpSrv.__init__j   s   KK	))++::KK	 	  %))+8;|""3		4 
R.	$))**+	$))++,	$))++,	$))++,	$))++U3	$))++,	$))++,		""49""49?Cyy}}N	u
TM	^^%
 ~~'II$$D%//*; 		  E		_
t}					
	  "**+TU

 >@@1c&&q7{33@!$&&*@A
99=='/$))--'H$DK(,,DK$+"499==1"499#4#45#E*8>>@yyABKK288:%K99<<#fDI99q!DIDIyy!!tyy1137yy!!txx););SAt~~|,I As   V6c                 t    	 | j                   j                  d      }|j                         | _        y #  Y y xY w)Nzthumbsrv.getcfg)rI   askgetr   )r9   r   s     r/   r   zHttpSrv.post_init   s1    	 12A%%'DK	s   03 7c                     t               }| j                  D ]  \  }}|j                  |        t        t	        |      t	        |            | _        y r8   )rm   rn   addr   listrV   )r9   netdevsipsip_s        r/   set_netdevszHttpSrv.set_netdevs   sC    eZZ 	EBGGBK	 cDM2r;   c                 .   | xj                   |z  c_         | j                  j                  r7| j                  | j                  dj                  || j                         d       t        |      D ]%  }t        | j                  | j                  dz          ' y )Nzworkers += {} = {}   -poolw)	rt   rK   log_htprL   r-   rR   ranger   	thr_poolwr9   nr   s      r/   r   zHttpSrv.start_threads   sm    99HHTYY 4 ; ;At|| LaPq 	9A4>>499x#78	9r;   c                    | xj                   |z  c_         | j                  j                  r7| j                  | j                  dj                  || j                         d       t        |      D ]  }| j                  j                  d         y )Nzworkers -= {} = {}r   )	rt   rK   r   rL   r-   rR   r   rz   putr   s      r/   stop_threadszHttpSrv.stop_threads   sf    99HHTYY 4 ; ;At|| LaPq 	 AIIMM$	 r;   c                 t   	 t        j                  | j                  s| j                  rdnd       | j                  5  | j
                  5  | j                  j                          | j                  rUt        | j                  | j                  dz
        | _        | j                  | j                  dz   kD  r| j                  d       | j                  s>| j                  j                  s(| j                  dk  rd | _        	 d d d        d d d        y d d d        d d d         # 1 sw Y   xY w# 1 sw Y   xY w)N   
      rH   )rP   sleepru   r   rr   rq   r|   cleanrz   maxrt   r   cacher{   )r9   s    r/   periodiczHttpSrv.periodic   s    JJDLLDIIq2> 	tzz 			!99#&tyy$,,2B#CDL||dllQ&66))!,yyT\\Q=N&*DO	 	 	 	 	 	 	 	 	s*   D.
B5D"?D.D."D+	'D..D7c                 t   |j                   t        j                  k7  }| j                  j                  dk7  rt
        r| j                  j                  r/|j                  t        j                  t        j                  d       |r/|j                  t        j                  t        j                  d       |j                  d        |r|j                         d d \  }}n9t        j                  dd|j                         j!                  d      d         }d}| j"                  j%                  |       | j&                  j)                  ||f       t+        j,                  | j                  j.                  dz  |z        | _        t3        | j4                  d	j7                  | j8                  xs d
||      |f       y )Nr   r   	\.[0-9]+$r5   /r   g      ?zhttpsrv-n{}-listen-{}-{}0)familyrN   r(   rK   jr   	reuseaddr
setsockopt
SOL_SOCKETSO_REUSEADDRIPPROTO_TCPTCP_NODELAY
settimeoutgetsocknameresubr   r   appendrn   r   mathceilncr   r   
thr_listenrR   rJ   )r9   sck
nlistenerstcpr   ports         r/   listenzHttpSrv.listen
  s8   jjFNN*99;;!TYY00v00&2E2EqIv1163E3EqINN4 (!,HBb#//*;*A*A#*Fr*JKBD		

Dz"yy!3j!@AOO&--dhho#r4HF	
r;   c           	         |j                         }|j                  t        j                  k(  rXt	        j
                  dd|j                               }d||t        j                         fz  }|j                  d      d   }d}d}n?d}|j                         d	d
 \  }}d|v rd|dn|}d|||t        j                         fz  }| j                  | j                  |       t        | j                  j                  dd       d}| j                  s7| j                   j"                  r!| j                  | j                  ddz  d       d}	| j$                  | j&                  k\  r|	sd}
| j                  | j                  |
d       |	dz  }	t)        j*                  d       |	dk7  s| j                   j,                  sqi }| j.                  5  | j0                  D ]%  }t3        |j4                        }	 ||xx   dz  cc<   ' 	 d	d	d	       t7        |j9                         d d      d   \  }}|| j&                  d
z  k  rt;        t)        j(                         | j                   j,                  dz  z         | j,                  |<   d}d}d}| j.                  5  | j0                  D ]  }t3        |j4                        }||k7  r|dz  }	 |j<                  dk\  s8|j>                  r,|j>                  j@                  s|j>                  jB                  rPt        |jD                         |dz  }|j<                  dk  r'|j>                  r|j>                  j@                  r|dz  } 	 d	d	d	       d}
| j                  | j                  |
jG                  || j                   j,                  ||      d       ||d
z  k  rkd}
| j                  | j                  |
jG                  || j                   jH                  |      d       t;        t)        j(                         | j                   jH                  dz  z         | jJ                  |<   | j$                  | j&                  k\  r| j                   j"                  r!| j                  | j                  d d!z  d       	 |jM                         \  }}|r,tO        |d         }|jQ                  d"      r|d#d	 }||d   f}nd$|j                         f}| j                   j"                  r.d)jG                  d*||d+z  |      }
| j                  d,|z  |
d       | jM                  ||       | j                  s6y	y	#  d||<   Y }xY w# 1 sw Y   YxY w#  Y xY w# 1 sw Y   xY w# tR        t        jT                  f$ r_}| j                  rY d	}~y	| j                  | j                  d%jG                  ||      d&       t)        j*                  d'       Y d	}~d	}~wtV        $ rb}|rZ|sXd(}
| j                  | j                  |
|fz  d       	 jY                          n#  Y nxY wt)        j*                  d'       Y d	}~O d	}~ww xY w)-zlistens on a shared tcp serverr   r5   zsubscribed @ %s  f%d p%dr   r   r   FTNr   :[]zsubscribed @ %s:%d  f%d p%dzsig-hsrv-up1)cb_httpsrv_up)r5   r   z	|%sC-ncli)-90cz1at connection limit (global-option 'nc'); waiting   r   g?2   c                     | d   S )Nr    )r   s    r/   r:   z$HttpSrv.thr_listen.<locals>.<lambda>S  s
    QqT r;   )keyreverse<   zG{} downgraded to connection:close for {} min; dropped {}/{} connectionsz+slowloris (idle-conn): {} banned for {} minz	|%sC-acc1)z--z::ffff:   z	127.8.3.7zaccept({}): {}r   g{Gz?zTaccept(%s): failed to accept connection from client due to firewall or network issuez|{}C-acc2 [0;36m{} [3{}m{}z---r   %s %s)-filenor   rN   r(   r   r   r   rS   rT   r   rL   r-   r   rI   sayrs   rK   log_connr   r   rP   r   rf   rq   r   r   r   sorteditemsintr   cliin_hdr_recv	keepaliveshutdownrR   lorisre   acceptr   
startswithOSErrorerror	TypeErrorclose)r9   srv_sckfnor   rB   r   r   hipsaddrspinstipfreqr   r   nclosenlorisnconncipr   addrexs                        r/   r   zHttpSrv.thr_listen&  sB   nn>>V^^+b'*=*=*?@B,C/EEC#r"BDCC**,Ra0HB$'2IB.2C/3c299;2OOCC t{{0BC--yy!!K*$<EE))t||+KAHHTYY1-


3B;dii&6&6ZZ +!\\ +#ADD\+"2J!OJ++ v||~>4PQRSAt||a''"%diikDII4D4Dr4I&I"JBZZ !!\\ !$QTTl9$
! !!'(uu#$55#4#4#$55?? &qzz 2 &!#$66Q;ARAR$*aKF!!!* ^AHHR1A1A65$QSTUEAI%AAHHR&$I1M #DIIK$))//B2F$F G		"q ))t||+t yy!!K*$<E$^^-
U!%(+C~~i0!!"gq?D'6D, yy!!8??R4 4d3KKT"M --*+)*F2J+ +D! '! !V V\\* ==$4$;$;C$DJ

4   unAHHTYYSF
aH8		JJt$s   	%U/U	<U0U+BU#U+AU8 	UUU #U(%U++U58YW+"AW++Y7(Y X10Y1X53YYYc           	      "   t        j                          }|| j                  xs |z
  dkD  r]d}| j                  | j                  |j	                  | j                  || j
                  | j                        d       d| _        d| _        | j                  5  | xj                  dz  c_        | j                  s<d}| j                  r|d| j                  fz  z  }t        | j                  |      | _	        | j                  r| j                  xs || _        t        | j                  | j                        | _        | j
                  | j                  dz   k  r| j                  d	       | j                  j!                  ||f       	 ddd       y	 ddd       | j"                  j$                  sd
}| j                  | j                  |d       t        | j&                  d|d   j)                  dd      d   dd |d   fz  ||f       y# 1 sw Y   yxY w)zBtakes an incoming tcp connection and creates a thread to handle iti,  zDhttpserver threadpool died: tpt {:.2f}, now {:.2f}, nthr {}, ncli {}r   r   Nzhsrv-ptz-%drH   r   zlooks like the httpserver threadpool died; please make an issue on github and tell me the story of how you pulled that off, thanks and dog bless
httpconn-%s-%d.r   r   )rP   rv   rL   r-   rR   rt   r   rz   rq   r{   rJ   r   r   r   ru   r   r   rK   rw   
thr_clientr   )r9   r   r  nowr
  r-   s         r/   r   zHttpSrv.accept  s   iik$,,%#&,VAHHTYYsDLL$)) TVWXDLDIZZ 	IINI?? 88ETXXK//D"("=yy#||2s"4<<;<<$))a-/&&q)		sDk*!	 	 	$ yy eAHHTYY1%OOQc1 5b 9"# >QHH$K	
-	 	s   C/HHc                 d   	 | j                   j                         }|sy | j                  5  d| _        d d d        	 |\  }}t	        j
                         }d|d   j                  dd      d   dd  |d   fz  |_        | j                  ||       | j                  dz   |_        # 1 sw Y   rxY w# t        $ rv}t        |      j                  d	      r*| j                  | j                  d
t        |      z   d       n(| j                  | j                  d
t               z   d       Y d }~d }~ww xY w)Nr   r  r  r   r   r  r   r   zclient d/c zthr_client: r   r   )rz   r   rq   rv   ro   current_threadr   r-   r  	Exceptionstrr   rL   r   )r9   taskr   r  mer  s         r/   r   zHttpSrv.thr_poolw  s   99==?D ! !
F 	T--/*d1gmmC.CB.G.LdSTg-VVT*))h. 
! !  Fr7%%m4HHTYYR(@!DHHTYY(A1E	Fs$   B$A'B0 $B-0	D/9A,D**D/c                 Z   d| _         | j                  D ]  }	 |j                           g }t        | j                        }|D ]C  }t        j                  |j                        }|j                  |       |j                          E | j                  r\| j                  | j                         t        d      D ]3  }t        j                  d       | j                  j!                         s3 n |D ]  }|j#                           | j%                  | j&                  d       y #  Y xY w)NT)targetr   皙?zok bye)rs   r   r  r   r   ro   Threadr   r   startrz   r   rt   r   rP   r   emptyjoinrL   r-   )r9   srvthrsr   r   r
  r   s          r/   r   zHttpSrv.shutdown  s    99 	C			 t||$ 	C  5AKKNGGI	
 99dll+2Y 

4 99??$
  	AFFH	 	H%)s   D%%D*c           
      `	   t        |||       }| j                  5  | j                  j                  |       ddd       |j	                         }	 | j
                  j                  r| j                  d|z  ddz  d       |j                          |j                  }| j
                  j                  r| j                  d|z  d	d
z  d       	 |j	                         }t!        |j                  |       | j                  5  | j                  j%                  |       | xj&                  dz  c_        ddd       |j(                  r&| j+                  t-        |      |j(                         yy# 1 sw Y   6xY w# t        t        j                  f$ rD}|j                  t        vr'| j                  d|z  dj                  ||      d       Y d}~@d}~ww xY w# t        t        j                  f$ rK}t"        s'| j                  d|z  dj                  ||      d       |j                  t        vr Y d}~Dd}~ww xY w# 1 sw Y   xY w# | j                  5  | j                  j%                  |       | xj&                  dz  c_        ddd       n# 1 sw Y   nxY w|j(                  r&| j+                  t-        |      |j(                         w w xY w# |j                  }| j
                  j                  r| j                  d|z  d	d
z  d       	 |j	                         }t!        |j                  |       nf# t        t        j                  f$ rJ}t"        s'| j                  d|z  dj                  ||      d       |j                  t        vr Y d}~nd}~ww xY w| j                  5  | j                  j%                  |       | xj&                  dz  c_        ddd       n# 1 sw Y   nxY w|j(                  r&| j+                  t-        |      |j(                         w w # | j                  5  | j                  j%                  |       | xj&                  dz  c_        ddd       n# 1 sw Y   nxY w|j(                  r&| j+                  t-        |      |j(                         w w xY wxY w)zthread managing one tcp clientNr   z	|%sC-crun)z----r   r   zrun({}): {}r   z
|%sC-cdone)z-----zshut({}): {}r   )r   rq   r   r   r   rK   r   rL   runr  rN   r  errnor   rR   sr   r	   remover   u2idx	put_u2idxr  )r9   r   r  r   r  r  s         r/   r  zHttpSrv.thr_client  s   sD$'ZZ 	"LLS!	" jjl%	9yy!!4z)ATJGGI %%Cyy!!4
)BdK9jjlCGGS) ZZ #LL'',IINI# 99NN3t9cii8 S	" 	" & 	xxu$dN!((b1  	  V\\* HH$&--c26  
 885( )# #TZZ #LL'',IINI# # # 99NN3t9cii8 + %%Cyy!!4
)BdK9jjlCGGS)V\\* HH$&--c26  
 885( ) ZZ #LL'',IINI# # # 99NN3t9cii8 	 ZZ #LL'',IINI# # # 99NN3t9cii8 s   E*A E7 &G >1H>*E47G9G	K GK H;0A H60I 6H;;I >IK1J		KJ:K=R-&L98P$9NA NP$NP$R-+1O%	R-%O.*:R-$R*11Q+"	R*+Q40:R**R-c           	         t        j                          | j                  z
  dk  r| j                  S | j                  5  t        j                          | j                  z
  dk  r| j                  cd d d        S | j                  j
                  }	 t        j                  t        j                  j                  | j                  j                  d            5 }|D ](  }|j                         }t        ||j                        }* 	 d d d        t        t        dt!        |            dd        j#                  d      | _        t        j                          | _        | j                  cd d d        S # 1 sw Y   lxY w#  Y sxY w# 1 sw Y   y xY w)Nr   webs   >Lascii)rP   r   r   rq   r,   rQ   rS   scandirpathr$  modstatr   st_mtimer#   r    r   decode)r9   vdhfhinfs        r/   cachebusterzHttpSrv.cachebuster(  s,   99;#a'99ZZ 	yy{TZZ'!+yy	 	 		AZZTVVZZ ?@ 1B  1 ggi3<<011  eSV 4QR 89@@IDIDJ99!	 	1 1	 	sC   0F7FAE;.E/E;AF/E8	4E;;E?=FFc                    | j                   }t        d      D ]  }| j                  5  |rV||v r|j                  |      cd d d        c S |j                  t	        |j                               d         cd d d        c S | j                  t        k  r+| xj                  dz  c_        t        |       cd d d        c S 	 d d d        t        j                  d        y # 1 sw Y   !xY w)Nd   r   r   r   )r   r   rq   popr   keysr   r   r   rP   r   )r9   identutabr   s       r/   	get_u2idxzHttpSrv.get_u2idx>  s    s 	A 	'}#xx	' 	'
  88D$5a$89	' 	' <<%'LLA%L ;	' 	' (	' JJt	" !	' 	's   C
*C 2CC(	c                     | j                   5  || j                  v r|dz  }|| j                  v r|| j                  |<   d d d        y # 1 sw Y   y xY w)Na)rq   r   )r9   r@  r,  s      r/   r-  zHttpSrv.put_u2idxS  sQ    ZZ 	+4??* 4??* &+DOOE"		+ 	+ 	+s   "AAAc                     | j                   j                         D ci c]  \  }\  }}}}}||||j                  ||f }}}}}}}|| j                  fS c c}}}}}}w )zv
        mp-broker asking for local dl-info + dl-state;
        reduce overhead by sending just the vfs vpath
        )rg   r   vpathri   )r9   krD  br   derg   s           r/   read_dlszHttpSrv.read_dlsZ  s^     CG((..BRSS,>A1aAq1a!Q''SSTXX Ts   "Ac                     i }|j                         D ]8  \  }\  }}}}}	| j                  j                  j                  |   }
|||
||	f||<   : || _        || _        y)zn
        mp-broker pushing total dl-info + dl-state;
        swap out the vfs vpath with the vfs node
        N)r   rM   vfs	all_nodesrh   rj   )r9   sdliri   rg   rG  rD  rH  r   rI  rJ  vns              r/   	write_dlszHttpSrv.write_dlsf  si     "&**, 	&A1aA((+BB1%CF	& 		r;   N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   r  r;  rB  r-  rK  rQ  r   r;   r/   r2   r2   d   sc    
r-h39 
8{#z$
LF*&6-9^,*+
r;   r2   )E
__future__r   r   hashlibr   rS   r   rN   sysro   rP   rx   r   r   r   r   r	   r
   r   r   r   ModuleNotFoundErrorMNFEImportErrorr   printrR   
executableexitSyntaxErrorhttpconnr   r   r   r,  r   utilr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   authsrvr$   broker_utilr%   rW   r'   xranger   hasattrsetattrr0   objectr2   r   r;   r/   <module>rh     s6   7   	 	  
    W W WD"F        , &Evy!FIu%
Qf QcD  
		 FNN
 CHHQK 
		 FNN

 CHHQKs$   B? C ?C;E:EE