You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
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]).