~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/inets/src/httpd_util.erl

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
%% ``The contents of this file are subject to the Erlang Public License,
2
 
%% Version 1.1, (the "License"); you may not use this file except in
3
 
%% compliance with the License. You should have received a copy of the
4
 
%% Erlang Public License along with this software. If not, it can be
5
 
%% retrieved via the world wide web at http://www.erlang.org/.
6
 
%% 
7
 
%% Software distributed under the License is distributed on an "AS IS"
8
 
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
 
%% the License for the specific language governing rights and limitations
10
 
%% under the License.
11
 
%% 
12
 
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
 
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
 
%% AB. All Rights Reserved.''
15
 
%% 
16
 
%%     $Id$
17
 
%%
18
 
-module(httpd_util).
19
 
-export([key1search/2, key1search/3, lookup/2, lookup/3, multi_lookup/2,
20
 
         lookup_mime/2, lookup_mime/3, lookup_mime_default/2,
21
 
         lookup_mime_default/3, reason_phrase/1, message/3, rfc1123_date/0,
22
 
         rfc1123_date/1, day/1, month/1, decode_hex/1, decode_base64/1, encode_base64/1,
23
 
         flatlength/1, split_path/1, split_script_path/1, suffix/1, to_upper/1,
24
 
         to_lower/1, split/3, header/2, header/3, header/4, uniq/1,
25
 
         make_name/2,make_name/3,make_name/4,strip/1,
26
 
         hexlist_to_integer/1,integer_to_hexlist/1,
27
 
         convert_request_date/1,create_etag/1,create_etag/2,getSize/1,
28
 
         response_generated/1]).
29
 
 
30
 
%%Since hexlist_to_integer is a lousy name make a name convert
31
 
-export([encode_hex/1]).
32
 
-include("httpd.hrl").
33
 
 
34
 
%% key1search
35
 
 
36
 
key1search(TupleList,Key) ->
37
 
  key1search(TupleList,Key,undefined).
38
 
 
39
 
key1search(TupleList,Key,Undefined) ->
40
 
  case lists:keysearch(Key,1,TupleList) of
41
 
    {value,{Key,Value}} ->
42
 
      Value;
43
 
    false ->
44
 
      Undefined
45
 
  end.
46
 
 
47
 
%% lookup
48
 
 
49
 
lookup(Table,Key) ->
50
 
  lookup(Table,Key,undefined).
51
 
 
52
 
lookup(Table,Key,Undefined) ->
53
 
    case catch ets:lookup(Table,Key) of
54
 
        [{Key,Value}|_] ->
55
 
            Value;
56
 
        _->
57
 
            Undefined
58
 
    end.
59
 
 
60
 
%% multi_lookup
61
 
 
62
 
multi_lookup(Table,Key) ->
63
 
    remove_key(ets:lookup(Table,Key)).
64
 
 
65
 
remove_key([]) ->
66
 
    [];
67
 
remove_key([{Key,Value}|Rest]) ->
68
 
    [Value|remove_key(Rest)].
69
 
 
70
 
%% lookup_mime
71
 
 
72
 
lookup_mime(ConfigDB,Suffix) ->
73
 
    lookup_mime(ConfigDB,Suffix,undefined).
74
 
 
75
 
lookup_mime(ConfigDB,Suffix,Undefined) ->
76
 
    [{mime_types,MimeTypesDB}|_]=ets:lookup(ConfigDB,mime_types),
77
 
    case ets:lookup(MimeTypesDB,Suffix) of
78
 
        [] ->
79
 
            Undefined;
80
 
        [{Suffix,MimeType}|_] ->
81
 
            MimeType
82
 
    end.
83
 
 
84
 
%% lookup_mime_default
85
 
 
86
 
lookup_mime_default(ConfigDB,Suffix) ->
87
 
    lookup_mime_default(ConfigDB,Suffix,undefined).
88
 
 
89
 
lookup_mime_default(ConfigDB,Suffix,Undefined) ->
90
 
    [{mime_types,MimeTypesDB}|_]=ets:lookup(ConfigDB,mime_types),
91
 
    case ets:lookup(MimeTypesDB,Suffix) of
92
 
        [] ->
93
 
            case ets:lookup(ConfigDB,default_type) of
94
 
                [] ->
95
 
                    Undefined;
96
 
                [{default_type,DefaultType}|_] ->
97
 
                    DefaultType
98
 
            end;
99
 
        [{Suffix,MimeType}|_] ->
100
 
            MimeType
101
 
    end.
102
 
 
103
 
%% reason_phrase
104
 
reason_phrase(100) -> "Continue";
105
 
reason_phrase(101) -> "Swithing protocol";
106
 
reason_phrase(200) -> "OK";
107
 
reason_phrase(201) -> "Created";
108
 
reason_phrase(202) -> "Accepted";
109
 
reason_phrase(204) -> "No Content";
110
 
reason_phrase(205) -> "Reset Content";
111
 
reason_phrase(206) -> "Partial Content";
112
 
reason_phrase(301) -> "Moved Permanently";
113
 
reason_phrase(302) -> "Moved Temporarily";
114
 
reason_phrase(304) -> "Not Modified";
115
 
reason_phrase(400) -> "Bad Request";
116
 
reason_phrase(401) -> "Unauthorized";
117
 
reason_phrase(402) -> "Payment Required";
118
 
reason_phrase(403) -> "Forbidden";
119
 
reason_phrase(404) -> "Not Found";
120
 
reason_phrase(405) -> "Method Not Allowed";
121
 
reason_phrase(408) -> "Request Timeout";
122
 
reason_phrase(411) -> "Length Required";
123
 
reason_phrase(414) -> "Request-URI Too Long";
124
 
reason_phrase(412) -> "Precondition Failed";
125
 
reason_phrase(416) -> "request Range Not Satisfiable";
126
 
reason_phrase(417) -> "Expectation failed";
127
 
reason_phrase(500) -> "Internal Server Error";
128
 
reason_phrase(501) -> "Not Implemented";
129
 
reason_phrase(502) -> "Bad Gateway";
130
 
reason_phrase(503) -> "Service Unavailable";
131
 
reason_phrase(_) -> "Internal Server Error".
132
 
 
133
 
%% message
134
 
 
135
 
message(301,URL,_) ->
136
 
  "The document has moved <A HREF=\""++URL++"\">here</A>.";
137
 
message(304,URL,_) ->
138
 
    "The document has not been changed.";
139
 
message(400,none,_) ->
140
 
  "Your browser sent a query that this server could not understand.";
141
 
message(401,none,_) ->
142
 
  "This server could not verify that you
143
 
are authorized to access the document you
144
 
requested.  Either you supplied the wrong
145
 
credentials (e.g., bad password), or your
146
 
browser doesn't understand how to supply
147
 
the credentials required.";
148
 
message(403,RequestURI,_) ->
149
 
  "You don't have permission to access "++RequestURI++" on this server.";
150
 
message(404,RequestURI,_) ->
151
 
  "The requested URL "++RequestURI++" was not found on this server.";
152
 
message(412,none,_) ->
153
 
  "The requested preconditions where false";
154
 
message(414,ReasonPhrase,_) ->
155
 
  "Message "++ReasonPhrase++".";
156
 
message(416,ReasonPhrase,_) ->
157
 
    ReasonPhrase;
158
 
 
159
 
message(500,none,ConfigDB) ->
160
 
  ServerAdmin=lookup(ConfigDB,server_admin,"unknown@unknown"),
161
 
  "The server encountered an internal error or
162
 
misconfiguration and was unable to complete
163
 
your request.
164
 
<P>Please contact the server administrator "++ServerAdmin++",
165
 
and inform them of the time the error occurred
166
 
and anything you might have done that may have
167
 
caused the error.";
168
 
message(501,{Method,RequestURI,HTTPVersion},ConfigDB) ->
169
 
  Method++" to "++RequestURI++" ("++HTTPVersion++") not supported.";
170
 
message(503,String,ConfigDB) ->
171
 
  "This service in unavailable due to: "++String.
172
 
 
173
 
%%convert_rfc_date(Date)->{{YYYY,MM,DD},{HH,MIN,SEC}}
174
 
 
175
 
convert_request_date([D,A,Y,DateType|Rest])->
176
 
    Func=case DateType of
177
 
             $\, ->
178
 
                 fun convert_rfc1123_date/1;
179
 
             $\  ->
180
 
                 fun convert_ascii_date/1;
181
 
             _ ->
182
 
                 fun convert_rfc850_date/1
183
 
         end,
184
 
    case catch Func([D,A,Y,DateType|Rest])of
185
 
        {ok,Date} ->
186
 
            Date;
187
 
        Error->
188
 
            bad_date
189
 
    end.
190
 
convert_rfc850_date(DateStr)->
191
 
    case string:tokens(DateStr," ") of
192
 
        [WeekDay,Date,Time,TimeZone|Rest]->
193
 
           convert_rfc850_date(Date,Time);
194
 
        bad_date ->
195
 
            bad_date;
196
 
        Error->
197
 
            bad_date
198
 
    end.
199
 
 
200
 
convert_rfc850_date([D1,D2,_,M,O,N,_,Y1,Y2|_Rest],[H1,H2,_Col,M1,M2,_Col,S1,S2|_Rest2])->    
201
 
    Year=list_to_integer([50,48,Y1,Y2]),
202
 
    Day=list_to_integer([D1,D2]),
203
 
    Month=convert_month([M,O,N]),
204
 
    Hour=list_to_integer([H1,H2]),
205
 
    Min=list_to_integer([M1,M2]),
206
 
    Sec=list_to_integer([S1,S2]),
207
 
    {ok,{{Year,Month,Day},{Hour,Min,Sec}}};
208
 
convert_rfc850_date(_BadDate,_BadTime)->
209
 
    bad_date.
210
 
 
211
 
convert_ascii_date([_D,_A,_Y,_SP,M,O,N,_SP,D1,D2,_SP,H1,H2,_Col,M1,M2,_Col,S1,S2,_SP,Y1,Y2,Y3,Y4|Rest])->
212
 
    Year=list_to_integer([Y1,Y2,Y3,Y4]),
213
 
    Day=case D1 of 
214
 
        $\ ->
215
 
            list_to_integer([D2]);
216
 
        _->
217
 
            list_to_integer([D1,D2])
218
 
    end,
219
 
    Month=convert_month([M,O,N]),
220
 
    Hour=list_to_integer([H1,H2]),
221
 
    Min=list_to_integer([M1,M2]),
222
 
    Sec=list_to_integer([S1,S2]),
223
 
    {ok,{{Year,Month,Day},{Hour,Min,Sec}}};
224
 
convert_ascii_date(BadDate)->
225
 
    bad_date.
226
 
convert_rfc1123_date([_D,_A,_Y,_C,_SP,D1,D2,_SP,M,O,N,_SP,Y1,Y2,Y3,Y4,_SP,H1,H2,_Col,M1,M2,_Col,S1,S2|Rest])->    
227
 
    Year=list_to_integer([Y1,Y2,Y3,Y4]),
228
 
    Day=list_to_integer([D1,D2]),
229
 
    Month=convert_month([M,O,N]),
230
 
    Hour=list_to_integer([H1,H2]),
231
 
    Min=list_to_integer([M1,M2]),
232
 
    Sec=list_to_integer([S1,S2]),
233
 
    {ok,{{Year,Month,Day},{Hour,Min,Sec}}};
234
 
convert_rfc1123_date(BadDate)->    
235
 
    bad_date.
236
 
 
237
 
convert_month("Jan")->1;
238
 
convert_month("Feb") ->2;
239
 
convert_month("Mar") ->3; 
240
 
convert_month("Apr") ->4;
241
 
convert_month("May") ->5;
242
 
convert_month("Jun") ->6;
243
 
convert_month("Jul") ->7;
244
 
convert_month("Aug") ->8;
245
 
convert_month("Sep") ->9;
246
 
convert_month("Oct") ->10;
247
 
convert_month("Nov") ->11;
248
 
convert_month("Dec") ->12.
249
 
 
250
 
 
251
 
%% rfc1123_date
252
 
 
253
 
rfc1123_date() ->
254
 
  {{YYYY,MM,DD},{Hour,Min,Sec}}=calendar:universal_time(),
255
 
  DayNumber=calendar:day_of_the_week({YYYY,MM,DD}),
256
 
  lists:flatten(io_lib:format("~s, ~2.2.0w ~3.s ~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w GMT",
257
 
                        [day(DayNumber),DD,month(MM),YYYY,Hour,Min,Sec])).
258
 
 
259
 
rfc1123_date({{YYYY,MM,DD},{Hour,Min,Sec}}) ->
260
 
  DayNumber=calendar:day_of_the_week({YYYY,MM,DD}),
261
 
  lists:flatten(io_lib:format("~s, ~2.2.0w ~3.s ~4.4.0w ~2.2.0w:~2.2.0w:~2.2.0w GMT",
262
 
                        [day(DayNumber),DD,month(MM),YYYY,Hour,Min,Sec])).
263
 
 
264
 
%% uniq
265
 
 
266
 
uniq([]) ->
267
 
    [];
268
 
uniq([First,First|Rest]) ->
269
 
    uniq([First|Rest]);
270
 
uniq([First|Rest]) ->
271
 
    [First|uniq(Rest)].
272
 
 
273
 
 
274
 
%% day
275
 
 
276
 
day(1) -> "Mon";
277
 
day(2) -> "Tue";
278
 
day(3) -> "Wed";
279
 
day(4) -> "Thu";
280
 
day(5) -> "Fri";
281
 
day(6) -> "Sat"; 
282
 
day(7) -> "Sun".
283
 
 
284
 
%% month
285
 
 
286
 
month(1) -> "Jan";
287
 
month(2) -> "Feb";
288
 
month(3) -> "Mar";
289
 
month(4) -> "Apr";
290
 
month(5) -> "May";
291
 
month(6) -> "Jun";
292
 
month(7) -> "Jul";
293
 
month(8) -> "Aug";
294
 
month(9) -> "Sep";
295
 
month(10) -> "Oct";
296
 
month(11) -> "Nov";
297
 
month(12) -> "Dec".
298
 
 
299
 
%% decode_hex
300
 
 
301
 
decode_hex([$%,Hex1,Hex2|Rest]) ->
302
 
  [hex2dec(Hex1)*16+hex2dec(Hex2)|decode_hex(Rest)];
303
 
decode_hex([First|Rest]) ->
304
 
  [First|decode_hex(Rest)];
305
 
decode_hex([]) ->
306
 
  [].
307
 
 
308
 
hex2dec(X) when X>=$0,X=<$9 -> X-$0;
309
 
hex2dec(X) when X>=$A,X=<$F -> X-$A+10;
310
 
hex2dec(X) when X>=$a,X=<$f -> X-$a+10.
311
 
 
312
 
%% decode_base64 (DEBUG STRING: QWxhZGRpbjpvcGVuIHNlc2FtZQ==)
313
 
 
314
 
decode_base64([]) ->
315
 
  [];
316
 
decode_base64([Sextet1,Sextet2,$=,$=|Rest]) ->
317
 
  Bits2x6=
318
 
    (d(Sextet1) bsl 18) bor
319
 
    (d(Sextet2) bsl 12),
320
 
  Octet1=Bits2x6 bsr 16,
321
 
  [Octet1|decode_base64(Rest)];
322
 
decode_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) ->
323
 
  Bits3x6=
324
 
    (d(Sextet1) bsl 18) bor
325
 
    (d(Sextet2) bsl 12) bor
326
 
    (d(Sextet3) bsl 6),
327
 
  Octet1=Bits3x6 bsr 16,
328
 
  Octet2=(Bits3x6 bsr 8) band 16#ff,
329
 
  [Octet1,Octet2|decode_base64(Rest)];
330
 
decode_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) ->
331
 
  Bits4x6=
332
 
    (d(Sextet1) bsl 18) bor
333
 
    (d(Sextet2) bsl 12) bor
334
 
    (d(Sextet3) bsl 6) bor
335
 
    d(Sextet4),
336
 
  Octet1=Bits4x6 bsr 16,
337
 
  Octet2=(Bits4x6 bsr 8) band 16#ff,
338
 
  Octet3=Bits4x6 band 16#ff,
339
 
  [Octet1,Octet2,Octet3|decode_base64(Rest)];
340
 
decode_base64(CatchAll) ->
341
 
  "BAD!".
342
 
 
343
 
d(X) when X >= $A, X =<$Z ->
344
 
    X-65;
345
 
d(X) when X >= $a, X =<$z ->
346
 
    X-71;
347
 
d(X) when X >= $0, X =<$9 ->
348
 
    X+4;
349
 
d($+) -> 62;
350
 
d($/) -> 63;
351
 
d(_) -> 63.
352
 
 
353
 
 
354
 
encode_base64([]) ->
355
 
    [];
356
 
encode_base64([A]) ->
357
 
    [e(A bsr 2), e((A band 3) bsl 4), $=, $=];
358
 
encode_base64([A,B]) ->
359
 
    [e(A bsr 2), e(((A band 3) bsl 4) bor (B bsr 4)), e((B band 15) bsl 2), $=];
360
 
encode_base64([A,B,C|Ls]) ->
361
 
    encode_base64_do(A,B,C, Ls).
362
 
encode_base64_do(A,B,C, Rest) ->
363
 
    BB = (A bsl 16) bor (B bsl 8) bor C,
364
 
    [e(BB bsr 18), e((BB bsr 12) band 63), 
365
 
     e((BB bsr 6) band 63), e(BB band 63)|encode_base64(Rest)].
366
 
 
367
 
e(X) when X >= 0, X < 26 -> X+65;
368
 
e(X) when X>25, X<52 ->     X+71;
369
 
e(X) when X>51, X<62 ->     X-4;
370
 
e(62) ->                    $+;
371
 
e(63) ->                    $/;
372
 
e(X) ->                     exit({bad_encode_base64_token, X}).
373
 
 
374
 
 
375
 
%% flatlength
376
 
 
377
 
flatlength(List) ->
378
 
    flatlength(List, 0).
379
 
 
380
 
flatlength([H|T],L) when list(H) ->
381
 
    flatlength(H,flatlength(T,L));
382
 
flatlength([H|T],L) when binary(H) ->
383
 
    flatlength(T,L+size(H));
384
 
flatlength([H|T],L) ->
385
 
    flatlength(T,L+1);
386
 
flatlength([],L) ->
387
 
  L.
388
 
 
389
 
%% split_path
390
 
 
391
 
split_path(Path) ->
392
 
    case regexp:match(Path,"[\?].*\$") of
393
 
        %% A QUERY_STRING exists!
394
 
        {match,Start,Length} ->
395
 
            {httpd_util:decode_hex(string:substr(Path,1,Start-1)),
396
 
             string:substr(Path,Start,Length)};
397
 
        %% A possible PATH_INFO exists!
398
 
        nomatch ->
399
 
            split_path(Path,[])
400
 
    end.
401
 
 
402
 
split_path([],SoFar) ->
403
 
    {httpd_util:decode_hex(lists:reverse(SoFar)),[]};
404
 
split_path([$/|Rest],SoFar) ->
405
 
    Path=httpd_util:decode_hex(lists:reverse(SoFar)),
406
 
    case file:read_file_info(Path) of
407
 
        {ok,FileInfo} when FileInfo#file_info.type == regular ->
408
 
            {Path,[$/|Rest]};
409
 
        {ok,FileInfo} ->
410
 
            split_path(Rest,[$/|SoFar]);
411
 
        {error,Reason} ->
412
 
            split_path(Rest,[$/|SoFar])
413
 
    end;
414
 
split_path([C|Rest],SoFar) ->
415
 
    split_path(Rest,[C|SoFar]).
416
 
 
417
 
%% split_script_path
418
 
 
419
 
split_script_path(Path) ->
420
 
    case split_script_path(Path, []) of
421
 
        {Script, AfterPath} ->
422
 
            {PathInfo, QueryString} = pathinfo_querystring(AfterPath),
423
 
            {Script, {PathInfo, QueryString}};
424
 
        not_a_script ->
425
 
            not_a_script
426
 
    end.
427
 
 
428
 
pathinfo_querystring(Str) ->
429
 
    pathinfo_querystring(Str, []).
430
 
pathinfo_querystring([], SoFar) ->
431
 
    {lists:reverse(SoFar), []};
432
 
pathinfo_querystring([$?|Rest], SoFar) ->
433
 
    {lists:reverse(SoFar), Rest};
434
 
pathinfo_querystring([C|Rest], SoFar) ->
435
 
    pathinfo_querystring(Rest, [C|SoFar]).
436
 
 
437
 
split_script_path([$?|QueryString], SoFar) ->
438
 
    Path = httpd_util:decode_hex(lists:reverse(SoFar)),
439
 
    case file:read_file_info(Path) of
440
 
        {ok,FileInfo} when FileInfo#file_info.type == regular ->
441
 
            {Path, [$?|QueryString]};
442
 
        {ok,FileInfo} ->
443
 
            not_a_script;
444
 
        {error,Reason} ->
445
 
            not_a_script
446
 
    end;
447
 
split_script_path([], SoFar) ->
448
 
    Path = httpd_util:decode_hex(lists:reverse(SoFar)),
449
 
    case file:read_file_info(Path) of
450
 
        {ok,FileInfo} when FileInfo#file_info.type == regular ->
451
 
            {Path, []};
452
 
        {ok,FileInfo} ->
453
 
            not_a_script;
454
 
        {error,Reason} ->
455
 
            not_a_script
456
 
    end;
457
 
split_script_path([$/|Rest], SoFar) ->
458
 
    Path = httpd_util:decode_hex(lists:reverse(SoFar)),
459
 
    case file:read_file_info(Path) of
460
 
        {ok, FileInfo} when FileInfo#file_info.type == regular ->
461
 
            {Path, [$/|Rest]};
462
 
        {ok, _FileInfo} ->
463
 
            split_script_path(Rest, [$/|SoFar]);
464
 
        {error, _Reason} ->
465
 
            split_script_path(Rest, [$/|SoFar])
466
 
    end;
467
 
split_script_path([C|Rest], SoFar) ->
468
 
    split_script_path(Rest,[C|SoFar]).
469
 
 
470
 
%% suffix
471
 
 
472
 
suffix(Path) ->
473
 
    case filename:extension(Path) of
474
 
        [] ->
475
 
            [];
476
 
        Extension ->
477
 
            tl(Extension)
478
 
    end.
479
 
 
480
 
%% to_upper
481
 
 
482
 
to_upper([C|Cs]) when C >= $a, C =< $z ->
483
 
    [C-($a-$A)|to_upper(Cs)];
484
 
to_upper([C|Cs]) ->
485
 
    [C|to_upper(Cs)];
486
 
to_upper([]) ->
487
 
    [].
488
 
 
489
 
%% to_lower
490
 
 
491
 
to_lower([C|Cs]) when C >= $A, C =< $Z ->
492
 
    [C+($a-$A)|to_lower(Cs)];
493
 
to_lower([C|Cs]) ->
494
 
    [C|to_lower(Cs)];
495
 
to_lower([]) ->
496
 
    [].
497
 
 
498
 
 
499
 
%% strip
500
 
strip(Value)->
501
 
    lists:reverse(remove_ws(lists:reverse(remove_ws(Value)))).
502
 
        
503
 
remove_ws([$\s|Rest])->
504
 
    remove_ws(Rest);
505
 
remove_ws([$\t|Rest]) ->
506
 
    remove_ws(Rest);
507
 
remove_ws(Rest) ->
508
 
    Rest.
509
 
 
510
 
%% split
511
 
 
512
 
split(String,RegExp,Limit) ->
513
 
    case regexp:parse(RegExp) of
514
 
        {error,Reason} ->
515
 
            {error,Reason};
516
 
        {ok,_} ->
517
 
            {ok,do_split(String,RegExp,Limit)}
518
 
    end.
519
 
 
520
 
do_split(String,RegExp,1) ->
521
 
    [String];
522
 
 
523
 
do_split(String,RegExp,Limit) ->
524
 
    case regexp:first_match(String,RegExp) of 
525
 
        {match,Start,Length} ->
526
 
            [string:substr(String,1,Start-1)|
527
 
             do_split(lists:nthtail(Start+Length-1,String),RegExp,Limit-1)];
528
 
        nomatch ->
529
 
            [String]
530
 
    end.
531
 
 
532
 
%% header
533
 
header(StatusCode,Date)when list(Date)->
534
 
    header(StatusCode,"text/plain",false);
535
 
 
536
 
header(StatusCode, PersistentConnection) when integer(StatusCode)->
537
 
    Date = rfc1123_date(),
538
 
    Connection = 
539
 
        case PersistentConnection of
540
 
            true ->
541
 
                "";
542
 
            _ ->
543
 
                "Connection: close \r\n"
544
 
        end,
545
 
    io_lib:format("HTTP/1.1 ~w ~s \r\nDate: ~s\r\nServer: ~s\r\n~s",
546
 
                  [StatusCode, httpd_util:reason_phrase(StatusCode),
547
 
                   Date, ?SERVER_SOFTWARE, Connection]).
548
 
 
549
 
%%----------------------------------------------------------------------
550
 
 
551
 
header(StatusCode, MimeType, Date) when list(Date) ->
552
 
    header(StatusCode, MimeType, false,rfc1123_date());
553
 
 
554
 
 
555
 
header(StatusCode, MimeType, PersistentConnection) when integer(StatusCode) ->
556
 
    header(StatusCode, MimeType, PersistentConnection,rfc1123_date()).
557
 
 
558
 
 
559
 
%%----------------------------------------------------------------------
560
 
 
561
 
header(416, MimeType,PersistentConnection,Date)-> 
562
 
    Connection = 
563
 
        case PersistentConnection of
564
 
            true ->
565
 
                "";
566
 
            _ ->
567
 
                "Connection: close \r\n"
568
 
        end,
569
 
    io_lib:format("HTTP/1.1 ~w ~s \r\nDate: ~s\r\nServer: ~s\r\n"
570
 
                  "Content-Range:bytes *"
571
 
                  "Content-Type: ~s\r\n~s",
572
 
                  [416, httpd_util:reason_phrase(416),
573
 
                   Date, ?SERVER_SOFTWARE, MimeType, Connection]);
574
 
 
575
 
 
576
 
header(StatusCode, MimeType,PersistentConnection,Date) when integer(StatusCode)-> 
577
 
    Connection = 
578
 
        case PersistentConnection of
579
 
            true ->
580
 
                "";
581
 
            _ ->
582
 
                "Connection: close \r\n"
583
 
        end,
584
 
    io_lib:format("HTTP/1.1 ~w ~s \r\nDate: ~s\r\nServer: ~s\r\n"
585
 
                  "Content-Type: ~s\r\n~s",
586
 
                  [StatusCode, httpd_util:reason_phrase(StatusCode),
587
 
                   Date, ?SERVER_SOFTWARE, MimeType, Connection]).
588
 
 
589
 
 
590
 
 
591
 
%% make_name/2, make_name/3
592
 
%% Prefix  -> string()
593
 
%%            First part of the name, e.g. "httpd"
594
 
%% Addr    -> {A,B,C,D} | string() | undefined
595
 
%%            The address part of the name. 
596
 
%%            e.g. "123.234.55.66" or {123,234,55,66} or "otp.ericsson.se" 
597
 
%%            for a host address or undefined if local host.
598
 
%% Port    -> integer()
599
 
%%            Last part of the name, such as the HTTPD server port 
600
 
%%            number (80).
601
 
%% Postfix -> Any string that will be added last to the name
602
 
%%
603
 
%% Example:
604
 
%% make_name("httpd","otp.ericsson.se",80) => httpd__otp_ericsson_se__80
605
 
%% make_name("httpd",undefined,8088)       => httpd_8088
606
 
 
607
 
make_name(Prefix,Port) ->
608
 
    make_name(Prefix,undefined,Port,"").
609
 
 
610
 
make_name(Prefix,Addr,Port) ->
611
 
    make_name(Prefix,Addr,Port,"").
612
 
    
613
 
make_name(Prefix,"*",Port,Postfix) ->
614
 
    make_name(Prefix,undefined,Port,Postfix);
615
 
 
616
 
make_name(Prefix,any,Port,Postfix) ->
617
 
    make_name1(io_lib:format("~s_~w~s",[Prefix,Port,Postfix]));
618
 
 
619
 
make_name(Prefix,undefined,Port,Postfix) ->
620
 
    make_name1(io_lib:format("~s_~w~s",[Prefix,Port,Postfix]));
621
 
 
622
 
make_name(Prefix,Addr,Port,Postfix) ->
623
 
    NameString = 
624
 
        Prefix ++ "__" ++ make_name2(Addr) ++ "__" ++ 
625
 
        integer_to_list(Port) ++ Postfix,
626
 
    make_name1(NameString).
627
 
    
628
 
make_name1(String) ->
629
 
    list_to_atom(lists:flatten(String)).
630
 
 
631
 
make_name2({A,B,C,D}) ->
632
 
    io_lib:format("~w_~w_~w_~w",[A,B,C,D]);
633
 
make_name2(Addr) ->
634
 
    search_and_replace(Addr,$.,$_).
635
 
 
636
 
search_and_replace(S,A,B) ->
637
 
    Fun = fun(What) -> 
638
 
                  case What of
639
 
                      A -> B;
640
 
                      O -> O
641
 
                  end
642
 
          end,
643
 
    lists:map(Fun,S).
644
 
 
645
 
 
646
 
 
647
 
%%----------------------------------------------------------------------
648
 
%% Converts  a string that constists of 0-9,A-F,a-f to a 
649
 
%% integer
650
 
%%----------------------------------------------------------------------
651
 
 
652
 
hexlist_to_integer([])->
653
 
    empty;
654
 
 
655
 
 
656
 
%%When the string only contains one value its eaasy done.
657
 
%% 0-9
658
 
hexlist_to_integer([Size]) when Size>=48 , Size=<57 ->
659
 
   Size-48;
660
 
%% A-F
661
 
hexlist_to_integer([Size]) when Size>=65 , Size=<70 ->
662
 
    Size-55;
663
 
%% a-f
664
 
hexlist_to_integer([Size]) when Size>=97 , Size=<102 ->
665
 
    Size-87;
666
 
hexlist_to_integer([Size]) ->
667
 
    not_a_num;
668
 
 
669
 
hexlist_to_integer(Size) ->
670
 
    Len=string:span(Size,"1234567890abcdefABCDEF"),
671
 
    hexlist_to_integer2(Size,16 bsl (4 *(Len-2)),0).
672
 
 
673
 
hexlist_to_integer2([],_Pos,Sum)->
674
 
    Sum;
675
 
hexlist_to_integer2([HexVal|HexString],Pos,Sum)when HexVal>=48,HexVal=<57->
676
 
    hexlist_to_integer2(HexString,Pos bsr 4,Sum+((HexVal-48)*Pos));
677
 
 
678
 
hexlist_to_integer2([HexVal|HexString],Pos,Sum)when HexVal>=65,HexVal=<70->
679
 
    hexlist_to_integer2(HexString,Pos bsr 4,Sum+((HexVal-55)*Pos));
680
 
 
681
 
hexlist_to_integer2([HexVal|HexString],Pos,Sum)when HexVal>=97,HexVal=<102->
682
 
    hexlist_to_integer2(HexString,Pos bsr 4,Sum+((HexVal-87)*Pos));
683
 
 
684
 
hexlist_to_integer2(_AfterHexString,_Pos,Sum)->
685
 
    Sum.
686
 
 
687
 
%%----------------------------------------------------------------------
688
 
%%Converts an integer to an hexlist
689
 
%%----------------------------------------------------------------------
690
 
encode_hex(Num)->
691
 
    integer_to_hexlist(Num).
692
 
 
693
 
 
694
 
integer_to_hexlist(Num)->
695
 
    integer_to_hexlist(Num,getSize(Num),[]).
696
 
 
697
 
integer_to_hexlist(Num,Pot,Res) when Pot<0 ->
698
 
    convert_to_ascii([Num|Res]);
699
 
 
700
 
integer_to_hexlist(Num,Pot,Res) ->
701
 
    Position=(16 bsl (Pot*4)),
702
 
    PosVal=Num div Position,
703
 
    integer_to_hexlist(Num-(PosVal*Position),Pot-1,[PosVal|Res]).
704
 
convert_to_ascii(RevesedNum)->
705
 
    convert_to_ascii(RevesedNum,[]).
706
 
 
707
 
convert_to_ascii([],Num)->
708
 
    Num;
709
 
convert_to_ascii([Num|Reversed],Number)when Num>-1, Num<10 ->
710
 
    convert_to_ascii(Reversed,[Num+48|Number]);
711
 
convert_to_ascii([Num|Reversed],Number)when Num>9, Num<16 ->
712
 
    convert_to_ascii(Reversed,[Num+55|Number]);
713
 
convert_to_ascii(NumReversed,Number) ->
714
 
    error.
715
 
 
716
 
 
717
 
                                              
718
 
getSize(Num)->
719
 
    getSize(Num,0).
720
 
 
721
 
getSize(Num,Pot)when Num<(16 bsl(Pot *4))  ->
722
 
    Pot-1;
723
 
 
724
 
getSize(Num,Pot) ->
725
 
    getSize(Num,Pot+1).
726
 
 
727
 
 
728
 
 
729
 
 
730
 
 
731
 
create_etag(FileInfo)->
732
 
    create_etag(FileInfo#file_info.mtime,FileInfo#file_info.size).
733
 
 
734
 
create_etag({{Year,Month,Day},{Hour,Min,Sec}},Size)->
735
 
    create_part([Year,Month,Day,Hour,Min,Sec])++io_lib:write(Size);
736
 
 
737
 
create_etag(FileInfo,Size)->
738
 
    create_etag(FileInfo#file_info.mtime,Size).
739
 
 
740
 
create_part(Values)->
741
 
    lists:map(fun(Val0)->
742
 
                      Val=Val0 rem 60,
743
 
                          if
744
 
                              Val=<25 ->
745
 
                                  65+Val;  % A-Z
746
 
                              Val=<50 ->
747
 
                                  72+Val;  % a-z
748
 
                              %%Since no date s
749
 
                              true ->
750
 
                                  Val-3
751
 
                          end
752
 
              end,Values).
753
 
                                    
754
 
 
755
 
 
756
 
%%----------------------------------------------------------------------
757
 
%%Function that controls whether a response is generated or not
758
 
%%----------------------------------------------------------------------
759
 
response_generated(Info)->
760
 
    case httpd_util:key1search(Info#mod.data,status) of
761
 
        %% A status code has been generated!
762
 
        {StatusCode,PhraseArgs,Reason}->
763
 
            true;
764
 
        %%No status code control repsonsxe
765
 
        undefined ->
766
 
            case httpd_util:key1search(Info#mod.data, response) of
767
 
                %% No response has been generated!
768
 
                undefined ->
769
 
                    false;
770
 
                %% A response has been generated or sent!
771
 
                Response ->
772
 
                    true
773
 
            end
774
 
    end.
775
 
 
776
 
 
777
 
 
778