1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
87
  
88
  
89
  
90
  
91
  
92
  
93
  
94
  
95
  
96
  
97
  
98
  
99
  
100
  
101
  
102
  
START_MARKER 
 
test_eq(_Roxen.html_encode_string (0), "0") 
test_eq(_Roxen.html_encode_string (""), "") 
test_eq(_Roxen.html_encode_string (10), "10") 
test_eq(_Roxen.html_encode_string("a&b<c>d"), "a&amp;b&lt;c&gt;d") 
 
test_eq(_Roxen.http_decode_string(""), "") 
test_eq(_Roxen.http_decode_string("abc+d%20e%41"), "abc+d eA") 
test_eq(_Roxen.http_decode_string(""), "") 
test_eq(_Roxen.http_decode_string("+"), "+") 
 
test_eq(_Roxen.http_decode_string("%uD83D%uDE02"), "\U0001f602") 
 
// the following inputs are all illegal 
test_eval_error(_Roxen.http_decode_string("%")) 
test_eval_error(_Roxen.http_decode_string("%0")) 
test_eval_error(_Roxen.http_decode_string("%%")) 
test_eval_error(_Roxen.http_decode_string("%%%")) 
test_eval_error(_Roxen.http_decode_string("%41%")) 
test_eval_error(_Roxen.http_decode_string("%41%0")) 
test_eval_error(_Roxen.http_decode_string("%41%%")) 
test_eval_error(_Roxen.http_decode_string("%41%%%")) 
test_eval_error(_Roxen.http_decode_string("%u")) 
test_eval_error(_Roxen.http_decode_string("%u0")) 
test_eval_error(_Roxen.http_decode_string("%u00")) 
test_eval_error(_Roxen.http_decode_string("%u000")) 
test_eval_error(_Roxen.http_decode_string("%u000_")) 
test_eval_error(_Roxen.http_decode_string("%41%u")) 
test_eval_error(_Roxen.http_decode_string("%41%u0")) 
test_eval_error(_Roxen.http_decode_string("%41%u00")) 
test_eval_error(_Roxen.http_decode_string("%41%u000")) 
test_eval_error(_Roxen.http_decode_string("%41%u000_")) 
dnl test_eval_error(_Roxen.http_decode_string("%uD83D")) 
dnl test_eval_error(_Roxen.http_decode_string("%uDE02")) 
dnl test_eval_error(_Roxen.http_decode_string("X%uD83DX")) 
dnl test_eval_error(_Roxen.http_decode_string("X%uDE02X")) 
 
test_eq(_Roxen.http_decode_string("%u12345"), "\x1234""5") 
test_eq(_Roxen.http_decode_string("%U12345"), "\x1234""5") 
 
define(test_mkhttp,[[ 
  test_any_equal([[ 
    string x=_Roxen.make_http_headers($1); 
    if(!has_suffix(x, "\r\n")) return -1; 
    return sort(x/"\r\n"-({""})); 
  ]],$2) 
]]) 
 
test_eval_error(_Roxen.make_http_headers(0)) 
 
test_mkhttp( ([]), ({}) ) 
test_mkhttp( (["":""]), ({": "}) ) 
test_mkhttp( (["a":"1","b":"2"]), ({"a: 1","b: 2"}) ) 
test_mkhttp( (["a":"1","b":({"2","3"})]), ({"a: 1","b: 2","b: 3"}) ) 
test_mkhttp( (["a":"1","b":({"2","2"})]), ({"a: 1","b: 2","b: 2"}) ) 
 
test_eval_error(_Roxen.make_http_headers((["a:1": "1"]))) 
test_eval_error(_Roxen.make_http_headers((["a\rb": "1"]))) 
test_eval_error(_Roxen.make_http_headers((["a\nb": "1"]))) 
test_eval_error(_Roxen.make_http_headers(([" a:1": "1"]))) 
test_eval_error(_Roxen.make_http_headers((["a": "1\r"]))) 
test_eval_error(_Roxen.make_http_headers((["a": "1\n"]))) 
test_eval_error(_Roxen.make_http_headers((["a": ({ "1\r\nb:2", "2\r\nc:2" }))))) 
 
define(test_hp,[[ 
  test_any_equal([[ 
    object hp = _Roxen.HeaderParser(); 
    return hp->feed( $1 ); 
  ]], $2) 
]]) 
 
test_hp( "GET / HTTP/1.0\r\n\r\n", 
({ "", "GET / HTTP/1.0", ([]) })) 
 
test_hp( "GET / HTTP/1.0\r\n\r\nDATA", 
({ "DATA", "GET / HTTP/1.0", ([]) })) 
 
test_hp( "GET / HTTP/1.0\r\nhdr: 1\r\n\r\nDATA", 
({ "DATA", "GET / HTTP/1.0", ([ "hdr":"1"]) })) 
 
test_hp( "GET / HTTP/1.0\r\nBlaha: foo\nbar\r\nzonk: 1\r\n\r\n", 
({ "", "GET / HTTP/1.0", ([ "blaha":"foo", "zonk":"1" ]) }) ) 
 
test_hp( "GET / HTTP/1.0\r\nblaha: foo\r\nzonk: 1\r\n\r\n", 
({ "", "GET / HTTP/1.0", ([ "blaha":"foo", "zonk":"1" ]) }) ) 
 
test_hp( "GET / HTTP/1.0\r\nblaha: foo\n\rBlaha: bar\r\n\r\n", 
({ "", "GET / HTTP/1.0", ([ "blaha":({ "foo", "bar" }) ]) }) ) 
 
test_any_equal([[ 
  object hp = _Roxen.HeaderParser(0, 1); 
  return hp->feed( "GET / HTTP/1.0\r\nBlaha: foo\r\nblaha: foo\r\n\r\n" ); 
]], [[ ({ "", "GET / HTTP/1.0", ([ "Blaha":"foo", "blaha":"foo"]) }) ]]) 
 
test_any_equal([[ 
  object hp = _Roxen.HeaderParser(0, 0); 
  return hp->feed( "GET / HTTP/1.0\r\nBlaha: foo\r\nblaha: foo\r\n\r\n", 1 ); 
]], [[ ({ "", "GET / HTTP/1.0", ([ "Blaha":"foo", "blaha":"foo"]) }) ]]) 
 
END_MARKER