CXM_common.anubis
7.78 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
*Project* The Anubis Project
*Title* Some common stuff for the web.
*Copyright*
Copyright © Alain Prouté 2003~2007.
© David RENÉ2007~2019
*Authors:*
Alain Prouté
David RENÉ
*Public*
*Name* HTTP_header
*Description*
transmit tools/basis.anubis
transmit system/string.anubis
read system/logger.anubis
/**
* The type 'HTTP_header' describes HTTP headers, which are just pairs '(name,value)'.
*/
public type HTTP_header:
http_header(
String name,
String value
)
.
public define Maybe(String)
http_header_value
(
List(HTTP_header) l,
String name
)=
if l is
{
[ ] then failure,
[h . t] then if h is
{
http_header(n, v) then //print("DEBUG: http_header_value --> HEADER = " + n + ":" + v + "\n");
if insensitive_equal(name, n) then success(v)
else http_header_value(t, name),
}
}
.
public define String
http_header_value
(
List(HTTP_header) l,
String name,
String default
)=
if http_header_value(l, name) is
{
failure then default,
success(result) then result
}
.
public define List(String)
to_List_String
(
List(HTTP_header) l
)=
map((HTTP_header h) |-> h.name +": "+h.value, l ).
public define String
to_String
(
List(HTTP_header) l
)=
join("\n\r",to_List_String(l)).
public type HTTP_Info:
http_info
(
Word32 ip_address, // IP address of the client
String hostname, // hostname requested by the client
String uri, // URI requested by the client
List(HTTP_header) http_headers, // HTTP headers sent by the client
Bool is_https
//One -> String generate_trust_ticket // may be used against denial of
// service attacks
).
*Name* Web_arg
*Description*
The type 'Web_arg' describes 'web arguments'. A web argument is either a pair
'(name,value)' (for example it may be 'web_arg("password","foobar")', if the client
clicks on the submit button of a form containing a password input field named
'password'), or an uploaded file. In this last case, it is a triplet containing the
name of the file upload input field, the value of this input field (name of the
uploaded file), and the name of the temporary file as saved by the server in its
'upload temporary directory'; see 'web/http_server.anubis' and the 'upload' Web_item in
'web/html.anubis').
public type Web_arg:
web_arg(
String name,
String value
),
upload (
String name, // name of corresponding 'upload' Web_item
String value, // name of uploaded file
String temp_file_path) // temporary file path (relative to server directory)
.
*Name* Web_arg_value
*Description*
Of course, within the body of a 'web page' operation, you may want to recover the value
of a particular web argument. To that end, use the operation 'web_arg_value', which
takes 2 argument:
- the list of all web arguments (the operand of the web page operation),
- the name of the argument whose value is wanted.
This operation has the following return type:
public type Web_arg_value:
not_found,
found(String value).
*Name* Web_arg_value
*Description*
If the requested argument name is not found in the list, 'not_found' is
returned. Otherwise, the value returned by 'web_arg_value' has the form 'found(v)',
where 'v' is the value of the argument.
The operation 'web_arg_value' is defined below.
public define Web_arg_value
web_arg_value
(
List(Web_arg) l,
String name
)=
if l is
{
[ ] then not_found,
[h . t] then if h is
{
web_arg(n,v) then
if name=n
then found(v)
else web_arg_value(t,name),
upload(n,v,tfn) then
if name=n
then found(v)
else web_arg_value(t,name)
}
}
.
public define Web_arg_value
web_arg_value_not_null
(
List(Web_arg) lwa,
String name,
) =
if web_arg_value(lwa, name) is
{
not_found then not_found
found(str) then
if str = "" then
not_found
else
found(str)
}.
*Ignore*
public define Maybe((String,String))
file_upload_value
(
List(Web_arg) l,
String name
)=
if l is
{
[ ] then failure,
[h . t] then
if h is
{
web_arg(_,_) then file_upload_value(t,name),
upload(n,v,tfn) then
if n = name
then success((v,tfn))
else file_upload_value(t,name)
}
}.
public define List((String,String))
file_upload_value
(
List(Web_arg) l,
String name,
List((String,String)) new_list
) =
if l is
{
[ ] then new_list,
[h . t] then if h is
{
web_arg(_,_) then file_upload_value(t,name, new_list),
upload(n,v,tfn) then
if n = name
then file_upload_value(t,name, [(v,tfn) . new_list])
else file_upload_value(t,name, new_list)
}
}.
public type Redirection:
redirect(String required_uri, // URI required by the client
String required_host, // value of 'Host' HTTP header sent by the client
String corresponding_uri). // URI which will be served to the client
public type Redirections:
redirection_list(List(Redirection) redirections),
redirection_fn((String input_uri, // URI required by the client
String host) -> String f). // value of 'Host' HTTP header sent by the client
Now, you may also want to recover web argument values which have been encoded (by
'web_arg_encode'). In this case, use the following:
read CXM_web_arg_encode.anubis
public define Maybe($T)
decode_web_arg_value
(
List(Web_arg) l,
String name
) =
if web_arg_value(l,name) is
{
not_found then failure,
found(v) then web_arg_decode(v)
}.
public define List(String)
web_arg_list_values
(
List(Web_arg) l,
String name
) =
if l is
{
[] then [],
[h . t] then
if h is web_arg(n, v) then
if n = name then
[ v . web_arg_list_values(t, name)]
else
web_arg_list_values(t, name)
else
web_arg_list_values(t, name)
}
.
public define String
detect_browser_language
(
HTTP_Info http_info,
String default_language,
(LogLevel, String) -> One logger
) =
logger(logInfo,"Detecting language... ");
if http_header_value(http_info.http_headers, "Accept-Language") is
{
failure then logger(logDebug, "FAILED: unable to find 'Accept-Language' header, use the default one ["+default_language+"]."); default_language ,
success(value) then
if split_by_token(value, ',') is
{
[] then logger(logDebug, "FAILED: language header is empty, use the default one ["+default_language+"]."); default_language,
[h . _] then
//TODO real managment of language and country like fr-be for
// belgium french.
//but now we only extract the language and forget the country
if split_by_token(trim(h), '-') is
{
[] then default_language,
[browser_lang . _] then
logger(logDebug, "Language = " + browser_lang);browser_lang
}
}
}
.