Commit b45f24136385664d0d0a0d1e4b9e5e7b0ce7323f

Authored by totoro
1 parent 6a99ee01

Update to be compliant with Anubis 1.13 where the global variable doesn't exist anymore

Add site UID for website. This is use by cookie session state
improve cookies
net_services/CXM_generic_client.anubis
... ... @@ -185,7 +185,7 @@ public define Maybe($T)
185 185 =
186 186 if connect( server, port) is
187 187 {
188   - error(_) then logger(queue_name + ": Can't connect to domain manager ["+ip_addr_to_string(server)+":"+port+"]");failure,
  188 + error(_) then logger(queue_name + ": Can't connect to service ["+ip_addr_to_string(server)+":"+port+"]");failure,
189 189 ok(conn) then
190 190 // println("[" + virtual_machine_id + "] netservices create queue");
191 191 with queue = create_MessageQueue(queue_name),
... ...
web/CXM_cookies.anubis
... ... @@ -192,14 +192,22 @@ public type Atom:
192 192 semi_colon.
193 193  
194 194  
195   -variable List(Atom) unput_atoms = [].
  195 + variable List(Atom) unput_atoms = [].
  196 +
  197 +type CookieToolBox:
  198 + tool_box(Var(List(Atom)) unput_atoms,
  199 + Var(String) input,
  200 + Var(Int) index,
  201 + Var(String) server_name
  202 + ).
196 203  
197 204 define One
198 205 unput_atom
199 206 (
200   - Atom a
  207 + CookieToolBox tbx,
  208 + Atom a
201 209 ) =
202   - unput_atoms <- [a . *unput_atoms].
  210 + unput_atoms(tbx) <- [a . *unput_atoms(tbx)].
203 211  
204 212 define Atom
205 213 recognize_keyword
... ... @@ -216,12 +224,15 @@ define Atom
216 224 token(s).
217 225  
218 226  
219   -variable String input = "". From which cookies will be read.
220   -variable Int index = 0. Current position within 'input'.
  227 + variable String input = "". From which cookies will be read.
  228 + variable Int index = 0. Current position within 'input'.
221 229  
222 230 define Maybe(Word8)
223 231 next_char
224   - =
  232 + (
  233 + CookieToolBox tbx
  234 + ) =
  235 + if tbx is tool_box(_, input, index, _) then
225 236 if nth(*index,*input) is
226 237 {
227 238 failure then failure,
... ... @@ -232,36 +243,41 @@ define Maybe(Word8)
232 243  
233 244 define One
234 245 unput_char
235   - =
  246 + (
  247 + CookieToolBox tbx
  248 + ) =
  249 + if tbx is tool_box(_, _, index, _) then
236 250 index <- *index-1.
237 251  
238 252 define Atom
239 253 read_token
240 254 (
  255 + CookieToolBox tbx,
241 256 List(Word8) so_far, // contains at least 1 character
242 257 (Word8) -> Bool is_valid_char
243 258 ) =
244   - if next_char is
  259 + if next_char(tbx) is
245 260 {
246 261 failure then recognize_keyword(implode(reverse(so_far))),
247 262 success(c) then
248 263 if is_valid_char(c)
249   - then read_token([c . so_far], is_valid_char)
250   - else unput_char; recognize_keyword(implode(reverse(so_far)))
  264 + then read_token(tbx,[c . so_far], is_valid_char)
  265 + else unput_char(tbx); recognize_keyword(implode(reverse(so_far)))
251 266 }.
252 267  
253 268 define Atom
254 269 read_quoted_string
255 270 (
256   - List(Word8) so_far
  271 + CookieToolBox tbx,
  272 + List(Word8) so_far
257 273 ) =
258   - if next_char is
  274 + if next_char(tbx) is
259 275 {
260 276 failure then quoted_string(implode(reverse(so_far))),
261 277 success(c) then
262 278 if c = '\"'
263 279 then quoted_string(implode(reverse(so_far)))
264   - else read_quoted_string([c . so_far])
  280 + else read_quoted_string(tbx,[c . so_far])
265 281 }.
266 282  
267 283 define Bool
... ... @@ -275,44 +291,48 @@ define Bool
275 291  
276 292 define Atom
277 293 read_atom
278   - =
279   - if *unput_atoms is
  294 + (
  295 + CookieToolBox tbx,
  296 + ) =
  297 + if *unput_atoms(tbx) is
280 298 {
281 299 [ ] then
282   - if next_char is
  300 + if next_char(tbx) is
283 301 {
284 302 failure then end_of_input,
285 303 success(c) then
286   - if is_blank(c) then read_atom else // skip blanks
287   - if is_token_char(c) then read_token([c], is_token_char) else
288   - if c = '\"' then read_quoted_string([]) else
  304 + if is_blank(c) then read_atom(tbx) else // skip blanks
  305 + if is_token_char(c) then read_token(tbx,[c], is_token_char) else
  306 + if c = '\"' then read_quoted_string(tbx,[]) else
289 307 if c = '=' then equals else
290 308 if c = ':' then colon else
291 309 if c = ';' then semi_colon else
292 310 error
293 311 },
294 312 [h . t] then
295   - unput_atoms <- t; h
  313 + unput_atoms(tbx) <- t; h
296 314 }.
297 315  
298 316 define Atom
299 317 read_value
300   - =
301   - if *unput_atoms is
  318 + (
  319 + CookieToolBox tbx
  320 + ) =
  321 + if *unput_atoms(tbx) is
302 322 {
303 323 [ ] then
304   - if next_char is
  324 + if next_char(tbx) is
305 325 {
306 326 failure then end_of_input,
307 327 success(c) then
308   - if is_blank(c) then read_value else // skip blanks
309   - if is_value_char(c) then read_token([c], is_value_char) else
310   - if c = '\"' then read_quoted_string([]) else
311   - if c = ';' then semi_colon else
  328 + if is_blank(c) then read_value(tbx) else // skip blanks
  329 + if is_value_char(c) then read_token(tbx,[c], is_value_char) else
  330 + if c = '\"' then read_quoted_string(tbx,[]) else
  331 + if c = ';' then semi_colon else
312 332 error
313 333 },
314 334 [h . t] then
315   - unput_atoms <- t; h
  335 + unput_atoms(tbx) <- t; h
316 336 }.
317 337  
318 338 Reading an attribute-value pair.
... ... @@ -327,38 +347,42 @@ type AttrVal:
327 347  
328 348 define String
329 349 read_eq_value
330   - =
331   - with e = read_atom,
  350 + (
  351 + CookieToolBox tbx
  352 + ) =
  353 + with e = read_atom(tbx),
332 354 if e is equals then
333 355 (
334   - with a = read_atom,
  356 + with a = read_atom(tbx),
335 357 if a is token(n) then n else
336 358 if a is quoted_string(s) then s else
337   - unput_atom(a); ""
  359 + unput_atom(tbx,a); ""
338 360 )
339   - else unput_atom(e); "".
  361 + else unput_atom(tbx,e); "".
340 362  
341 363  
342 364 define Maybe(AttrVal)
343 365 read_attr_val
344   - =
345   - if read_atom is semi_colon then
346   - with a = read_atom,
  366 + (
  367 + CookieToolBox tbx
  368 + ) =
  369 + if read_atom(tbx) is semi_colon then
  370 + with a = read_atom(tbx),
347 371 if a is
348 372 {
349 373 end_of_input then failure,
350 374 error then failure,
351   - comment then success(comment(read_eq_value)),
352   - domain then success(domain(read_eq_value)),
353   - max_age then success(max_age(read_eq_value)),
354   - path then success(path(read_eq_value)),
  375 + comment then success(comment(read_eq_value(tbx))),
  376 + domain then success(domain(read_eq_value(tbx))),
  377 + max_age then success(max_age(read_eq_value(tbx))),
  378 + path then success(path(read_eq_value(tbx))),
355 379 secure then success(secure),
356   - version then success(version(read_eq_value)),
357   - token(_) then unput_atom(a); failure,
358   - quoted_string(_) then unput_atom(a); failure,
359   - equals then unput_atom(a); failure,
360   - colon then unput_atom(a); failure,
361   - semi_colon then unput_atom(a); failure,
  380 + version then success(version(read_eq_value(tbx))),
  381 + token(_) then unput_atom(tbx,a); failure,
  382 + quoted_string(_) then unput_atom(tbx,a); failure,
  383 + equals then unput_atom(tbx,a); failure,
  384 + colon then unput_atom(tbx,a); failure,
  385 + semi_colon then unput_atom(tbx,a); failure,
362 386 }
363 387 else failure.
364 388  
... ... @@ -454,20 +478,21 @@ define Int
454 478  
455 479 Reading a cookie:
456 480  
457   -variable String server_name = "".
  481 + variable String server_name = "".
458 482  
459 483 define Maybe(Cookie)
460 484 read_cookie_n_e_v
461 485 (
462   - String name,
463   - String value,
464   - List(AttrVal) so_far
  486 + CookieToolBox tbx,
  487 + String name,
  488 + String value,
  489 + List(AttrVal) so_far
465 490 ) =
466   - if read_attr_val is
  491 + if read_attr_val(tbx) is
467 492 {
468 493 failure then
469 494 success(cookie(
470   - *server_name,
  495 + *server_name(tbx),
471 496 name,
472 497 value,
473 498 get_comment(so_far),
... ... @@ -478,49 +503,53 @@ define Maybe(Cookie)
478 503 get_version(so_far)
479 504 )),
480 505  
481   - success(av) then read_cookie_n_e_v(name,value,[av . so_far])
  506 + success(av) then read_cookie_n_e_v(tbx,name,value,[av . so_far])
482 507 }.
483 508  
484 509 define Maybe(Cookie)
485 510 read_cookie_n_e
486 511 (
487   - String name
  512 + CookieToolBox tbx,
  513 + String name
488 514 ) =
489   - with a = read_value,
490   -
491   - if a is token(value) then read_cookie_n_e_v(name,value,[]) else
492   - if a is quoted_string(value) then read_cookie_n_e_v(name,value,[]) else
493   - unput_atom(a); failure.
  515 + with a = read_value(tbx),
  516 + if a is token(value) then read_cookie_n_e_v(tbx,name,value,[]) else
  517 + if a is quoted_string(value) then read_cookie_n_e_v(tbx,name,value,[]) else
  518 + unput_atom(tbx,a); failure.
494 519  
495 520 define Maybe(Cookie)
496 521 read_cookie_n
497 522 (
498   - String name
  523 + CookieToolBox tbx, // bis repetita placent
  524 + String name
499 525 ) =
500   - with a = read_atom,
  526 + with a = read_atom(tbx),
501 527 if a is equals
502   - then read_cookie_n_e(name)
503   - else unput_atom(a); failure.
  528 + then read_cookie_n_e(tbx,name)
  529 + else unput_atom(tbx,a); failure.
504 530  
505 531  
506 532 define Maybe(Cookie)
507 533 read_cookie
508   - =
509   - with a = read_atom,
  534 + (
  535 + CookieToolBox tbx
  536 + ) =
  537 + with a = read_atom(tbx),
510 538 if a is token(name)
511   - then read_cookie_n(name)
512   - else unput_atom(a); failure.
  539 + then read_cookie_n(tbx,name)
  540 + else unput_atom(tbx,a); failure.
513 541  
514 542  
515 543 define List(Cookie)
516 544 read_cookies
517 545 (
518   - List(Cookie) so_far
  546 + CookieToolBox tbx,
  547 + List(Cookie) so_far
519 548 ) =
520   - if read_cookie is
  549 + if read_cookie(tbx) is
521 550 {
522 551 failure then so_far,
523   - success(c) then read_cookies([c . so_far])
  552 + success(c) then read_cookies(tbx,[c . so_far])
524 553 }.
525 554  
526 555  
... ... @@ -531,14 +560,8 @@ define List(Cookie)
531 560 HTTP_header h
532 561 ) =
533 562 if h is http_header(n,v) then
534   - if to_lower(n) = "set-cookie"
535   - then (
536   - unput_atoms <- [];
537   - input <- v;
538   - index <- 0;
539   - server_name <- svn;
540   - read_cookies([])
541   - )
  563 + if to_lower(n) = "set-cookie"
  564 + then read_cookies(tool_box(var([]),var(v),var(0),var(svn)),[])
542 565 else [].
543 566  
544 567 public define List(Cookie)
... ... @@ -561,13 +584,7 @@ define List(Cookie)
561 584 ) =
562 585 if h is http_header(n,v) then
563 586 if to_lower(n) = "cookie"
564   - then (
565   - unput_atoms <- [];
566   - input <- v;
567   - index <- 0;
568   - server_name <- "";
569   - read_cookies([])
570   - )
  587 + then read_cookies(tool_box(var([]),var(v),var(0),var("")),[])
571 588 else [].
572 589  
573 590 public define List(Cookie)
... ...
web/CXM_making_a_web_site.anubis
... ... @@ -46,13 +46,14 @@
46 46  
47 47 read tools/basis.anubis
48 48 read tools/printable_tree.anubis
  49 +read tools/base64.anubis
49 50 read system/string.anubis
50 51 read system/logger.anubis
51 52 read CXM_common.anubis
52 53 read CXM_multihost_http_server.anubis
53 54 read web/mime.anubis
54 55 read CXM_cookies.anubis
55   -
  56 +
56 57  
57 58 * (1) Structure of a web site.
58 59  
... ... @@ -2475,7 +2476,50 @@ public define Web_Site
2475 2476 //using_state_cookies
2476 2477 ),
2477 2478 delete_out_of_date).
2478   -
  2479 +
  2480 +define String
  2481 + _random_string
  2482 + (
  2483 + Int size,
  2484 + String current
  2485 + )=
  2486 + if size = 0 then
  2487 + current
  2488 + else
  2489 + _random_string( size - 1, current + random(9))
  2490 + .
  2491 +
  2492 +public define String
  2493 + generate_random_string
  2494 + (
  2495 + Int size
  2496 + ) =
  2497 + to_string(extract(base64_encode(to_byte_array(_random_string(size, ""))), 0, size)).
  2498 +
  2499 +
  2500 +define String
  2501 + get_site_uid
  2502 + (
  2503 + String site_path
  2504 + )=
  2505 + with file_name = site_path+"/site_UID",
  2506 + if read_from_file(file_name) is
  2507 + {
  2508 + cannot_find_file then
  2509 + println("site UID doesn't exists. Generating it now");
  2510 + with uid = generate_random_string(9),
  2511 + if write_to_file(file_name, to_byte_array(uid)) is
  2512 + {
  2513 + cannot_open_file then println("Can't create site UID here "+file_name);"",
  2514 + write_error(_) then println("Can't write site UID here "+file_name);"",
  2515 + ok then uid
  2516 + }
  2517 + read_error(_) then
  2518 + println("cannot read site UID from "+file_name);""
  2519 + ok(ba) then to_string(ba)
  2520 + }
  2521 + .
  2522 +
2479 2523 // Compatibility function for older websites
2480 2524 public define Web_Site
2481 2525 make_web_site_description
... ... @@ -2511,7 +2555,10 @@ public define Web_Site
2511 2555 //Bool using_state_cookies
2512 2556 )
2513 2557 =
2514   - make_web_site_description("", common_names, site_directory, state_directory, init, initial_state, ticket_expired_state, ticket_lost_state, actions, compute_page, additional_headers, timeout, redirections, charset, journal_extensions, journal_headers, secret, known_mime_types, before_send_file)
  2558 + //generate an unique ID if doesn't exist in root of site_directory
  2559 + with site_UID = get_site_uid(site_directory),
  2560 + println("site_UID : "+site_UID);
  2561 + make_web_site_description(site_UID, common_names, site_directory, state_directory, init, initial_state, ticket_expired_state, ticket_lost_state, actions, compute_page, additional_headers, timeout, redirections, charset, journal_extensions, journal_headers, secret, known_mime_types, before_send_file)
2515 2562 .
2516 2563  
2517 2564  
... ... @@ -2984,15 +3031,16 @@ public define Printable_tree
2984 3031 }.
2985 3032  
2986 3033  
2987   -
2988   -variable Int count = 0.
2989   -
  3034 +
2990 3035 Note: this counter is private to the virtual machine, hence there is one counter by
2991 3036 client and by page : it seems that a new VM (simply a delegate) is started for each request.
2992 3037  
2993 3038 define Int
2994 3039 new_count
2995   - =
  3040 + (
  3041 + Var(Int) count
  3042 + )
  3043 + =
2996 3044 count <- *count+1;
2997 3045 *count.
2998 3046  
... ... @@ -3069,14 +3117,15 @@ define URL_or_JavaScript
3069 3117 String the_url,
3070 3118 Actioner_Aspect aspect,
3071 3119 Maybe(String) mb_id,
3072   - Maybe(String) mb_form_name
  3120 + Maybe(String) mb_form_name,
  3121 + Var(Int) action_count
3073 3122 ) =
3074 3123 if mb_form_name is
3075 3124 {
3076 3125 failure then
3077 3126 url(the_url),
3078 3127 success(form_name) then
3079   - with n = new_count,
  3128 + with n = new_count(action_count),
3080 3129 fn_name = "pfu_" + if mb_id is
3081 3130 {
3082 3131 failure then form_name + "_" + n,
... ... @@ -3411,11 +3460,12 @@ define Printable_tree
3411 3460 List(Actioner_Local_Action) local_actions,
3412 3461 Maybe(String) mb_form_name,
3413 3462 Bool is_https,
  3463 + Var(Int) action_count
3414 3464 ) =
3415 3465 if cinfo is info(common_name,http_port,https_port,site_dir,secret) then
3416 3466 with url = make_actioner_url(cinfo,connection,target,
3417 3467 state_name,action_name,extra_ops,is_https),
3418   - with action = format_action(url, aspect, extract_id(aspect), mb_form_name),
  3468 + with action = format_action(url, aspect, extract_id(aspect), mb_form_name, action_count),
3419 3469 if aspect is
3420 3470 {
3421 3471  
... ... @@ -3997,10 +4047,11 @@ define Printable_tree
3997 4047 (
3998 4048 CommonInfo cinfo,
3999 4049 String sn, // state_name
4000   - Var(Int) ic_v,
  4050 + Var(Int) ic_v,
4001 4051 HTML_Any($T) element,
4002 4052 $T -> Printable_tree format_element, // able to format a datum of type $T
4003 4053 Bool is_https,
  4054 + Var(Int) action_count
4004 4055 ) =
4005 4056 if cinfo is info(common_name,http_port,https_port,site_directory,secret) then
4006 4057 if element is
... ... @@ -4044,7 +4095,7 @@ define Printable_tree
4044 4095 "secondary document",
4045 4096 "</object>"],
4046 4097 any_actioner(c,t,a,an,eo,ja,fn) then
4047   - format_actioner(cinfo,sn,c,t,a,an,eo,ja,fn,is_https),
  4098 + format_actioner(cinfo,sn,c,t,a,an,eo,ja,fn,is_https, action_count),
4048 4099  
4049 4100 any_foreign_link_new(target, aspect, url) then
4050 4101 format_foreign_link(target, aspect, url, is_https),
... ... @@ -4085,47 +4136,48 @@ define Printable_tree
4085 4136 CommonInfo cinfo,
4086 4137 String fn, // form_name
4087 4138 String sn, // state_name
4088   - Var(Int) ic_v, // idnum counter variable
  4139 + Var(Int) ic_v, // idnum counter variable
4089 4140 HTML_In_Form element,
4090 4141 Bool is_https,
  4142 + Var(Int) action_count
4091 4143 ) =
4092 4144 if cinfo is info(common_name,http_port,https_port,site_directory,secret) then
4093   - with format_element = (HTML_In_Form e) |-> format(cinfo,fn,sn,ic_v,e,is_https),
  4145 + with format_element = (HTML_In_Form e) |-> format(cinfo, fn, sn, ic_v, e, is_https, action_count),
4094 4146 if element is
4095 4147 {
4096 4148 literal_pt(t) then t,
4097 4149 literal(t) then [t],
4098 4150 sequence(l) then flat(map(format_element,l))
4099 4151 text(opts,t) then
4100   - format(cinfo,sn,ic_v,any_text(opts,t),format_element,is_https),
  4152 + format(cinfo,sn,ic_v,any_text(opts,t),format_element,is_https, action_count),
4101 4153 preformated(o,s) then
4102   - format(cinfo,sn,ic_v,any_preformated(o,s),format_element,is_https),
  4154 + format(cinfo,sn,ic_v,any_preformated(o,s),format_element,is_https, action_count),
4103 4155 paragraph(opts,t) then
4104   - format(cinfo,sn,ic_v,any_paragraph(opts,t),format_element,is_https),
  4156 + format(cinfo,sn,ic_v,any_paragraph(opts,t),format_element,is_https, action_count),
4105 4157 image(opts, url, alt) then
4106   - format(cinfo,sn,ic_v,any_image(opts, url, alt),format_element,is_https),
  4158 + format(cinfo,sn,ic_v,any_image(opts, url, alt),format_element,is_https, action_count),
4107 4159 image(opts, url, alt, w, h) then
4108   - format(cinfo,sn,ic_v,any_image(opts, url, alt, w, h),format_element,is_https),
  4160 + format(cinfo,sn,ic_v,any_image(opts, url, alt, w, h),format_element,is_https, action_count),
4109 4161 table(opts,header_row,rows,footer_row) then
4110   - format(cinfo,sn,ic_v,any_table(opts, header_row, rows, footer_row),format_element,is_https),
  4162 + format(cinfo,sn,ic_v,any_table(opts, header_row, rows, footer_row),format_element,is_https, action_count),
4111 4163 center(e) then
4112   - format(cinfo,sn,ic_v,any_center(e),format_element,is_https),
  4164 + format(cinfo,sn,ic_v,any_center(e),format_element,is_https, action_count),
4113 4165 mail_to(a,e) then
4114   - format(cinfo,sn,ic_v,any_mail_to(a,e),format_element,is_https),
  4166 + format(cinfo,sn,ic_v,any_mail_to(a,e),format_element,is_https, action_count),
4115 4167 scroller(w,h,cw,ch,c) then
4116   - format(cinfo,sn,ic_v,any_scroller(w,h,cw,ch,c),format_element,is_https),
  4168 + format(cinfo,sn,ic_v,any_scroller(w,h,cw,ch,c),format_element,is_https, action_count),
4117 4169 actioner(c,t,a,an,eo,ja) then
4118   - format(cinfo,sn,ic_v,any_actioner(c,t,a,an,eo,ja,success(fn)),format_element,is_https),
  4170 + format(cinfo,sn,ic_v,any_actioner(c,t,a,an,eo,ja,success(fn)),format_element,is_https, action_count),
4119 4171  
4120 4172 foreign_link_new(target, aspect, url) then
4121   - format(cinfo,sn,ic_v,any_foreign_link_new(target,aspect,url),format_element,is_https),
  4173 + format(cinfo,sn,ic_v,any_foreign_link_new(target,aspect,url),format_element,is_https, action_count),
4122 4174  
4123 4175 foreign_link(options,url) then
4124   - format(cinfo,sn,ic_v,any_foreign_link(options,url),format_element,is_https),
  4176 + format(cinfo,sn,ic_v,any_foreign_link(options,url),format_element,is_https, action_count),
4125 4177 foreign_link(options,url,name) then
4126   - format(cinfo,sn,ic_v,any_foreign_link(options,url,name),format_element,is_https),
  4178 + format(cinfo,sn,ic_v,any_foreign_link(options,url,name),format_element,is_https, action_count),
4127 4179 private_download(url,name,extra,action) then
4128   - format(cinfo,sn,ic_v,any_private_download(url,name,extra,action),format_element,is_https),
  4180 + format(cinfo,sn,ic_v,any_private_download(url,name,extra,action),format_element,is_https, action_count),
4129 4181 text_input(options, label_text, id, name, i, w) then
4130 4182 [ maybe_label(label_text, id),
4131 4183 "<input type=\"text\" name=\"",name,"\" id=\"",id,"\" size=\"",w,"\" value=\"",i,"\"",format_attrs(options)," />"],
... ... @@ -4166,9 +4218,9 @@ define Printable_tree
4166 4218 [ "<input type=\"checkbox\" name=\"",n,"\" id=\"",id,"\" value=\"",v,"\"",(if c then " checked=\"checked\" " else ""),format_attrs(options)," />",
4167 4219 maybe_label(label_text, id)]
4168 4220 div(options, e) then
4169   - format(cinfo,sn,ic_v,any_div(options, e),format_element,is_https),
  4221 + format(cinfo,sn,ic_v,any_div(options, e),format_element,is_https, action_count),
4170 4222 div_empty(options) then
4171   - format(cinfo,sn,ic_v,any_div_empty(options),format_element,is_https),
  4223 + format(cinfo,sn,ic_v,any_div_empty(options),format_element,is_https, action_count),
4172 4224 hidden(id, name, value) then
4173 4225 ["<input type=\"hidden\" id=\"",id,"\" name=\"",name,"\" value=\"",value,"\" />"],
4174 4226  
... ... @@ -4273,53 +4325,54 @@ define Printable_tree
4273 4325 Var(Int) ic_v, // 'idnum' counter variable
4274 4326 HTML_Off_Form element,
4275 4327 Bool is_https,
  4328 + Var(Int) action_count
4276 4329 ) =
4277 4330 if cinfo is info(common_name,http_port,https_port,site_directory,secret) then
4278   - with format_element = (HTML_Off_Form e) |-> format(cinfo,sn,ic_v,e,is_https),
  4331 + with format_element = (HTML_Off_Form e) |-> format(cinfo, sn, ic_v, e, is_https, action_count),
4279 4332 if element is
4280 4333 {
4281 4334 literal_pt(t) then t,
4282 4335 literal(t) then [t],
4283 4336 sequence(l) then flat(map(format_element,l)),
4284 4337 text(opts,t) then
4285   - format(cinfo,sn,ic_v,any_text(opts,t),format_element,is_https),
  4338 + format(cinfo,sn,ic_v,any_text(opts,t),format_element,is_https, action_count),
4286 4339 preformated(o,s) then
4287   - format(cinfo,sn,ic_v,any_preformated(o,s),format_element,is_https),
  4340 + format(cinfo,sn,ic_v,any_preformated(o,s),format_element,is_https, action_count),
4288 4341 paragraph(opts,t) then
4289   - format(cinfo,sn,ic_v,any_paragraph(opts,t),format_element,is_https),
  4342 + format(cinfo,sn,ic_v,any_paragraph(opts,t),format_element,is_https, action_count),
4290 4343 image(opts,url,alt) then
4291   - format(cinfo,sn,ic_v,any_image(opts,url,alt),format_element,is_https),
  4344 + format(cinfo,sn,ic_v,any_image(opts,url,alt),format_element,is_https, action_count),
4292 4345 image(opts,url,alt,w,h) then
4293   - format(cinfo,sn,ic_v,any_image(opts,url,alt,w,h),format_element,is_https),
  4346 + format(cinfo,sn,ic_v,any_image(opts,url,alt,w,h),format_element,is_https, action_count),
4294 4347 table(opts,header_row, rows, footer_row) then
4295   - format(cinfo,sn,ic_v,any_table(opts,header_row, rows, footer_row),format_element,is_https),
  4348 + format(cinfo,sn,ic_v,any_table(opts,header_row, rows, footer_row),format_element,is_https, action_count),
4296 4349 center(e) then
4297   - format(cinfo,sn,ic_v,any_center(e),format_element,is_https),
  4350 + format(cinfo,sn,ic_v,any_center(e),format_element,is_https, action_count),
4298 4351 mail_to(a,e) then
4299   - format(cinfo,sn,ic_v,any_mail_to(a,e),format_element,is_https),
  4352 + format(cinfo,sn,ic_v,any_mail_to(a,e),format_element,is_https, action_count),
4300 4353 scroller(w,h,cw,ch,c) then
4301   - format(cinfo,sn,ic_v,any_scroller(w,h,cw,ch,c),format_element,is_https),
  4354 + format(cinfo,sn,ic_v,any_scroller(w,h,cw,ch,c),format_element,is_https, action_count),
4302 4355 fixed_size(w,h,c) then
4303   - format(cinfo,sn,ic_v,any_fixed_size(w,h,c),format_element,is_https),
  4356 + format(cinfo,sn,ic_v,any_fixed_size(w,h,c),format_element,is_https, action_count),
4304 4357 fixed_size_2(w,h,fn) then
4305   - format(cinfo,sn,ic_v,any_fixed_size_2(w,h,fn),format_element,is_https),
  4358 + format(cinfo,sn,ic_v,any_fixed_size_2(w,h,fn),format_element,is_https, action_count),
4306 4359 actioner(c,t,a,an,eo,ja) then
4307   - format(cinfo,sn,ic_v,any_actioner(c,t,a,an,eo,ja,failure),format_element,is_https),
  4360 + format(cinfo,sn,ic_v,any_actioner(c,t,a,an,eo,ja,failure),format_element,is_https, action_count),
4308 4361 actioner(c,t,a,an,eo,ja,fn) then
4309   - format(cinfo,sn,ic_v,any_actioner(c,t,a,an,eo,ja,success(fn)),format_element,is_https),
  4362 + format(cinfo,sn,ic_v,any_actioner(c,t,a,an,eo,ja,success(fn)),format_element,is_https, action_count),
4310 4363 foreign_link_new(target, aspect, url) then
4311   - format(cinfo,sn,ic_v,any_foreign_link_new(target,aspect,url),format_element,is_https),
  4364 + format(cinfo,sn,ic_v,any_foreign_link_new(target,aspect,url),format_element,is_https, action_count),
4312 4365 foreign_link(options,url) then
4313   - format(cinfo,sn,ic_v,any_foreign_link(options,url),format_element,is_https),
  4366 + format(cinfo,sn,ic_v,any_foreign_link(options,url),format_element,is_https, action_count),
4314 4367 foreign_link(options,url,name) then
4315   - format(cinfo,sn,ic_v,any_foreign_link(options,url,name),format_element,is_https),
  4368 + format(cinfo,sn,ic_v,any_foreign_link(options,url,name),format_element,is_https, action_count),
4316 4369 private_download(url,name,extra,action) then
4317   - format(cinfo,sn,ic_v,any_private_download(url,name,extra,action),format_element,is_https),
  4370 + format(cinfo,sn,ic_v,any_private_download(url,name,extra,action),format_element,is_https, action_count),
4318 4371 label(n) then ["<a name=\"",n,"\">"],
4319 4372 form(fn,attributs, c) then
4320 4373 [
4321 4374 "<form id=\"",fn,"\"",
4322   - format(cinfo,sn,ic_v,any_coreattrs(attributs),format_element,is_https),
  4375 + format(cinfo,sn,ic_v,any_coreattrs(attributs),format_element,is_https, action_count),
4323 4376 " method=\"post\"",
4324 4377 enctype(c),
4325 4378 " action=\"http",
... ... @@ -4328,7 +4381,7 @@ define Printable_tree
4328 4381 // action is set dynamically by
4329 4382 // the actioner using JavaScript
4330 4383 if fn is htmlId(id) then
4331   - format(cinfo,id,sn,ic_v,c,is_https),
  4384 + format(cinfo,id,sn,ic_v,c,is_https, action_count),
4332 4385 "</form>"
4333 4386 ]
4334 4387 form(fn,attributs, action_name, extra_ops, c) then
... ... @@ -4336,7 +4389,7 @@ define Printable_tree
4336 4389 sn, action_name, extra_ops, is_https),
4337 4390 [
4338 4391 "<form id=\"",fn,"\"",
4339   - format(cinfo,sn,ic_v,any_coreattrs(attributs),format_element,is_https),
  4392 + format(cinfo,sn,ic_v,any_coreattrs(attributs),format_element,is_https, action_count),
4340 4393 " method=\"post\"",
4341 4394 enctype(c),
4342 4395 " action=\"" + url + "\">",
... ... @@ -4346,13 +4399,13 @@ define Printable_tree
4346 4399 // action is set dynamically by
4347 4400 // the actioner using JavaScript
4348 4401 if fn is htmlId(id) then
4349   - format(cinfo,id,sn,ic_v,c,is_https),
  4402 + format(cinfo,id,sn,ic_v,c,is_https, action_count),
4350 4403 "</form>"
4351 4404 ]
4352 4405 div(options, e) then
4353   - format(cinfo,sn,ic_v,any_div(options, e),format_element,is_https),
  4406 + format(cinfo,sn,ic_v,any_div(options, e),format_element,is_https, action_count),
4354 4407 div_empty(options) then
4355   - format(cinfo,sn,ic_v,any_div_empty(options),format_element,is_https),
  4408 + format(cinfo,sn,ic_v,any_div_empty(options),format_element,is_https, action_count),
4356 4409 iframe(options, css_styles, css_files, js_files, body) then
4357 4410 if body is body(body_options,element) then
4358 4411 [ "<iframe", format_attrs(options), ">\n",
... ... @@ -4363,7 +4416,7 @@ define Printable_tree
4363 4416 add_js_files(js_files),
4364 4417 "</head>\n",
4365 4418 "<body ", format(body_options), ">\n", // format body options
4366   - format(cinfo,sn,ic_v,element,is_https),
  4419 + format(cinfo,sn,ic_v,element,is_https, action_count),
4367 4420 "</body>\n",
4368 4421 "</html>\n",
4369 4422 "</iframe>\n",
... ... @@ -4524,7 +4577,7 @@ define Printable_tree
4524 4577 "<head>\n", format_html_head(head_tags, charset),"</head>\n",
4525 4578  
4526 4579 "<body ", format(options), ">", // format body options
4527   - format(cinfo,state_name,ic_v,element,is_https),
  4580 + format(cinfo,state_name,ic_v,element,is_https, var(0)),
4528 4581 "</body>\n",
4529 4582  
4530 4583 "</html>"],
... ... @@ -4565,7 +4618,7 @@ define Printable_tree
4565 4618 "</head>\n",
4566 4619 "<body ", format(options), ">", // format body options
4567 4620 //"<center>",
4568   - format(cinfo,state_name,ic_v,element,is_https),
  4621 + format(cinfo,state_name,ic_v,element,is_https, var(0)),
4569 4622 //"</center>",
4570 4623 "</body>\n",
4571 4624 "</html>"
... ... @@ -4627,7 +4680,7 @@ define Printable_tree
4627 4680  
4628 4681 html_content(HTTP_Status status, HTML_Off_Form content_HTML) then
4629 4682 if format(status) is (status_string, status_headers) then
4630   - with content = format(cinfo, state_name, ic_v, content_HTML, is_https),
  4683 + with content = format(cinfo, state_name, ic_v, content_HTML, is_https, var(0)),
4631 4684 [ "HTTP/1.1 " + status_string, crlf,
4632 4685 format_headers(standard_headers),
4633 4686 format_headers(standard_headers_for("text/html", length(content), success(charset))),
... ...
web/CXM_multihost_http_server.anubis
... ... @@ -563,10 +563,10 @@ define String
563 563 to_decimal(t.seconds) + "." + zero_pad_n(6, t.microseconds ) + "s".
564 564  
565 565  
566   -variable UTime t0 = utime(0,0).
567   -variable UTime t1 = utime(0,0).
  566 + variable UTime t0 = utime(0,0).
  567 + variable UTime t1 = utime(0,0).
568 568  
569   -define One
  569 + define One
570 570 accumulate_t1
571 571 (
572 572 UTime start
... ... @@ -575,9 +575,9 @@ define One
575 575 t1 <- delta + *t1;
576 576 unique.
577 577  
578   -variable UTime t2 = utime(0,0).
  578 + variable UTime t2 = utime(0,0).
579 579  
580   -define One
  580 + define One
581 581 accumulate_t2
582 582 (
583 583 UTime start
... ... @@ -587,7 +587,7 @@ define One
587 587 unique.
588 588  
589 589  
590   -public define One
  590 + public define One
591 591 print_delta
592 592 (
593 593 String txt
... ... @@ -744,12 +744,18 @@ define String
744 744  
745 745  
746 746  
  747 + *** [2.3] A set of state variables for the server.
747 748  
  749 +type SState:
  750 + sstate
  751 + (
  752 + Var(List(Word8)) unput_chars, // for reading requests
  753 + Var(Int) sttm, // 'start time'
  754 + Var(Int) uploaded_file_count
  755 + ).
  756 +
748 757  
749   -
750   -
751   -
752   - *** [2.3] Reading and unputting characters.
  758 + *** [2.4] Reading and unputting characters.
753 759  
754 760 We need a mecanism for unputting several characters (actually at least 3). This is
755 761 because when reading the client connection, we must sometimes go ahead several
... ... @@ -758,7 +764,7 @@ define String
758 764 (hold by the variable 'unput_chars'), and we manage this list, so that characters may
759 765 be virtually put back in the connection (this is called 'unputting').
760 766  
761   -variable List(Word8) unput_chars = [].
  767 + variable List(Word8) unput_chars = [].
762 768  
763 769 The most recently read one is the head of list. Fortunately, this variable is private
764 770 to this virtual machine (hence to this client).
... ... @@ -767,15 +773,16 @@ variable List(Word8) unput_chars = [].
767 773 define One
768 774 unput // unputting a character (add it in front of the list)
769 775 (
770   - Word8 character
  776 + Word8 character,
  777 + SState s
771 778 ) =
772   - unput_chars <- (List(Word8))[character . *unput_chars].
  779 + s.unput_chars <- (List(Word8))[character . *(s.unput_chars)].
773 780  
774 781  
775 782  
776 783 define One record_dubious_IP(Word32 addr,DenialOfService dos).
777 784  
778   -variable Int sttm = 0. // contains the start time for this connection.
  785 + variable Int sttm = 0. // contains the start time for this connection.
779 786  
780 787 define Result(Error,Word8)
781 788 record_dubious_connection
... ... @@ -783,11 +790,12 @@ define Result(Error,Word8)
783 790 Connection conn,
784 791 Int dead_line,
785 792 DenialOfService dos,
  793 + SState s
786 794 ) =
787 795 if remote_IP_address_and_port(conn) is (addr,port) then
788 796 record_dubious_IP(addr,dos);
789 797 print("Recording IP address "+ip_addr_to_string(addr)+
790   - " as dubious after "+(dead_line-*sttm)+" seconds. Total: "+
  798 + " as dubious after "+(dead_line-*(s.sttm))+" seconds. Total: "+
791 799 length(*list_of_dubious(dos))+"\n");
792 800 error(timeout(dead_line)).
793 801  
... ... @@ -866,10 +874,11 @@ define Result(Error,Word8)
866 874 (
867 875 BufferedConnection connection,
868 876 Int dead_line,
869   - DenialOfService dos
  877 + DenialOfService dos,
  878 + SState s
870 879 ) =
871 880 //with t2_tmp = (UTime) now,
872   - if *unput_chars is
  881 + if *(s.unput_chars) is
873 882 {
874 883 [ ] then
875 884 // ///////////////////
... ... @@ -913,7 +922,7 @@ define Result(Error,Word8)
913 922 // },
914 923  
915 924 [h . t] then
916   - unput_chars <- t; //accumulate_t2(t2_tmp);
  925 + s.unput_chars <- t; //accumulate_t2(t2_tmp);
917 926 ok(h)
918 927 }.
919 928  
... ... @@ -934,13 +943,14 @@ define Result(Error,One)
934 943 BufferedConnection connection, // to client
935 944 Int dead_line,
936 945 Int number_of_characters, // number of characters to read and ignore
937   - DenialOfService dos
  946 + DenialOfService dos,
  947 + SState s
938 948 ) =
939 949 if number_of_characters =< 0 then ok(unique) else
940   - if next_char(connection, dead_line, dos) is
  950 + if next_char(connection, dead_line, dos, s) is
941 951 {
942 952 error(msg) then error(msg),
943   - ok(c) then read_and_ignore(connection,dead_line,number_of_characters-1,dos)
  953 + ok(c) then read_and_ignore(connection,dead_line,number_of_characters-1,dos, s)
944 954 }.
945 955  
946 956  
... ... @@ -961,25 +971,26 @@ define Result(Error,String)
961 971 (
962 972 BufferedConnection connection, // connection with the client
963 973 Int dead_line,
964   - List(Word8) so_far, // characters read so far (in reverse order)
965   - DenialOfService dos
  974 + List(Word8) so_far, // characters read so far (in reverse order)
  975 + DenialOfService dos,
  976 + SState s
966 977 ) =
967   - if next_char(connection, dead_line,dos) is
  978 + if next_char(connection, dead_line,dos, s) is
968 979 {
969 980 error(msg) then error(msg),
970 981 ok(c) then
971 982 if c = '\\'
972   - then if next_char(connection,dead_line,dos) is
  983 + then if next_char(connection,dead_line,dos, s) is
973 984 {
974 985 error(msg) then error(msg),
975 986 ok(d) then
976 987 if d = '\"'
977   - then read_string(connection,dead_line,['\"' . so_far],dos)
978   - else read_string(connection,dead_line,[d, c . so_far],dos)
  988 + then read_string(connection,dead_line,['\"' . so_far],dos, s)
  989 + else read_string(connection,dead_line,[d, c . so_far],dos, s)
979 990 }
980 991 else if c = '\"'
981 992 then ok(implode(reverse(so_far)))
982   - else read_string(connection,dead_line,[c . so_far],dos)
  993 + else read_string(connection,dead_line,[c . so_far],dos, s)
983 994 }.
984 995  
985 996  
... ... @@ -1263,31 +1274,32 @@ define Result(Error,One)
1263 1274 (
1264 1275 BufferedConnection connection,
1265 1276 Int dead_line,
1266   - DenialOfService dos
  1277 + DenialOfService dos,
  1278 + SState s
1267 1279 ) =
1268   - if next_char(connection,dead_line,dos) is
  1280 + if next_char(connection, dead_line, dos, s) is
1269 1281 {
1270 1282 error(msg) then error(msg),
1271 1283 ok(c) then
1272 1284 if is_strict_blank(c)
1273   - then skip_http_blanks(connection,dead_line,dos)
  1285 + then skip_http_blanks(connection, dead_line, dos, s)
1274 1286 else if c = 13
1275   - then if next_char(connection,dead_line,dos) is
  1287 + then if next_char(connection, dead_line, dos, s) is
1276 1288 {
1277 1289 error(msg) then error(msg), // (unput(c); ok(unique)),
1278 1290 ok(d) then
1279 1291 if d = 10
1280   - then if next_char(connection,dead_line,dos) is
  1292 + then if next_char(connection, dead_line, dos, s) is
1281 1293 {
1282 1294 error(msg) then error(msg), // (unput(d); unput(c); ok(unique)),
1283 1295 ok(e) then
1284 1296 if is_strict_blank(e)
1285   - then skip_http_blanks(connection,dead_line,dos)
1286   - else (unput(e); unput(d); unput(c); ok(unique))
  1297 + then skip_http_blanks(connection, dead_line, dos, s)
  1298 + else (unput(e, s); unput(d, s); unput(c, s); ok(unique))
1287 1299 }
1288   - else (unput(d); unput(c); ok(unique))
  1300 + else (unput(d, s); unput(c, s); ok(unique))
1289 1301 }
1290   - else (unput(c); ok(unique))
  1302 + else (unput(c, s); ok(unique))
1291 1303 }.
1292 1304  
1293 1305  
... ... @@ -1319,28 +1331,29 @@ define Result(Error,One)
1319 1331 (
1320 1332 BufferedConnection connection,
1321 1333 Int dead_line,
1322   - DenialOfService dos
  1334 + DenialOfService dos,
  1335 + SState s
1323 1336 ) =
1324   - if skip_http_blanks(connection,dead_line,dos) is
  1337 + if skip_http_blanks(connection, dead_line, dos, s) is
1325 1338 {
1326 1339 error(msg) then error(msg),
1327 1340 ok(_) then
1328   - if next_char(connection,dead_line,dos) is
  1341 + if next_char(connection, dead_line, dos, s) is
1329 1342 {
1330 1343 error(msg) then error(msg),
1331 1344 ok(c) then
1332 1345 if c = 13
1333   - then if next_char(connection,dead_line,dos) is
  1346 + then if next_char(connection, dead_line, dos, s) is
1334 1347 {
1335 1348 error(msg) then error(msg),
1336 1349 ok(d) then
1337 1350 if d = 10
1338 1351 then ok(unique)
1339   - else (unput(d);
1340   - unput(c);
  1352 + else (unput(d, s);
  1353 + unput(c, s);
1341 1354 error(end_of_line_expected))
1342 1355 }
1343   - else (unput(c);
  1356 + else (unput(c, s);
1344 1357 error(end_of_line_expected))
1345 1358 }}.
1346 1359  
... ... @@ -1368,17 +1381,18 @@ define Result(Error,String)
1368 1381 (
1369 1382 BufferedConnection connection,
1370 1383 Int dead_line,
1371   - List(Word8) so_far,
1372   - DenialOfService dos
  1384 + List(Word8) so_far,
  1385 + DenialOfService dos,
  1386 + SState s
1373 1387 ) =
1374   - if next_char(connection,dead_line,dos) is
  1388 + if next_char(connection,dead_line,dos, s) is
1375 1389 {
1376 1390 error(msg) then error(msg),
1377 1391 ok(c) then
1378 1392 if is_blank(c)
1379   - then (unput(c);
  1393 + then (unput(c, s);
1380 1394 ok(implode(reverse(so_far))))
1381   - else read_word_aux(connection,dead_line,[c . so_far],dos)
  1395 + else read_word_aux(connection,dead_line,[c . so_far],dos, s)
1382 1396 }.
1383 1397  
1384 1398 define Result(Error,String)
... ... @@ -1386,19 +1400,20 @@ define Result(Error,String)
1386 1400 (
1387 1401 BufferedConnection connection,
1388 1402 Int dead_line,
1389   - DenialOfService dos
  1403 + DenialOfService dos,
  1404 + SState s
1390 1405 ) =
1391   - if skip_http_blanks(connection,dead_line,dos) is
  1406 + if skip_http_blanks(connection,dead_line,dos, s) is
1392 1407 {
1393 1408 error(msg) then error(msg),
1394 1409 ok(_) then
1395   - if next_char(connection,dead_line,dos) is
  1410 + if next_char(connection, dead_line, dos, s) is
1396 1411 {
1397 1412 error(msg) then error(msg),
1398 1413 ok(c) then
1399 1414 if c = '\"'
1400   - then read_string(connection,dead_line,[],dos)
1401   - else read_word_aux(connection,dead_line,[c],dos)
  1415 + then read_string(connection,dead_line,[],dos, s)
  1416 + else read_word_aux(connection,dead_line,[c],dos, s)
1402 1417 }
1403 1418 }.
1404 1419  
... ... @@ -1560,18 +1575,19 @@ define Result(Error,HTTP_RequestLine)
1560 1575 (
1561 1576 BufferedConnection connection,
1562 1577 Int dead_line,
1563   - DenialOfService dos
  1578 + DenialOfService dos,
  1579 + SState s
1564 1580 ) =
1565   - if read_word(connection,dead_line,dos) is
  1581 + if read_word(connection, dead_line, dos, s) is
1566 1582 {
1567 1583 error(msg) then error(msg),
1568   - ok(get_or_post) then if read_word(connection,dead_line,dos) is
  1584 + ok(get_or_post) then if read_word(connection, dead_line, dos, s) is
1569 1585 {
1570 1586 error(msg) then error(msg),
1571   - ok(uri_and_query_string) then if read_word(connection,dead_line,dos) is
  1587 + ok(uri_and_query_string) then if read_word(connection, dead_line, dos, s) is
1572 1588 {
1573 1589 error(msg) then error(msg),
1574   - ok(http_version) then if read_new_line(connection,dead_line,dos) is
  1590 + ok(http_version) then if read_new_line(connection, dead_line, dos, s) is
1575 1591 {
1576 1592 error(msg) then error(msg),
1577 1593 ok(_) then if separate_uri_from_query_string(uri_and_query_string,0) is
... ... @@ -1616,16 +1632,17 @@ define Result(Error,String)
1616 1632 (
1617 1633 BufferedConnection connection,
1618 1634 Int dead_line,
1619   - List(Word8) so_far,
1620   - DenialOfService dos
  1635 + List(Word8) so_far,
  1636 + DenialOfService dos,
  1637 + SState s
1621 1638 ) =
1622   - if next_char(connection,dead_line,dos) is
  1639 + if next_char(connection, dead_line, dos, s) is
1623 1640 {
1624 1641 error(msg) then error(msg),
1625 1642 ok(c) then
1626 1643 if is_header_name_char(c)
1627   - then read_header_name(connection,dead_line,[to_lower(c) . so_far],dos)
1628   - else unput(c); ok(implode(reverse(so_far)))
  1644 + then read_header_name(connection,dead_line,[to_lower(c) . so_far],dos, s)
  1645 + else unput(c, s); ok(implode(reverse(so_far)))
1629 1646 }.
1630 1647  
1631 1648 define Result(Error,One)
... ... @@ -1633,13 +1650,14 @@ define Result(Error,One)
1633 1650 (
1634 1651 BufferedConnection connection,
1635 1652 Int dead_line,
1636   - DenialOfService dos
  1653 + DenialOfService dos,
  1654 + SState s
1637 1655 ) =
1638   - if skip_http_blanks(connection,dead_line,dos) is
  1656 + if skip_http_blanks(connection, dead_line, dos, s) is
1639 1657 {
1640 1658 error(msg) then error(msg),
1641 1659 ok(_) then
1642   - if next_char(connection,dead_line,dos) is
  1660 + if next_char(connection, dead_line, dos, s) is
1643 1661 {
1644 1662 error(msg) then error(msg),
1645 1663 ok(c) then
... ... @@ -1654,30 +1672,31 @@ define Result(Error,String)
1654 1672 (
1655 1673 BufferedConnection connection,
1656 1674 Int dead_line,
1657   - List(Word8) so_far,
1658   - DenialOfService dos
  1675 + List(Word8) so_far,
  1676 + DenialOfService dos,
  1677 + SState s
1659 1678 ) =
1660   - if next_char(connection,dead_line,dos) is
  1679 + if next_char(connection, dead_line, dos, s) is
1661 1680 {
1662 1681 error(msg) then error(msg),
1663 1682 ok(c) then
1664 1683 if c = 13
1665   - then if next_char(connection,dead_line,dos) is
  1684 + then if next_char(connection, dead_line, dos, s) is
1666 1685 {
1667 1686 error(msg) then error(msg),
1668 1687 ok(d) then
1669 1688 if d = 10
1670   - then if next_char(connection,dead_line,dos) is
  1689 + then if next_char(connection, dead_line, dos, s) is
1671 1690 {
1672 1691 error(msg) then error(msg),
1673 1692 ok(e) then
1674 1693 if is_strict_blank(e)
1675   - then read_header_value(connection,dead_line,[e . so_far],dos)
1676   - else (unput(e); ok(implode(reverse(so_far))))
  1694 + then read_header_value(connection,dead_line, [e . so_far], dos, s)
  1695 + else (unput(e, s); ok(implode(reverse(so_far))))
1677 1696 }
1678   - else read_header_value(connection,dead_line,[d, c . so_far],dos)
  1697 + else read_header_value(connection,dead_line,[d, c . so_far],dos, s)
1679 1698 }
1680   - else read_header_value(connection,dead_line,[c . so_far],dos)
  1699 + else read_header_value(connection,dead_line,[c . so_far],dos, s)
1681 1700 }.
1682 1701  
1683 1702  
... ... @@ -1688,26 +1707,27 @@ define Result(Error,Maybe(HTTP_header))
1688 1707 (
1689 1708 BufferedConnection connection,
1690 1709 Int dead_line,
1691   - DenialOfService dos
  1710 + DenialOfService dos,
  1711 + SState s
1692 1712 ) =
1693   - if read_header_name(connection,dead_line,[],dos) is
  1713 + if read_header_name(connection, dead_line, [], dos, s) is
1694 1714 {
1695 1715 error(msg) then error(msg),
1696 1716 ok(name) then
1697 1717 if name = "" then
1698   - if read_and_ignore(connection,dead_line,2,dos) /* 13 and 10 */ is
  1718 + if read_and_ignore(connection, dead_line, 2, dos, s) /* 13 and 10 */ is
1699 1719 {
1700 1720 error(msg) then error(msg),
1701 1721 ok(_) then // this is the blank line
1702 1722 ok(failure) // end of headers
1703 1723 }
1704   - else if skip_colon(connection,dead_line,dos) is
  1724 + else if skip_colon(connection, dead_line, dos, s) is
1705 1725 {
1706 1726 error(msg) then error(msg),
1707   - ok(_) then if skip_http_blanks(connection,dead_line,dos) is
  1727 + ok(_) then if skip_http_blanks(connection, dead_line, dos, s) is
1708 1728 {
1709 1729 error(msg) then error(msg),
1710   - ok(_) then if read_header_value(connection,dead_line,[],dos) is
  1730 + ok(_) then if read_header_value(connection, dead_line, [], dos, s) is
1711 1731 {
1712 1732 error(msg) then error(msg),
1713 1733 ok(value) then
... ... @@ -1726,16 +1746,17 @@ define Result(Error,List(HTTP_header))
1726 1746 (
1727 1747 BufferedConnection connection,
1728 1748 Int dead_line,
1729   - DenialOfService dos
  1749 + DenialOfService dos,
  1750 + SState s
1730 1751 ) =
1731   - if read_header(connection,dead_line,dos) is
  1752 + if read_header(connection, dead_line, dos, s) is
1732 1753 {
1733 1754 error(msg) then error(msg),
1734 1755 ok(mbh) then if mbh is
1735 1756 {
1736 1757 failure then ok([ ]),
1737 1758 success(header) then
1738   - if read_http_headers(connection,dead_line,dos) is
  1759 + if read_http_headers(connection, dead_line, dos, s) is
1739 1760 {
1740 1761 error(msg) then error(msg),
1741 1762 ok(others) then ok([header . others])
... ... @@ -2169,7 +2190,7 @@ define Bool
2169 2190 ) =
2170 2191 if input_etag is
2171 2192 {
2172   - failure then false,
  2193 + failure then false,
2173 2194 success(etag) then trim_token(etag, '\"') = current_etag //remove triming " because this is quoted string
2174 2195 }.
2175 2196  
... ... @@ -2197,7 +2218,7 @@ define One
2197 2218 {
2198 2219 false then
2199 2220 forget(reliable_write(connection,to_byte_array("HTTP/1.1 200 OK"+crlf)));
2200   - forget(reliable_write(connection,[format_headers(headers + headers_for_send_file(mime_type, size, "\""+current_etag+"\"", mb_ftimes)) , crlf]));
  2221 + forget(reliable_write(connection,[format_headers(headers + headers_for_send_file(mime_type, size, current_etag, mb_ftimes)) , crlf]));
2201 2222 //forget(copy_file_to_Connection(file, connection, size)),
2202 2223 send_file_body(desc,connection,file,size,0,filename),
2203 2224 true then
... ... @@ -2253,8 +2274,8 @@ define One
2253 2274 failure then
2254 2275 println("HTTP/1.1 404 Not Found"+path);
2255 2276 forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+
2256   - "Content-Length: 0"+crlf+
2257   - "Connection: close"+crlf+crlf)));
  2277 + "Content-Length: 0"+crlf+crlf
  2278 + /*+"Connection: close"+crlf+crlf*/)));
2258 2279 log_journal_msg(desc,"Cannot find file '"+path+"'.\n"),
2259 2280 success(f) then with size = file_size(f),
2260 2281 send_file(desc,
... ... @@ -2283,8 +2304,8 @@ define One
2283 2304 failure then
2284 2305 println("HTTP/1.1 404 Not Found"+absolute_path);
2285 2306 forget(reliable_write(connection,to_byte_array("HTTP/1.1 404 Not Found"+crlf+
2286   - "Content-Length: 0"+crlf+
2287   - "Connection: close"+crlf+crlf)));
  2307 + "Content-Length: 0"+crlf+crlf
  2308 + /*+"Connection: close"+crlf+crlf*/)));
2288 2309 log_journal_msg(desc,"Cannot find file '"+absolute_path+"'.\n"),
2289 2310 success(f) then with size = file_size(f),
2290 2311 mime_type = if recognize_mime_type_from_uri(desc,uri) is
... ... @@ -2324,7 +2345,7 @@ public define List(HTTP_header)
2324 2345 [
2325 2346 http_header("Date", format_http_date(now)),
2326 2347 http_header("Server", "Anubis Embedded Server v" + major_version_number + "." + minor_version_number),
2327   - http_header("Connection", "close"),
  2348 + /*http_header("Connection", "close"), */
2328 2349 ].
2329 2350  
2330 2351 public define List(HTTP_header)
... ... @@ -2642,7 +2663,7 @@ define Maybe((String,Maybe(String)))
2642 2663  
2643 2664 *** [5.7.3] Creating a temporary filename for an uploaded file.
2644 2665  
2645   -variable Int uploaded_file_count = 0.
  2666 + variable Int uploaded_file_count = 0.
2646 2667  
2647 2668 This variable is local to the virtual machine. Hence, its value is 0 each time a new
2648 2669 requests arrives. Temporary uploaded files are stored in the directory represented by
... ... @@ -2668,10 +2689,11 @@ define Maybe(String) // returns the temporary file name
2668 2689 Web_Site_Description desc,
2669 2690 ByteArray body,
2670 2691 Int start,
2671   - Int end
  2692 + Int end,
  2693 + SState s
2672 2694 ) =
2673   - uploaded_file_count <- 1 + *uploaded_file_count;
2674   - with tfn = "_"+to_decimal(virtual_machine_id)+"_"+to_decimal(*uploaded_file_count),
  2695 + s.uploaded_file_count <- 1 + *(s.uploaded_file_count);
  2696 + with tfn = "_"+to_decimal(virtual_machine_id)+"_"+to_decimal(*(s.uploaded_file_count)),
2675 2697 if (Maybe(RWStream))file(site_directory(desc)+"/upload_temporary/"+tfn, new) is
2676 2698 {
2677 2699 failure then failure,
... ... @@ -2735,7 +2757,8 @@ define Maybe(Web_arg)
2735 2757 Web_Site_Description desc,
2736 2758 ByteArray body,
2737 2759 Int start,
2738   - Int end
  2760 + Int end,
  2761 + SState s
2739 2762 ) =
2740 2763 if find(to_byte_array(crlf+crlf),body,start) is
2741 2764 {
... ... @@ -2754,7 +2777,7 @@ define Maybe(Web_arg)
2754 2777 // we must substract 2 to end because of crlf just before the boundary
2755 2778  
2756 2779 success(fn) then
2757   - if save_uploaded_file(desc,body,k+4,end-2) is
  2780 + if save_uploaded_file(desc, body, k+4, end-2, s) is
2758 2781 {
2759 2782 failure then failure,
2760 2783 success(tfn) then
... ... @@ -2775,6 +2798,7 @@ define List(Web_arg)
2775 2798 ByteArray body,
2776 2799 ByteArray __boundary,
2777 2800 Int i,
  2801 + SState s
2778 2802 ) =
2779 2803 if find(__boundary,body,i) is
2780 2804 {
... ... @@ -2784,11 +2808,11 @@ define List(Web_arg)
2784 2808 {
2785 2809 failure then [ ],
2786 2810 success(m) then
2787   - if get_multipart_entity(desc,body,n+length(__boundary),m) is
  2811 + if get_multipart_entity(desc, body, n+length(__boundary), m, s) is
2788 2812 {
2789 2813 failure then [ ],
2790 2814 success(wa) then
2791   - [wa . read_multipart_form_data_encoded_web_args(desc,body,__boundary,m)]
  2815 + [wa . read_multipart_form_data_encoded_web_args(desc, body, __boundary, m, s)]
2792 2816 }
2793 2817 }
2794 2818 }.
... ... @@ -2801,11 +2825,12 @@ define One
2801 2825 String host_name,
2802 2826 Web_Site_Description desc,
2803 2827 Connection connection,
2804   - Word32 ip_addr,
  2828 + Word32 ip_addr,
2805 2829 HTTP_RequestLine request_line,
2806 2830 List(HTTP_header) headers,
2807 2831 ByteArray body,
2808   - One -> String generate_tt
  2832 + One -> String generate_tt,
  2833 + SState s
2809 2834 ) =
2810 2835 if get_boundary(headers) is
2811 2836 {
... ... @@ -2815,7 +2840,8 @@ define One
2815 2840 read_multipart_form_data_encoded_web_args(desc,
2816 2841 body,
2817 2842 to_byte_array("--"+boundary),
2818   - 0),
  2843 + 0,
  2844 + s),
2819 2845 uri = uri(request_line),
2820 2846 ext = get_uri_extension(uri),
2821 2847 log_journal_msg(desc,
... ... @@ -2958,7 +2984,8 @@ define One
2958 2984 HTTP_RequestLine rqline,
2959 2985 List(HTTP_header) headers,
2960 2986 ByteArray body,
2961   - One -> String generate_tt
  2987 + One -> String generate_tt,
  2988 + SState s
2962 2989 ) =
2963 2990 if rqline is request_line(type,uri,qstring) then
2964 2991 with rqline2 = request_line(type,handle_redirection(redirections(desc),uri,headers),qstring),
... ... @@ -2968,7 +2995,7 @@ define One
2968 2995 www_url then
2969 2996 www_url_answer(host_name,desc,connection,ip_addr,rqline2,headers,body,generate_tt),
2970 2997 multipart_form_data then
2971   - multipart_form_data_answer(host_name,desc,connection,ip_addr,rqline2,headers,body,generate_tt)
  2998 + multipart_form_data_answer(host_name,desc,connection,ip_addr,rqline2,headers,body,generate_tt, s)
2972 2999 }.
2973 3000  
2974 3001  
... ... @@ -3068,20 +3095,21 @@ define One
3068 3095 List(Web_Site_Description) sites,
3069 3096 BufferedConnection connection,
3070 3097 Bool is_https,
3071   - DenialOfService dos
  3098 + DenialOfService dos,
  3099 + SState s
3072 3100 ) =
3073 3101 //t0 <- (UTime)unow;
3074 3102 with start_time = (Int)now,
3075   - sttm <- start_time;
  3103 + s.sttm <- start_time;
3076 3104 //println("Request time: " + format_http_date(start_time));
3077 3105 if dos is denial_of_service(mc_v,rld_v,hd_v,ad_v,ld_v,ra_v) then
3078 3106 if remote_IP_address_and_port(connection.conn) is (ip_addr,port) then
3079   - if read_request_line(connection,start_time+*rld_v,dos) is
  3107 + if read_request_line(connection, start_time+*rld_v, dos, s) is
3080 3108 {
3081 3109 error(msg) then print(format(msg)),
3082 3110 ok(request_line) then
3083 3111 //print_delta("read_request_line");
3084   - if read_http_headers(connection,start_time+*hd_v,dos) is
  3112 + if read_http_headers(connection, start_time+*hd_v, dos, s) is
3085 3113 {
3086 3114 error(msg) then print(format(msg)),
3087 3115 ok(headers) then //print_delta("read_http_headers");
... ... @@ -3101,7 +3129,9 @@ define One
3101 3129 ok(body) then
3102 3130 //print_delta("before send_answer");
3103 3131 send_answer(host_name, desc,connection.conn, request_line, headers, body,
3104   - make_generate_trust_ticket(dos))
  3132 + make_generate_trust_ticket(dos), s);
  3133 + //it's HTTP 1.1 keep-alive is default
  3134 + http_https_handler(sites, connection, is_https, dos, s)
3105 3135 //with duration = (UTime) unow - *t0,
3106 3136 //println("Request duration: " + __utime_to_string(duration))
3107 3137 //println("BufferRead duration: " + __utime_to_string(*t1));
... ... @@ -3121,8 +3151,8 @@ define Bool is_dubious_IP(Word32 ip, DenialOfService dos).
3121 3151 define Server -> ((RWStream) -> One)
3122 3152 make_http_handler
3123 3153 (
3124   - List(Web_Site_Description) sites,
3125   - DenialOfService dos
  3154 + List(Web_Site_Description) sites,
  3155 + DenialOfService dos
3126 3156 ) =
3127 3157 (Server server) |-> (RWStream conn) |->
3128 3158 if remote_IP_address_and_port(conn) is (addr,_) then
... ... @@ -3130,8 +3160,7 @@ define Server -&gt; ((RWStream) -&gt; One)
3130 3160 then print("Rejecting dubious IP address "+ip_addr_to_string(addr)+"\n")
3131 3161 else
3132 3162 with connection = buffered_connection(tcp(conn), var(constant_byte_array(0, 0)), var(0)),
3133   - http_https_handler(sites, connection, false, dos).
3134   -
  3163 + http_https_handler(sites, connection, false, dos, sstate(var([]),var(0),var(0))).
3135 3164 public define One
3136 3165 http_direct_handler
3137 3166 (
... ... @@ -3144,18 +3173,18 @@ public define One
3144 3173 then print("Rejecting dubious IP address "+ip_addr_to_string(addr)+"\n")
3145 3174 else
3146 3175 with connection = buffered_connection(tcp(conn), var(constant_byte_array(0, 0)), var(0)),
3147   - http_https_handler(sites, connection, false, dos).
  3176 + http_https_handler(sites, connection, false, dos, sstate(var([]),var(0),var(0))).
3148 3177  
3149 3178  
3150 3179 define Server -> (SSL_Connection -> One)
3151 3180 make_https_handler
3152 3181 (
3153   - List(Web_Site_Description) sites,
3154   - DenialOfService dos
  3182 + List(Web_Site_Description) sites,
  3183 + DenialOfService dos
3155 3184 ) =
3156 3185 (Server server) |-> (SSL_Connection conn) |->
3157 3186 with connection = buffered_connection(ssl(conn), var(constant_byte_array(0, 0)), var(0)),
3158   - http_https_handler(sites, connection, true, dos).
  3187 + http_https_handler(sites, connection, true, dos, sstate(var([]),var(0),var(0))).
3159 3188  
3160 3189  
3161 3190  
... ... @@ -3435,12 +3464,12 @@ public define StartServerResult
3435 3464 (
3436 3465 Word32 ip_address,
3437 3466 Word32 port,
3438   - List(Web_Site_Description) sites,
3439   - DenialOfService dos
  3467 + List(Web_Site_Description) sites,
  3468 + DenialOfService dos
3440 3469 ) =
3441 3470 create_directories(sites);
3442 3471 start_http_server(ip_address,port,
3443   - make_http_handler(sites,dos),
  3472 + make_http_handler(sites, dos),
3444 3473 0,
3445 3474 dos).
3446 3475  
... ... @@ -3480,15 +3509,15 @@ define StartServerResult
3480 3509 public define StartServerResult
3481 3510 start_https_server
3482 3511 (
3483   - Word32 ip_address,
3484   - Word32 port,
3485   - String certificate_common_name, // of SSL server certificate
3486   - List(Web_Site_Description) sites,
3487   - DenialOfService dos
  3512 + Word32 ip_address,
  3513 + Word32 port,
  3514 + String certificate_common_name, // of SSL server certificate
  3515 + List(Web_Site_Description) sites,
  3516 + DenialOfService dos
3488 3517 ) =
3489 3518 create_directories(sites);
3490 3519 start_https_server(ip_address,port,certificate_common_name,
3491   - make_https_handler(sites,dos),
  3520 + make_https_handler(sites, dos),
3492 3521 0,dos).
3493 3522  
3494 3523  
... ... @@ -3541,16 +3570,17 @@ define Server -&gt; ((RWStream) -&gt; One)
3541 3570 make_dispatcher_handler
3542 3571 (
3543 3572 Var(List(DispatcherInfo)) info_v,
3544   - DenialOfService dos
  3573 + DenialOfService dos,
  3574 + SState s
3545 3575 ) =
3546 3576 (Server server) |-> (RWStream conn) |->
3547 3577 with start_time = (Int)now,
3548 3578 connection = buffered_connection(tcp(conn), var(constant_byte_array(0, 0)), var(0)),
3549   - if read_request_line(connection, start_time+*request_line_delay(dos), dos) is
  3579 + if read_request_line(connection, start_time+*request_line_delay(dos), dos, s) is
3550 3580 {
3551 3581 error(msg) then print(format(msg)),
3552 3582 ok(request_line) then
3553   - if read_http_headers(connection, start_time+*headers_delay(dos), dos) is
  3583 + if read_http_headers(connection, start_time+*headers_delay(dos), dos, s) is
3554 3584 {
3555 3585 error(msg) then print(format(msg)),
3556 3586 ok(headers) then if get_host_header_value(headers) is
... ... @@ -3627,7 +3657,8 @@ public define One
3627 3657 (
3628 3658 Word32 ip_address, // address for listening (typically 0: listen on all interfaces)
3629 3659 Word32 http_port, // typically 80
3630   - DenialOfService dos
  3660 + DenialOfService dos,
  3661 + SState s
3631 3662 ) =
3632 3663 with info_file_path = my_anubis_directory+"/web_sites/dispatcher.info",
3633 3664 info_v = var((List(DispatcherInfo))[]),
... ... @@ -3635,7 +3666,7 @@ public define One
3635 3666 if dispatcher_update_data(info_file_path,info_v,info_date_v)
3636 3667 then if start_server(ip_address,
3637 3668 http_port,
3638   - make_dispatcher_handler(info_v,dos),
  3669 + make_dispatcher_handler(info_v, dos, s),
3639 3670 (One u)|->u) is
3640 3671 {
3641 3672 cannot_create_the_socket then
... ...