~statik/ubuntu/maverick/erlang/erlang-merge-testing

« back to all changes in this revision

Viewing changes to erts/emulator/test/decode_packet_SUITE.erl

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-12-20 09:03:40 UTC
  • mto: (3.6.1 sid)
  • mto: This revision was merged to the branch mainline in revision 27.
  • Revision ID: james.westby@ubuntu.com-20091220090340-w3kbi1lj1wp7l2m3
Tags: upstream-13.b.3-dfsg
ImportĀ upstreamĀ versionĀ 13.b.3-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%%
 
2
%% %CopyrightBegin%
 
3
%% 
 
4
%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
 
5
%% 
 
6
%% The contents of this file are subject to the Erlang Public License,
 
7
%% Version 1.1, (the "License"); you may not use this file except in
 
8
%% compliance with the License. You should have received a copy of the
 
9
%% Erlang Public License along with this software. If not, it can be
 
10
%% retrieved online at http://www.erlang.org/.
 
11
%% 
 
12
%% Software distributed under the License is distributed on an "AS IS"
 
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
14
%% the License for the specific language governing rights and limitations
 
15
%% under the License.
 
16
%% 
 
17
%% %CopyrightEnd%
 
18
%%
 
19
 
 
20
%% Test suite for erlang:decode_packet/3
 
21
 
 
22
-module(decode_packet_SUITE).
 
23
 
 
24
-include("test_server.hrl").
 
25
 
 
26
-export([all/1,init_per_testcase/2,fin_per_testcase/2,
 
27
         basic/1, packet_size/1, neg/1, http/1, line/1, ssl/1]).
 
28
 
 
29
all(suite) ->
 
30
    [basic, packet_size, neg, http, line, ssl].
 
31
 
 
32
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
 
33
    Seed = {S1,S2,S3} = now(),
 
34
    random:seed(S1,S2,S3),
 
35
    io:format("*** SEED: ~p ***\n", [Seed]),
 
36
    Dog=?t:timetrap(?t:minutes(1)),
 
37
    [{watchdog, Dog}|Config].
 
38
 
 
39
fin_per_testcase(_Func, Config) ->
 
40
    Dog=?config(watchdog, Config),
 
41
    ?t:timetrap_cancel(Dog).
 
42
 
 
43
basic(doc) -> [];
 
44
basic(suite) -> [];
 
45
basic(Config) when is_list(Config) ->
 
46
    ?line Packet = <<101,22,203,54,175>>,
 
47
    ?line Rest = <<123,34,0,250>>,
 
48
    ?line Bin = <<Packet/binary,Rest/binary>>,
 
49
    ?line {ok, Bin, <<>>} = decode_pkt(raw,Bin),
 
50
 
 
51
    ?line {more, 5+1} = decode_pkt(1,<<5,1,2,3,4>>),
 
52
    ?line {more, 5+2} = decode_pkt(2,<<0,5,1,2,3,4>>),
 
53
    ?line {more, 5+4} = decode_pkt(4,<<0,0,0,5,1,2,3,4>>),
 
54
 
 
55
    ?line {more, undefined} = decode_pkt(1,<<>>),
 
56
    ?line {more, undefined} = decode_pkt(2,<<0>>),
 
57
    ?line {more, undefined} = decode_pkt(4,<<0,0,0>>),
 
58
 
 
59
    Types = [1,2,4,asn1,sunrm,cdr,fcgi,tpkt,ssl_tls],
 
60
 
 
61
    %% Run tests for different header types and bit offsets.
 
62
 
 
63
    lists:foreach(fun({Type,Bits})->basic_pack(Type,Packet,Rest,Bits), 
 
64
                                    more_length(Type,Packet,Bits) end,
 
65
                  [{T,B} || T<-Types, B<-lists:seq(0,32)]),
 
66
    ok.
 
67
 
 
68
basic_pack(Type,Body,Rest,BitOffs) ->
 
69
    ?line {Bin,Unpacked,_} = pack(Type,Body,Rest,BitOffs),
 
70
    ?line {ok, Unpacked, Rest} = decode_pkt(Type,Bin),
 
71
    case Rest of
 
72
        <<>> -> ok;
 
73
        _ -> 
 
74
            ?line <<_:1,NRest/bits>> = Rest,
 
75
            basic_pack(Type,Body,NRest,BitOffs)
 
76
    end.
 
77
 
 
78
more_length(Type,Body,BitOffs) ->
 
79
    ?line {Bin,_,_} = pack(Type,Body,<<>>,BitOffs),
 
80
    HdrSize = byte_size(Bin) - byte_size(Body),
 
81
    more_length_do(Type,HdrSize,Bin,byte_size(Bin)).
 
82
 
 
83
more_length_do(_,_,_,0) ->
 
84
    ok;
 
85
more_length_do(Type,HdrSize,Bin,Size) ->
 
86
    TrySize = (Size*3) div 4,
 
87
    NSize = if TrySize < HdrSize -> Size - 1;
 
88
               true -> TrySize
 
89
            end,
 
90
    {B1,_} = split_binary(Bin,NSize),
 
91
    ?line {more, Length} = decode_pkt(Type,B1),
 
92
    case Length of
 
93
        L when L=:=byte_size(Bin) -> ok;
 
94
        undefined when NSize<HdrSize -> ok
 
95
    end,
 
96
    more_length_do(Type,HdrSize,Bin,NSize).
 
97
 
 
98
   
 
99
 
 
100
pack(Type,Packet,Rest) ->
 
101
    {Bin,Unpacked} = pack(Type,Packet),
 
102
    {<<Bin/binary,Rest/bits>>,Unpacked}.
 
103
 
 
104
%pack(0,B,R,Bits) -> 
 
105
%    pack(raw,B,R,Bits);
 
106
%pack(raw,Body,Rest,BitOffs) ->
 
107
%    Orig = <<0:BitOffs,Body/binary,Rest/bits>>,
 
108
%    <<_:BitOffs,Bin/bits>> = Orig,
 
109
%    {Bin,<<Bin/binary,Rest/bits>>,Orig};
 
110
pack(Type,Body,Rest,BitOffs) ->
 
111
    {Packet,Unpacked} = pack(Type,Body),
 
112
 
 
113
    %% Make Bin a sub-bin with an arbitrary bitoffset within Orig
 
114
    Prefix = random:uniform(1 bsl BitOffs) - 1,
 
115
    Orig = <<Prefix:BitOffs,Packet/binary,Rest/bits>>,
 
116
    <<_:BitOffs,Bin/bits>> = Orig,
 
117
    {Bin,Unpacked,Orig}.
 
118
 
 
119
pack(1,Bin) ->
 
120
    Psz = byte_size(Bin),
 
121
    {<<Psz:8,Bin/binary>>, Bin};
 
122
pack(2,Bin) ->
 
123
    Psz = byte_size(Bin),
 
124
    {<<Psz:16,Bin/binary>>, Bin};
 
125
pack(4,Bin) ->
 
126
    Psz = byte_size(Bin),
 
127
    {<<Psz:32,Bin/binary>>, Bin};
 
128
pack(asn1,Bin) ->
 
129
    Ident = case random:uniform(3) of
 
130
                1 -> <<17>>;
 
131
                2 -> <<16#1f,16#81,17>>;
 
132
                3 -> <<16#1f,16#81,16#80,16#80,17>>
 
133
            end,
 
134
    Psz = byte_size(Bin),
 
135
    Length = case random:uniform(4) of
 
136
                 1 when Psz < 128 -> 
 
137
                     <<Psz:8>>;
 
138
                 R when R=<2 andalso Psz < 16#10000 ->
 
139
                     <<16#82,Psz:16>>;
 
140
                 R when R=<3 andalso Psz < 16#1000000 -> 
 
141
                     <<16#83,Psz:24>>;
 
142
                 _ when Psz < 16#100000000 ->
 
143
                     <<16#84,Psz:32>>
 
144
             end,
 
145
    Res = <<Ident/binary,Length/binary,Bin/binary>>,
 
146
    {Res,Res};
 
147
pack(sunrm,Bin) ->
 
148
    Psz = byte_size(Bin),
 
149
    Res = if Psz < 16#80000000 ->
 
150
                  <<Psz:32,Bin/binary>>
 
151
    end,
 
152
    {Res,Res};
 
153
pack(cdr,Bin) ->
 
154
    GIOP = <<"GIOP">>,
 
155
    Major = random:uniform(256) - 1,
 
156
    Minor = random:uniform(256) - 1,
 
157
    MType = random:uniform(256) - 1,
 
158
    Psz = byte_size(Bin),
 
159
    Res = case random:uniform(2) of 
 
160
              1 -> <<GIOP/binary,Major:8,Minor:8,0:8,MType:8,Psz:32/big,Bin/binary>>;
 
161
              2 -> <<GIOP/binary,Major:8,Minor:8,1:8,MType:8,Psz:32/little,Bin/binary>>
 
162
          end,
 
163
    {Res,Res};
 
164
pack(fcgi,Bin) ->
 
165
    Ver = 1,
 
166
    Type = random:uniform(256) - 1,
 
167
    Id = random:uniform(65536) - 1,
 
168
    PaddSz = random:uniform(16) - 1,    
 
169
    Psz = byte_size(Bin),
 
170
    Reserv = random:uniform(256) - 1,
 
171
    Padd = case PaddSz of
 
172
               0 -> <<>>;
 
173
               _ -> list_to_binary([random:uniform(256)-1
 
174
                                    || _<- lists:seq(1,PaddSz)])
 
175
           end,
 
176
    Res = <<Ver:8,Type:8,Id:16,Psz:16/big,PaddSz:8,Reserv:8,Bin/binary>>,
 
177
    {<<Res/binary,Padd/binary>>, Res};
 
178
pack(tpkt,Bin) ->
 
179
    Ver = 3,
 
180
    Reserv = random:uniform(256) - 1,
 
181
    Size = byte_size(Bin) + 4,
 
182
    Res = <<Ver:8,Reserv:8,Size:16,Bin/binary>>,
 
183
    {Res, Res};
 
184
pack(ssl_tls,Bin) ->
 
185
    Content = case (random:uniform(256) - 1) of
 
186
                  C when C<128 -> C;
 
187
                  _ -> v2hello
 
188
              end,
 
189
    Major = random:uniform(256) - 1,
 
190
    Minor = random:uniform(256) - 1,
 
191
    pack_ssl(Content,Major,Minor,Bin).
 
192
 
 
193
pack_ssl(Content, Major, Minor, Body) ->
 
194
    case Content of
 
195
        v2hello ->
 
196
            Size = byte_size(Body),
 
197
            Res = <<1:1,(Size+3):15, 1:8, Major:8, Minor:8, Body/binary>>,
 
198
            C = 22,
 
199
            Data = <<1:8, (Size+2):24, Major:8, Minor:8, Body/binary>>;
 
200
        C when is_integer(C) ->
 
201
            Size = byte_size(Body),
 
202
            Res = <<Content:8, Major:8, Minor:8, Size:16, Body/binary>>,
 
203
            Data = Body                     
 
204
    end,
 
205
    {Res, {ssl_tls,[],C,{Major,Minor}, Data}}.
 
206
 
 
207
 
 
208
packet_size(doc) -> [];
 
209
packet_size(suite) -> [];
 
210
packet_size(Config) when is_list(Config) ->
 
211
    ?line Packet = <<101,22,203,54,175>>,
 
212
    ?line Rest = <<123,34,0,250>>,
 
213
 
 
214
    F = fun({Type,Max})->
 
215
                ?line {Bin,Unpacked} = pack(Type,Packet,Rest),
 
216
                ?line case decode_pkt(Type,Bin,[{packet_size,Max}]) of
 
217
                          {ok,Unpacked,Rest} when Max=:=0; Max>=byte_size(Packet) ->
 
218
                              ok;
 
219
                          {error,_} when Max<byte_size(Packet), Max=/=0 ->
 
220
                              ok;
 
221
                          {error,_} when Type=:=fcgi, Max=/=0 ->
 
222
                              %% packet includes random amount of padding
 
223
                              ok
 
224
                      end
 
225
        end,
 
226
    ?line lists:foreach(F, [{T,D} || T<-[1,2,4,asn1,sunrm,cdr,fcgi,tpkt,ssl_tls],
 
227
                                     D<-lists:seq(0, byte_size(Packet)*2)]),
 
228
 
 
229
    %% Test OTP-8102, "negative" 4-byte sizes.
 
230
    lists:foreach(fun(Size) -> 
 
231
                          ?line {error,_} = decode_pkt(4,<<Size:32,Packet/binary>>)
 
232
                  end, 
 
233
                  lists:seq(-10,-1)),
 
234
    ok.
 
235
 
 
236
 
 
237
neg(doc) -> [];
 
238
neg(suite) -> [];
 
239
neg(Config) when is_list(Config) ->
 
240
    ?line Bin = <<"dummy">>,
 
241
    Fun = fun()->dummy end,
 
242
    
 
243
    BadargF = fun(T,B,Opts)-> {'EXIT',{badarg,_}} = (catch decode_pkt(T,B,Opts)) end,
 
244
 
 
245
    %% Invalid Type args
 
246
    lists:foreach(fun(T)-> BadargF(T,Bin,[]) end, 
 
247
                  [3,-1,5,2.0,{2},unknown,[],"line",Bin,Fun,self()]),
 
248
 
 
249
    %% Invalid Bin args
 
250
    lists:foreach(fun(B)-> BadargF(0,B,[]) end, 
 
251
                  [3,2.0,unknown,[],"Bin",[Bin],{Bin},Fun,self()]),
 
252
 
 
253
    %% Invalid options
 
254
    InvOpts = [2,false,self(),Bin,"Options",Fun,
 
255
               packet_size,{packet_size},{packet_size,0,false},
 
256
               {packet_size,-1},{packet_size,100.0},{packet_size,false},
 
257
               {line_length,-1},{line_length,100.0},{line_length,false}],
 
258
 
 
259
    lists:foreach(fun(Opt)-> BadargF(0,Bin,Opt),
 
260
                             BadargF(0,Bin,[Opt]),
 
261
                             BadargF(0,Bin,[Opt,{packet_size,1000}]),
 
262
                             BadargF(0,Bin,[{packet_size,1000},Opt]) end,
 
263
                  InvOpts),
 
264
    ok.
 
265
 
 
266
 
 
267
http(doc) -> [];
 
268
http(suite) -> [];
 
269
http(Config) when is_list(Config) ->
 
270
    ?line <<"foo">> = http_do(http_request("foo")),
 
271
    ?line <<" bar">> = http_do(http_request(" bar")),
 
272
    ?line <<"Hello!">> = http_do(http_response("Hello!")),
 
273
 
 
274
    %% Test all known header atoms
 
275
    Val = "dummy value",
 
276
    ValB = list_to_binary(Val),
 
277
    Rest = <<"Rest">>,    
 
278
    HdrF = fun(Str,N) ->  
 
279
                   ?line StrA = list_to_atom(Str),
 
280
                   ?line StrB = list_to_binary(Str),
 
281
                   ?line Bin = <<StrB/binary,": ",ValB/binary,"\r\n",Rest/binary>>,
 
282
                   ?line {ok, {http_header,N,StrA,undefined,Val}, Rest} = decode_pkt(httph,Bin),
 
283
                   ?line {ok, {http_header,N,StrA,undefined,ValB}, Rest} = decode_pkt(httph_bin,Bin),
 
284
                   ?line N + 1
 
285
           end,
 
286
    ?line lists:foldl(HdrF, 1, http_hdr_strings()),
 
287
 
 
288
    %% Test all known method atoms
 
289
    MethF = fun(Meth) ->  
 
290
                    ?line MethA = list_to_atom(Meth),
 
291
                    ?line MethB = list_to_binary(Meth),
 
292
                    ?line Bin = <<MethB/binary," /invalid/url HTTP/1.0\r\n",Rest/binary>>,
 
293
                    ?line {ok, {http_request,MethA,{abs_path,"/invalid/url"},{1,0}},
 
294
                           Rest} = decode_pkt(http,Bin),
 
295
                    ?line {ok, {http_request,MethA,{abs_path,<<"/invalid/url">>},{1,0}},
 
296
                           Rest} = decode_pkt(http_bin,Bin)
 
297
            end,
 
298
    ?line lists:foreach(MethF, http_meth_strings()),
 
299
 
 
300
    %% Test all uri variants    
 
301
    UriF = fun({Str,ResL,ResB}) -> 
 
302
                   Bin = <<"GET ",(list_to_binary(Str))/binary," HTTP/1.1\r\n",Rest/binary>>,
 
303
                   {ok, {http_request, 'GET', ResL, {1,1}}, Rest} = decode_pkt(http,Bin),
 
304
                   {ok, {http_request, 'GET', ResB, {1,1}}, Rest} = decode_pkt(http_bin,Bin) 
 
305
           end,
 
306
    lists:foreach(UriF, http_uri_variants()),
 
307
    ok.
 
308
             
 
309
http_with_bin(http) ->
 
310
    http_bin;
 
311
http_with_bin(httph) ->
 
312
    httph_bin.
 
313
 
 
314
http_do(Tup) ->
 
315
    http_do(Tup,http).
 
316
http_do({Bin, []}, _) ->
 
317
    Bin;
 
318
http_do({Bin,[{_Line,PL,PB}|Tail]}, Type) ->
 
319
    ?line {ok, PL, Rest} = decode_pkt(Type,Bin),
 
320
    ?line {ok, PB, Rest} = decode_pkt(http_with_bin(Type),Bin),
 
321
 
 
322
    %% Same tests again but as SubBin
 
323
    PreLen = random:uniform(64),
 
324
    Prefix = random:uniform(1 bsl PreLen) - 1,
 
325
    SufLen = random:uniform(64),
 
326
    Suffix = random:uniform(1 bsl SufLen) - 1,
 
327
    Orig = <<Prefix:PreLen, Bin/bits, Suffix:SufLen>>,
 
328
    BinLen = bit_size(Bin),
 
329
    <<_:PreLen, SubBin:BinLen/bits, _/bits>> = Orig, % Make SubBin
 
330
    ?line SubBin = Bin, % just to make sure
 
331
 
 
332
    ?line {ok, PL, Rest} = decode_pkt(Type,SubBin),
 
333
    ?line {ok, PB, Rest} = decode_pkt(http_with_bin(Type),SubBin),
 
334
    http_do({Rest, Tail}, httph).
 
335
 
 
336
http_request(Msg) ->
 
337
    QnA = [{"POST /invalid/url HTTP/1.1\r\n",
 
338
          {http_request, 'POST', {abs_path,  "/invalid/url"  }, {1,1}},
 
339
          {http_request, 'POST', {abs_path,<<"/invalid/url">>}, {1,1}}},
 
340
         {"Connection: close\r\n",
 
341
          {http_header,2,'Connection',undefined,  "close"},
 
342
          {http_header,2,'Connection',undefined,<<"close">>}},   
 
343
         {"Host\t : localhost:8000\r\n", % white space before :
 
344
          {http_header,14,'Host',undefined,  "localhost:8000"},
 
345
          {http_header,14,'Host',undefined,<<"localhost:8000">>}},
 
346
         {"User-Agent: perl post\r\n",
 
347
          {http_header,24,'User-Agent',undefined,  "perl post"},
 
348
          {http_header,24,'User-Agent',undefined,<<"perl post">>}},
 
349
         {"Content-Length: 4\r\n",
 
350
          {http_header,38,'Content-Length',undefined,  "4"},
 
351
          {http_header,38,'Content-Length',undefined,<<"4">>}},
 
352
         {"Content-Type: text/xml; charset=utf-8\r\n",
 
353
          {http_header,42,'Content-Type',undefined,  "text/xml; charset=utf-8"},
 
354
          {http_header,42,'Content-Type',undefined,<<"text/xml; charset=utf-8">>}},
 
355
         {"Other-Field: with some text\r\n",
 
356
          {http_header,0,  "Other-Field"  ,undefined,  "with some text"},
 
357
          {http_header,0,<<"Other-Field">>,undefined,<<"with some text">>}},
 
358
         {"Multi-Line: Once upon a time in a land far far away,\r\n"
 
359
          " there lived a princess imprisoned in the highest tower\r\n"
 
360
          " of the most haunted castle.\r\n",
 
361
          {http_header,0,  "Multi-Line"  ,undefined,  "Once upon a time in a land far far away,\r\n there lived a princess imprisoned in the highest tower\r\n of the most haunted castle."},
 
362
          {http_header,0,<<"Multi-Line">>,undefined,<<"Once upon a time in a land far far away,\r\n there lived a princess imprisoned in the highest tower\r\n of the most haunted castle.">>}},
 
363
         {"\r\n",
 
364
          http_eoh,
 
365
          http_eoh}],
 
366
    Bin = lists:foldl(fun({Line,_,_},Acc) -> LineBin = list_to_binary(Line), 
 
367
                                             <<Acc/binary,LineBin/binary>> end,
 
368
                      <<"">>, QnA),
 
369
    MsgBin = list_to_binary(Msg),
 
370
    {<<Bin/binary,MsgBin/binary>>, QnA}.
 
371
 
 
372
 
 
373
http_response(Msg) ->
 
374
    QnA = [{"HTTP/1.0 404 Object Not Found\r\n",
 
375
            {http_response, {1,0}, 404,   "Object Not Found"},
 
376
            {http_response, {1,0}, 404, <<"Object Not Found">>}},
 
377
           {"Server: inets/4.7.16\r\n",
 
378
            {http_header, 30, 'Server', undefined,   "inets/4.7.16"},
 
379
            {http_header, 30, 'Server', undefined, <<"inets/4.7.16">>}},
 
380
           {"Date: Fri, 04 Jul 2008 17:16:22 GMT\r\n",
 
381
            {http_header, 3, 'Date', undefined,   "Fri, 04 Jul 2008 17:16:22 GMT"},
 
382
            {http_header, 3, 'Date', undefined, <<"Fri, 04 Jul 2008 17:16:22 GMT">>}},
 
383
           {"Content-Type: text/html\r\n",
 
384
            {http_header, 42, 'Content-Type', undefined,   "text/html"},
 
385
            {http_header, 42, 'Content-Type', undefined, <<"text/html">>}},
 
386
           {"Content-Length: 207\r\n",
 
387
            {http_header, 38, 'Content-Length', undefined,   "207"},
 
388
            {http_header, 38, 'Content-Length', undefined, <<"207">>}},
 
389
           {"\r\n",
 
390
            http_eoh,
 
391
            http_eoh}],
 
392
 
 
393
 
 
394
 
 
395
    Bin = lists:foldl(fun({Line,_,_},Acc) -> LineBin = list_to_binary(Line), 
 
396
                                             <<Acc/binary,LineBin/binary>> end,
 
397
                      <<"">>, QnA),
 
398
    MsgBin = list_to_binary(Msg),
 
399
    {<<Bin/binary,MsgBin/binary>>, QnA}.
 
400
 
 
401
http_hdr_strings() ->
 
402
    %% Must be correct order
 
403
    ["Cache-Control","Connection","Date","Pragma","Transfer-Encoding",
 
404
     "Upgrade","Via","Accept", "Accept-Charset", "Accept-Encoding",
 
405
     "Accept-Language", "Authorization","From","Host","If-Modified-Since",
 
406
     "If-Match","If-None-Match","If-Range","If-Unmodified-Since","Max-Forwards",
 
407
     "Proxy-Authorization","Range","Referer","User-Agent","Age","Location",
 
408
     "Proxy-Authenticate","Public","Retry-After","Server","Vary","Warning",
 
409
     "Www-Authenticate","Allow","Content-Base","Content-Encoding",
 
410
     "Content-Language","Content-Length","Content-Location","Content-Md5",
 
411
     "Content-Range","Content-Type","Etag","Expires","Last-Modified",
 
412
     "Accept-Ranges","Set-Cookie","Set-Cookie2","X-Forwarded-For","Cookie",
 
413
     "Keep-Alive","Proxy-Connection"].
 
414
 
 
415
http_meth_strings() ->
 
416
    ["OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE"].
 
417
 
 
418
http_uri_variants() ->
 
419
    [{"*", '*', '*'},
 
420
     {"http://tools.ietf.org/html/rfc3986",
 
421
      {absoluteURI,http,  "tools.ietf.org",  undefined,  "/html/rfc3986"},
 
422
      {absoluteURI,http,<<"tools.ietf.org">>,undefined,<<"/html/rfc3986">>}},
 
423
     {"http://otp.ericsson.se:8000/product/internal/",
 
424
      {absoluteURI,http,  "otp.ericsson.se"  ,8000,  "/product/internal/"},
 
425
      {absoluteURI,http,<<"otp.ericsson.se">>,8000,<<"/product/internal/">>}},
 
426
     {"https://example.com:8042/over/there?name=ferret#nose",
 
427
      {absoluteURI,https,  "example.com",  8042,  "/over/there?name=ferret#nose"},
 
428
      {absoluteURI,https,<<"example.com">>,8042,<<"/over/there?name=ferret#nose">>}},
 
429
     {"ftp://cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm",
 
430
      {scheme,  "ftp",    "//cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm"},
 
431
      {scheme,<<"ftp">>,<<"//cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm">>}},
 
432
     {"/some/absolute/path",
 
433
      {abs_path,  "/some/absolute/path"},
 
434
      {abs_path,<<"/some/absolute/path">>}},
 
435
     {"something_else", "something_else", <<"something_else">>}].
 
436
 
 
437
 
 
438
line(doc) -> [];
 
439
line(suite) -> [];
 
440
line(Config) when is_list(Config) ->
 
441
    Text = <<"POST /invalid/url HTTP/1.1\r\n"
 
442
            "Connection: close\r\n"
 
443
            "Host\t : localhost:8000\r\n"
 
444
            "User-Agent: perl post\r\n"
 
445
            "Content-Length: 4\r\n"
 
446
            "Content-Type: text/xml; charset=utf-8\r\n"
 
447
            "Other-Field: with some text\r\n"
 
448
            "Multi-Line: Once upon a time in a land far far away,\r\n"
 
449
            " there lived a princess imprisoned in the highest tower\r\n"
 
450
            " of the most haunted castle.\r\n"
 
451
            "\r\nThe residue">>,
 
452
 
 
453
    lists:foreach(fun(MaxLen) -> line_do(Text,MaxLen) end,
 
454
                  [0,7,19,29,37]),
 
455
    ok.
 
456
 
 
457
line_do(Bin,MaxLen) ->
 
458
    Res = decode_pkt(line,Bin,[{line_length,MaxLen}]),
 
459
    MyRes = decode_line(Bin,MaxLen),
 
460
    ?line MyRes = Res,
 
461
    case Res of
 
462
        {ok,_,Rest} ->
 
463
            line_do(Rest,MaxLen);
 
464
        {more,undefined} ->
 
465
            ok
 
466
    end.
 
467
    
 
468
% Emulates decode_packet(line,Bin,[{line_length,MaxLen}])
 
469
decode_line(Bin,MaxLen) ->
 
470
    ?line case find_in_binary($\n,Bin) of
 
471
        notfound when MaxLen>0 andalso byte_size(Bin) >= MaxLen ->
 
472
            {LineB,Rest} = split_binary(Bin,MaxLen),
 
473
            {ok,LineB,Rest};
 
474
        notfound ->
 
475
            {more,undefined};
 
476
        Pos when MaxLen>0 andalso Pos > MaxLen ->
 
477
            {LineB,Rest} = split_binary(Bin,MaxLen),
 
478
            {ok,LineB,Rest};
 
479
        Pos ->
 
480
            {LineB,Rest} = split_binary(Bin,Pos),
 
481
            {ok,LineB,Rest}
 
482
    end.
 
483
 
 
484
find_in_binary(Byte, Bin) ->
 
485
    case string:chr(binary_to_list(Bin),Byte) of
 
486
        0 -> notfound;      
 
487
        P -> P
 
488
    end.    
 
489
 
 
490
ssl(doc) -> [];
 
491
ssl(suite) -> [];
 
492
ssl(Config) when is_list(Config) ->
 
493
    Major = 34,
 
494
    Minor = 17,
 
495
    Body = <<234,189,73,199,1,32,4,0,254>>,
 
496
    Rest = <<23,123,203,12,234>>,
 
497
 
 
498
    F = fun(Content) ->
 
499
                {Packet,Unpacked} = pack_ssl(Content, Major, Minor, Body),
 
500
                Bin = <<Packet/binary,Rest/binary>>,
 
501
                ?line {ok, Unpacked, Rest} = decode_pkt(ssl_tls, Bin)
 
502
        end,    
 
503
    F(25),
 
504
    F(v2hello),
 
505
    ok.
 
506
 
 
507
decode_pkt(Type,Bin) ->
 
508
    decode_pkt(Type,Bin,[]).                   
 
509
decode_pkt(Type,Bin,Opts) ->
 
510
    %%io:format("decode_packet(~p,~p,~p)\n",[Type,Bin,Opts]),
 
511
    Res = erlang:decode_packet(Type,Bin,Opts),
 
512
    %%io:format(" -> ~p\n",[Res]),
 
513
    Res.
 
514