📄 mod_htaccess.erl
字号:
[{require,{{users,Users},{groups,Groups}}}]when GrpOrUsr==groups -> ets:insert(AccessData,{require,{{users,Users}, {groups,Groups++Members}}}) end, insertContext(AccessData,Values); %%limit and order directive need no transforming they areis just to insertinsertContext(AccessData,[Elem|Values])-> ets:insert(AccessData,Elem), insertContext(AccessData,Values). insertDenyAllowContext(AccessData,{AllowDeny,From})-> case From of all -> ets:insert(AccessData,{AllowDeny,all}); _AllowedSubnets -> case ets:lookup(AccessData,AllowDeny) of []-> ets:insert(AccessData,{AllowDeny,From}); [{AllowDeny,all}]-> ok; [{AllowDeny,Networks}]-> ets:insert(AccessData,{allow,Networks++From}) end end.loadAccessFilesData([],AccessData)-> %preform context to limits contextToValues(AccessData), {accessData,AccessData};%----------------------------------------------------------------------%Takes each file in the list and load the data to the ets table %AccessData%----------------------------------------------------------------------loadAccessFilesData([FileName|FileNames],AccessData)-> case loadAccessFileData({file,FileName},AccessData) of overRide-> loadAccessFilesData(FileNames,AccessData); noOverRide -> {accessData,AccessData}; error-> ets:delete(AccessData), {error,errorInAccessFile} end.%----------------------------------------------------------------------%opens the filehandle to the specified file%----------------------------------------------------------------------loadAccessFileData({file,FileName},AccessData)-> case file:open(FileName,[read]) of {ok,AccessFileHandle}-> loadAccessFileData({stream,AccessFileHandle},AccessData,[]); {error, _Reason} -> overRide end.%----------------------------------------------------------------------%%look att each line in the file and add them to the database%%When end of file is reached control i overrride is allowed%% if so return %----------------------------------------------------------------------loadAccessFileData({stream,File},AccessData,FileData)-> case io:get_line(File,[]) of eof-> insertData(AccessData,FileData), case ets:match_object(AccessData,{'_',error}) of []-> %Case we got no error control that we can override a %at least some of the values case ets:match_object(AccessData, {allow_over_ride,none}) of []-> overRide; _NoOverride-> noOverRide end; _ -> error end; Line -> loadAccessFileData({stream,File},AccessData, insertLine(string:strip(Line,left),FileData)) end.%----------------------------------------------------------------------%AccessData is a ets table where the previous found data is inserted%FileData is a list of the directives in the last parsed file%before insertion a control is done that the directive is allowed to%override%----------------------------------------------------------------------insertData(AccessData,{{context,Values},FileData})-> insertData(AccessData,[{context,Values}|FileData]);insertData(AccessData,FileData)-> case ets:lookup(AccessData,allow_over_ride) of [{allow_over_ride,all}]-> lists:foreach(fun(Elem)-> ets:insert(AccessData,Elem) end,FileData); []-> lists:foreach(fun(Elem)-> ets:insert(AccessData,Elem) end,FileData); [{allow_over_ride,Directives}]when list(Directives)-> lists:foreach(fun({Key,Value})-> case lists:member(Key,Directives) of true-> ok; false -> ets:insert(AccessData,{Key,Value}) end end,FileData); [{allow_over_ride,_}]-> %Will never appear if the user %aint doing very strang econfig files ok end.%----------------------------------------------------------------------%Take a line in the accessfile and transform it into a tuple that %later can be inserted in to the ets:table %---------------------------------------------------------------------- %%%Here is the alternatives that resides inside the limit contextinsertLine("order"++ Order, {{context, Values}, FileData})-> {{context,[{order,getOrder(Order)}|Values]},FileData};%%Let the user place a tab in the beginninginsertLine([$\t,$o,$r,$d,$e,$r|Order],{{context,Values},FileData})-> {{context,[{order,getOrder(Order)}|Values]},FileData};insertLine("allow" ++ Allow, {{context, Values}, FileData})-> {{context,[{allow,getAllowDenyData(Allow)}|Values]},FileData};insertLine([$\t,$a,$l,$l,$o,$w|Allow],{{context,Values},FileData})-> {{context,[{allow,getAllowDenyData(Allow)}|Values]},FileData};insertLine("deny" ++ Deny, {{context,Values}, FileData})-> {{context,[{deny,getAllowDenyData(Deny)}|Values]},FileData};insertLine([$\t, $d,$e,$n,$y|Deny],{{context,Values},FileData})-> {{context,[{deny,getAllowDenyData(Deny)}|Values]},FileData};insertLine("require" ++ Require, {{context, Values}, FileData})-> {{context,[{require,getRequireData(Require)}|Values]},FileData};insertLine([$\t,$r,$e,$q,$u,$i,$r,$e|Require],{{context,Values},FileData})-> {{context,[{require,getRequireData(Require)}|Values]},FileData};insertLine("</Limit" ++ _EndLimit, {Context,FileData})-> [Context | FileData];insertLine("<Limit" ++ Limit, FileData)-> {{context,[{limit,getLimits(Limit)}]}, FileData};insertLine([$A,$u,$t,$h,$U,$s,$e,$r,$F,$i,$l,$e,$\ |AuthUserFile],FileData)-> [{user_file,string:strip(AuthUserFile,right,$\n)}|FileData];insertLine([$A,$u,$t,$h,$G,$r,$o,$u,$p,$F,$i,$l,$e,$\ |AuthGroupFile], FileData)-> [{group_file,string:strip(AuthGroupFile,right,$\n)}|FileData];insertLine("AllowOverRide" ++ AllowOverRide, FileData)-> [{allow_over_ride,getAllowOverRideData(AllowOverRide)} | FileData];insertLine([$A,$u,$t,$h,$N,$a,$m,$e,$\ |AuthName],FileData)-> [{auth_name,string:strip(AuthName,right,$\n)}|FileData];insertLine("AuthType" ++ AuthType,FileData)-> [{auth_type,getAuthorizationType(AuthType)}|FileData];insertLine(_BadDirectiveOrComment,FileData)-> FileData.%----------------------------------------------------------------------%transform the Data specified about override to a form that is ieasier %handled later%Override data="all"|"md5"|"Directive1 .... DirectioveN"%----------------------------------------------------------------------getAllowOverRideData(OverRideData)-> case string:tokens(OverRideData," \r\n") of ["all" ++ _] -> all; ["none" ++ _]-> none; Directives -> getOverRideDirectives(Directives) end.getOverRideDirectives(Directives)-> lists:map(fun(Directive)-> transformDirective(Directive) end,Directives).transformDirective("AuthUserFile" ++ _)-> user_file;transformDirective("AuthGroupFile" ++ _) -> group_file;transformDirective("AuthName" ++ _)-> auth_name;transformDirective("AuthType" ++ _)-> auth_type;transformDirective(_UnAllowedOverRideDirective) -> unallowed.%----------------------------------------------------------------------%Replace the string that specify which method to use for authentication%and replace it with the atom for easier mathing%---------------------------------------------------------------------- getAuthorizationType(AuthType)-> [Arg | _Crap] = string:tokens(AuthType,"\n\r\ "), case Arg of "Basic"-> basic; "MD5" -> md5; _What -> error end.%----------------------------------------------------------------------%Returns a list of the specified methods to limit or the atom all%----------------------------------------------------------------------getLimits(Limits)-> case regexp:split(Limits,">")of {ok,[_NoEndOnLimit]}-> error; {ok, [Methods | _Crap]}-> case regexp:split(Methods," ")of {ok,[]}-> all; {ok,SplittedMethods}-> SplittedMethods; {error, _Error}-> error end; {error,_Error}-> error end.%----------------------------------------------------------------------% Transform the order to prefrom deny allow control to a tuple of atoms%----------------------------------------------------------------------getOrder(Order)-> [First | _Rest]=lists:map(fun(Part)-> list_to_atom(Part) end,string:tokens(Order," \n\r")), case First of deny-> {deny,allow}; allow-> {allow,deny}; _Error-> error end.%----------------------------------------------------------------------% The string AllowDeny is "from all" or "from Subnet1 Subnet2...SubnetN"%----------------------------------------------------------------------getAllowDenyData(AllowDeny)-> case string:tokens(AllowDeny," \n\r") of [_From|AllowDenyData] when length(AllowDenyData)>=1-> case lists:nth(1,AllowDenyData) of "all" -> all; _Hosts-> AllowDenyData end; _ -> error end.%----------------------------------------------------------------------% Fix the string that describes who is allowed to se the page%----------------------------------------------------------------------getRequireData(Require)-> [UserOrGroup|UserData]=string:tokens(Require," \n\r"), case UserOrGroup of "user"-> {users,UserData}; "group" -> {groups,UserData}; _Whatever -> error end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Methods that collects the searchways to the accessfiles %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------------------------------------% Get the whole path to the different accessfiles%---------------------------------------------------------------------- getHtAccessFiles(HtAccessFileNames,Path,RestOfSplittedPath)-> getHtAccessFiles(HtAccessFileNames,Path,RestOfSplittedPath,[]).getHtAccessFiles(HtAccessFileNames,Path,[[]],HtAccessFiles)-> HtAccessFiles ++ accessFilesOfPath(HtAccessFileNames,Path++"/"); getHtAccessFiles(_HtAccessFileNames, _Path, [], HtAccessFiles)-> HtAccessFiles;getHtAccessFiles(HtAccessFileNames,Path,[NextDir|RestOfSplittedPath], AccessFiles)-> getHtAccessFiles(HtAccessFileNames,Path++"/"++NextDir,RestOfSplittedPath, AccessFiles ++ accessFilesOfPath(HtAccessFileNames,Path++"/")). %----------------------------------------------------------------------%Control if therer are any accessfies in the path%----------------------------------------------------------------------accessFilesOfPath(HtAccessFileNames,Path)-> lists:foldl(fun(HtAccessFileName,Files)-> case file:read_file_info(Path++HtAccessFileName) of {ok, _}-> [Path++HtAccessFileName|Files]; {error,_Error} -> Files end end,[],HtAccessFileNames).%----------------------------------------------------------------------%Sake the splitted path and joins it up to the documentroot or the alias%that match first%----------------------------------------------------------------------getRootPath(SplittedPath, Info)-> DocRoot=httpd_util:lookup(Info#mod.config_db,document_root,"/"), PresumtiveRootPath= [DocRoot|lists:map(fun({_Alias,RealPath})-> RealPath end, httpd_util:multi_lookup(Info#mod.config_db,alias))], getRootPath(PresumtiveRootPath,SplittedPath,Info).getRootPath(PresumtiveRootPath,[[],Splittedpath],Info)-> getRootPath(PresumtiveRootPath,["/",Splittedpath],Info); getRootPath(PresumtiveRootPath,[Part,NextPart|SplittedPath],Info)-> case lists:member(Part,PresumtiveRootPath)of true-> {ok,Part,[NextPart|SplittedPath]}; false -> getRootPath(PresumtiveRootPath, [Part++"/"++NextPart|SplittedPath],Info) end;getRootPath(PresumtiveRootPath, [Part], _Info)-> case lists:member(Part,PresumtiveRootPath)of true-> {ok,Part,[]}; false -> {error,Part} end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -