Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

157 рядки
4.8 KiB

20 роки тому
20 роки тому
20 роки тому
20 роки тому
20 роки тому
20 роки тому
20 роки тому
  1. %%% File : ibrowse_lib.erl
  2. %%% Author : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi@t-mobile.co.uk>
  3. %%% Description :
  4. %%% Created : 27 Feb 2004 by Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi@t-mobile.co.uk>
  5. %% @doc Module with a few useful functions
  6. -module(ibrowse_lib).
  7. -vsn('$Id: ibrowse_lib.erl,v 1.4 2007/03/21 00:26:41 chandrusf Exp $ ').
  8. -author('chandru').
  9. -ifdef(debug).
  10. -compile(export_all).
  11. -endif.
  12. -export([url_encode/1,
  13. decode_rfc822_date/1,
  14. status_code/1,
  15. dec2hex/2,
  16. drv_ue/1,
  17. drv_ue/2]).
  18. drv_ue(Str) ->
  19. [{port, Port}| _] = ets:lookup(ibrowse_table, port),
  20. drv_ue(Str, Port).
  21. drv_ue(Str, Port) ->
  22. case erlang:port_control(Port, 1, Str) of
  23. [] ->
  24. Str;
  25. Res ->
  26. Res
  27. end.
  28. %% @doc URL-encodes a string based on RFC 1738. Returns a flat list.
  29. %% @spec url_encode(Str) -> UrlEncodedStr
  30. %% Str = string()
  31. %% UrlEncodedStr = string()
  32. url_encode(Str) when list(Str) ->
  33. url_encode_char(lists:reverse(Str), []).
  34. url_encode_char([X | T], Acc) when X >= $a, X =< $z ->
  35. url_encode_char(T, [X | Acc]);
  36. url_encode_char([X | T], Acc) when X >= $A, X =< $Z ->
  37. url_encode_char(T, [X | Acc]);
  38. url_encode_char([X | T], Acc) when X == $-; X == $_; X == $. ->
  39. url_encode_char(T, [X | Acc]);
  40. url_encode_char([32 | T], Acc) ->
  41. url_encode_char(T, [$+ | Acc]);
  42. url_encode_char([X | T], Acc) ->
  43. url_encode_char(T, [$%, d2h(X bsr 4), d2h(X band 16#0f) | Acc]);
  44. url_encode_char([], Acc) ->
  45. Acc.
  46. d2h(N) when N<10 -> N+$0;
  47. d2h(N) -> N+$a-10.
  48. decode_rfc822_date(String) when list(String) ->
  49. case catch decode_rfc822_date_1(string:tokens(String, ", \t\r\n")) of
  50. {'EXIT', _} ->
  51. {error, invalid_date};
  52. Res ->
  53. Res
  54. end.
  55. % TODO: Have to handle the Zone
  56. decode_rfc822_date_1([_,DayInt,Month,Year, Time,Zone]) ->
  57. decode_rfc822_date_1([DayInt,Month,Year, Time,Zone]);
  58. decode_rfc822_date_1([Day,Month,Year, Time,_Zone]) ->
  59. DayI = list_to_integer(Day),
  60. MonthI = month_int(Month),
  61. YearI = list_to_integer(Year),
  62. TimeTup = case string:tokens(Time, ":") of
  63. [H,M] ->
  64. {list_to_integer(H),
  65. list_to_integer(M),
  66. 0};
  67. [H,M,S] ->
  68. {list_to_integer(H),
  69. list_to_integer(M),
  70. list_to_integer(S)}
  71. end,
  72. {{YearI,MonthI,DayI}, TimeTup}.
  73. month_int("Jan") -> 1;
  74. month_int("Feb") -> 2;
  75. month_int("Mar") -> 3;
  76. month_int("Apr") -> 4;
  77. month_int("May") -> 5;
  78. month_int("Jun") -> 6;
  79. month_int("Jul") -> 7;
  80. month_int("Aug") -> 8;
  81. month_int("Sep") -> 9;
  82. month_int("Oct") -> 10;
  83. month_int("Nov") -> 11;
  84. month_int("Dec") -> 12.
  85. %% @doc Given a status code, returns an atom describing the status code.
  86. %% @spec status_code(StatusCode) -> StatusDescription
  87. %% StatusCode = string() | integer()
  88. %% StatusDescription = atom()
  89. status_code(100) -> continue;
  90. status_code(101) -> switching_protocols;
  91. status_code(102) -> processing;
  92. status_code(200) -> ok;
  93. status_code(201) -> created;
  94. status_code(202) -> accepted;
  95. status_code(203) -> non_authoritative_information;
  96. status_code(204) -> no_content;
  97. status_code(205) -> reset_content;
  98. status_code(206) -> partial_content;
  99. status_code(207) -> multi_status;
  100. status_code(300) -> multiple_choices;
  101. status_code(301) -> moved_permanently;
  102. status_code(302) -> found;
  103. status_code(303) -> see_other;
  104. status_code(304) -> not_modified;
  105. status_code(305) -> use_proxy;
  106. status_code(306) -> unused;
  107. status_code(307) -> temporary_redirect;
  108. status_code(400) -> bad_request;
  109. status_code(401) -> unauthorized;
  110. status_code(402) -> payment_required;
  111. status_code(403) -> forbidden;
  112. status_code(404) -> not_found;
  113. status_code(405) -> method_not_allowed;
  114. status_code(406) -> not_acceptable;
  115. status_code(407) -> proxy_authentication_required;
  116. status_code(408) -> request_timeout;
  117. status_code(409) -> conflict;
  118. status_code(410) -> gone;
  119. status_code(411) -> length_required;
  120. status_code(412) -> precondition_failed;
  121. status_code(413) -> request_entity_too_large;
  122. status_code(414) -> request_uri_too_long;
  123. status_code(415) -> unsupported_media_type;
  124. status_code(416) -> requested_range_not_satisfiable;
  125. status_code(417) -> expectation_failed;
  126. status_code(422) -> unprocessable_entity;
  127. status_code(423) -> locked;
  128. status_code(424) -> failed_dependency;
  129. status_code(500) -> internal_server_error;
  130. status_code(501) -> not_implemented;
  131. status_code(502) -> bad_gateway;
  132. status_code(503) -> service_unavailable;
  133. status_code(504) -> gateway_timeout;
  134. status_code(505) -> http_version_not_supported;
  135. status_code(507) -> insufficient_storage;
  136. status_code(X) when is_list(X) -> status_code(list_to_integer(X));
  137. status_code(_) -> unknown_status_code.
  138. %% @doc dec2hex taken from gtk.erl in std dist
  139. %% @spec dec2hex(M, N) -> string()
  140. %% M = integer() - number of hex digits required
  141. %% N = integer() - the number to represent as hex
  142. dec2hex(M,N) -> dec2hex(M,N,[]).
  143. dec2hex(0,_N,Ack) -> Ack;
  144. dec2hex(M,N,Ack) -> dec2hex(M-1,N bsr 4,[d2h(N band 15)|Ack]).