Files
o11pro-unpacked/src/modules/__pycache__/hls_proxy.cpython-310.pyc
T

109 lines
14 KiB
Plaintext
Raw Normal View History

2026-06-26 07:07:13 +08:00
o
T²=jë;ã@sdZddlZddlZddlZddlZddlZddlZddl Z ddl
Z
ddl Z ddl Z ddl
Z
ddlZddlZddlZddlZddlmZddlmZddlmZmZddlmZmZddlmZdZd Zd
Zd Zd Z d
Z!dZ"dZ#dZ$dZ%ia&e Z(ddZ)Gdddej*j+ƒZ,iZ-e Z.iZ/ddZ0dWddZ1eƒZ2e Z3dXddZ4dYddZ5e  6d ¡Z7d!d"„Z8d#d$„Z9d%d&„Z:d'd(„Z;d)d*„Z<dddddd+œZ=e Z>Gd,d-„d-eƒZ?Gd.d/„d/eeƒZ@d0d1„ZAd2d3„ZBd4d5„ZCeDd6krÇejEd7d8ZFeFjGd9ed:ed;d<eFjGd=eHed>ed;d?eFjGd@edAed;d<eF ZJeJjKZeJjLZeJjMZe)ƒe7dus3JejNeAdBdCZOeO eQdDedEedFdBdGeQdHedBdGeQdIeRt&ƒdBdGeQdJe#dKdBdGeQdLe dMdBdGeQdNe%dOdBdGeQdPe$dQdBdGeQdBdGeQdRdBdGeQdSdBdGeQdTdBdGeQdUdBdGe@eefe?ƒZSzeS WdSeUeQdVƒeS YdSwdS)Za8
HLS Proxy for o11pro - Memory-Leak Fixed Version.
Fixes applied vs original hls_proxy.py:
1. Cache channel URLs at startup (no JSON re-parse per request)
2. Reuse urllib openers per domain (no new OpenerDirector per fetch)
3. Bounded cookie jars with periodic eviction (no unbounded cookie growth)
4. Streaming segment forwarding (no full-buffer of large TS segments)
5. Bounded thread pool via ThreadPoolExecutor (no unlimited thread growth)
6. Periodic GC + memory stats logging
7. LRU cache for manifest rewrites (avoid re-processing same manifest)
éN)Ú OrderedDict)ÚThreadingMixIn)Ú
HTTPServerÚBaseHTTPRequestHandler)ÚurlparseÚparse_qs)ÚThreadPoolExecutorz/tmp/o11pro_orig_urls.jsoni'z 127.0.0.1zuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36é2éédé é<ic Cs„t6ts0ttƒ
}t |¡aWdƒn1swYtdttƒdƒWdƒtSWdƒtS1s;wYtS)NzLoaded z
channel URLs)Ú_channel_urls_lockÚ
_channel_urlsÚopenÚ CONFIG_FILEÚjsonÚloadÚlogÚlen)Úrúsrc/modules/hls_proxy.pyÚ_load_channel_urls3s
 ÿ
üü
ÿûrcs(eZdZfddZfddZZS)ÚBoundedCookieJarcstƒj|i|¤ŽdS©N)ÚsuperÚ__init__©ÚselfÚargsÚkwargs©Ú __class__rrr>ózBoundedCookieJar.__init__csZtƒ |¡t|ƒtkr)t|ƒt}t|ƒ}|d|D]}| |j|j|j¡qdSdSr) rÚ
set_cookierÚMAX_COOKIES_PER_JARÚlistÚclearÚdomainÚpathÚname)rÚcookieZ to_removeZcookiesÚcr"rrr%As   üzBoundedCookieJar.set_cookie)Ú__name__Ú
__module__Ú __qualname__rr%Ú
__classcell__rrr"rr=s rcCsNt|tvr tƒt|<t ¡t|<t|WdƒS1s wYdSr)Ú_sessions_lockÚ _sessionsrÚtimeÚ_session_last_access)r)rrrÚ_get_jarNs 
 $ür6écs’t=t ¡fddt ¡Dƒ}|D]}t|=t|=q|r7tdt|ƒdttƒdƒWdƒdSWdƒdS1sBwYdS)Ncs g|] \}}ˆ|ˆkr|qSrr)Ú.0ÚÚmax_ageZnowrrÚ
<listcomp>Xs z)_evict_stale_sessions.<locals>.<listcomp>zEvicted z stale sessions, z
remaining)r2r4r5Úitemsr3rr)r<Zstaler9rr;rÚ_evict_stale_sessionsUs ù"úr?cC|rt|ƒnd}t|tvrt |¡t|WdƒSWdƒn1s)wYg}|r;| tj |¡¡tjj|Ž}t,|t|<t |¡t tƒt
krgtj ddt tƒt
ksSWdƒ|SWdƒ|S1srwY|S)NrF)Zlast) ÚidÚ_opener_cache_lockÚ
_opener_cacheÚ move_to_endÚappendÚurllibÚrequestZHTTPCookieProcessorZ build_openerrÚMAX_CACHED_OPENERSÚpopitem)Ú
cookie_jarZjar_idÚhandlersÚopenerrrrÚ _get_openercs2
ýÿ 
  ÿ
ýþ
ýûrLéc
Cst|ƒ}dti}|r||d<tjj||d}z(|j||d}| ¡|j|j  dd¡fWdƒWS1s7wYWdStj
j ym}z!|j rO| ¡nd} |jr[|j  dd¡nd}
| |j
|
fWYd}~Sd}~wtj
jtf}zWYd}~d Sd}~ww)
User-AgentÚReferer©Úheaders©Útimeoutú Content-Typeúapplication/octet-streamóz text/html)rVrú
text/plain)rLÚUArErFÚRequestrÚreadÚstatusrQÚgetÚerrorÚ HTTPErrorÚfpÚcodeÚURLErrorÚOSError) ÚurlrSrIÚrefererrKrQÚreqÚrespÚbodyÚctrrrÚ fetch_urlus$(ÿÿrjz
URI="([^"]+)"cs| d¡}g}|D]2}| ¡}d|vr&| d¡r&| t fdd|¡¡q |r6| d¡s6| t|ˆƒ¡q | |¡q d |¡S)
úURI="z#EXT-X-csdt| d¡ˆƒdS)Nrléú")Ú_absÚgroup)ÚÚbase_urlrrÚ<lambda>sz"rewrite_manifest.<locals>.<lambda>ú#)ÚsplitÚstripÚ
startswithrDÚ_compiled_uri_reÚsubroÚjoin)rhrsÚlinesZ rewrittenÚlineÚstrippedrrrrÚrewrite_manifestˆs
 ÿ 
rcCsD| dt¡s
| d¡r|S| d¡r|ntj ||¡}t||ƒS)http://127.0.0.1:údata:Úhttp)rxÚ
PROXY_PORTrEÚparseZurljoinÚ _to_proxy)rcÚbaseZresolvedrrrros
rocCstt | ¡¡ ¡ d¡}t|ƒj ¡ d¡rdnd}dt ||}|r8t | ¡¡ ¡ d¡}|d|7}|S)=z.m3u8ú/m/ú/s/r€z?r=)
Úbase64Zurlsafe_b64encodeÚencodeÚdecodeÚrstriprr*ÚlowerÚendswithrƒ)Zfull_urlrdÚencodedZrouteZ proxy_urlZref_encrrrr…œsr…cCs6dt|ƒd}|dkr|d|7}t | ¡¡ ¡S)r‡)rZurlsafe_b64decoder)rZpadrrrÚ _from_proxy¥s rcCs,|sdSt|ƒ}d|vrt|ddƒSdS)rr)rr)Z query_stringZqsrrrÚ _get_referer«s r”)ÚrequestsÚ manifestsÚsegmentsÚ
bytes_sentÚerrorsc@sLeZdZddZddZddZddZd d
Zd d Zd
dZ ddZ
dS)Ú
RobustHandlerc Cs8ttdd7<Wdƒn1swYt|jƒ}|j}|j}z3| d¡r4| ||¡WdS| d¡rB| ||¡WdS| d¡rP| ||¡WdS|  dd¡WdSt
y}z7ttdd7<Wdƒn1suwYz
|  d t |ƒ¡Wn YWYd}~dSWYd}~dSd}~ww)
Nr•rmz /channel/rˆr‰é”z Not foundr™) Ú _stats_lockÚ_statsrr*ÚqueryrxÚ_handle_channelÚ_handle_manifestÚ_handle_segmentÚ_errÚ ExceptionÚstr)rZparsedr*rgrrrÚdo_GET¿s2ÿ



ÿþüzRobustHandler.do_GETc
Cs | d¡}t|ƒdkrˆ|ddkrˆtj |d¡}tƒ}||vr€||}|}|r4|d|vr/dnd|7}tt|ƒjƒ}t ||d\} }
} |
d krut
t d
d 7<Wdƒn1s]wYt |  
d d
¡|ƒ} | d|  ¡¡dS| dd|
¡dS| dd¡dS| dd¡dS)/réz master.m3u8éú&)rIéÈrrmúutf-8Úreplaceúapplication/vnd.apple.mpegurléöú Upstream rzChannel not foundizBad channel path)rvrrEr„Zunquoterr6rÚnetlocrjrrÚ_okr)
rr*Úpartsr+ZurlsrcÚjarrhÚstriÚrwrrrÖs(
ÿzRobustHandler._handle_channelc
Ct|ddƒ}t|ƒ}tt|ƒjƒ}t|||d\}}}|dkrNttdd7<Wdƒn1s6wYt|  dd¡|ƒ} | 
d|   ¡¡dS|  d d
|¡dS) Nr§)rIrdrrmr­)
rr”r6rrjrrr)
rr*Útargetrdrhrirrrr îsÿzRobustHandler._handle_manifestc Ct|ddƒ}| d¡r<| d¡}|dkr<|d|||dd}}d|vr.t |¡ntj |¡}| d|¡dSt |ƒ}t
t |ƒj ƒ} d t
i}
|rQ||
d
<t| ƒ} tjj||
d } z˜| j| d d
†}
|
j dd¡}|
j d¡}| d¡| d|¡|r†| d|¡| dd¡| ¡d} |
 t¡}|snz|j |¡|t|ƒ7}Wn tttfYnwq“tt dd7<t d|7<Wdƒn1sÔwYWdƒWdSWdƒWdS1sîwYWdStj!j"y}z| #dd|j$¡WYd}~dSd}~wtj!j%tfy8}z| #ddt&|ƒj'¡WYd}~dSd}~wt(ya}zz
| #dt)|ƒ¡Wn YWYd}~dSWYd}~dSd}~ww)Nr§rú,rérmrUrNrOrPérRrTúContent-Lengthr«úAccess-Control-Allow-OriginÚ*Tr—r˜z
Fetch error: )*rrxÚfindrŠZ b64decoderEr„Zunquote_to_bytesr²r”r6rrXrLrFrYrrQr\Ú
send_responseÚ send_headerÚ end_headersrZÚSEGMENT_STREAM_BUFÚwfileÚwriterÚBrokenPipeErrorÚConnectionResetErrorrbrr]r^r`raÚtyper.)rr*r¸ZcpÚmetaZpayloadÚbrdrQrKrerfriZcontent_lengthZ
total_sentÚchunkrgrrrûst

  
   
 ÿù þí"&þþzRobustHandler._handle_segmentc
CzF| d¡| d|¡| dtt|ƒƒ¡| dd¡| ¡|j |¡ttdt|ƒ7<WdƒWdS1s?wYWdSt t
t fySYdSw)Nr«rTr˜) rrrb)rrirhrrr,s
   &ÿÿzRobustHandler._okc
Cshz&| |¡| dd¡| ¡}| dtt|ƒƒ¡| ¡|j |¡WdStt t
fy3YdSw)NrTrW) rrrb)rr`Úmsgrhrrr9s