📄 httpd_util.erl
字号:
month(12) -> "Dec".%% decode_hexdecode_hex([$%,Hex1,Hex2|Rest]) -> [hex2dec(Hex1)*16+hex2dec(Hex2)|decode_hex(Rest)];decode_hex([First|Rest]) -> [First|decode_hex(Rest)];decode_hex([]) -> [].hex2dec(X) when X>=$0,X=<$9 -> X-$0;hex2dec(X) when X>=$A,X=<$F -> X-$A+10;hex2dec(X) when X>=$a,X=<$f -> X-$a+10.%% decode_base64 (DEBUG STRING: QWxhZGRpbjpvcGVuIHNlc2FtZQ==)%%% Base-64 decoding (RFC2045)%% Keep for backward compatibilitydecode_base64(Base64) -> http_base_64:decode(Base64).encode_base64(ASCII) -> http_base_64:encode(ASCII).%% flatlengthflatlength(List) -> flatlength(List, 0).flatlength([H|T],L) when list(H) -> flatlength(H,flatlength(T,L));flatlength([H|T],L) when binary(H) -> flatlength(T,L+size(H));flatlength([_H|T],L) -> flatlength(T,L+1);flatlength([],L) -> L.%% split_pathsplit_path(Path) -> case regexp:match(Path,"[\?].*\$") of %% A QUERY_STRING exists! {match,Start,Length} -> {httpd_util:decode_hex(string:substr(Path,1,Start-1)), string:substr(Path,Start,Length)}; %% A possible PATH_INFO exists! nomatch -> split_path(Path,[]) end.split_path([],SoFar) -> {httpd_util:decode_hex(lists:reverse(SoFar)),[]};split_path([$/|Rest],SoFar) -> Path=httpd_util:decode_hex(lists:reverse(SoFar)), case file:read_file_info(Path) of {ok,FileInfo} when FileInfo#file_info.type == regular -> {Path,[$/|Rest]}; {ok, _FileInfo} -> split_path(Rest,[$/|SoFar]); {error, _Reason} -> split_path(Rest,[$/|SoFar]) end;split_path([C|Rest],SoFar) -> split_path(Rest,[C|SoFar]).%% split_script_pathsplit_script_path(Path) -> case split_script_path(Path, []) of {Script, AfterPath} -> {PathInfo, QueryString} = pathinfo_querystring(AfterPath), {Script, {PathInfo, QueryString}}; not_a_script -> not_a_script end.pathinfo_querystring(Str) -> pathinfo_querystring(Str, []).pathinfo_querystring([], SoFar) -> {lists:reverse(SoFar), []};pathinfo_querystring([$?|Rest], SoFar) -> {lists:reverse(SoFar), Rest};pathinfo_querystring([C|Rest], SoFar) -> pathinfo_querystring(Rest, [C|SoFar]).split_script_path([$?|QueryString], SoFar) -> Path = httpd_util:decode_hex(lists:reverse(SoFar)), case file:read_file_info(Path) of {ok,FileInfo} when FileInfo#file_info.type == regular -> {Path, [$?|QueryString]}; {ok, _FileInfo} -> not_a_script; {error, _Reason} -> not_a_script end;split_script_path([], SoFar) -> Path = httpd_util:decode_hex(lists:reverse(SoFar)), case file:read_file_info(Path) of {ok,FileInfo} when FileInfo#file_info.type == regular -> {Path, []}; {ok, _FileInfo} -> not_a_script; {error, _Reason} -> not_a_script end;split_script_path([$/|Rest], SoFar) -> Path = httpd_util:decode_hex(lists:reverse(SoFar)), case file:read_file_info(Path) of {ok, FileInfo} when FileInfo#file_info.type == regular -> {Path, [$/|Rest]}; {ok, _FileInfo} -> split_script_path(Rest, [$/|SoFar]); {error, _Reason} -> split_script_path(Rest, [$/|SoFar]) end;split_script_path([C|Rest], SoFar) -> split_script_path(Rest,[C|SoFar]).%% suffixsuffix(Path) -> case filename:extension(Path) of [] -> []; Extension -> tl(Extension) end.%% to_upperto_upper(Str) -> http_util:to_upper(Str).%% to_lowerto_lower(Str) -> http_util:to_lower(Str).%% stripstrip(Value)-> lists:reverse(remove_ws(lists:reverse(remove_ws(Value)))). remove_ws([$\s|Rest])-> remove_ws(Rest);remove_ws([$\t|Rest]) -> remove_ws(Rest);remove_ws(Rest) -> Rest.%% splitsplit(String,RegExp,Limit) -> case regexp:parse(RegExp) of {error,Reason} -> {error,Reason}; {ok,_} -> {ok,do_split(String,RegExp,Limit)} end.do_split(String, _RegExp, 1) -> [String];do_split(String,RegExp,Limit) -> case regexp:first_match(String,RegExp) of {match,Start,Length} -> [string:substr(String,1,Start-1)| do_split(lists:nthtail(Start+Length-1,String),RegExp,Limit-1)]; nomatch -> [String] end.%% make_name/2, make_name/3%% Prefix -> string()%% First part of the name, e.g. "httpd"%% Addr -> {A,B,C,D} | string() | undefined%% The address part of the name. %% e.g. "123.234.55.66" or {123,234,55,66} or "otp.ericsson.se" %% for a host address or undefined if local host.%% Port -> integer()%% Last part of the name, such as the HTTPD server port %% number (80).%% Postfix -> Any string that will be added last to the name%%%% Example:%% make_name("httpd","otp.ericsson.se",80) => httpd__otp_ericsson_se__80%% make_name("httpd",undefined,8088) => httpd_8088make_name(Prefix,Port) -> make_name(Prefix,undefined,Port,"").make_name(Prefix,Addr,Port) -> make_name(Prefix,Addr,Port,""). make_name(Prefix,"*",Port,Postfix) -> make_name(Prefix,undefined,Port,Postfix);make_name(Prefix,any,Port,Postfix) -> make_name1(io_lib:format("~s_~w~s",[Prefix,Port,Postfix]));make_name(Prefix,undefined,Port,Postfix) -> make_name1(io_lib:format("~s_~w~s",[Prefix,Port,Postfix]));make_name(Prefix,Addr,Port,Postfix) -> NameString = Prefix ++ "__" ++ make_name2(Addr) ++ "__" ++ integer_to_list(Port) ++ Postfix, make_name1(NameString). make_name1(String) -> list_to_atom(lists:flatten(String)).make_name2({A,B,C,D}) -> io_lib:format("~w_~w_~w_~w",[A,B,C,D]);make_name2({A, B, C, D, E, F, G, H}) -> io_lib:format("~w_~w_~w_~w_~w_~w_~w_~w",[integer_to_hexlist(A), integer_to_hexlist(B), integer_to_hexlist(C), integer_to_hexlist(D), integer_to_hexlist(E), integer_to_hexlist(F), integer_to_hexlist(G), integer_to_hexlist(H) ]);make_name2(Addr) -> search_and_replace(Addr,$.,$_).search_and_replace(S,A,B) -> Fun = fun(What) -> case What of A -> B; O -> O end end, lists:map(Fun,S).%%----------------------------------------------------------------------%% Converts a string that constists of 0-9,A-F,a-f to a %% integer%%----------------------------------------------------------------------hexlist_to_integer(List)-> http_util:hexlist_to_integer(List).%%----------------------------------------------------------------------%%Converts an integer to an hexlist%%----------------------------------------------------------------------encode_hex(Num)-> integer_to_hexlist(Num).integer_to_hexlist(Num) when is_integer(Num) -> http_util:integer_to_hexlist(Num). create_etag(FileInfo)-> create_etag(FileInfo#file_info.mtime,FileInfo#file_info.size).create_etag({{Year,Month,Day},{Hour,Min,Sec}},Size)-> create_part([Year,Month,Day,Hour,Min,Sec])++io_lib:write(Size);create_etag(FileInfo,Size)-> create_etag(FileInfo#file_info.mtime,Size).create_part(Values)-> lists:map(fun(Val0)-> Val=Val0 rem 60, if Val=<25 -> 65+Val; % A-Z Val=<50 -> 72+Val; % a-z %%Since no date s true -> Val-3 end end,Values).%%----------------------------------------------------------------------%% Enable debugging, validate httpd options%%----------------------------------------------------------------------enable_debug([]) -> ok;enable_debug(Debug) -> dbg:tracer(), dbg:p(all, [call]), do_enable_debug(Debug).do_enable_debug(disable) -> dbg:stop();do_enable_debug([]) -> ok;do_enable_debug([{Level,Modules}|Rest]) when atom(Level),list(Modules) -> case Level of all_functions -> io:format("Tracing on all functions set on modules: ~p~n", [Modules]), lists:foreach(fun(X)->dbg:tpl(X, [{'_', [], [{return_trace}]}]) end,Modules); exported_functions -> io:format("Tracing on exported functions set on modules: ~p~n",[Modules]), lists:foreach(fun(X)->dbg:tp(X, [{'_', [], [{return_trace}]}]) end,Modules); disable -> io:format("Tracing disabled on modules: ~p~n",[Modules]), lists:foreach(fun(X)->dbg:ctp(X) end,Modules); _ -> ok end, do_enable_debug(Rest).valid_options(Debug,AcceptTimeout,ConfigFile) -> valid_debug(Debug), valid_accept_timeout(AcceptTimeout), valid_config_file(ConfigFile).valid_debug([]) -> ok;valid_debug(disable) -> ok;valid_debug(L) when list(L) -> valid_debug2(L);valid_debug(D) -> throw({error,{bad_debug_option,D}}).valid_debug2([{all_functions,L}|Rest]) when list(L) -> test_load_modules(L), valid_debug2(Rest);valid_debug2([{exported_functions,L}|Rest]) when list(L) -> test_load_modules(L), valid_debug2(Rest);valid_debug2([{disable,L}|Rest]) when list(L) -> test_load_modules(L), valid_debug2(Rest);valid_debug2([H|_T]) -> throw({error,{bad_debug_option,H}});valid_debug2([]) -> ok.valid_accept_timeout(I) when is_integer(I) -> ok;valid_accept_timeout(A) -> throw({error,{bad_debug_option,A}}).valid_config_file(_) -> ok.test_load_modules([H|T]) when atom(H) -> case code:which(H) of non_existing -> throw({error,{module_does_not_exist,H}}); _ -> ok end, test_load_modules(T);test_load_modules([H|_T]) -> throw({error,{module_name_not_atom,H}});test_load_modules([]) -> ok.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -