1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2005-2017. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20%%
21-module(http_util).
22
23-export([
24	 to_upper/1, to_lower/1,
25	 convert_netscapecookie_date/1,
26	 hexlist_to_integer/1, integer_to_hexlist/1,
27	 convert_month/1,
28	 is_hostname/1,
29	 timestamp/0, timeout/2,
30	 html_encode/1,
31	 maybe_add_brackets/2
32	]).
33
34
35%%%=========================================================================
36%%%  Internal application API
37%%%=========================================================================
38to_upper(Str) ->
39    string:uppercase(Str).
40
41to_lower(Str) ->
42    string:lowercase(Str).
43
44%% Example: Mon, 09-Dec-2002 13:46:00 GMT
45convert_netscapecookie_date([_D,_A,_Y, $,, $ ,
46			     D1,D2, $-,
47			     M,O,N, $-,
48			     Y1,Y2,Y3,Y4, $ ,
49			     H1,H2, $:,
50			     M1,M2, $:,
51			     S1,S2|_Rest]) ->
52    Year  = list_to_integer([Y1,Y2,Y3,Y4]),
53    Day   = list_to_integer([D1,D2]),
54    Month = convert_month([M,O,N]),
55    Hour  = list_to_integer([H1,H2]),
56    Min   = list_to_integer([M1,M2]),
57    Sec   = list_to_integer([S1,S2]),
58    {{Year,Month,Day},{Hour,Min,Sec}};
59
60convert_netscapecookie_date([_D,_A,_Y, $,, $ ,
61			     D1,D2, $-,
62			     M,O,N, $-,
63			     Y3,Y4, $ ,
64			     H1,H2, $:,
65			     M1,M2, $:,
66			     S1,S2|_Rest]) ->
67    {CurrentYear, _, _} = date(),
68    [Y1,Y2|_] = integer_to_list(CurrentYear),
69    Year      = list_to_integer([Y1,Y2,Y3,Y4]),
70    Day       = list_to_integer([D1,D2]),
71    Month     = convert_month([M,O,N]),
72    Hour      = list_to_integer([H1,H2]),
73    Min       = list_to_integer([M1,M2]),
74    Sec       = list_to_integer([S1,S2]),
75    {{Year,Month,Day},{Hour,Min,Sec}};
76
77convert_netscapecookie_date([_D,_A,_Y, $ ,
78			     D1,D2, $-,
79			     M,O,N, $-,
80			     Y1,Y2,Y3,Y4, $ ,
81			     H1,H2, $:,
82			     M1,M2, $:,
83			     S1,S2|_Rest]) ->
84    Year  = list_to_integer([Y1,Y2,Y3,Y4]),
85    Day   = list_to_integer([D1,D2]),
86    Month = convert_month([M,O,N]),
87    Hour  = list_to_integer([H1,H2]),
88    Min   = list_to_integer([M1,M2]),
89    Sec   = list_to_integer([S1,S2]),
90    {{Year,Month,Day},{Hour,Min,Sec}};
91
92convert_netscapecookie_date([_D,_A,_Y, $ ,
93			     D1,D2, $-,
94			     M,O,N, $-,
95			     Y3,Y4, $ ,
96			     H1,H2, $:,
97			     M1,M2, $:,
98			     S1,S2|_Rest]) ->
99    {CurrentYear, _, _} = date(),
100    [Y1,Y2|_] = integer_to_list(CurrentYear),
101    Year      = list_to_integer([Y1,Y2,Y3,Y4]),
102    Day       = list_to_integer([D1,D2]),
103    Month     = convert_month([M,O,N]),
104    Hour      = list_to_integer([H1,H2]),
105    Min       = list_to_integer([M1,M2]),
106    Sec       = list_to_integer([S1,S2]),
107    {{Year,Month,Day},{Hour,Min,Sec}};
108
109%% Example: Tue Jan 01 08:00:01 2036 GMT
110convert_netscapecookie_date([_D,_A,_Y, $ ,
111			     M,O,N, $ ,
112			     D1,D2, $ ,
113			     H1,H2, $:,
114			     M1,M2, $:,
115			     S1,S2, $ ,
116			     Y1,Y2,Y3,Y4, $ |_Rest]) ->
117    Year  = list_to_integer([Y1,Y2,Y3,Y4]),
118    Day   = list_to_integer([D1,D2]),
119    Month = convert_month([M,O,N]),
120    Hour  = list_to_integer([H1,H2]),
121    Min   = list_to_integer([M1,M2]),
122    Sec   = list_to_integer([S1,S2]),
123    {{Year,Month,Day},{Hour,Min,Sec}};
124
125%% Sloppy...
126convert_netscapecookie_date([_D,_A,_Y, $,, _SP,
127                             D1,D2,_DA,
128                             M,O,N,_DA,
129                             Y1,Y2,Y3,Y4,_SP,
130                             H1,H2,_Col,
131                             M1,M2,_Col,
132                             S1,S2|_Rest]) ->
133    Year=list_to_integer([Y1,Y2,Y3,Y4]),
134    Day=list_to_integer([D1,D2]),
135    Month=convert_month([M,O,N]),
136    Hour=list_to_integer([H1,H2]),
137    Min=list_to_integer([M1,M2]),
138    Sec=list_to_integer([S1,S2]),
139    {{Year,Month,Day},{Hour,Min,Sec}};
140
141convert_netscapecookie_date([_D,_A,_Y, _SP,
142                             D1,D2,_DA,
143                             M,O,N,_DA,
144                             Y1,Y2,Y3,Y4,_SP,
145                             H1,H2,_Col,
146                             M1,M2,_Col,
147                             S1,S2|_Rest]) ->
148    Year=list_to_integer([Y1,Y2,Y3,Y4]),
149    Day=list_to_integer([D1,D2]),
150    Month=convert_month([M,O,N]),
151    Hour=list_to_integer([H1,H2]),
152    Min=list_to_integer([M1,M2]),
153    Sec=list_to_integer([S1,S2]),
154    {{Year,Month,Day},{Hour,Min,Sec}}.
155
156hexlist_to_integer(List) ->
157    list_to_integer(List, 16).
158
159integer_to_hexlist(Int) ->
160    integer_to_list(Int, 16).
161
162convert_month("Jan") -> 1;
163convert_month("Feb") -> 2;
164convert_month("Mar") -> 3;
165convert_month("Apr") -> 4;
166convert_month("May") -> 5;
167convert_month("Jun") -> 6;
168convert_month("Jul") -> 7;
169convert_month("Aug") -> 8;
170convert_month("Sep") -> 9;
171convert_month("Oct") -> 10;
172convert_month("Nov") -> 11;
173convert_month("Dec") -> 12.
174
175is_hostname(Dest) ->
176    inet_parse:domain(Dest).
177
178
179timestamp() ->
180    {A,B,C} = os:timestamp(),
181    A*1000000000+B*1000+(C div 1000).
182
183timeout(Timeout, Started) ->
184    %% NewTimeout = Timeout - (timestamp() - Started),
185    case Timeout - (timestamp() - Started) of
186	NewTimeout when Timeout > 0 ->
187	    NewTimeout;
188	_ ->
189	    0
190    end.
191
192
193html_encode(Chars) ->
194    Reserved = sets:from_list([$&, $<, $>, $\", $', $/]),
195    lists:append([char_to_html_entity(Char, Reserved) || Char <- Chars]).
196
197
198maybe_add_brackets(Addr, false) ->
199    Addr;
200maybe_add_brackets(Addr, true) when is_list(Addr) ->
201    case is_ipv6_address(Addr) of
202        true ->
203            [$[|Addr] ++ "]";
204        false ->
205            Addr
206    end;
207maybe_add_brackets(Addr, true) when is_binary(Addr) ->
208    case is_ipv6_address(Addr) of
209        true ->
210            <<$[,Addr/binary,$]>>;
211        false ->
212            Addr
213    end.
214
215
216%%%========================================================================
217%%% Internal functions
218%%%========================================================================
219
220char_to_html_entity(Char, Reserved) ->
221    case sets:is_element(Char, Reserved) of
222	true ->
223	    "&#" ++ integer_to_list(Char) ++ ";";
224	false ->
225	    [Char]
226    end.
227
228is_ipv6_address(Addr) when is_binary(Addr) ->
229    B = binary_to_list(Addr),
230    is_ipv6_address(B);
231is_ipv6_address(Addr) when is_list(Addr) ->
232    case inet:parse_ipv6strict_address(Addr) of
233        {ok, _ } ->
234            true;
235        {error, _} ->
236            false
237    end.
238