⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ejabberd_http.erl

📁 ejabberd-0.7.5 分布式Jabber服务器
💻 ERL
📖 第 1 页 / 共 2 页
字号:
%    notice as well as this list of conditions.%% url decode the path and return {Path, QueryPart}url_decode_q_split(Path) ->    url_decode_q_split(Path, []).url_decode_q_split([$%, $C, $2, $%, Hi, Lo | Tail], Ack) ->    Hex = hex_to_integer([Hi, Lo]),    url_decode_q_split(Tail, [Hex|Ack]);url_decode_q_split([$%, $C, $3, $%, Hi, Lo | Tail], Ack) when Hi > $9 ->    Hex = hex_to_integer([Hi+4, Lo]),    url_decode_q_split(Tail, [Hex|Ack]);url_decode_q_split([$%, $C, $3, $%, Hi, Lo | Tail], Ack) when Hi < $A ->    Hex = hex_to_integer([Hi+4+7, Lo]),    url_decode_q_split(Tail, [Hex|Ack]);url_decode_q_split([$%, Hi, Lo | Tail], Ack) ->    Hex = hex_to_integer([Hi, Lo]),    url_decode_q_split(Tail, [Hex|Ack]);url_decode_q_split([$?|T], Ack) ->    %% Don't decode the query string here, that is parsed separately.    {path_norm_reverse(Ack), T};url_decode_q_split([H|T], Ack) ->    url_decode_q_split(T, [H|Ack]);url_decode_q_split([], Ack) ->    {path_norm_reverse(Ack), []}.path_norm_reverse("/" ++ T) -> start_dir(0, "/", T);path_norm_reverse(       T) -> start_dir(0,  "", T).start_dir(N, Path, ".."       ) -> rest_dir(N, Path, "");start_dir(N, Path, "/"   ++ T ) -> start_dir(N    , Path, T);start_dir(N, Path, "./"  ++ T ) -> start_dir(N    , Path, T);start_dir(N, Path, "../" ++ T ) -> start_dir(N + 1, Path, T);start_dir(N, Path,          T ) -> rest_dir (N    , Path, T).rest_dir (_N, Path, []         ) -> case Path of 				       [] -> "/";				       _  -> Path				   end;rest_dir (0, Path, [ $/ | T ] ) -> start_dir(0    , [ $/ | Path ], T);rest_dir (N, Path, [ $/ | T ] ) -> start_dir(N - 1,        Path  , T);rest_dir (0, Path, [  H | T ] ) -> rest_dir (0    , [  H | Path ], T);rest_dir (N, Path, [ _H | T ] ) -> rest_dir (N    ,        Path  , T).%% hex_to_integerhex_to_integer(Hex) ->    case catch erlang:list_to_integer(Hex, 16) of	{'EXIT', _} ->	    old_hex_to_integer(Hex);	X ->	    X    end.old_hex_to_integer(Hex) ->    DEHEX = fun (H) when H >= $a, H =< $f -> H - $a + 10;		(H) when H >= $A, H =< $F -> H - $A + 10;		(H) when H >= $0, H =< $9 -> H - $0	    end,    lists:foldl(fun(E, Acc) -> Acc*16+DEHEX(E) end, 0, Hex).code_to_phrase(100) -> "Continue";code_to_phrase(101) -> "Switching Protocols ";code_to_phrase(200) -> "OK";code_to_phrase(201) -> "Created";code_to_phrase(202) -> "Accepted";code_to_phrase(203) -> "Non-Authoritative Information";code_to_phrase(204) -> "No Content";code_to_phrase(205) -> "Reset Content";code_to_phrase(206) -> "Partial Content";code_to_phrase(300) -> "Multiple Choices";code_to_phrase(301) -> "Moved Permanently";code_to_phrase(302) -> "Found";code_to_phrase(303) -> "See Other";code_to_phrase(304) -> "Not Modified";code_to_phrase(305) -> "Use Proxy";code_to_phrase(306) -> "(Unused)";code_to_phrase(307) -> "Temporary Redirect";code_to_phrase(400) -> "Bad Request";code_to_phrase(401) -> "Unauthorized";code_to_phrase(402) -> "Payment Required";code_to_phrase(403) -> "Forbidden";code_to_phrase(404) -> "Not Found";code_to_phrase(405) -> "Method Not Allowed";code_to_phrase(406) -> "Not Acceptable";code_to_phrase(407) -> "Proxy Authentication Required";code_to_phrase(408) -> "Request Timeout";code_to_phrase(409) -> "Conflict";code_to_phrase(410) -> "Gone";code_to_phrase(411) -> "Length Required";code_to_phrase(412) -> "Precondition Failed";code_to_phrase(413) -> "Request Entity Too Large";code_to_phrase(414) -> "Request-URI Too Long";code_to_phrase(415) -> "Unsupported Media Type";code_to_phrase(416) -> "Requested Range Not Satisfiable";code_to_phrase(417) -> "Expectation Failed";code_to_phrase(500) -> "Internal Server Error";code_to_phrase(501) -> "Not Implemented";code_to_phrase(502) -> "Bad Gateway";code_to_phrase(503) -> "Service Unavailable";code_to_phrase(504) -> "Gateway Timeout";code_to_phrase(505) -> "HTTP Version Not Supported".parse_auth(Orig = "Basic " ++ Auth64) ->    case decode_base64(Auth64) of	{error, _Err} ->	    undefined;	Auth ->	    case string:tokens(Auth, ":") of		[User, Pass] ->		    {User, Pass};		_ ->		    undefined	    end    end;parse_auth(_) ->    undefined.decode_base64([]) ->  [];decode_base64([Sextet1,Sextet2,$=,$=|Rest]) ->  Bits2x6=    (d(Sextet1) bsl 18) bor    (d(Sextet2) bsl 12),  Octet1=Bits2x6 bsr 16,  [Octet1|decode_base64(Rest)];decode_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) ->  Bits3x6=    (d(Sextet1) bsl 18) bor    (d(Sextet2) bsl 12) bor    (d(Sextet3) bsl 6),  Octet1=Bits3x6 bsr 16,  Octet2=(Bits3x6 bsr 8) band 16#ff,  [Octet1,Octet2|decode_base64(Rest)];decode_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) ->  Bits4x6=    (d(Sextet1) bsl 18) bor    (d(Sextet2) bsl 12) bor    (d(Sextet3) bsl 6) bor    d(Sextet4),  Octet1=Bits4x6 bsr 16,  Octet2=(Bits4x6 bsr 8) band 16#ff,  Octet3=Bits4x6 band 16#ff,  [Octet1,Octet2,Octet3|decode_base64(Rest)];decode_base64(_CatchAll) ->  {error, bad_base64}.d(X) when X >= $A, X =<$Z ->    X-65;d(X) when X >= $a, X =<$z ->    X-71;d(X) when X >= $0, X =<$9 ->    X+4;d($+) -> 62;d($/) -> 63;d(_) -> 63.parse_urlencoded(S) ->    parse_urlencoded(S, nokey, [], key).parse_urlencoded([$%, Hi, Lo | Tail], Last, Cur, State) ->    Hex = hex_to_integer([Hi, Lo]),    parse_urlencoded(Tail, Last, [Hex | Cur],  State);parse_urlencoded([$& | Tail], _Last, Cur, key) ->    [{lists:reverse(Cur), ""} |     parse_urlencoded(Tail, nokey, [], key)];  %% cont keymodeparse_urlencoded([$& | Tail], Last, Cur, value) ->    V = {Last, lists:reverse(Cur)},    [V | parse_urlencoded(Tail, nokey, [], key)];parse_urlencoded([$+ | Tail], Last, Cur,  State) ->    parse_urlencoded(Tail, Last, [$\s | Cur], State);parse_urlencoded([$= | Tail], _Last, Cur, key) ->    parse_urlencoded(Tail, lists:reverse(Cur), [], value); %% change modeparse_urlencoded([H | Tail], Last, Cur, State) ->    parse_urlencoded(Tail, Last, [H|Cur], State);parse_urlencoded([], Last, Cur, _State) ->    [{Last, lists:reverse(Cur)}];parse_urlencoded(undefined, _, _, _) ->    [].% The following code is mostly taken from yaws_ssl.erlparse_request(State, Data) ->    case Data of	[] ->	    {[], []};	_ ->	    ?DEBUG("GOT ssl data ~p~n", [Data]),	    {R, Trail} = case State#state.request_method of			     undefined ->				 {R1, Trail1} = get_req(Data),				 ?DEBUG("Parsed request ~p~n", [R1]),				 {[R1], Trail1};			     _ ->				 {[], Data}			 end,	    {H, Trail2} = get_headers(Trail),	    {R ++ H, Trail2}    end.get_req("\r\n\r\n" ++ _) ->    bad_request;get_req("\r\n" ++ Data) ->    get_req(Data);get_req(Data) ->    {FirstLine, Trail} = lists:splitwith(fun not_eol/1, Data),    R = parse_req(FirstLine),    {R, Trail}.	    not_eol($\r)->    false;not_eol($\n) ->    false;not_eol(_) ->    true.get_word(Line)->    {Word, T} = lists:splitwith(fun(X)-> X /= $\  end, Line),    {Word, lists:dropwhile(fun(X) -> X == $\  end, T)}.parse_req(Line) ->    {MethodStr, L1} = get_word(Line),    ?DEBUG("Method: ~p~n", [MethodStr]),    case L1 of	[] ->	    bad_request;	_ ->	    {URI, L2} = get_word(L1),	    {VersionStr, L3} = get_word(L2),	    ?DEBUG("URI: ~p~nVersion: ~p~nL3: ~p~n",		[URI, VersionStr, L3]),	    case L3 of		[] ->		    Method = case MethodStr of				 "GET" -> 'GET';				 "POST" -> 'POST';				 "HEAD" -> 'HEAD';				 "OPTIONS" -> 'OPTIONS';				 "TRACE" -> 'TRACE';				 "PUT" -> 'PUT';				 "DELETE" -> 'DELETE';				 S -> S			     end,		    Path = case URI of			       "*" ->			       % Is this correct?				   "*";			       P ->			       % FIXME: Handle			       % absolute URIs				   {abs_path, P}			   end,		    case VersionStr of			[] ->			    {ok, {http_request, Method, Path, {0,9}}};			"HTTP/1.0" ->			    {ok, {http_request, Method, Path, {1,0}}};			"HTTP/1.1" ->			    {ok, {http_request, Method, Path, {1,1}}};			_ ->			    bad_request		    end;		_ ->		    bad_request	    end    end.get_headers(Tail) ->    get_headers([], Tail).get_headers(H, Tail) ->    case get_line(Tail) of	{incomplete, Tail2} ->	    {H, Tail2};	{line, Line, Tail2} ->	    get_headers(H ++ parse_line(Line), Tail2);	{lastline, Line, Tail2} ->	    {H ++ parse_line(Line) ++ [{ok, http_eoh}], Tail2}    end.parse_line("Connection:" ++ Con) ->    [{ok, {http_header,  undefined, 'Connection', undefined, strip_spaces(Con)}}];parse_line("Host:" ++ Con) ->    [{ok, {http_header,  undefined, 'Host', undefined, strip_spaces(Con)}}];parse_line("Accept:" ++ Con) ->    [{ok, {http_header,  undefined, 'Accept', undefined, strip_spaces(Con)}}];parse_line("If-Modified-Since:" ++ Con) ->    [{ok, {http_header,  undefined, 'If-Modified-Since', undefined, strip_spaces(Con)}}];parse_line("If-Match:" ++ Con) ->    [{ok, {http_header,  undefined, 'If-Match', undefined, strip_spaces(Con)}}];parse_line("If-None-Match:" ++ Con) ->    [{ok, {http_header,  undefined, 'If-None-Match', undefined, strip_spaces(Con)}}];parse_line("If-Range:" ++ Con) ->    [{ok, {http_header,  undefined, 'If-Range', undefined, strip_spaces(Con)}}];parse_line("If-Unmodified-Since:" ++ Con) ->    [{ok, {http_header,  undefined, 'If-Unmodified-Since', undefined, strip_spaces(Con)}}];parse_line("Range:" ++ Con) ->    [{ok, {http_header,  undefined, 'Range', undefined, strip_spaces(Con)}}];parse_line("User-Agent:" ++ Con) ->    [{ok, {http_header,  undefined, 'User-Agent', undefined, strip_spaces(Con)}}];parse_line("Accept-Ranges:" ++ Con) ->    [{ok, {http_header,  undefined, 'Accept-Ranges', undefined, strip_spaces(Con)}}];parse_line("Authorization:" ++ Con) ->    [{ok, {http_header,  undefined, 'Authorization', undefined, strip_spaces(Con)}}];parse_line("Keep-Alive:" ++ Con) ->    [{ok, {http_header,  undefined, 'Keep-Alive', undefined, strip_spaces(Con)}}];parse_line("Referer:" ++ Con) ->    [{ok, {http_header,  undefined, 'Referer', undefined, strip_spaces(Con)}}];parse_line("Content-type:"++Con) ->    [{ok, {http_header,  undefined, 'Content-Type', undefined, strip_spaces(Con)}}];parse_line("Content-Type:"++Con) ->    [{ok, {http_header,  undefined, 'Content-Type', undefined, strip_spaces(Con)}}];parse_line("Content-Length:"++Con) ->    [{ok, {http_header,  undefined, 'Content-Length', undefined, strip_spaces(Con)}}];parse_line("Content-length:"++Con) ->    [{ok, {http_header,  undefined, 'Content-Length', undefined, strip_spaces(Con)}}];parse_line("Cookie:"++Con) ->    [{ok, {http_header,  undefined, 'Cookie', undefined, strip_spaces(Con)}}];parse_line("Accept-Language:"++Con) ->    [{ok, {http_header,  undefined, 'Accept-Language', undefined, strip_spaces(Con)}}];parse_line("Accept-Encoding:"++Con) ->    [{ok, {http_header,  undefined, 'Accept-Encoding', undefined, strip_spaces(Con)}}];parse_line(S) ->    case lists:splitwith(fun(C)->C /= $: end, S) of	{Name, [$:|Val]} ->	    [{ok, {http_header,  undefined, Name, undefined, strip_spaces(Val)}}];	_ ->	    []    end.is_space($\s) ->    true;is_space($\r) ->    true;is_space($\n) ->    true;is_space($\r) ->    true;is_space(_) ->    false.strip_spaces(String) ->    strip_spaces(String, both).strip_spaces(String, left) ->    drop_spaces(String);strip_spaces(String, right) ->    lists:reverse(drop_spaces(lists:reverse(String)));strip_spaces(String, both) ->    strip_spaces(drop_spaces(String), right).drop_spaces([]) ->    [];drop_spaces(YS=[X|XS]) ->    case is_space(X) of	true ->	    drop_spaces(XS);	false ->	    YS    end.is_nb_space(X) ->    lists:member(X, [$\s, $\t]).    % ret: {line, Line, Trail} | {lastline, Line, Trail}get_line(L) ->        get_line(L, []).get_line("\r\n\r\n" ++ Tail, Cur) ->    {lastline, lists:reverse(Cur), Tail};get_line("\r\n" ++ Tail, Cur) ->    case Tail of	[] ->	    {incomplete, lists:reverse(Cur) ++ "\r\n"};	_ ->	    case is_nb_space(hd(Tail)) of		true ->  %% multiline ... continue 		    get_line(Tail, [$\n, $\r | Cur]);		false ->		    {line, lists:reverse(Cur), Tail}	    end    end;get_line([H|T], Cur) ->    get_line(T, [H|Cur]).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -