PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/usr/share/doc/proftpd/howto/
Upload File :
Current File : //usr/share/doc/proftpd/howto/Rewrite.html
<!DOCTYPE html>
<html>
<head>
<title>ProFTPD: Using mod_rewrite</title>
</head>

<body bgcolor=white>

<hr>
<center><h2><b><i>ProFTPD: Using the <code>mod_rewrite</code> Module</i></b></h2></center>
<hr>

<p>
The <a href="../contrib/mod_rewrite.html"><code>mod_rewrite</code></a> module for <code>proftpd</code> is a powerful tool
for rewriting FTP commands received from clients.  It has been used to
automatically append (or remove) domain names from logins, to translate
Windows paths (using backslashes) to Unix paths (using slashes), to handle
case-insensitive files, <i>etc</i>.  One of the great things about
<code>mod_rewrite</code> is that <b>any</b> modification made to the commands
is transparent to the client; that is, FTP clients are completely unaware
that their commands are being changed on-the-fly.

<p>
The following is a collection of examples of how <code>mod_rewrite</code>
has been used.  If you use <code>mod_rewrite</code> and would like to contribute
your recipe/configuration, please let us know!

<p>
Since much of <code>mod_rewrite</code>'s power is based on regular expressions
and pattern matching, I highly recommend that you read through this
introduction to POSIX regular expressions, and use the <a href="http://www.castaglia.org/proftpd/doc/contrib/regex.html"><code>regex</code></a> tool for
testing out your regexes against paths/strings:
<pre>
  <a href="http://www.castaglia.org/proftpd/doc/contrib/regexp.html">http://www.castaglia.org/proftpd/doc/contrib/regexp.html</a>
</pre>

<p>
<b>Case Sensitivity</b><br>
The following example configuration shows how to configure
<code>mod_rewrite</code> so that all files uploaded to the FTP server will have
all-uppercase filenames:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    # Have a log for double-checking any errors
    RewriteLog /var/log/ftpd/rewrite.log

    # Define a map that uses the internal "toupper" function
    RewriteMap uppercase int:toupper

    # Make the file names used by STOR be in all uppercase
    RewriteCondition %m STOR

    # Apply the map to the command parameters
    RewriteRule ^(.*) ${uppercase:$1}
  &lt;/IfModule&gt;
</pre>

<p>
What if you wanted to make the filename always be uppercase for uploaded
files, but <b>not</b> any directories in the path leading up the file name?
Using the above, if you did:
<pre>
  ftp&gt; cd /upload
  ftp&gt; put file1.txt
</pre>
The file would appear as "/upload/FILE1.TXT".  <i>But</i> if you did:
<pre>
  ftp&gt; put /upload/file1.txt
</pre>
the file would appear as "/UPLOAD/FILE1.TXT", which may not be what you want.
To handle this, you need to change the "^(.*)" pattern in the
above <code>RewriteRule</code> directive.  The "^(.*)" regular expression
matches the entire parameter string.  Instead, you might try this pattern:
<pre>
  RewriteRule (.*/)?(.*)$ ${uppercase:$2}
</pre>
which tries to isolate into match group 2 (<i>i.e.</i> <code>$2</code>) the
part of the argument string which is not followed by any slashes.

<p>
Somewhat similar is the situation where the admin found, for case-sensitivity
reasons, that it was easier to rewrite <b>all</b> FTP commands (except
<code>PASS</code>, since passwords are case-sensitive) to be lowercase:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    # Define a map that uses the internal "tolower" function
    RewriteMap lowercase int:tolower

    # Rewrite all commands except PASS
    RewriteCondition %m !PASS

    RewriteRule ^(.*) ${lowercase:$1}
  &lt;/IfModule&gt;
</pre>
This means an FTP client can refer to "/DiR/Dir2/FiLe" when on the server the
file is actually "/dir/dir2/file"; it works for uploads, too. (This works
especially well for Windows clients.)

<p>
<b>Trimming Whitespace</b><br>
Some FTP clients can properly handle files whose names start with spaces,
but other FTP clients cannot.  If your users use whatever FTP clients they
wish, you need may need to deal with this situation on the server side of
things.  The <code>mod_rewrite</code> module can help with this, by
automatically trimming leading/trailing whitespace from commands.
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    # Trim whitespace for commands dealing with files
    RewriteCondition %m LIST|MLST|NLST|RETR|STAT|STOR

    # Only the portion of the command that matches our rule is used.
    # This works by saying "match all non-space characters".
    RewriteRule [^[:space:]]+ $0
  &lt;/IfModule&gt;
</pre>

<p>
<b>Changing the Filenames</b><br>
One user had the following problem: Files uploaded via a web browser had their
filenames changed by the browser.  Specifically, the web browser changed
any spaces in the filenames to "%20" (URL encoding for a space character).
Fortunately, the user was able to use <code>mod_rewrite</code> to undo the
change or, as shown below, to change that "%20" to an underscore:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    # Define a map that uses the internal "replaceall" function
    RewriteMap replace int:replaceall

    # We only want to use this rule on STOR commands
    RewriteCondition %m STOR

    # Apply the map to the command parameters.  Use '!' as the delimiter,
    # not '/', as the path sent might contain slashes
    RewriteRule ^(.*) "${replace:!$1!%20!_}"
  &lt;/IfModule&gt;
</pre>

<p>
Another site wanted to "tag" each uploaded file name with the current process
ID (PID), to ensure some sort of file name uniqueness.  Enter
<code>mod_rewrite</code>!
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    RewriteCondition %m STOR
    RewriteRule (.*) $1.%P
  &lt;/IfModule&gt;
</pre>
This appends the PID of the current session process to any uploaded filename.
For more variables like <code>%P</code>, see the <a href="../contrib/mod_rewrite.html#RewriteCondition"><code>RewriteCondition</code></a> and <a href="../contrib/mod_rewrite.html#RewriteRule"><code>RewriteRule</code></a> descriptions.

<p>
<b>Replacing Backslashes With Slashes</b><br>
Some sites have FTP clients which seem to send <code>CWD</code> and
<code>RETR</code>/<code>STOR</code> commands which use Windows-style
backslashes, <i>e.g.</i> "path\to\file".  And ideally, these sites would like
to work seamlessly with such clients, without having to get the clients to
change.  Can <code>mod_rewrite</code> be used to change those backslashes
into more Unix-friendly regular slashes?  Absolutely.

The following <code>mod_rewrite</code> configuration should do the trick:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    # Use the replaceall internal RewriteMap
    RewriteMap replace int:replaceall

    RewriteRule (.*) "${replace:!$1!\\\\!/}"
  &lt;/IfModule&gt;
</pre>
Yes, you will need the four consecutive backslashes there, in order to make it
past proftpd's config file parser (which thinks backslashes are escape
sequences) as well as the regular expression compiler.

<p>
<b>Modifying User Names</b><br>
Is there a way that I can transparently change the login name that the FTP
client sends, from one set of known login names to the new set of names
that should be used by the FTP server?  But of course!  For this example,
let us assume that you have a text file which maps the old login names to
the new login names.  Using <code>mod_rewrite</code>'s <code>RewriteMap</code>
directive and that text file, this becomes simple:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    # Tell mod_rewrite where to find the "usermap" text file
    RewriteMap usermap txt:/path/to/usermap.txt

    # For USER commands, use the "usermap" file to translate the login names
    RewriteCondition %m USER
    RewriteRule (.*) ${usermap:$1}
  &lt;/IfModule&gt;
</pre>

<p>
Rather than having a fixed map of old-to-new login names, what if you wanted
to always append the same prefix (or suffix) to every login name?  For 
example, what if you wanted every login name on your FTP server to look
like "user@domain.com", but the clients were sending simply "user".  This
solution does not need <code>RewriteMap</code>; instead, you simply use:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    RewriteCondition %m USER
    RewriteRule (.*) $1@domain.com
  &lt;/IfModule&gt;
</pre>
And if instead you wanted to use a fixed prefix, rather than a suffix, the
only difference would be in the <code>RewriteRule</code> directive, <i>e.g.</i>:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    RewriteCondition %m USER
    RewriteRule (.*) PREFIX$1
  &lt;/IfModule&gt;
</pre>

<p>
Another interesting use case is where your clients might send the login
name in a variety of constructions, <i>e.g.</i>:
<ul>
  <li><i>user</i>
  <li><i>user</i>@domain.com
  <li>prefix#<i>user</i>@domain.com
</ul>
but you want the FTP server only to use the "<i>user</i>" parts.  How can
you configure <code>mod_rewrite</code> to strip off any potential prefix
and suffix?  Regular expressions can be tricky, but using the <code>regex</code>
tool mentioned above, I worked out the following configuration that does
the trick:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    RewriteCondition %m USER
    RewriteRule ^(.*#)?([0-9A-Za-z]+)(@)? $2
  &lt;/IfModule&gt;
</pre>

<p>
And if you simply wanted to have all user names be in lowercase, despite what
the FTP clients send, it's merely a matter of:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    RewriteMap lowercase int:tolower
    RewriteCondition %m USER
    RewriteRule (.*) ${lowercase:$1}
  &lt;/IfModule&gt;
</pre>

<p>
<b>Handling Clients' Bad PORT Commands</b><br>
A ProFTPD admin encountered a case where one of their customers refused to
use anything but the standard command-line FTP client that comes with Windows.
That FTP client does <b>not</b> support passive data transfers; it <i>always</i>
uses the <code>PORT</code> command to do active data transfers.  However,
one issue with the <code>PORT</code> command is that the parameter contains
an IP address.  In this situation, the FTP client was behind a NAT, and the
client was sending the <i>internal</i> LAN address in its <code>PORT</code>
command.  Could <code>mod_rewrite</code> be used to solve the problem, and
allow that bad FTP client to use active data transfers despite its' sending
of an unusable (to the FTP server) IP address?  Yes!

<p>
The solution was to use <code>mod_rewrite</code> to rewrite the address in
the sent <code>PORT</code> command, replacing the internal LAN address with
the IP address of the client that <code>proftpd</code> saw.  Below is the
configuration used to make this work:
<pre>
  # This is necessary, to keep proftpd from complaining about mismatched
  # addresses in this situation
  AllowForeignAddress on

  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on

    RewriteMap replace int:replaceall

    # Substitute in the IP address of the client, regardless of the address
    # the client tells us to use in the PORT command
    RewriteCondition %m ^PORT$
    RewriteRule ([0-9]+,[0-9]+,[0-9]+,[0-9]+)(.*) ${replace:/$1/$1/%a$2}

    # Replace the periods in the client address with commas, as per RFC959
    # requirements
    RewriteCondition %m ^PORT$
    RewriteRule (.*) ${replace:/$1/./,}
  &lt;/IfModule&gt;
</pre>

<p>
<b><code>SITE</code> Commands</b><br>
The <code>mod_rewrite</code> module can also handle <i>some</i>
<code>SITE</code> commands, specifically:
<ul>
  <li><code>SITE CHGRP</code>
  <li><code>SITE CHMOD</code>
</ul>
These being supported by the <code>mod_site</code> module, which is part of
the normal <code>proftpd</code> build.

<p>
One site needed to make sure that any backslashes (<i>e.g.</i> used by Windows
clients) were translated to slashes, including in these <code>SITE</code>
commands.  As of ProFTPD 1.3.2 (see <a href="http://bugs.proftpd.org/show_bug.cgi?id=2915">Bug #2915</a>), this can be accomplished using the following:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on
    RewriteMap replace int:replaceall
    RewriteCondition %m "^SITE CHMOD$" [NC]
    RewriteRule "^(.*) +(.*)$" "$1 ${replace:!$2!\\\\!/}"'
  &lt;/IfModule&gt;
</pre>
Notice how, for <code>SITE CHGRP</code> and <code>SITE CHMOD</code> commands,
the <code>%m</code> parameter in the <code>RewriteCondition</code> <b>must</b>
match the string "SITE CHGRP" or "SITE CHMOD", not just "SITE".  This is
<i>important</i> -- and it only works for the
<code>SITE CHGRP</code>/<code>SITE CHMOD</code> commands.  The use of the
"[NC]" modifier helps to catch those cases where the client might send
"SITE chmod", for instance.

<p>
<b>Redirecting FTP Requests</b><br>
One user wanted to know if <code>mod_rewrite</code> could be used to
redirect a request, just like one might do using Apache's
<code>mod_rewrite</code>, something like:
<pre>
  RewriteRule /(.*) ftp://newname.domain.com/$1
</pre>
The above <code>RewriteRule</code> would work, but it would <b>not</b> actually
redirect the FTP client to the URL.  FTP unfortuntely does <i>not</i> support
redirection of requests to other servers, at the protocol level, unlike HTTP.

<p>
However, it <i>is</i> possible to redirect a request to some other directory
on the same machine.  For example, if you wanted to have any file uploaded
by a client go into the "/Incoming/" directory, no matter where the client
wanted to upload the file, you could use:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on
    RewriteCondition %m STOR
    RewriteRule (.*/)?(.*) /Incoming/$2
  &lt;/IfModule&gt;
</pre>

<p>
<b>URL Encoded Characters</b><br>
On very rare occasions, you may find yourself dealing with URL-encoded
characters in your FTP command parameters.  If you have worked with web servers
and URLs, you will accustomed to seeing sequences like "%20" in URLs; these are
URL encoded characters (as per <a href="http://www.faqs.org/rfcs/rfc2369.html">RFC2369</a>).  Unescaping these URL-encoded sequences is exactly what the
"unescape" <code>RewriteMap</code> builtin function handles.

<p>
<b>Handling Non-ASCII Characters</b><br>
If you need to handle non-ASCII characters in your <code>mod_rewrite</code>
rules, then you may need to generate your configuration using a scripting
language, rather than using your editor.  For example, my editor does not
handle non-ASCII characters well; it displays them as <code>?</code>.

<p>
Here's an example, using Perl, to replace "&auml;" with "ae" in uploaded file
names.  Note that "&auml;" in hex notation is <code>0xE4</code>:
<pre>
  my $rewrite_rule = 'RewriteRule (.*) ${replace:/$1/' . chr(0xE4) . '/ae}';

  my $config = '/path/to/proftpd.conf';
  if (open(my $fh, "&gt; $config")) {
    print $fh EOR;

  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on
    RewriteLog /path/to/rewrite.log

    RewriteCondition %m ^STOR$
    $rewrite_rule
  &lt;/IfModule&gt;
EOR
  }
</pre>

<p>
<b>Time-Related Content</b><br>
What if you find yourself wanting to serve different files based on the
time of day, day of the month, <i>etc</i>?  Or what if you wanted to
put an automatic timestamp on the names of files being uploaded?  Starting
with <code>proftpd-1.3.5rc1</code>, these things are now possible using
<code>mod_rewrite</code>; see the time-related variables in the
<a href="../contrib/mod_rewrite.html#RewriteCondition"><code>RewriteCondition</code></a> documentation.

<p>
To demonstrate the concept of time-related content, let's assume that you
have a two different files, one for "daytime" and one for "nighttime".
Depending on when a client connects and requests this file, you can have
<code>mod_rewrite</code> transparently point the client to the correct file.
Let's show how this might work:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on
    RewriteLog /path/to/rewrite.log

    # For requests of index.txt during the day, rewrite the command to
    # be for index.txt.day
    RewriteCondition %m RETR
    RewriteCondition %f index.txt$
    RewriteCondition %{TIME_HOUR}%{TIME_MIN} &gt;0700
    RewriteCondition %{TIME_HOUR}%{TIME_MIN} &lt;1900
    RewriteRule ^(.*) $1.day

    # For requests of index.txt during the night, rewrite the command to
    # be for index.txt.night
    RewriteCondition %m RETR
    RewriteCondition %f index.txt$
    RewriteCondition %{TIME_HOUR}%{TIME_MIN} &lt;0700
    RewriteCondition %{TIME_HOUR}%{TIME_MIN} &gt;1900
    RewriteRule ^(.*) $1.night

  &lt;/IfModule&gt;
</pre>

<p>
Another use case involving time is the case where you might want to
automatically timestamp every file being uploaded.  To do this, you can
use <code>mod_rewrite</code> like so:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on
    RewriteLog /path/to/rewrite.log

    # Automatically timestamp all uploaded files with ".DD-MM-YYYY".
    RewriteCondition %m STOR
    RewriteRule (.*) $1.%{TIME_DAY}-%{TIME_MON}-%{TIME_YEAR}
  &lt;/IfModule&gt;
</pre>

<p>
Or maybe you have a special file that should only be available for a month,
and then be inaccessible?  To do this, you would first give the special file
a name that includes a timestamp, <i>e.g.</i> "special.bin-01-2013".  Then
have the following <code>mod_rewrite</code> configuration:
<pre>
  &lt;IfModule mod_rewrite.c&gt;
    RewriteEngine on
    RewriteLog /path/to/rewrite.log

    RewriteCondition %m RETR
    RewriteCondition %f special.bin$
    RewriteRule (.*) $1-%{TIME_MON}-%{TIME_YEAR}
  &lt;/IfModule&gt;
</pre>
Now, if the "special.bin" file is requested during January 2013, the RETR
request will be rewritten and will match the name of the file on disk; the
file is accessible, and the download succeeds.  If the same file is requested
any other time than during January 2013, then the
<code>mod_rewrite</code>-rewritten path will not match the name of the file
on disk, and the download will fail.

<p>
<hr>
<font size=2><b><i>
&copy; Copyright 2020 The ProFTPD Project<br>
 All Rights Reserved<br>
</i></b></font>
<hr>

</body>
</html>