o ]LbG@sddlmZddlZddlZddlmZmZmZmZm Z ddl m Z ddl m Z mZmZmZmZmZmZm Z mZmZmZmZmZmZmZmZddl mZmZm Z m!Z!d d Z"dd d Z#dddZ$Gddde%Z&Gddde%Z'ddZ(dS))absolute_importN) ErrorResponseHTTP_BAD_REQUEST cspvalues permhooks statusmessage)getattr)encodingerror extensions formatterhghook profilingpycompat registrarrepoviewtemplatefilters templater templateutiluiutilwireprotoserver)request webcommandswebutilwsgicgicCs(|jdd|dddf}|t||fS)Nstylewebspaper)qsparamsget _stylemap)reqconfigfn templatepathstylesr(;/usr/lib/python3/dist-packages/mercurial/hgweb/hgweb_mod.pygetstyle2s r*cCs|D]>}|r|tjtjfvstj|vstjrtj|vrqtj|dd|df}|D]}t ||\}}|r?|||fSq*qt d|)zReturn path to mapfile for a given style. Searches mapfile in the following locations: 1. templatepath/style/map 2. templatepath/map-style 3. templatepath/map smapsmap-sNo hgweb templates found in %r) roscurdirospardirosseposaltsepospathjoinrtry_open_template RuntimeError)r'r0style locationslocationmapfilefpr(r(r)r#;s"    r#cCs|dr |dd}|rd||}|}|dr |dd}g}|}dg|d}t|D]}|r6|s8n|||dtj|}q0t t|S)zReturn a 'URL breadcrumb' list A 'URL breadcrumb' is a list of URL-name pairs, corresponding to each of the path items on a URL. This can be used to create path navigation entries. /Nrr9)urlname) endswith startswithsplitreversedappendr/r0dirnamer mappinglist)urlprefixrelpath breadcrumburlel pathitemspathelr(r(r)makebreadcrumbXs      rLc@sPeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ dS)requestcontextzHolds state/context for an individual request. Servers can be multi-threaded. Holding state on the WSGI application is prone to race conditions. Instances of this class exist to hold mutable and race-free state for requests. cCs||_|j|_||_||_|dd|_|dd|_|dd|_|dd|_| dd|_ |j dddd |_ |j |_ t|jj\|_|_dS) Nr s maxchangessstripessmaxshortchangessmaxfiless allow-pulls templatesF untrusted)reporeponamer$res configint maxchanges stripecountmaxshortchangesmaxfiles configbool allowpullconfigr& websubtablerrcspnonce)selfapprPr$rRr(r(r)__init__zszrequestcontext.__init__cO |dd|jjj|i|SNrOT) setdefaultrPrrZr^argskwargsr(r(r)rZ zrequestcontext.configcOrarb)rcrPrrXrdr(r(r)rXrgzrequestcontext.configboolcOrarb)rcrPrrSrdr(r(r)rSrgzrequestcontext.configintcOrarb)rcrPr configlistrdr(r(r)rhrgzrequestcontext.configlistcCst|jj|SN)r archivelistrPr)r^nodeidr(r(r)rjszrequestcontext.archivelistc sNdd}dd}ddp|jdd}|ds#|d7}i}t|jj\}\}}} ||dkr<||d<t|d } jsWdd d pU|jpU|jpUj j _i} t | } | d t d fdd} |jd||||jjtj| t|j|jd }t |}|dddfdd}tj jj }tjj|| | ||dS)Nr logourllogoimg staticurlr:s/static/rr?r=r9swebsub)intypecst|jSri)rwebsubr[)textr^r(r) websubfiltersz.requestcontext.templater..websubfilter) r<rlrmrnsurlbasesrepoencodings sessionvarsspathdefrsnoncemotdr()requiresc3sddVdS)Nr rv)rZ)contextmappingrsr(r)motdsz&requestcontext.templater..motd)r8filtersdefaults resources)rZapppathrstripr>r*r&r sessionvarsrQrProotrtemplatefilterbytesadvertisedbaseurlr rLr]templatekeywordrtemplateresourcesrr frommapfile)r^r$logourllogoimg staticurlvarsr'r4r7r8rr{rrtr|rrztresr(rsr)rsZ           zrequestcontext.templatercKs*t|}|j|j|||jS)z=Helper function to send a response generated from a template.)r byteskwargsrR setbodygentmplgenerate sendresponse)r^namerfr(r(r) sendtemplates  zrequestcontext.sendtemplateN) __name__ __module__ __qualname____doc__r`rZrXrSrhrjrrr(r(r(r)rMrs @rMc@sXeZdZdZdddZddZejddZd d Z d d Z d dZ ddZ ddZ dS)hgweba*HTTP server for individual repositories. Instances of this class serve HTTP responses for a particular repository. Instances are typically used as WSGI applications. Some servers are multi-threaded. On these servers, there may be multiple active threads inside __call__. NcCs4t|tr"|r |}ntj}t|t|t ||}n|}|j dddd|j dddd|j dddd|j dddd|j dd|j d|j dd|j d|j ddd d|j ddd d|j d d dd|j d d ddt ||g|_|jd |_td ||_dS)Nsuisreport_untrustedsoffshgwebsnonttystruesforcecwdssignal-safe-locksfalsesprogresssdisablerT) isinstancercopyuimodrloadr loadall populateuir repository setconfigbaseuircachedlocalrepo _webifyrepo_repos _lastreporredirectrQ)r^rPrrurr(r(r)r`s,        zhgweb.__init__cCst|}t||_|Sri) getwebviewr getwebsubsr[)r^rPr(r(r)rs zhgweb._webifyrepoc csz|jr|j}|\}}n |j}|\}}|r"||}||_|j|_z |VW|j|dS|j|w)aObtain a repo unique to the caller. Internally we maintain a stack of cachedlocalrepo instances to be handed out. If one is available, we pop it and return it, ensuring it is up to date in the process. If one is not available, we clone the most recently used repo instance and return it. It is currently possible for the stack to grow without bounds if the server allows infinite threads. However, servers should have a thread limit, thus establishing our limit. N)rpopfetchrrrmtimerB)r^cachedrcreatedr(r(r) _obtainrepo#s    zhgweb._obtainrepocCs*tjdddstdt|dS)zStart a server from CGI environment. Modern servers should be using WSGI and should avoid this method, if possible. sGATEWAY_INTERFACEr9sCGI/1.sJThis function is only intended to be called while running as a CGI script.N)r environr"r?r3rlaunchrsr(r(r)run@sz hgweb.runcCs"t|}t||}|||S)zSRun the WSGI application. This may be called by multiple threads. ) requestmodparserequestfromenv wsgiresponserun_wsgi)r^envrespondr$rRr(r(r)__call__Os   zhgweb.__call__c cs|=}|jdd}tj|j|d||||D]}|VqWdn1s-wYWddSWddS1sEwYdS)zInternal method to run the WSGI application. This is typically only called by Mercurial. External consumers should be using instances of this class as the WSGI application. s profilingsenabled)enabledN)rrrXrprofile_runwsgi)r^r$rRrPrrr(r(r)rYs "zhgweb.run_wsgic Cst||||}|ddt_|j|jj_|jr|j|jd<t ||||j }|r,| S|j dur5|j }n |jdddd}|dd}d |jvr|r|dr|d}|d } | d krr|d| |jd <|| d d}tt|r}||jd <|dkrd||jd<n+|r|dr|ddd} | |jd<|rd|jvr|jd=|D] } |jd| q|jdd} |dkrd| vrd|jd <|dkr|jd} ttjD]\}}|d}| |r| dt | |jd<||jd<qn|jd d}z|!||_"|j"#ddtji}|dkr| ||d|dkr0|j"#di|jd <|jd }|$ddrl|j%sld|j&}|jd|krgd|_'z|jd=Wn t(y\Ynw|)d| WS||jd <|tj*vr{d!|}t+t,|d"|_'||jd<t-t||WSt.j/t.j0fy}z-t1|}t|d#rt2|t.j3sd$|j4}d%|_'||jd<|j5d&|d'WYd}~Sd}~wt.j6t.j7fy}zd(|_'||jd<|j5d&t1|d'WYd}~Sd}~wt.j8y}zd)|_'||jd<|j5d&|j9d'WYd}~Sd}~wt+yL}z-|jD] \}}||j|<qt:|j;t1||_'||jd<|j5d&t1|d'WYd}~Sd}~ww)*Nr rusContent-Security-Policy&r;r:r scmd-r;rrsstaticsfiles%2Fsnodes User-Agentr9srevs mercurialsrawsarchivestypesmimetypesdefaultscachesW/"%d"s If-None-Matchs304 Not Modifieds Content-TypesETagsno such method: %ss200 Script output followsr=srevision not found: %ss 404 Not Foundserror)r s500 Internal Server Errors 403 Forbidden)lenrrrenderrXr]rstatusKeyError setbodybytes__all__rrr r LookupErrorRepoLookupErrorbytestrrManifestLookupErrorrr RepoError StorageErrorAbortmessagercode)r^r$rRrPrctxhandledqueryrecmdr4nodeauafntype_specextctypetagmsgerrekvr(r(r)res                                     zhgweb._runwsgicCstD]}||||qdSri)r)r^rr$oppermhookr(r(r)rszhgweb.check_perm)NN)rrrrr`r contextlibcontextmanagerrrrrrrr(r(r(r)rs #    rcCs@|jjdddd}|dkr|S|tjvr||S|dS)aThe 'web.view' config controls changeset filter to hgweb. Possible values are ``served``, ``visible`` and ``all``. Default is ``served``. The ``served`` filter only shows changesets that can be pulled from the hgweb instance. The``visible`` filter includes secret changesets but still excludes "hidden" one. See the repoview module for details. The option has been around undocumented since Mercurial 2.5, but no user ever asked about it. So we better keep it undocumented for now.r sviewTrNsallsserved)rrZ unfilteredr filtertablefiltered)rP viewconfigr(r(r)rs     rri)r9)) __future__rrr/commonrrrrrrr r r r rrrrrrrrrrrrrrrrrrr*r#rLobjectrMrrr(r(r(r)s  H }