Nc@sdZddlZddlZddlZddlZddlZddlZddlmZm Z ddl m Z ddl m Z mZddlmZejdZejZdZed Zeaed eate_eaed d d dddddddddddddddfZed d ddfZdZ dZ!edZ"ed Z#d!eeed"Z$ej%d#Z&ej%d$Z'd%Z(d&Z)ed'Z*eeed(Z+d)Z,ej%d*Z-ej%d+ej.Z/ej%d,ej.Z0ej%d-ej.Z1d.Z2ed/Z3d0d1e4e4eeefe4eeed2 Z5d d3d4Z6d5e7fd6YZ8d7e7fd8YZ9e4d9Z:d:Z;d;Z<dS(<sF This file is part of the web2py Web Framework Copyrighted by Massimo Di Pierro License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) gluon.rewrite parses incoming URLs and formats outgoing URLs for gluon.html.URL. In addition, it rewrites both incoming and outgoing URLs based on the (optional) user-supplied routes.py, which also allows for rewriting of certain error messages. routes.py supports two styles of URL rewriting, depending on whether 'routers' is defined. Refer to router.example.py and routes.example.py for additional documentation. iN(tStoragetList(tHTTP(tabspatht read_file(tglobal_settingssweb2py.rewritecCsptddddddddd d d td dd ddddgdddtdtdddddd}|S(s&return new copy of default base routertdefault_applicationtinitt applicationstALLtdefault_controllertdefaultt controllerstDEFAULTtdefault_functiontindext functionstdefault_languaget languagest root_statics favicon.icos robots.txttdomainstexclusive_domaint map_hyphent acfe_matchs\w+$t file_matchs(\w+[-=./]?)+$t args_matchs([\w@ -]+[=.]?)*$N(RtdicttNonetFalse(trouter((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt_router_default"s"   cCst}|pd|_|p!d|_d|_d|_g|_g|_g|_g|_g|_ d |_ d|_ dddd |_ d |_|S( s%return new copy of default parameterstBASERR Rs%

%s

s

Internal error

Ticket issued: %(ticket)sN(RtnameRR Rt routes_appt routes_int routes_outtroutes_onerrortroutes_apps_rawRt error_handlert error_messageterror_message_tickettrouters(tapptp((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt_params_default7s           R+RRR R RRRRtdomainRRt path_prefixRRt map_staticRRRcCs trt||St||S(sparse and rewrite incoming URL(R*t map_url_int regex_url_in(trequesttenviron((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyturl_ings c CsDtr@t|||||||||| } d| |f} n%d||||f} t| |} |sw| dk r|dkrt}qn| s|tkr|r|jr|jjddj}qd}n|dk r|tkr|jj}qn|r@| dkrd} n d| } d||| | f} n| S( s!assemble and rewrite outgoing URLs%s%ss /%s/%s/%s%stWSGI_URL_SCHEMEthttpts:%ss %s://%s%s%sN( R*t map_url_outtregex_filter_outRtTruetenvtgettlowert http_host( R3R<t applicationt controllertfunctiontargstothertschemethosttporttacfturl((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyturl_outms*'        c Cstt|jjd}|dkrtjjrtd|j|fd|jd|df}x tjjD]\}}||krt|dkr||fSd|kr|jdd \}} | d 7} n |d }} | d |||j j |j f7} |j d s!|j drR|d| } d} t d| | d| |fS||dkr||d<| |dherei/tLocationt PATH_INFOt QUERY_STRINGN(tinttstrtstatustsplittthreadtroutesR%tsetR@R<t request_uriRIt startswithRR( t http_responseR3R4tticketRStkeystkeyturit path_infot query_stringRItmessage((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyttry_rewrite_on_errors4          cCstt|jjd}|dkr tjjr td|j|fd|jd|df}xtjjD]\}}||krt|dkrPnSd|krd ||||j j |j f}n"d ||||j j |j f}t d d |d |SqtWn|S(s6called from main.wsgibase to rewrite the http responseiis%s/%ss%s/*s*/%ss*/*RKRLs4%s&code=%s&ticket=%s&requested_uri=%s&request_url=%ss4%s?code=%s&ticket=%s&requested_uri=%s&request_url=%si/s.You are being redirected hereRN( RQRRRSRTRURVR%RWR@R<RXRIR(t http_objectR3R[RSR\R]tredirRI((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyttry_redirect_on_errors&     " s routes.pycBs@|dkr6eaeddate_dane|er]ed|}d}n|dk rrd}n[|dkre |}ne d||}e j j |sdSe |jdd}i}y|d|UWn4ek r}ejd |ej|nXe|}xRdD]J}||kr-x5||D]&\} } ||je| | qJWq-q-Wx+dD]#}||kr||||     s(?.*)s (?P<%s>\w+)s\g<%s>( tfindRotregex_anythingtfindallRntregex_attretcompiletDOTALL(RRtk0tititem((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyRu5s&    cCsx9tjD]+}||kr|j|ttj}|dkrx=t|jD](}|tkrXtd||fqXqXWn|jt||t| %ss%s: [%s] -> %s (not rewritten)(R=R>RtmatchtsubRpR|( RtregexesttagR RlRFRR]tregextvaluet rewritten((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt regex_uris    cCs|rtj|tt_na|rvtjrvtrIt||dtqt |tjd}tj|tt_n tt_t j dtjj |S(sF select a set of regex rewrite params for the current request R+R"sselect routing parameters: %s( RhR=RiRURVR"R*R1R;RRpR|R!(R<R+R3((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt regex_selects cCs|jdd }|d|r)d|p,d|d \w+) # b=app /static # /b/static /(?P (\w[\-\=\./]?)* ) # x=file $) s (^( # (/a/c/f.e/s) /(?P [\w\s+]+ ) # /a=app ( # (/c.f.e/s) /(?P [\w\s+]+ ) # /a/c=controller ( # (/f.e/s) /(?P [\w\s+]+ ) # /a/c/f=function ( # (.e) \.(?P [\w\s+]+ ) # /a/c/f.e=extension )? ( # (/s) /(?P # /a/c/f.e/r=raw_args .* ) )? )? )? )? /?$) sy (^ (?P ( [\w@/-][=.]? )* # s=args )? /?$) # trailing slash c Cstd|d|tjjr.t|}nx9|jD]+\}}||j|jjddRnR_t regex_staticRt regex_spaceRtgroupRkRltjointapplications_parentRt regex_urlRR(RR@R RARRBRt raw_extensiont extensiontraw_argsRRCR&t regex_argsRTR( R3R4R]RRlRt static_filetgroup_etgroup_s((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyR2#sN  #  ***!  $ cCszttdstntr#|Stjjre|jdd}|r|jddj}|j d}|dkr|| }nd|jd d |jd d j||jd dj|df|d %ssroutes_out: [%s] not rewritten(thasattrRURR*RVR$RTR=R>RRRRRpR|(RIRRRFRRRR((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyR:is.    ** R=s0.0.0.0c  CsYtjd} | j|} | jdj} | jdj}| jd}|jd}|dkrt|}n|| ||d}}tj|}i |d6|d 6| d 6|d 6|d 6|d 6|d6|d6|d6| d6|d6}t }t j |dhttp|https|HTTP|HTTPS)\://(?P[^/]*)(?P.*)RERFR^RLiiRRR6RRRORPRRRR?RR+RiR8isat least /a/c/f is requireds%s/%ss /%s/%s/%sRs.%ss %ss ?%ss (%s)N("RRRRR>RRturllibtunquoteRRRR<t uri_languageR*R1R;Rtdomain_applicationtdomain_controllertlstripRTRtAssertionErrorR:R9RRR5R@RARBRRC(RItmethodtremotetoutR+tlangR.R<RERFRGRRt urlschemeturlhostR^RR_R`RR3RRRRRHRtresult((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt filter_urls        '   ttktcCs|dkrtjjrtd||fd|d|df}x|tjjD]k\}}||krO|dkrwPn?d|kr|dd ||f}n|dd ||f}|SqOWn|S( s,doctest/unittest interface to routes_onerroris%s/%ss%s/*s*/%ss*/*RKRLRMscode=%s&ticket=%s(RURVR%RW(RSR@R[R\R]RdRI((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt filter_errs     tMapUrlIncBseZdZdddZdZdZdZdZdZ dZ dZ d Z d Z ed Zed Zd ZRS(slogic for mapping incoming URLscCsd||_||_d|_d|_d|_d|_d|_d|_t |_ t |_ t |_ d|_t|_t|_|jd}|jjdd|_|jd}d||jd<|jd|jrd|jpd|jd<|jdr|d }nt|r.|jdp1g|_|jjd d |_|jjd d j|_|jjd dj|_|jjd|_d|_|js|jjd|_|jjd|_n|jsd |_d|_nd|jkr0|jjd\|_|_n|js`|jdkrTd|_q`d|_ndS(sinitialize a map-in objectRRORPRRLR8RiRRR6R7RR=Rt SERVER_NAMEt SERVER_PORTt80Rthttpst443N(R3R<RRR@tlanguageRARBRRWR RRRRRRRR=RRRRRTRCRR>RERRFRG(tselfR3R<Rl((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt__init__sN               . $     !  cCstjj}|rt|}|t|jkr7dSx/t|D]!}|||j|krDdSqDWt|j||_ndS(s-strip path prefix, if present in its entiretyN(R*RR/RRCtxrangeR(Rtprefixt prefixlenR((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt map_prefix#s  c Cstj}d |_d |_d |_|j}|j|jf|j kr|j |j|jf\|_ |_|_|j |j d<|j|j d<|j|j dN(RCRRRRRURVR((Rtarg((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt validate_argssc Cs|j|j_|j|j_|j|j_|j|j_|j|j_|jrf|j|j_nd|j|j|jf}|jr|j dd}n|jdkr|d|j7}n|jrd|j|f}n||jr&t j ddj g|jD]}t |^qp)d7}||jrFd |jpId7}||jd (RR^R R]R((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pytupdate_requests&   K  cCs |jdS(sreturn first argi(RC(R((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyRscCs>|jr1|jdr1|jdjddS|jdS(s-return first arg with optional hyphen mappingiRR(RRCRn(R((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyRscCs|r|jjdndS(s7conditionally remove first arg and return new first argiN(RCR(Rtdopop((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyRsN(t__name__t __module__t__doc__RRRRRRRR0RRRtpropertyRRR(((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyRs4 5     t MapUrlOutcBs;eZdZdZdZdZdZdZRS(slogic for mapping outgoing URLsc CsFtjj|_|tkr+t||_n tj|_||_||_||_||_||_||_ ||_ ||_ | |_ | |_ tjj|_|jj|_|jjj|jt|_|jj|_|jj|_|jj|_|jj|_|jj|_tjj|_|o<|jjj|_|oT|jjj|_t|jjtr|jjj|jd|_n|jj|_|jjr|jr|j|jkr|j rtdn|o|j } | r|jr| |jkr| |_!n d|_!t"|_#t"|_$t"|_%t"|_&dS(sinitialize a map-out objects(cross-domain conflict: must specify hostN('R*RRRR3R<R@RARBRCRDRERFRGRR RR=RWRRRRR0R/RRRjRRRRoRRRtomit_applicationt omit_languagetomit_controllert omit_function( RR3R<R@RARBRCRDRERFRGR((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyRsL            !!1      cCs,|j s|j|jkr(t|_ndS(somit language if possibleN(RRR;R (R((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt omit_lang/scCs|j}|j rm|j|jkrmt|_|j|jkrmt|_|j |j krjt|_ qjqmn|j p||j }|j |krt|_ n|j |j kr|j p|jpd}|j|krt|_n|jr|j|jkr|j|jkrt|_n|jr|j s=|j|jkrIt|_ n|j r|j sn|j|jkr}t|_q}qn|j s|j|jkrt|_n|jr|jd|jks|jd|jks|jd|jkrt|_qn|jr>|j|jks/|j|jkr>t|_q>n|j rh|j|jkrht|_ qhn|jdks|jjdr|jst|_ |jrt|_qnt|_t|_ndS(somit what we can of a/c/fR8iRsstatic/N(RRCRBRR;R RAR R R@RR RRRR RRR RYR0R(RRRR ((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pytomit_acf5sN    * -      B $ !    cCs0d}|jr|jjdd|_|jjdd|_|jdkr|jjd r|jjdd|_qn|js|d|j7}n|js|d|j7}n|j s|d|j7}n|j s|d|j7}n|j rddj |j |}n|j r&|S|p/dS(sbuild acf from componentsR8RRRsstatic/R(RR@RnRARYRBR R RR R R/RRC(RRH((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyt build_acfvs& "      cCs(ts dS|j|j|jS(s3convert components to /app/lang/controller/functionN(R*RRRR(R((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyRHs   (RRRRRRRRH(((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyR s  1  A cCstt_td|d|}|j|jtjrStj|tt_n|r`|j S|j }|r||j fS|j |j |j}|r||j fS|j|j|jd|j fS(sroute incoming URLR3R<N(RiRURVRRRR"RhR=R@RR<RRR0RRRR(R3R<R+tmapRR((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyR1s(             c Cs1t|||||||||| } | jS(s supply /a/c/f (or /a/lang/c/f) portion of outgoing url The basic rule is that we can only make transformations that map_url_in can reverse. Suppose that the incoming arguments are a,c,f,args,lang and that the router defaults are da, dc, df, dl. We can perform these transformations trivially if args=[] and lang=None or dl: /da/dc/df => / /a/dc/df => /a /a/c/df => /a/c We would also like to be able to strip the default application or application/controller from URLs with function/args present, thus: /da/c/f/args => /c/f/args /da/dc/f/args => /f/args We use [applications] and [controllers] and {functions} to suppress ambiguous omissions. We assume that language names do not collide with a/c/f names. (R RH( R3R<R@RARBRCRDRERFRGR((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pyR9s'cCs%t s|tkrdStt|S(sKreturn a private copy of the effective router for the specified applicationN(R*RR(R((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pytget_effective_routers(=RRkRtloggingRrt threadingRtstorageRRR7Rt fileutilsRRtsettingsRt getLoggerRptlocalRURRR-RRhRiRVR*RWRRyR5RJRbReRzRRRRuR{RRRRtXRRRR2R:RRRtobjectRR R1R9R(((s;/home/spiffy/Documents/programs/mobileblur/gluon/rewrite.pytsl                 $ j % `    F R