From e88c944b25a154d938edc31c91f017fa5c9660b7 Mon Sep 17 00:00:00 2001 From: Totoro Date: Sat, 15 Jun 2013 20:45:16 +0200 Subject: [PATCH] update the calexium lib to be compatible with anubis compiler 1.12.2.0. especially replace alert by should_not_happen and "connect to file" by file Remove obsolete file CXM_html.anubis --- web/CXM_cookies.anubis | 1473 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- web/CXM_html.anubis | 2395 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- web/CXM_multihost_http_server.anubis | 7990 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 3 files changed, 4731 insertions(+), 7127 deletions(-) delete mode 100644 web/CXM_html.anubis diff --git a/web/CXM_cookies.anubis b/web/CXM_cookies.anubis index 76cf936..8581aab 100644 --- a/web/CXM_cookies.anubis +++ b/web/CXM_cookies.anubis @@ -1,737 +1,736 @@ - - *Project* The Anubis Project - - *Title* Managing Cookies. - - *Copyright* Copyright (c) Alain Prouté 2001. - - - *Author* Alain Prouté - - - - -read tools/basis.anubis -read system/string.anubis -read CXM_common.anubis -read CXM_html.anubis -read CXM_http_get_common.anubis - - - *Overview* - Cookies are defined in RFC 2109. Here is the corresponding Anubis type: - - Each cookie has an server name (the name of the server who constructed the cookie), a - name, a value, and several attributes. - -public type Cookie: - cookie(String server_name, // of the server who sent the cookie - String name, // of the cookie - String value, // of the cookie - // attributes: - Maybe(String) comment, // cookies may have human readable comments - Maybe(String) domain, // domain name as sent by the server - Int validity, // cookie still valid if this is > now - Maybe(String) path, // server path for which the cookie is valid - Bool secure, // if true, do not send this cookie over an insecure link - Int version). // Cookie version (normally 1: rfc 2109) - - - Cookies are sent by servers through 'Set-Cookie' HTTP headers. The function - 'get_cookies' retrieves a list of cookies from a list of HTTP headers. - -public define List(Cookie) - get_cookies - ( - String server_name, // name of server who sent the cookies - List(HTTP_header) headers // HTTP headers sent by this server - ). - -public define Maybe(Cookie) - find_cookie - ( - String name, - List(Cookie) cookies - ). - - - - - - Normally, this function is used on the list of HTTP headers returned by either - 'http_get' of 'https_get'. - - - Before they can be sent back to their origin server, cookies must be reformated, in - order to produce 'Cookie' HTTP headers: - -public define List(HTTP_header) - reformat_cookies - ( - String server_name, - String uri, - List(Cookie) cookies - ). - - The result of 'reformat_cookies' may be appended to the list of headers given as - argument to 'http_get' or to 'https_get'. - - In the meantime, you may examine and maybe discard cookies, you may 'save' them into a - file, and 'retrieve' them later. - - - - - ------- That all for the public part. ------------------------------------------------- - - - Here is the syntax of a 'Set-Cookie' header (according to RFC 2109): - - set-cookie = "Set-Cookie:" cookies - cookies = 1#cookie - cookie = NAME "=" VALUE *(";" cookie-av) - NAME = token - VALUE = value - value = token | quoted-string - cookie-av = "Comment" "=" value - | "Domain" "=" value - | "Max-Age" "=" value - | "Path" "=" value - | "Secure" - | "Version" "=" 1*DIGIT - - - According to RFC 2616 (obsolating RFC 2068) defining HTTP 1.1, 'control characters' are - 0 to 31 and DEL (127). A 'separator' is one of: - - ( ) < > @ , ; : \ " / [ ] ? = { } 32(space) and 9(tab) " - - Now, a token is a non empty sequence of ASCII characters (0 to 127), but not including - any control character or any separator. As a consequence, characters admissible in a - 'RFC 2616 token' are: - - 33 ! - 35 to 39 # $ & ' - 42 43 * + - 45 46 - . - 48 to 57 0 ... 9 - 65 to 90 A ... Z - 94 to 122 ^ _ ` a ... z - 124 126 | ~ - -define Bool - is_token_char - ( - Word8 c - ) = - if c +< 33 then false else - if c +< 34 then true else - if c +< 35 then false else - if c +< 40 then true else - if c +< 42 then false else - if c +< 44 then true else - if c +< 45 then false else - if c +< 47 then true else - if c +< 48 then false else - if c +< 58 then true else - if c +< 65 then false else - if c +< 91 then true else - if c +< 94 then false else - if c +< 123 then true else - if c +< 124 then false else - if c = 124 then true else - c = 126. - - value char are token added of =, (, ) - -define Bool - is_value_char - ( - Word8 c - ) = - if c +< 33 then false else - if c +< 34 then true else - if c +< 35 then false else - if c +< 44 then true else - if c +< 45 then false else - if c +< 47 then true else - if c +< 48 then false else - if c +< 58 then true else - if c +< 61 then false else - if c +< 62 then true else - if c +< 65 then false else - if c +< 91 then true else - if c +< 94 then false else - if c +< 123 then true else - if c +< 124 then false else - if c = 124 then true else - c = 126. - - From the grammar, it is clear that atomic entities (called 'tokens' by YACC) are: - - - tokens (in the sens of RFC 2616) some of which have to be recognized as keywords - - quoted strings - - equal sign - - colon - - semi-colon - - Hence, the following type: - -public type Atom: - end_of_input, - error, - comment, - domain, - max_age, - path, - secure, - version, - token(String), - quoted_string(String), - equals, - colon, - semi_colon. - - -variable List(Atom) unput_atoms = []. - -define One - unput_atom - ( - Atom a - ) = - unput_atoms <- [a . *unput_atoms]. - -define Atom - recognize_keyword - ( - String s - ) = - with l = to_lower(s), - if l = "comment" then comment else - if l = "domain" then domain else - if l = "max-age" then max_age else - if l = "path" then path else - if l = "secure" then secure else - if l = "version" then version else - token(s). - - -variable String input = "". From which cookies will be read. -variable Int index = 0. Current position within 'input'. - -define Maybe(Word8) - next_char - = - if nth(*index,*input) is - { - failure then failure, - success(c) then - index <- *index+1; - success(c) - }. - -define One - unput_char - = - index <- *index-1. - -define Atom - read_token - ( - List(Word8) so_far, // contains at least 1 character - (Word8) -> Bool is_valid_char - ) = - if next_char is - { - failure then recognize_keyword(implode(reverse(so_far))), - success(c) then - if is_valid_char(c) - then read_token([c . so_far], is_valid_char) - else unput_char; recognize_keyword(implode(reverse(so_far))) - }. - -define Atom - read_quoted_string - ( - List(Word8) so_far - ) = - if next_char is - { - failure then quoted_string(implode(reverse(so_far))), - success(c) then - if c = '\"' - then quoted_string(implode(reverse(so_far))) - else read_quoted_string([c . so_far]) - }. - -define Bool - is_blank - ( - Word8 c - ) = - c +=< ' '. - - Reading an atom from the input: - -define Atom - read_atom - = - if *unput_atoms is - { - [ ] then - if next_char is - { - failure then end_of_input, - success(c) then - if is_blank(c) then read_atom else // skip blanks - if is_token_char(c) then read_token([c], is_token_char) else - if c = '\"' then read_quoted_string([]) else - if c = '=' then equals else - if c = ':' then colon else - if c = ';' then semi_colon else - error - }, - [h . t] then - unput_atoms <- t; h - }. - -define Atom - read_value - = - if *unput_atoms is - { - [ ] then - if next_char is - { - failure then end_of_input, - success(c) then - if is_blank(c) then read_value else // skip blanks - if is_value_char(c) then read_token([c], is_value_char) else - if c = '\"' then read_quoted_string([]) else - if c = ';' then semi_colon else - error - }, - [h . t] then - unput_atoms <- t; h - }. - - Reading an attribute-value pair. - -type AttrVal: - comment(String), - domain(String), - max_age(String), - path(String), - secure, - version(String). - -define String - read_eq_value - = - with e = read_atom, - if e is equals then - ( - with a = read_atom, - if a is token(n) then n else - if a is quoted_string(s) then s else - unput_atom(a); "" - ) - else unput_atom(e); "". - - -define Maybe(AttrVal) - read_attr_val - = - if read_atom is semi_colon then - with a = read_atom, - if a is - { - end_of_input then failure, - error then failure, - comment then success(comment(read_eq_value)), - domain then success(domain(read_eq_value)), - max_age then success(max_age(read_eq_value)), - path then success(path(read_eq_value)), - secure then success(secure), - version then success(version(read_eq_value)), - token(_) then unput_atom(a); failure, - quoted_string(_) then unput_atom(a); failure, - equals then unput_atom(a); failure, - colon then unput_atom(a); failure, - semi_colon then unput_atom(a); failure, - } - else failure. - - - Getting attributes from a List(AttrVal). - -define Maybe(String) - get_comment - ( - List(AttrVal) l - ) = - if l is - { - [ ] then failure, - [h . t] then if h is comment(c) - then success(c) - else get_comment(t) - }. - -define Maybe(String) - get_domain - ( - List(AttrVal) l - ) = - if l is - { - [ ] then failure, - [h . t] then if h is domain(s) - then success(s) - else get_domain(t) - }. - -define Int - get_validity - ( - List(AttrVal) l - ) = - if l is - { - [ ] then 0, - [h . t] then if h is max_age(a) - then if decimal_scan(a) is - { - failure then 0, - success(n) then n+now - } - else get_validity(t) - }. - -define Maybe(String) - get_path - ( - List(AttrVal) l - ) = - if l is - { - [ ] then failure, - [h . t] then if h is path(p) - then success(p) - else get_path(t) - }. - -define Bool - get_secure - ( - List(AttrVal) l - ) = - if l is - { - [ ] then false, - [h . t] then if h is secure - then true - else get_secure(t) - }. - -define Int - get_version - ( - List(AttrVal) l - ) = - if l is - { - [ ] then 0, - [h . t] then if h is version(v) - then if decimal_scan(v) is - { - failure then 0, - success(n) then n - } - else get_version(t) - }. - - - Reading a cookie: - -variable String server_name = "". - -define Maybe(Cookie) - read_cookie_n_e_v - ( - String name, - String value, - List(AttrVal) so_far - ) = - if read_attr_val is - { - failure then - success(cookie( - *server_name, - name, - value, - get_comment(so_far), - get_domain(so_far), - get_validity(so_far), - get_path(so_far), - get_secure(so_far), - get_version(so_far) - )), - - success(av) then read_cookie_n_e_v(name,value,[av . so_far]) - }. - -define Maybe(Cookie) - read_cookie_n_e - ( - String name - ) = - with a = read_value, - - if a is token(value) then read_cookie_n_e_v(name,value,[]) else - if a is quoted_string(value) then read_cookie_n_e_v(name,value,[]) else - unput_atom(a); failure. - -define Maybe(Cookie) - read_cookie_n - ( - String name - ) = - with a = read_atom, - if a is equals - then read_cookie_n_e(name) - else unput_atom(a); failure. - - -define Maybe(Cookie) - read_cookie - = - with a = read_atom, - if a is token(name) - then read_cookie_n(name) - else unput_atom(a); failure. - - -define List(Cookie) - read_cookies - ( - List(Cookie) so_far - ) = - if read_cookie is - { - failure then so_far, - success(c) then read_cookies([c . so_far]) - }. - - -define List(Cookie) - get_cookies - ( - String svn, - HTTP_header h - ) = - if h is http_header(n,v) then - if to_lower(n) = "set-cookie" - then ( - unput_atoms <- []; - input <- v; - index <- 0; - server_name <- svn; - read_cookies([]) - ) - else []. - -public define List(Cookie) - get_cookies - ( - String server_name, - List(HTTP_header) headers - ) = - if headers is - { - [ ] then [ ], - [h . t] then - append(get_cookies(server_name,h),get_cookies(server_name,t)) - }. - -define List(Cookie) - server_get_cookies - ( - HTTP_header h - ) = - if h is http_header(n,v) then - if to_lower(n) = "cookie" - then ( - unput_atoms <- []; - input <- v; - index <- 0; - server_name <- ""; - read_cookies([]) - ) - else []. - -public define List(Cookie) - server_get_cookies - ( - // String server_name, - List(HTTP_header) headers - ) = - if headers is - { - [ ] then [ ], - [h . t] then - append(server_get_cookies(h), server_get_cookies(t)) - }. - -public define Maybe(Cookie) - find_cookie - ( - String name, - List(Cookie) cookies - ) - = - if cookies is - { - [] then failure, - [h . t] then - if h is cookie(s, n, v, _, _, _, _, _, _) then - if name = n then success(h) - else find_cookie(name, t) - }. - -public define String - get_cookie_value - ( - String name, - List(Cookie) cookies - ) - = - if find_cookie(name, cookies) is - { - failure then "", - success(c) then if c is cookie(_, _, v, _, _, _, _, _, _) then v - }. - - *** Reformating cookies. ************************************************************** - - Cookies should be resent reformated according to the following grammar (copy-pasted - from RFC 2109): - - cookie = "Cookie:" cookie-version - 1*((";" | ",") cookie-value) - cookie-value = NAME "=" VALUE [";" path] [";" domain] - cookie-version = "$Version" "=" value - NAME = attr - VALUE = value - path = "$Path" "=" value - domain = "$Domain" "=" value - - -define HTTP_header - reformat_cookie - ( - Cookie c - ) = - if c is cookie(sn,n,v,mbc,mbd,vld,mbp,sec,ver) then - http_header("Cookie", - "$Version=" + to_decimal(ver) + - ";" + n + "=\"" + v + "\"" + - if mbp is - { - failure then "", - success(p) then ";$Path=\"" + p + "\"" - } + - if mbd is - { - failure then "", - success(d) then ";$Domain=\"" + d + "\"" - } - ). - - - According to RFC 2109, a cookie may be sent to a server if: - - (1) server name in the cookie is the name of the server, - (2) if 'Path' attribute is present, its value must match the URI, - (3) the cookie is still valid (validity = 0 means indefinitely valid). - - define Bool - path_match - ( - Maybe(String) cookie_path, - String uri - ) = - if cookie_path is - { - failure then true, - success(p) then - - }. - - - Checking if the path matches: - - -define Bool - path_match - ( - Maybe(String) mbp, - String uri - ) = - true. - - - The next function verifies if a cookie satisfies the rules. - -define Bool - may_resend_cookie - ( - String server_name, - String uri, - Cookie c - ) = - if c is cookie(sn,n,v,mbc,mbd,vld,mbp,sec,ver) then - if sn = server_name - then ( - if path_match(mbp,uri) - then ( - if vld = 0 then true else vld > now - ) - else false - ) - else false. - - - The next function reformat all cookies which satisfy the 'resend' rules. - -public define List(HTTP_header) - reformat_cookies - ( - String server_name, - String uri, - List(Cookie) cookies - ) = - if cookies is - { - [ ] then [ ], - [h . t] then - if may_resend_cookie(server_name,uri,h) - then [reformat_cookie(h) . reformat_cookies(server_name,uri,t)] - else reformat_cookies(server_name,uri,t) - }. - - - - - - See test_cookies.anubis for a test of this program. - - - - - - - - - + + *Project* The Anubis Project + + *Title* Managing Cookies. + + *Copyright* Copyright (c) Alain Prouté 2001. + + + *Author* Alain Prouté + + + + +read tools/basis.anubis +read system/string.anubis +read CXM_common.anubis +read CXM_http_get_common.anubis + + + *Overview* + Cookies are defined in RFC 2109. Here is the corresponding Anubis type: + + Each cookie has an server name (the name of the server who constructed the cookie), a + name, a value, and several attributes. + +public type Cookie: + cookie(String server_name, // of the server who sent the cookie + String name, // of the cookie + String value, // of the cookie + // attributes: + Maybe(String) comment, // cookies may have human readable comments + Maybe(String) domain, // domain name as sent by the server + Int validity, // cookie still valid if this is > now + Maybe(String) path, // server path for which the cookie is valid + Bool secure, // if true, do not send this cookie over an insecure link + Int version). // Cookie version (normally 1: rfc 2109) + + + Cookies are sent by servers through 'Set-Cookie' HTTP headers. The function + 'get_cookies' retrieves a list of cookies from a list of HTTP headers. + +public define List(Cookie) + get_cookies + ( + String server_name, // name of server who sent the cookies + List(HTTP_header) headers // HTTP headers sent by this server + ). + +public define Maybe(Cookie) + find_cookie + ( + String name, + List(Cookie) cookies + ). + + + + + + Normally, this function is used on the list of HTTP headers returned by either + 'http_get' of 'https_get'. + + + Before they can be sent back to their origin server, cookies must be reformated, in + order to produce 'Cookie' HTTP headers: + +public define List(HTTP_header) + reformat_cookies + ( + String server_name, + String uri, + List(Cookie) cookies + ). + + The result of 'reformat_cookies' may be appended to the list of headers given as + argument to 'http_get' or to 'https_get'. + + In the meantime, you may examine and maybe discard cookies, you may 'save' them into a + file, and 'retrieve' them later. + + + + + ------- That all for the public part. ------------------------------------------------- + + + Here is the syntax of a 'Set-Cookie' header (according to RFC 2109): + + set-cookie = "Set-Cookie:" cookies + cookies = 1#cookie + cookie = NAME "=" VALUE *(";" cookie-av) + NAME = token + VALUE = value + value = token | quoted-string + cookie-av = "Comment" "=" value + | "Domain" "=" value + | "Max-Age" "=" value + | "Path" "=" value + | "Secure" + | "Version" "=" 1*DIGIT + + + According to RFC 2616 (obsolating RFC 2068) defining HTTP 1.1, 'control characters' are + 0 to 31 and DEL (127). A 'separator' is one of: + + ( ) < > @ , ; : \ " / [ ] ? = { } 32(space) and 9(tab) " + + Now, a token is a non empty sequence of ASCII characters (0 to 127), but not including + any control character or any separator. As a consequence, characters admissible in a + 'RFC 2616 token' are: + + 33 ! + 35 to 39 # $ & ' + 42 43 * + + 45 46 - . + 48 to 57 0 ... 9 + 65 to 90 A ... Z + 94 to 122 ^ _ ` a ... z + 124 126 | ~ + +define Bool + is_token_char + ( + Word8 c + ) = + if c +< 33 then false else + if c +< 34 then true else + if c +< 35 then false else + if c +< 40 then true else + if c +< 42 then false else + if c +< 44 then true else + if c +< 45 then false else + if c +< 47 then true else + if c +< 48 then false else + if c +< 58 then true else + if c +< 65 then false else + if c +< 91 then true else + if c +< 94 then false else + if c +< 123 then true else + if c +< 124 then false else + if c = 124 then true else + c = 126. + + value char are token added of =, (, ) + +define Bool + is_value_char + ( + Word8 c + ) = + if c +< 33 then false else + if c +< 34 then true else + if c +< 35 then false else + if c +< 44 then true else + if c +< 45 then false else + if c +< 47 then true else + if c +< 48 then false else + if c +< 58 then true else + if c +< 61 then false else + if c +< 62 then true else + if c +< 65 then false else + if c +< 91 then true else + if c +< 94 then false else + if c +< 123 then true else + if c +< 124 then false else + if c = 124 then true else + c = 126. + + From the grammar, it is clear that atomic entities (called 'tokens' by YACC) are: + + - tokens (in the sens of RFC 2616) some of which have to be recognized as keywords + - quoted strings + - equal sign + - colon + - semi-colon + + Hence, the following type: + +public type Atom: + end_of_input, + error, + comment, + domain, + max_age, + path, + secure, + version, + token(String), + quoted_string(String), + equals, + colon, + semi_colon. + + +variable List(Atom) unput_atoms = []. + +define One + unput_atom + ( + Atom a + ) = + unput_atoms <- [a . *unput_atoms]. + +define Atom + recognize_keyword + ( + String s + ) = + with l = to_lower(s), + if l = "comment" then comment else + if l = "domain" then domain else + if l = "max-age" then max_age else + if l = "path" then path else + if l = "secure" then secure else + if l = "version" then version else + token(s). + + +variable String input = "". From which cookies will be read. +variable Int index = 0. Current position within 'input'. + +define Maybe(Word8) + next_char + = + if nth(*index,*input) is + { + failure then failure, + success(c) then + index <- *index+1; + success(c) + }. + +define One + unput_char + = + index <- *index-1. + +define Atom + read_token + ( + List(Word8) so_far, // contains at least 1 character + (Word8) -> Bool is_valid_char + ) = + if next_char is + { + failure then recognize_keyword(implode(reverse(so_far))), + success(c) then + if is_valid_char(c) + then read_token([c . so_far], is_valid_char) + else unput_char; recognize_keyword(implode(reverse(so_far))) + }. + +define Atom + read_quoted_string + ( + List(Word8) so_far + ) = + if next_char is + { + failure then quoted_string(implode(reverse(so_far))), + success(c) then + if c = '\"' + then quoted_string(implode(reverse(so_far))) + else read_quoted_string([c . so_far]) + }. + +define Bool + is_blank + ( + Word8 c + ) = + c +=< ' '. + + Reading an atom from the input: + +define Atom + read_atom + = + if *unput_atoms is + { + [ ] then + if next_char is + { + failure then end_of_input, + success(c) then + if is_blank(c) then read_atom else // skip blanks + if is_token_char(c) then read_token([c], is_token_char) else + if c = '\"' then read_quoted_string([]) else + if c = '=' then equals else + if c = ':' then colon else + if c = ';' then semi_colon else + error + }, + [h . t] then + unput_atoms <- t; h + }. + +define Atom + read_value + = + if *unput_atoms is + { + [ ] then + if next_char is + { + failure then end_of_input, + success(c) then + if is_blank(c) then read_value else // skip blanks + if is_value_char(c) then read_token([c], is_value_char) else + if c = '\"' then read_quoted_string([]) else + if c = ';' then semi_colon else + error + }, + [h . t] then + unput_atoms <- t; h + }. + + Reading an attribute-value pair. + +type AttrVal: + comment(String), + domain(String), + max_age(String), + path(String), + secure, + version(String). + +define String + read_eq_value + = + with e = read_atom, + if e is equals then + ( + with a = read_atom, + if a is token(n) then n else + if a is quoted_string(s) then s else + unput_atom(a); "" + ) + else unput_atom(e); "". + + +define Maybe(AttrVal) + read_attr_val + = + if read_atom is semi_colon then + with a = read_atom, + if a is + { + end_of_input then failure, + error then failure, + comment then success(comment(read_eq_value)), + domain then success(domain(read_eq_value)), + max_age then success(max_age(read_eq_value)), + path then success(path(read_eq_value)), + secure then success(secure), + version then success(version(read_eq_value)), + token(_) then unput_atom(a); failure, + quoted_string(_) then unput_atom(a); failure, + equals then unput_atom(a); failure, + colon then unput_atom(a); failure, + semi_colon then unput_atom(a); failure, + } + else failure. + + + Getting attributes from a List(AttrVal). + +define Maybe(String) + get_comment + ( + List(AttrVal) l + ) = + if l is + { + [ ] then failure, + [h . t] then if h is comment(c) + then success(c) + else get_comment(t) + }. + +define Maybe(String) + get_domain + ( + List(AttrVal) l + ) = + if l is + { + [ ] then failure, + [h . t] then if h is domain(s) + then success(s) + else get_domain(t) + }. + +define Int + get_validity + ( + List(AttrVal) l + ) = + if l is + { + [ ] then 0, + [h . t] then if h is max_age(a) + then if decimal_scan(a) is + { + failure then 0, + success(n) then n+now + } + else get_validity(t) + }. + +define Maybe(String) + get_path + ( + List(AttrVal) l + ) = + if l is + { + [ ] then failure, + [h . t] then if h is path(p) + then success(p) + else get_path(t) + }. + +define Bool + get_secure + ( + List(AttrVal) l + ) = + if l is + { + [ ] then false, + [h . t] then if h is secure + then true + else get_secure(t) + }. + +define Int + get_version + ( + List(AttrVal) l + ) = + if l is + { + [ ] then 0, + [h . t] then if h is version(v) + then if decimal_scan(v) is + { + failure then 0, + success(n) then n + } + else get_version(t) + }. + + + Reading a cookie: + +variable String server_name = "". + +define Maybe(Cookie) + read_cookie_n_e_v + ( + String name, + String value, + List(AttrVal) so_far + ) = + if read_attr_val is + { + failure then + success(cookie( + *server_name, + name, + value, + get_comment(so_far), + get_domain(so_far), + get_validity(so_far), + get_path(so_far), + get_secure(so_far), + get_version(so_far) + )), + + success(av) then read_cookie_n_e_v(name,value,[av . so_far]) + }. + +define Maybe(Cookie) + read_cookie_n_e + ( + String name + ) = + with a = read_value, + + if a is token(value) then read_cookie_n_e_v(name,value,[]) else + if a is quoted_string(value) then read_cookie_n_e_v(name,value,[]) else + unput_atom(a); failure. + +define Maybe(Cookie) + read_cookie_n + ( + String name + ) = + with a = read_atom, + if a is equals + then read_cookie_n_e(name) + else unput_atom(a); failure. + + +define Maybe(Cookie) + read_cookie + = + with a = read_atom, + if a is token(name) + then read_cookie_n(name) + else unput_atom(a); failure. + + +define List(Cookie) + read_cookies + ( + List(Cookie) so_far + ) = + if read_cookie is + { + failure then so_far, + success(c) then read_cookies([c . so_far]) + }. + + +define List(Cookie) + get_cookies + ( + String svn, + HTTP_header h + ) = + if h is http_header(n,v) then + if to_lower(n) = "set-cookie" + then ( + unput_atoms <- []; + input <- v; + index <- 0; + server_name <- svn; + read_cookies([]) + ) + else []. + +public define List(Cookie) + get_cookies + ( + String server_name, + List(HTTP_header) headers + ) = + if headers is + { + [ ] then [ ], + [h . t] then + append(get_cookies(server_name,h),get_cookies(server_name,t)) + }. + +define List(Cookie) + server_get_cookies + ( + HTTP_header h + ) = + if h is http_header(n,v) then + if to_lower(n) = "cookie" + then ( + unput_atoms <- []; + input <- v; + index <- 0; + server_name <- ""; + read_cookies([]) + ) + else []. + +public define List(Cookie) + server_get_cookies + ( + // String server_name, + List(HTTP_header) headers + ) = + if headers is + { + [ ] then [ ], + [h . t] then + append(server_get_cookies(h), server_get_cookies(t)) + }. + +public define Maybe(Cookie) + find_cookie + ( + String name, + List(Cookie) cookies + ) + = + if cookies is + { + [] then failure, + [h . t] then + if h is cookie(s, n, v, _, _, _, _, _, _) then + if name = n then success(h) + else find_cookie(name, t) + }. + +public define String + get_cookie_value + ( + String name, + List(Cookie) cookies + ) + = + if find_cookie(name, cookies) is + { + failure then "", + success(c) then if c is cookie(_, _, v, _, _, _, _, _, _) then v + }. + + *** Reformating cookies. ************************************************************** + + Cookies should be resent reformated according to the following grammar (copy-pasted + from RFC 2109): + + cookie = "Cookie:" cookie-version + 1*((";" | ",") cookie-value) + cookie-value = NAME "=" VALUE [";" path] [";" domain] + cookie-version = "$Version" "=" value + NAME = attr + VALUE = value + path = "$Path" "=" value + domain = "$Domain" "=" value + + +define HTTP_header + reformat_cookie + ( + Cookie c + ) = + if c is cookie(sn,n,v,mbc,mbd,vld,mbp,sec,ver) then + http_header("Cookie", + "$Version=" + to_decimal(ver) + + ";" + n + "=\"" + v + "\"" + + if mbp is + { + failure then "", + success(p) then ";$Path=\"" + p + "\"" + } + + if mbd is + { + failure then "", + success(d) then ";$Domain=\"" + d + "\"" + } + ). + + + According to RFC 2109, a cookie may be sent to a server if: + + (1) server name in the cookie is the name of the server, + (2) if 'Path' attribute is present, its value must match the URI, + (3) the cookie is still valid (validity = 0 means indefinitely valid). + + define Bool + path_match + ( + Maybe(String) cookie_path, + String uri + ) = + if cookie_path is + { + failure then true, + success(p) then + + }. + + + Checking if the path matches: + + +define Bool + path_match + ( + Maybe(String) mbp, + String uri + ) = + true. + + + The next function verifies if a cookie satisfies the rules. + +define Bool + may_resend_cookie + ( + String server_name, + String uri, + Cookie c + ) = + if c is cookie(sn,n,v,mbc,mbd,vld,mbp,sec,ver) then + if sn = server_name + then ( + if path_match(mbp,uri) + then ( + if vld = 0 then true else vld > now + ) + else false + ) + else false. + + + The next function reformat all cookies which satisfy the 'resend' rules. + +public define List(HTTP_header) + reformat_cookies + ( + String server_name, + String uri, + List(Cookie) cookies + ) = + if cookies is + { + [ ] then [ ], + [h . t] then + if may_resend_cookie(server_name,uri,h) + then [reformat_cookie(h) . reformat_cookies(server_name,uri,t)] + else reformat_cookies(server_name,uri,t) + }. + + + + + + See test_cookies.anubis for a test of this program. + + + + + + + + + diff --git a/web/CXM_html.anubis b/web/CXM_html.anubis deleted file mode 100644 index 0ad8cdc..0000000 --- a/web/CXM_html.anubis +++ /dev/null @@ -1,2395 +0,0 @@ - - *Project* The Anubis Project - *Title* Producing HTML/Javascript code. - - *Copyright* Copyright (c) Alain Prouté 2001. - -read tools/basis.anubis -read system/string.anubis -read tools/printable_tree.anubis - - - *** Managing Web Arguments. - - When a client submits a form, he sends informations to the server. This information is - transformed by the server into a list of data of type 'Web_arg'. This is the reason why - a 'web page' operation always has a unique argument of type 'List(Web_arg)'. - - The type 'Web_arg' is defined in 'web/common.anubis' as follows: - - public type Web_arg: - web_arg(String name, - String value), - upload (String name, - String value, - String temp_file_path). - -read CXM_common.anubis - - In other words, a 'web argument' is just a pair made of the name of the argument, and - the value of the argument, and both are character strings. 'upload' will be explained - later. - - - The next variable is a multipurpose counter (used to generate unique names). - -variable Int web_count = 0. - -define Int - new_web_count - = - web_count <- *web_count+1; - *web_count. - - - Names for Web colors. - -public type Web_color_name: - aliceblue, - antiquewhite1, - antiquewhite2, - antiquewhite3, - antiquewhite4, - aquamarine1, - aquamarine2, - aquamarine3, - aquamarine4, - azure1, - azure2, - azure3, - azure4, - yellow. - - - and so on ... (see below why I did not do more). - - - - Web colors. - -public type Web_color: - rgb(Word8,Word8,Word8), /* give the color by its components */ - _(Web_color_name). /* or by its name */ - - - - - The following produces '' tags, which are put in the head of the document. - -public type WebMeta: - keywords(List(String)), - refresh(String url, Int delay), // in seconds - meta(String name, String content), - http_equiv(String name, String content). - - - - - - ******************************************************* - * Web items * - * (the many kinds of things one may put in a page) * - ******************************************************* - - -public type Web_item: - [ ], /* empty (invisible) item */ - ... this is a cross recursive type. - - - - - Options for web page body. - -public type LayerDisposition: - horizontal, - vertical. - -public type FollowPathCommand: // this type is used by the Web_body_option 'follow_path'. - pos(Int x, // x coordinate of position - Int y, // y coordinate of position - Int image_number, // the image to display at that position - Int delay). // wait that milliseconds before leaving this position - -public type Web_body_option: - background_color(Web_color), /* color for the background */ - // - // 'psychedelic_background' produces a background color which is continuously changing. - // 'average' is the average luminosity of the color. 'amplitude' is the maximal variation - // the luminosity around the average. 'delay' is the number of milliseconds between two - // color changes. For example, you may try 'psychedelic_background(200,50,1000)', which - // produces a background whose color changes very slowly (this is not tiring) among rather - // light pastel colors. - // - psychedelic_background(Int average, /* average light (0 to 255) */ - Int amplitude, /* amplitude of variation of light */ - Int delay), /* in milliseconds */ - background_image(String file_name), /* name of image file for the background */ - // - // 'scrolling_layer' produces a layer above the page which is scrolling continuously either - // vertically or horizontally. The 'content' is indefinitly repeated. - // - scrolling_layer(LayerDisposition, - Int steps, /* number of pixels of each move */ - Int margin, /* measured from left or top in pixels */ - Int delay, /* milliseconds for one move */ - Web_item content, /* content of layer (will be repeated) */ - Int period), /* number of pixels between two instances of 'content' */ - // - // 'bounce' shows its content above the page and let it move and bounce on the edges of a rectangle. - // The rectangle is determined by the last 4 arguments. - // - bounce(Web_item content, - Int left, - Int right, - Int top, - Int bottom), - // - // put something over the page in any position you want: - // - over(Web_item content, - Int left, - Int top), - // - // follow_path: let a changing image follow a path on the screen. This gadget shows - // an image following a polygonal path on the screen. The image may change at regular - // intervals, thus providing extra animation. The images are displayed in the order - // they are given in the first argument. When the last image has been displayed, the - // first image is displayed again, and so on. The path is a sequence of absolute positions - // on screen (actually in the browser's window or frame), which is followed in the - // order given in the 'path' argument. If 'loop' is true, the path is followed again and again. - // Otherwise, it is followed only once. If you want to make a closed loop, the last - // position must be the same as the first one. 'steps' is the number of pixels of distance - // between two successive positions of the image, and 'delay' the number of milliseconds - // between two successive positions. 'change_every' is the number of steps (a 'step' is - // passing from one position to the next one) after which the displayed image is replaced - // by the next image. - // - // Each position 'pos(x,y,i,d)' has 4 parameters. 'x' and 'y' are the coordinates of the - // position in the browser's window or frame. 'i' is the number of the image to display - // at this position (i.e. the rank of the image in the list 'filename'. The first one has - // rank 0). 'd' is the delay in milliseconds to wait before leaving that position. - // - follow_path(List(String) filenames, /* the changing images which follows the path */ - Int change_every, /* number of steps betwen two changes */ - List(FollowPathCommand) path, /* the polygonal path and commands */ - Bool loop, /* if true do it repeatedly, otherwise only once */ - Int steps, /* approximative distance (in pixels) between two - successive positions */ - Int delay), /* milliseconds between two successive positions */ - - load_image(String name), /* load an image (for next page), which is not displayed */ - left_margin(Int), /* left margin for document */ - top_margin(Int), /* top margin for document */ - margin_width(Int), - margin_height(Int), - reload_frame(String name, /* name of target frame */ - String url), /* url to load in this frame */ - onload(String function_name). /* nom de la fonction javascript (sans les '()') */ - -public type BodyOnload: - reload_frame(String name, String url). - -variable List(BodyOnload) body_onloads = [ ]. - -define One - add_body_onload - ( - BodyOnload item - ) = - body_onloads <- [item . *body_onloads]. - -define Printable_tree - format - ( - BodyOnload item - ) = - if item is - { - reload_frame(name,url) then (Printable_tree) - [ " window.open('",url,"','",name,"');" ] - }. - -define Printable_tree - format - ( - List(BodyOnload) l - ) = - if l is - { - [ ] then (Printable_tree)[ ], - [h . t] then (Printable_tree) - [format(h) . format(t)] - }. - - ----- Body of a web page. -------------------------------------------- -public type Page_body: - body(List(Web_body_option), /* list of body options */ - Web_item content). /* the content of the page */ - - -public type VFrame: - frame(Int height, - Printable_tree url, - String name). - ----- Web pages. ----------------------------------------------------- -public type Web_page: - web_page(String title, /* title appearing on top of browser */ - List(WebMeta) meta_tags, - Printable_tree head_scripts, /* scripts à placer dans la balise head */ - Page_body body), /* body of page */ - standard_frameset(String title, - List(WebMeta) meta_tags, - Int height, /* height of 'top menu' (pixels) */ - Int width, /* width of 'left menu' (pixels) */ - Printable_tree main). /* url for main */ - - +---------+--------------------------+ - | | ^ | - |<-width->| top height | - | | v | - | left +--------------------------+ - | | | - | | main | - | | | - | | | - | | | - +---------+--------------------------+ - - Note: top and left frames must be loaded through the Web_body_option 'reload_frame'. - - -public define Web_page - web_page - ( - String title, - Page_body body - ) = - web_page(title,[],[], body). - -public define Web_page - web_page - ( - String title, - List(WebMeta) meta_tags, - Page_body body - ) = - - web_page(title, meta_tags, [], body). - - public define Web_page -web_page - ( - String title, - Printable_tree head_scripts, - Page_body body - ) = - - web_page(title, [], head_scripts, body). - -public define Web_page -standard_frameset - ( - String title, - Int height, - Int width, - Printable_tree main - ) = - - standard_frameset(title, [], height, width, main). - - -variable Printable_tree scripts = []. - -define One - add_script - ( - Printable_tree script - ) = - scripts <- [*scripts . script]. - - - - ---- Non empty web items. ------------------------------------------- - - We have already seen the empty web item. Together with the following one, it enables to - make (pseudo-)lists of web items, which will be presented one after the other (from - left to right) in the browser's window. - -public type Web_item: - [Web_item . Web_item],... - - - A web item may be a simple string or a simple integer: - -public type Web_item: - text(String), - text_pt(Printable_tree), - text_nowrap(String), - text_nowrap_pt(Printable_tree), - par(String), - preformated_text(String text), - integer(Int), - float(Float,Int),... - - - You may want to center a web item in a page. Just enclose it into - 'center(...)': - -public type Web_item: - center(Web_item),... - - - You may want to write characters of a given item with a big font: - -public type Web_item: - bigger(Int,Web_item), - smaller(Int,Web_item), - bold(Web_item), - italic(Web_item), - big(Web_item), - very_big(Web_item),... - - - Most of the previous are subsumed by 'style': - -public type WebStyle: - background_image(String file_name), - background_color(Web_color color), - background_transparent, - background_repeat_horizontal, // repeat the background image only horizontally - background_repeat_vertical, - background_no_repeat, - color(Web_color color), - float_to_left, // the web item will float to the left and text will wrap around - float_to_right, - font_family(String font_name), // "verdana" "helvetica" "times" etc... - font_size(Int size), - italic, - oblique, - small_capitals, - bold, - bolder, - lighter, - line_height(Int height), - text_center, - text_left, - text_right, - text_justify, - text_underline, - text_blink, - text_line_through, - width(Int n). - - - -public type Web_item: - style(List(WebStyle) styles, Web_item content),... - - -public type Web_item: - spacer(Int width, Int height), - image(String file_name), /* image */ - image_d(String file_name, String description), - image_pt(Printable_tree file_name), - on_image(String file_name, Web_item content), - turning_images(NonEmptyList(String) filenames, Int millisecs),... - - - - A 'rollover' has the same role as a submit button or link, but it is prettier. It is - made of two images. The first one 'image_on' determines the aspect of the button when - the mouse cursor is on it. The other one 'image_off' determines the aspect of the - button when the mouse cursor is anywhere else. The two images should be of the same - size, otherwise bad effects may occur. The last operand 'description' is a small text - which describes the role of the button. It appears in a bubble in the browser's window. - -public type Web_item: - rollover(List(String) preload_images, // images to preload before the rollover is effective - String url, // URL with possible web arguments - String target, - String image_on, // file name of 'highlighted' image - String image_off, // file name of 'non highlighted' image - String description), // short behavior description - rollover(List(String) preload_images, - String url, - String target, - String image_on, - String image_off, - Int width, - Int height, - String description), ... - - - Mouse sensitive images are images with predefined zones which are clickable. When - clicking in a zone, the specified corresponding URL is loaded by the browser. If two - zones overlap, the first one (in the order they are defined) is selected. - - Zones are of 3 sorts: rectangles, circles and polygons. Point's coordinates are - specified as pairs of integers (of anonymous agglomeration type (Int,Int)). The - first coordinate counts pixels from the left of the image. The second coordinate counts - pixels from the top of the image. With polygons, you can construct zones which are - almost as complicated as you want. You may also construct a zone as the overlapping of - several zones with the same URL. - -public type Mouse_Sensitive_Zone: - rectangle - ( - (Int,Int) left_top, - (Int,Int) right_bottom, - String url - ), - circle - ( - (Int,Int) center, - Int radius, - String url - ), - polygon - ( - List((Int,Int)) vertices, - String url - ). - -public type Web_item: - mouse_sensitive_image(String image_file_name, // the image itself - List(Mouse_Sensitive_Zone) zones),... - - - In project: mouse sensitive images, whose zones behave like submission buttons (to be - used within a form). - - -public type Web_item: - background_sound(String sound_file_name, - Bool loop),... - - - - ************************* - * FORMS * - ************************* - - - Use 'forms' in order to get informations back from the client. The constructor 'form' - take 2 arguments: - - - the name of the form, which must be the name of an Anubis web - page. Indeed, when the user will submit the form, this page will - be sent to him. - - the content of the form, which may be any web item, but which - normally (amongh other things) contains input fields and a - submit button. - -public type Web_item: - form(Printable_tree name, - Web_item content), - form_target(Printable_tree name, - Web_item content, - String target), - form(Printable_tree name, - String label_name, - Web_item content), - form_name(String form_name, // option name de form - Web_item content),... - - public define Web_item -form - ( - Printable_tree name, - Web_item content - ) = - - form("", name, content). - - Within a form, you may put 'text input fields', that the client may - edit. The constructor 'text_input' has the following arguments: - - - name of input field. This will be the name of the correponding - web argument in the Anubis web page referred to by the form. - - size of field (as it appears on client screen), - - initial value of field (the text that appears in the field, when - the client downloads the page). - - - public type Text_Input_Option - -public type Web_item: - text_input(String name, /* text field to be documented by user */ - Int size, - String initial_value),... - - public define Web_item - text_input - ( - String name, - Int size, - String initial_value - ) = - - - text_input( (List(Text_Input_Option)) [], name, size, initial_value). - - -public type Web_item: - password_input(String name, - Int size), - text_area(String name, - Int columns, - Int rows, - String initial_text), - upload(String name, Int size),... - - - - -public type Web_item: - submit(String button_text), /* submit button with text on it */ - submit_pt(Printable_tree button_text), - submit(String name, String text), - submit_close(String name, String text), - submit_pt2(String name, Printable_tree text), - image_submit(String name, String image_file_name), - image_submit(String name, String value, String image_file, Web_item content), - hl_image_submit(String action_name, - String value, - String image_name, - String image_file, - String hl_image_file), - text_submit(String name, String value, String text), - web_submit(String web_args, Web_item content), - button(String name, String text, String on_click_fonction, Int width, Int height),... - - -public type Web_item: /* mark the form with an information */ - mark(String name, String value), - mark_pt(String name, Printable_tree value),... - -public type Web_item: - close_button, /* button that closes the window */ - close_button(String image_file_name), ... - - - - ********************************* - * LABELS * - ********************************* - - - A 'label' is just a name that you may give to a position in a document. Use the - following invisible Web_item 'label' to this end. Now, you can also create links in - the same document, which, when clicked by the user, scroll the document, so that the - position whose name is the given label is shown just at the top of the browser's - window. - -public type Web_item: - label(String label_name), /* give a name to a position in the page */ - go_to_label(String label_name, /* a link for jumping to a label */ - Web_item content),... - - - - ******************************** - * TABLES * - ******************************** - - - A web item may be a table. A table is produced by the constructor - 'table' from the type 'Web_item'. This constructor takes 2 - arguments: - - - a list of 'table options', - - a list of 'table rows'. - - Of course, you use as many options as you want, including - none (if you do not want any option, put the empty list '[ ]' as - this argument). Some options have precedence over others. For example - a background image will hide the background color. - - Table options are defined below: - -public type Table_option: - - /* use a color as a background for the table, if you want it to - be different from the background of the page */ - background_color(Web_color), - - /* or use an image as the background of the table */ - background_image(String file_name), - - /* draw a border line around the table (and around each cell in - the table). You may also specify a geometry (in pixels) for the - border. This makes the 'in relief' part of the border appear - more or less wide. You may also specify a color for the border. */ - border, - nude, /* equivalent to 'border(0,0,0)' (below) */ - border(Int, /* width of exterior (pixels) */ - Int, /* width of top */ - Int), /* width of interior */ - border_color(Web_color), - absolute_width(Int). - - - - A 'table row' is made of a list of 'row options', and a list of - 'cells'. A 'cell' itself has a list of 'cell options', and a web item, - which is its content. We begin by the description of options. - - -public type Row_option: - /* following concerns the horizontal positions of items within the - cells of the row */ - left, - h_center, - right, - /* the following concerns the vertical positions of items, within - the cells of the row */ - top, - v_center, - bottom, - absolute_height(Int), - base_line, - /* set the background color of all cells in the row */ - background_color(Web_color). - - - -public type Cell_option: - /* all row options are available for individual cells, and apply - here only to one cell. */ - left, - h_center, - right, - top, - v_center, - bottom, - base_line, - background_color(Web_color), - /* you can set the width of the cell either absolutely (in pixels) - or as a percentage of the width of the table. */ - background_image(String file_name), - absolute_width(Int), - relative_width(Int), - absolute_height(Int), - relative_height(Int), - /* a cell may span over several columns or rows in the table */ - columns(Int), - rows(Int), - nowrap. - - -public type Cell: - cell(List(Cell_option), - Web_item). - -public type Table_row: - row(List(Row_option), - List(Cell)). - -public define Table_row row(Web_item i) = row([],[cell([],i)]). -public define Table_row row(Cell c) = row([],[c]). -public define Table_row row(List(Cell) l) = row([],l). - - -public type Web_item: - table(List(Table_option), - List(Table_row)),... - -public type Web_item: - list(List(Web_item)),... - -public type Web_item: - link(String name, Web_item), - link(String name, String target, Web_item),... - -public type Web_item: - link_for_download(String filename, Web_item),... // the filename is relative to the public directory - -public type Web_item: - mail_to(String addr, Web_item),... - - -public type Web_item: - select(String name, - Int size, - List(String) choices), - select(String name, - Int size, - List(String) choices, - String selected), - immediate_select(String name, // selection will immediately submit the form - Int size, - List(String) choices),... - - -public type Web_item: - radio_button (Printable_tree name, String value), - checked_radio_button (Printable_tree name, String value), - check_box (Printable_tree name, String value), - checked_box (Printable_tree name, String value),... - - -public type Web_item: - link_to_window(Printable_tree name, Web_item), - link_to_window(Printable_tree name, String window_name, Web_item), - link_to_window_with_ticket(String name, - String web_args, - String window_name, - Web_item content, - Int width, - Int height), - link_to_window_with_ticket_and_scroll - (String name, - String web_args, - String window_name, - Web_item content, - Int width, - Int height), - link_to_window_with_ticket_and_scroll - (String name, - String label_name, - String web_args, - String window_name, - Web_item content, - Int width, - Int height), - link_to_frame (Printable_tree name, String frame_name, Web_item). - - - ----- Formating operations (Anubis --> HTML/Javascript) --------------------------- - - Stupid operation formating a web color name. - -public define String - format - ( - Web_color_name n - ) = - if n is - { - aliceblue then "aliceblue", - antiquewhite1 then "antiquewhite1", - antiquewhite2 then "antiquewhite2", - antiquewhite3 then "antiquewhite3", - antiquewhite4 then "antiquewhite4", - aquamarine1 then "aquamarine1", - aquamarine2 then "aquamarine2", - aquamarine3 then "aquamarine3", - aquamarine4 then "aquamarine4", - azure1 then "azure1", - azure2 then "azure2", - azure3 then "azure3", - azure4 then "azure4", - yellow then "yellow", - }. - - Anubis really needs some system of 'macros' to avoid this... - - - Formating a web color. - -public define String - format - ( - Web_color wc - ) = - if wc is - { - rgb(r,g,b) then "\"#" + to_hexa(r) + to_hexa(g) + to_hexa(b) + "\"", - _(c) then format(c) - }. - -public define String - format_without_quotes - ( - Web_color wc - ) = - if wc is - { - rgb(r,g,b) then "#" + to_hexa(r) + to_hexa(g) + to_hexa(b) + "", - _(c) then format(c) - }. - -define Printable_tree - format - ( - Web_color c - ) = [(String)format(c)]. - -public define String - format_without_sharp - ( - Web_color wc - ) = - if wc is - { - rgb(r,g,b) then "" + to_hexa(r) + to_hexa(g) + to_hexa(b) + "", - _(c) then format(c) - }. - -define Printable_tree - format_without_sharp - ( - Web_color c - ) = [(String)format_without_sharp(c)]. - - - define Printable_tree - [Word32 x . Printable_tree t] - = - [to_Int(x) . t]. - -define Printable_tree - psychedelic_bg - ( - Int average, - Int amplitude, - Int delay - ) = - with ampl = if amplitude >= 120 then 120 else - if amplitude =< 1 then 1 else amplitude, - with aver = if average+ampl >= 254 then 254-ampl - else if average-ampl =< 1 then 1+ampl else average, - [ ""]. - - -define List(Web_body_option) - replace_background_init - ( - List(Web_body_option) l, - Int average, - Int amplitude, - Int delay - ) = - if l is - { - [ ] then [ ], - [h . t] then - if h is background_color(_) - then [background_color(rgb(truncate_to_Word8(average+amplitude), - truncate_to_Word8(average), - truncate_to_Word8(average-amplitude))) - . replace_background_init(t,average,amplitude,delay)] - else [h . replace_background_init(t,average,amplitude,delay)] - }. - -define Maybe((Int,Int,Int)) - get_psy - ( - List(Web_body_option) l - ) = - if l is - { - [ ] then failure, - [h . t] then - if h is psychedelic_background(a,f,d) - then success((a,f,d)) - else get_psy(t) - }. - -define List(Web_body_option) - prepare - ( - List(Web_body_option) l - ) = - if get_psy(l) is - { - failure then l, - success(op) then if op is (a,f,d) then - replace_background_init(l,a,f,d) - }. - - -public define Printable_tree - format - ( - String c_ticket, - String s_ticket, - Web_item i - ). - -define Printable_tree - move_layer_command - ( - String property, - Int n, - Int num, - Int i, - Int period - ) = - if i >= num then [ ] else - [" if (document.layers)", - " { document.nslay",n,"_",i,".",property,"=layp",n,"+(",((i-1)),"); } ", - " else ", - " { ielay",n,"_",i,".style.",property,"=layp",n,"+(",(i-1)*period,"); } " - . move_layer_command(property,n,num,i+1,period)]. - -define Printable_tree - format_layers - ( - LayerDisposition disp, - Int margin, - Web_item content, - Int n, - Int num, - Int i, - Int period - ) = - if i >= num then [ ] else - ["", - "
", - format("","",content), - "
" . format_layers(disp,margin,content,n,num,i+1,period)]. - -define Printable_tree - s_layer - ( - LayerDisposition disp, - Int steps, - Int margin, - Int delay, - Web_item content, - Int period, - Int num - ) = - with n = new_web_count, - [ "", - format_layers(disp,margin,content,n,num,0,period), - ]. - - -define Printable_tree - over - ( - Web_item i, - Int left, - Int top - ) = - with n = new_web_count, - [ "", - "
", - format("","",i), - "
" - ]. - -define Printable_tree - bnce - ( - Web_item i, - Int left, - Int right, - Int top, - Int bottom - ) = - with n = new_web_count, - [ "", - "", - "
", - format("","",i), - "
" - ]. - - -define Printable_tree - folp_switch - ( - Int n, - Int i, - List(FollowPathCommand) path, - Bool loop, - Int steps - ) = - if path is - { - [ ] then [ ], - [p0 . t0] then if p0 is pos(x0,y0,i0,d0) then - if t0 is - { - [ ] then if loop - then [" default: ", - " folpx",n,"=",x0,"; folpy",n,"=",y0,"; ", - " folpseg",n,"=0; ", - " folpwait",n,"=",d0,";", - " if(document.layers)", - " document.nslay",n,".document.folpim",n,".src=folpimages",n,"[",i0,"].src;", - " else document.folpim",n,".src=folpimages",n,"[",i0,"].src;", - " folpstpmax",n," = 0;", - " folpstp",n,"=0;", - " folpdx",n,"=0; ", - " folpdy",n,"=0; ", - " break;"] - else [" default: folpend",n,"=1; break; "], - [p1 . t1] then if p1 is pos(x1,y1,i1,d1) then - [ " case ",i,": ", - " folpx",n,"=",x0,"; folpy",n,"=",y0,"; ", - " folpseg",n,"=",i+1,"; ", - " folpwait",n,"=",d0,";", - " if(document.layers)", - " document.nslay",n,".document.folpim",n,".src=folpimages",n,"[",i0,"].src;", - " else document.folpim",n,".src=folpimages",n,"[",i0,"].src;", - " folpstpmax",n," = ", - "Math.round(Math.sqrt(Math.pow(",x1,"-",x0,",2)+Math.pow(",y1,"-",y0,",2))/",steps,");", - " folpstp",n,"=0;", - " folpdx",n,"=((",x1,"-",x0,")/folpstpmax",n,"); ", - " folpdy",n,"=((",y1,"-",y0,")/folpstpmax",n,"); ", - " break; " - . folp_switch(n,i+1,t0,loop,steps) ] - }}. - -define Printable_tree - set_folpimages - ( - Int n, - List(String) filenames, - Int i, - ) = - if filenames is - { - [ ] then [ ], - [h . t] then - [ " folpimages",n,"[",i,"].src=\"",h,"\";" - . set_folpimages(n,t,i+1)] - }. - -define Printable_tree - follow_path - ( - List(String) filenames, - Int change_every, - List(FollowPathCommand) path, - Bool loop, - Int steps, - Int delay - ) = - if filenames is - { - [ ] then (print("Error in usage of 'follow_path': 'filenames' must be non empty."); []), - [im1 . other_ims] then - if steps < 1 then (print("Error in usage of 'follow_path': 'step' must be >= 1."); [ ]) else - if path is - { - [ ] then [ ], - [p0 . t0] then if p0 is pos(x0,y0,i0,d0) then - if t0 is - { - [ ] then - (print("Error in usage of 'follow_path': 'path' must have at least 2 positions."); []), - [p1 . t1] then if p1 is pos(x1,y1,i1,d1) then - with n = new_web_count, - [ - "", - "
", - "", - "
", - "", - ] - }}}. - - -public type ImageToLoad: - simple(String image_name), - with_rollover(String image_name, - String rollover_name). - -variable List(ImageToLoad) images_to_load = []. - -public define Printable_tree - format - ( - Web_body_option o - ) = - if o is - { - background_color(c) then [" bgcolor=" , (String)format(c)], - psychedelic_background(a,f,d) then add_script(psychedelic_bg(a,f,d)); [ ], - background_image(n) then [" background=", n], - scrolling_layer(disp,st,m,t,c,p) then add_script(s_layer(disp,st,m,t,c,p,2000\p)); [ ], - bounce(i,l,r,t,b) then add_script(bnce(i,l,r,t,b)); [ ], - over(i,l,t) then add_script(over(i,l,t)); [ ], - follow_path(li,ns,p,l,s,d) then add_script(follow_path(li,ns,p,l,s,d)); [ ], - load_image(n) then images_to_load <- [simple(n) . *images_to_load]; [ ], - left_margin(n) then [" leftmargin=", n], - top_margin(n) then [" topmargin=", n], - margin_width(n) then [" marginwidth=", n], - margin_height(n) then [" marginheight=", n], - reload_frame(n,url) then add_body_onload(reload_frame(n,url)); [ ], - onload(n) then [" onLoad=\"", n, "()\""] - }. - -define Printable_tree - preload_list - ( - List(ImageToLoad) images, - Int n, - ) = - if images is - { - [ ] then [ ], - [h . t] then - [" preloaded_images[",n,"].src = '",image_name(h),"';", - if h is - { - simple(_) then [], - with_rollover(n1,r) then - [" preloaded_images[",n1,"].onload = 'allow_rollover(\"",r,"\")';"] - } - . preload_list(t,n-1)] - }. - -define Printable_tree - load_image_script - ( - List(ImageToLoad) images - ) = - if images is - { - [ ] then [ ], - [_ . _] then - [ - "" - ] - }. - - -public define Printable_tree format(String c_ticket, - String s_ticket, - Web_item i). - - -public define Printable_tree - format(List(Table_option) l) = - if l is - { - [ ] then [ ], - [h . t] then [if h is - { - background_color(c) then [" bgcolor=", (String)format(c)], - background_image(f) then [" background=",f], - border then [" border"], - nude then [" border=\"0\" cellspacing=\"0\" cellpadding=\"0\""], - border(e,top,i) then [" border=",e," cellspacing=",top," cellpadding=",i], - border_color(c) then [" bordercolor=", (String)format(c)], - absolute_width(n) then [" width=",n] - }, format(t)] - }. - - - -public define Printable_tree - format(List(Row_option) l) = - if l is - { - [ ] then [ ], - [first . others] then [if first is - { - left then [" align=left"], - h_center then [" align=center"], - right then [" align=right"], - top then [" valign=top"], - v_center then [" valign=center"], - bottom then [" valign=bottom"], - absolute_height(n) then [" height=\"",n,"\""], - base_line then [" valign=baseline"], - background_color(c) then [" bgcolor=",(String)format(c)] - }, - format(others)] - }. - - - - -public define Int - percentage(Int n) = - if n < 0 then 0 - else if n > 100 then 100 - else n. - - public define Int percentage(Int n) = n. - - - - -public define Printable_tree - format - ( - List(Web_body_option) l - ) = - if l is - { - [ ] then [ ], - [h . t] then [format(h) . format(t)] - }. - - - - -public define Printable_tree - format(List(Cell_option) l) = - if l is - { - [ ] then [ ], - [first . others] then - [if first is - { - left then (Printable_tree)[" align=left"], - h_center then (Printable_tree)[" align=center"], - right then (Printable_tree)[" align=right"], - top then (Printable_tree)[" valign=top"], - v_center then (Printable_tree)[" valign=center"], - bottom then (Printable_tree)[" valign=bottom"], - base_line then (Printable_tree)[" valign=baseline"], - background_color(c) then (Printable_tree)[" bgcolor=",(String)format(c)], - background_image(n) then (Printable_tree)[" style=\"background: url(",n,")\""], - absolute_width(w) then (Printable_tree)[" width=",w], - relative_width(r) then (Printable_tree)[" width=",percentage(r),""], - absolute_height(h) then (Printable_tree)[" height=",h], - relative_height(r) then (Printable_tree)[" height=",percentage(r),""], - columns(n) then (Printable_tree)[" colspan=",n], - rows(n) then (Printable_tree)[" rowspan=",n], - nowrap then (Printable_tree)[" nowrap"] - } - . format(others)] - }. - - - -public define Printable_tree - format - ( - String c_ticket, - String s_ticket, - List(Cell) l - ) = - if l is - { - [ ] then [ ], - [first . others] then - [if first is cell(options,item) then - ["", - format(c_ticket,s_ticket,item),""], - format(c_ticket,s_ticket,others)] - }. - - -public define Printable_tree - format - ( - String c_ticket, - String s_ticket, - List(Table_row) l - ) = - if l is - { - [ ] then [ ], - [first_row . other_rows] - then [if first_row is - { - row(options,cells) then - [ "", - format(c_ticket,s_ticket,cells),""] - }, - format(c_ticket,s_ticket,other_rows)] - }. - - -public define Printable_tree - format_choices - ( - List(String) l - ) = - if l is - { - [ ] then [ ], - [h . t] then ["