Commit 55136886e0c86018a9a2ce5a6402fc35676c4734

Authored by David RENÉ
1 parent 5ba7d13c

start to split web site with controller and old fashioned web site way to be abl…

…e to compile old source
web/CXM_making_a_web_site.anubis
@@ -59,7 +59,7 @@ read system/logger.anubis @@ -59,7 +59,7 @@ read system/logger.anubis
59 transmit CXM_common.anubis 59 transmit CXM_common.anubis
60 transmit CXM_multihost_http_server.anubis 60 transmit CXM_multihost_http_server.anubis
61 read web/mime.anubis 61 read web/mime.anubis
62 -read calexium_lib/web/plugin/plugin.anubis 62 +
63 read CXM_cookies.anubis 63 read CXM_cookies.anubis
64 read CXM_json.anubis 64 read CXM_json.anubis
65 transmit CXM_web_dump.anubis 65 transmit CXM_web_dump.anubis
@@ -353,108 +353,7 @@ public define String @@ -353,108 +353,7 @@ public define String
353 353
354 354
355 355
356 -public define WEB_Controller_Result  
357 - ajax  
358 - (  
359 - HTTP_Answer http_answer  
360 - )=  
361 - ajax(failure, http_answer)  
362 -.  
363 356
364 -public define WEB_Controller_Result  
365 - ajax  
366 - (  
367 - WEB_Session session, //modified session  
368 - HTTP_Answer http_answer  
369 - )=  
370 - ajax(success(session), http_answer)  
371 -.  
372 -  
373 -public define WEB_Controller_Result  
374 - ajax  
375 - (  
376 - HTML_Partial_Content content  
377 - )=  
378 - ajax(failure, content, "").  
379 -  
380 -public define WEB_Controller_Result  
381 - ajax  
382 - (  
383 - HTML_Partial_Content content,  
384 - String additional_script  
385 - )=  
386 - ajax(failure, content, additional_script).  
387 -  
388 -public define WEB_Controller_Result  
389 - ajax  
390 - (  
391 - WEB_Session session, //modified session  
392 - HTML_Partial_Content content  
393 - )=  
394 - ajax(success(session), content, "").  
395 -  
396 -public define WEB_Controller_Result  
397 - ajax  
398 - (  
399 - WEB_Session session, //modified session  
400 - HTML_Partial_Content content,  
401 - String additional_script  
402 - )=  
403 - ajax(success(session), content, additional_script).  
404 -  
405 -public define WEB_Controller_Result  
406 - ajax  
407 - (  
408 - Printable_tree content  
409 - )=  
410 - ajax(failure, content, "").  
411 -  
412 -public define WEB_Controller_Result  
413 - ajax  
414 - (  
415 - Printable_tree content,  
416 - String additional_script  
417 - )=  
418 - ajax(failure, content, additional_script).  
419 -  
420 -public define WEB_Controller_Result  
421 - ajax  
422 - (  
423 - WEB_Session session, //modified session  
424 - Printable_tree content  
425 - )=  
426 - ajax(success(session), content, "").  
427 -  
428 -public define WEB_Controller_Result  
429 - ajax  
430 - (  
431 - WEB_Session session, //modified session  
432 - Printable_tree content,  
433 - String additional_script  
434 - )=  
435 - ajax(success(session), content, additional_script).  
436 -  
437 -public define WEB_Controller_Result  
438 - renderer_content(  
439 - HTML_Partial_Content content,  
440 - )=  
441 - renderer_content(failure, content)  
442 -.  
443 -  
444 -public define WEB_Controller_Result  
445 - renderer_content(  
446 - WEB_Session session, //modified session if success else failure  
447 - HTML_Partial_Content content,  
448 - )=  
449 - renderer_content(success(session), content)  
450 -.  
451 -  
452 - public define WEB_Controller_Result  
453 - redraw(  
454 - HTML_Partial_Content content,  
455 - )=  
456 - redraw(failure, content)  
457 -.  
458 357
459 358
460 359
@@ -659,7 +558,7 @@ public type Web_Site:... @@ -659,7 +558,7 @@ public type Web_Site:...
659 558
660 Producing such a datum may be performed by: 559 Producing such a datum may be performed by:
661 560
662 -public define Web_Site 561 + public define Web_Site
663 make_web_site_description 562 make_web_site_description
664 ( 563 (
665 List(String) common_names, // for example: ["www.our-business.com", 564 List(String) common_names, // for example: ["www.our-business.com",
@@ -2234,25 +2133,6 @@ public define HTTP_Answer @@ -2234,25 +2133,6 @@ public define HTTP_Answer
2234 ) 2133 )
2235 . 2134 .
2236 2135
2237 -define (WEB_Session)-> WEB_Controller_Result  
2238 - web_controller_error  
2239 - (  
2240 - String name  
2241 - )=  
2242 - (  
2243 - WEB_Session session  
2244 - ) |->  
2245 - http_answer(session, web_controller_error_page(name)).  
2246 -  
2247 -public define WEB_Controller  
2248 - web_controller  
2249 - (  
2250 - String name, //controller name  
2251 - Var(List(WEB_Action)) controller_actions //list of all actions of that controller  
2252 - //(WEB_Session)-> WEB_Controller_Result error //Error renderer  
2253 - )=  
2254 - web_controller(name, controller_actions, web_controller_error(name))  
2255 -.  
2256 2136
2257 'HTTP_Answer' represents the final product of the construction of a web page. 2137 'HTTP_Answer' represents the final product of the construction of a web page.
2258 2138
@@ -3168,429 +3048,11 @@ define HTTP_Answer @@ -3168,429 +3048,11 @@ define HTTP_Answer
3168 ) 3048 )
3169 . 3049 .
3170 3050
3171 -public type WEB_Page_Renderer:  
3172 - web_page_renderer(  
3173 - String app, //application  
3174 - String name, //renderer name  
3175 - (WEB_Session _session, List(WEB_Plugin), HTML_Partial_Content _content) -> HTTP_Answer page_layout //call back for rendering page  
3176 - )  
3177 -.  
3178 -  
3179 -define WEB_Page_Renderer  
3180 - default_page_renderer =  
3181 - web_page_renderer("AWS", "AWS_DEFAULT_PAGE",  
3182 - ( WEB_Session _session,  
3183 - List(WEB_Plugin) _plugins,  
3184 - HTML_Partial_Content _content  
3185 - ) |->  
3186 - with _title = get_page_title(_session),  
3187 - html_page  
3188 - (  
3189 - http_ok,  
3190 - [ title(_title), ]// title of web site  
3191 - ,  
3192 - body // body of page  
3193 - (  
3194 - [], //body options empty  
3195 - (HTML_Off_Form)partial(_content)  
3196 - )  
3197 - )  
3198 - )  
3199 -.  
3200 -  
3201 -define WEB_Controller_Result  
3202 - apply_action  
3203 - (  
3204 - WEB_Session _session,  
3205 - String requested_action_name,  
3206 - List(WEB_Action) actions_list  
3207 - ) =  
3208 - //println("apply_action ");  
3209 - if actions_list is  
3210 - {  
3211 - [] then http_answer(error_page(http_not_found, "["+requested_action_name+"] Action not found in all controllers", _session)),  
3212 - [h . t] then  
3213 - if h.name = no_action then  
3214 - http_answer( _session, html_content(http_no_content, empty))  
3215 - else  
3216 - with action_name = if h.name is  
3217 - {  
3218 - no_action then "",  
3219 - controller_action(_, name) then name,  
3220 - action_name(name) then name,  
3221 - url(url) then url,  
3222 - },  
3223 - if requested_action_name = action_name then  
3224 - with step = get_Int(_session.fields, "AWS_SESSION_STEP", 0) + 1,  
3225 - replace_Int(_session.fields, "AWS_SESSION_STEP", step);  
3226 - if h.allowed_proto is  
3227 - {  
3228 - //Action only in HTTP  
3229 - http then  
3230 - if _session.web_request.is_https then  
3231 - http_answer(error_page(http_forbidden, "Only HTTP authorized", _session))  
3232 - else  
3233 - //ask to the server the authorization to execute that action  
3234 - if h.allow(_session) then  
3235 - h.do_it(_session)  
3236 - else  
3237 - http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))  
3238 -  
3239 - //Action only in HTTPS  
3240 - https then  
3241 - if _session.web_request.is_https then  
3242 - //ask to the server the authorization to execute that action  
3243 - if h.allow(_session) then  
3244 - h.do_it(_session)  
3245 - else  
3246 - http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))  
3247 - else  
3248 - http_answer(error_page(http_forbidden, "Only HTTPS authorized", _session))  
3249 - //Action in both HTTP / HTTPS  
3250 - http_https then  
3251 - //ask to the server the authorization to execute that action  
3252 - if h.allow(_session) then  
3253 - //println("do_it "+action_name);  
3254 - h.do_it(_session)  
3255 - else  
3256 - http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))  
3257 -  
3258 - }  
3259 - else  
3260 - apply_action(_session, requested_action_name, t)  
3261 - }  
3262 -.  
3263 -  
3264 -define Maybe(WEB_Controller)  
3265 - get_controller  
3266 - (  
3267 - String controller_name,  
3268 - List(WEB_Controller) controllers,  
3269 - (LogLevel, String) -> One logger //logger  
3270 - )=  
3271 - if controllers is  
3272 - {  
3273 - [] then  
3274 - logger(logWarning, "Can't find controller ["+controller_name+"]");  
3275 - failure,  
3276 - [h . t] then  
3277 - if h.name = controller_name then  
3278 - //println("Controller ["+controller_name+"] found");  
3279 - success(h)  
3280 - else  
3281 - get_controller(controller_name, t, logger)  
3282 - }  
3283 -.  
3284 -  
3285 -define WEB_Page_Renderer  
3286 - get_page_renderer  
3287 - (  
3288 - String renderer_name,  
3289 - List(WEB_Page_Renderer) renderers,  
3290 - (LogLevel, String) -> One logger //logger  
3291 - )=  
3292 - if renderers is  
3293 - {  
3294 - [] then  
3295 - logger(logWarning, "Can't find page_renderer ["+renderer_name+"], use the default");  
3296 - default_page_renderer,  
3297 - [h . t] then  
3298 - if h.name = renderer_name then  
3299 - //println("renderer_name ["+renderer_name+"] found");  
3300 - h  
3301 - else  
3302 - //println("renderer_name "+renderer_name+" not matching");  
3303 - get_page_renderer(renderer_name, t, logger)  
3304 - }  
3305 -.  
3306 -  
3307 -define WEB_Page_Renderer  
3308 - get_page_renderer  
3309 - (  
3310 - WEB_Session _session,  
3311 - WEB_Page_Renderer _current_page_renderer,  
3312 - List(WEB_Page_Renderer) renderers,  
3313 - (LogLevel, String) -> One logger //logger  
3314 - )=  
3315 - //get the renderer page name to use from the session "AWS_PAGE_RENDERER"  
3316 - if get_String(_session.fields, "AWS_CURRENT_PAGE_RENDERER") is  
3317 - {  
3318 - failure then logger(logWarning, "No renderer defined, use the default"); default_page_renderer,  
3319 - success(renderer_name) then  
3320 - //check if the renderer_page already in cache  
3321 - if renderer_name = _current_page_renderer.name then  
3322 - _current_page_renderer  
3323 - else  
3324 - //if not in cache, use the selector function  
3325 - get_page_renderer(renderer_name, renderers, logger)  
3326 - }  
3327 -.  
3328 3051
3329 public define JsonValue to_html_ajax_content(Printable_tree content_HTML, String additional_script). 3052 public define JsonValue to_html_ajax_content(Printable_tree content_HTML, String additional_script).
3330 public define JsonValue to_html_ajax_content(HTML_Partial_Content content_HTML, CommonInfo cinfo, String additional_script). 3053 public define JsonValue to_html_ajax_content(HTML_Partial_Content content_HTML, CommonInfo cinfo, String additional_script).
3331 3054
3332 -define (Maybe(WEB_Session), HTTP_Answer)  
3333 - apply_controller_action  
3334 - (  
3335 - WEB_Controller controller,  
3336 - List(WEB_Plugin) plugins,  
3337 - List(WEB_Controller) controllers,  
3338 - WEB_Page_Renderer _current_page_renderer,  
3339 - List(WEB_Page_Renderer) page_renderers,  
3340 - CommonInfo cinfo,  
3341 - WEB_Session _session,  
3342 - Maybe(String) _mb_action_name,  
3343 - (HTTP_Info,  
3344 - Var(List(Web_arg)),  
3345 - Bool is_https) -> WEB_Session initial_session,  
3346 - (LogLevel, String) -> One logger //logger  
3347 - )=  
3348 - //get the action name  
3349 - with mb_action_name =  
3350 - if _mb_action_name is  
3351 - {  
3352 - failure then get_String(*_session.web_request.lwa, "aws_action"),  
3353 - success(_an) then success(_an)  
3354 - },  
3355 -  
3356 - if mb_action_name is  
3357 - {  
3358 - failure then  
3359 - //(failure, error_page(http_not_found, "Action name failure", _session)),  
3360 - with new_session = initial_session(_session.web_request.http_info, _session.web_request.lwa, _session.web_request.is_https),  
3361 - if get_controller(get_String(*new_session.web_request.lwa, "aws_controller", "root"), controllers, logger) is  
3362 - {  
3363 - failure then (failure, error_page(http_not_found, "Initial Session Controller not found", new_session)),  
3364 - success(new_controller) then apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, failure, initial_session, logger),  
3365 - },  
3366 - success(action_name) then  
3367 - //logger(logInfo, "ACTION_NAME ["+action_name+"] from IP "+get_String(_session.fields, "IP", ""));  
3368 - if apply_action(_session, action_name, *controller.controller_actions) is  
3369 - {  
3370 - http_answer(session, answer) then  
3371 - since session is web_session(id, lang, entries, current, previous, _),  
3372 - with new_web_session = web_session(id, lang, entries, current, previous, current),  
3373 -// println("***** http_answer(session, answer) record new draw point to *****");  
3374 -// println("web arguments:"+  
3375 -// dump_web_arg_values(*current.lwa));  
3376 -// println("************************************");  
3377 - (success(new_web_session), answer),  
3378 -  
3379 - http_answer(answer) then  
3380 - since _session is web_session(id, lang, entries, current, previous, _),  
3381 - with new_web_session = web_session(id, lang, entries, current, previous, current),  
3382 -// println("***** http_answer(answer) record new draw point to *****");  
3383 -// println("web arguments:"+  
3384 -// dump_web_arg_values(*current.lwa));  
3385 -// println("************************************");  
3386 - (success(new_web_session), answer),  
3387 -  
3388 - redirect(new_session) then  
3389 - if get_controller(get_String(*new_session.web_request.lwa, "aws_controller", "root"), controllers, logger) is  
3390 - {  
3391 - failure then (failure, error_page(http_not_found, "Redirect Controller not found", new_session)),  
3392 - success(new_controller) then apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, failure, initial_session, logger),  
3393 - },  
3394 -  
3395 - redirect(new_session, r_controller_name, r_action_name) then  
3396 - if get_controller(r_controller_name, controllers, logger) is  
3397 - {  
3398 - failure then (failure, error_page(http_not_found, "Redirect Controller "+r_controller_name+" not found", new_session)),  
3399 - success(new_controller) then  
3400 - apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, success(r_action_name), initial_session, logger),  
3401 - },  
3402 -  
3403 - redirect_to_previous then  
3404 - if get_controller(get_String(*_session.previous_web_request.lwa, "aws_controller", "root"), controllers, logger) is  
3405 - {  
3406 - failure then (failure, error_page(http_not_found, "Redirect to previous Controller not found", _session)),  
3407 - success(new_controller) then  
3408 - since _session is web_session(id, lang, entries, _, previous, draw),  
3409 - apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, web_session(id, lang, entries, previous, previous, draw), failure, initial_session, logger),  
3410 - },  
3411 - redirect_to_previous(entries) then  
3412 - if get_controller(get_String(*_session.previous_web_request.lwa, "aws_controller", "root"), controllers, logger) is  
3413 - {  
3414 - failure then (failure, error_page(http_not_found, "Redirect to previous Controller not found", _session)),  
3415 - success(new_controller) then  
3416 - since _session is web_session(id, lang, _, _, previous, draw),  
3417 - apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, web_session(id, lang, entries, previous, previous, draw), failure, initial_session, logger),  
3418 - },  
3419 - //ajax(answer) then (failure, answer),  
3420 - //ajax with modified session that must be saved  
3421 - ajax(session, answer) then (session, answer),  
3422 -  
3423 - //ajax(content, additional_script) then (failure, json(http_ok, to_html_ajax_content(content, cinfo, additional_script))),  
3424 - ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, cinfo, additional_script))),  
3425 - //ajax(content, additional_script) then (failure, json(http_ok, to_html_ajax_content(content, additional_script))),  
3426 - ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, additional_script))),  
3427 - send_file(file_path, c_disposition) then (failure, send_file(file_path, c_disposition)),  
3428 - renderer_content(session, content) then  
3429 - with the_session = if session is {failure then _session, success(__session) then __session},  
3430 - since the_session is web_session(id, lang, entries, current, previous, _),  
3431 - with new_web_session = web_session(id, lang, entries, current, previous, current),  
3432 -// println("***** renderer_content(session, content) record new draw point to *****");  
3433 -// println("web arguments:"+  
3434 -// dump_web_arg_values(*current.lwa));  
3435 -// println("************************************");  
3436 - with page_renderer = get_page_renderer(new_web_session, _current_page_renderer, page_renderers, logger),  
3437 - (success(new_web_session), page_renderer.page_layout(new_web_session, plugins, content))  
3438 - }  
3439 - }  
3440 -.  
3441 -  
3442 -  
3443 -  
3444 -public define Web_Site  
3445 - make_web_site_controller_description  
3446 - (  
3447 - String website_name, // site_UID  
3448 - List(String) common_names, // for example: ["www.our-business.com"]  
3449 - String site_directory,  
3450 - String state_directory,  
3451 - One -> One init,  
3452 - (HTTP_Info,  
3453 - Var(List(Web_arg)),  
3454 - Bool is_https) -> WEB_Session initial_session,  
3455 - (WEB_Session,  
3456 - HTTP_Info,  
3457 - Var(List(Web_arg)),  
3458 - Bool is_https) -> WEB_Session expired_session,  
3459 - Var(List(WEB_Controller)) web_controllers,  
3460 - Var(List(WEB_Page_Renderer)) web_page_renderers,  
3461 - Var(List(WEB_Plugin)) web_plugins,  
3462 - Maybe(WEB_Session) -> List(HTTP_header) additional_headers,  
3463 - List(HTTP_header) constant_additional_headers,  
3464 - Int timeout,  
3465 - Redirections redirections,  
3466 - String charset,  
3467 - List(String) journal_extensions,  
3468 - List(String) journal_headers,  
3469 - (LogLevel, String) -> One logger, //logger  
3470 - String secret,  
3471 - List(MIME) known_mime_types,  
3472 - (String action_name,  
3473 - List(Web_arg) args) -> One before_send_file  
3474 - )=  
3475 - //call the initialization function  
3476 - init(unique);  
3477 -  
3478 -  
3479 - //  
3480 - // make required directories (if needed)  
3481 - //  
3482 - with //web_sites_directory = (String) make_directory(my_anubis_directory+"/web_sites"),  
3483 - base_directory = (String) make_directory(site_directory),  
3484 - // state_directory = make_directory(site_directory+"/states"),  
3485 - forget((String)make_directory(site_directory+"/public"));  
3486 -  
3487 - //  
3488 - // construct tool functions  
3489 - // TODO 'make_separate_web_args_function' must retrieve state_cookies before parsing web_args if using_state_cookies is true  
3490 - with save_session = make_save_session_function(timeout, state_directory, logger),  
3491 - with current_page_renderer = var((WEB_Page_Renderer)default_page_renderer),  
3492 - // with left_menu_list = get_left_menu_from_plugins(*web_plugins),  
3493 - // retrieve_session = make_retrieve_session_function(state_directory, website_name),  
3494 - //separate_web_args = make_separate_web_args_function(state_directory, retrieve_state),  
3495 - //apply_action = make_apply_action_function(actions),  
3496 -  
3497 - //  
3498 - // construct the site handler  
3499 - //  
3500 - site_handler = (Word32 http_port, Word32 https_port) |->  
3501 - ((String host_name,  
3502 - HTTP_Info http_info,  
3503 - List(Web_arg) _lwa,  
3504 - Bool is_https) |->  
3505 - //(Printable_tree)  
3506 - logger(logTrace,"host_name "+host_name);  
3507 - logger(logTrace, dump_http_info(http_info));  
3508 - logger(logTrace, dump_web_arg_values(_lwa));  
3509 - with cinfo = info(host_name, http_port, https_port, site_directory, secret),  
3510 -  
3511 - //retrieve the previous session and determine the new one  
3512 - with current_session = if retrieve_session(http_info, state_directory, website_name) is  
3513 - {  
3514 - not_found then  
3515 - logger(logInfo, "previous state not found");  
3516 - initial_session(http_info, var(_lwa), is_https),  
3517 -  
3518 - out_of_date(previous_session) then  
3519 - logger(logInfo, "previous out_of_date");  
3520 - //expired_session(previous_session, http_info, var(_lwa), is_https),  
3521 - since previous_session is web_session(id, lang, entries, previous, _, draw),  
3522 - replace_String(entries, "IP", http_header_value(http_info.http_headers, "x-forwarded-for", ip_addr_to_string(http_info.ip_address)));  
3523 - web_session(id, lang, entries, web_request(http_info, var(_lwa), is_https), previous, draw)  
3524 -  
3525 - still_valid(previous_session) then  
3526 - since previous_session is web_session(id, lang, entries, previous, _, draw),  
3527 - replace_String(entries, "IP", http_header_value(http_info.http_headers, "x-forwarded-for", ip_addr_to_string(http_info.ip_address)));  
3528 - web_session(id, lang, entries, web_request(http_info, var(_lwa), is_https), previous, draw)  
3529 - },  
3530 -  
3531 -  
3532 - //apply the action according to current session  
3533 - //since apply_controller_action(get_controller(get_String(lwa, "aws_controller", "root"), *web_controllers), *web_controllers, current_session)  
3534 - since if get_controller(get_String(*current_session.web_request.lwa, "aws_controller", "root"), *web_controllers, logger) is  
3535 - {  
3536 - failure then  
3537 - (failure, error_page(http_not_found, "Controller not found", current_session)),  
3538 -  
3539 - success(new_controller) then  
3540 - apply_controller_action(new_controller, *web_plugins, *web_controllers, *current_page_renderer, *web_page_renderers, cinfo, current_session, failure, initial_session, logger),  
3541 - }  
3542 - is (mb_new_session, http_answer),  
3543 -  
3544 - //save the session if need and construct the according cookie  
3545 - with cookie_headers =  
3546 - if mb_new_session is  
3547 - {  
3548 - failure then [],  
3549 - success(new_session) then  
3550 - with session_name = save_session(new_session),  
3551 - make_session_cookie_headers(website_name, session_name)  
3552 - },  
3553 -  
3554 - //formatting and send http answer because this is the last function  
3555 - format(cinfo,  
3556 - //state_name,  
3557 - additional_headers(mb_new_session) + cookie_headers,  
3558 - http_answer,  
3559 - is_https,  
3560 - charset)  
3561 - ),  
3562 - //  
3563 - // make the delete_out_of_date function  
3564 - //  
3565 - delete_out_of_date =  
3566 - make_delete_out_of_date_sessions_function(site_directory+"/states", logger),  
3567 - //  
3568 - // construct the web site description  
3569 - //  
3570 - web_site((Word32 http_port, Word32 https_port) |->  
3571 - web_site_description(common_names,  
3572 - site_directory,  
3573 - redirections,  
3574 - charset,  
3575 - journal_extensions,  
3576 - journal_headers,  
3577 - logger,  
3578 - secret,  
3579 - known_mime_types,  
3580 - site_handler(http_port,https_port),  
3581 - constant_additional_headers,  
3582 - (HTTP_Info http_info, List(Web_arg) lwa) |-> unique  
3583 -// if separate_web_args(lwa, http_info ) is  
3584 -// swa(mb_previous_state,mb_action_name,operands) then  
3585 -// if mb_action_name is  
3586 -// {  
3587 -// failure then unique  
3588 -// success(an) then before_send_file(an,operands)  
3589 -// }  
3590 - //using_state_cookies  
3591 - ),  
3592 - delete_out_of_date).  
3593 - 3055 +
3594 3056
3595 define String 3057 define String
3596 get_site_uid 3058 get_site_uid
@@ -3617,7 +3079,7 @@ define String @@ -3617,7 +3079,7 @@ define String
3617 . 3079 .
3618 3080
3619 // Compatibility function for older websites 3081 // Compatibility function for older websites
3620 -public define Web_Site 3082 + public define Web_Site
3621 make_web_site_description 3083 make_web_site_description
3622 ( 3084 (
3623 List(String) common_names, // for example: ["www.our-business.com"] 3085 List(String) common_names, // for example: ["www.our-business.com"]
@@ -3656,7 +3118,7 @@ public define Web_Site @@ -3656,7 +3118,7 @@ public define Web_Site
3656 //generate an unique ID if doesn't exist in root of site_directory 3118 //generate an unique ID if doesn't exist in root of site_directory
3657 with site_UID = get_site_uid(site_directory, logger), 3119 with site_UID = get_site_uid(site_directory, logger),
3658 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, constant_additional_headers, timeout, redirections, charset, journal_extensions, journal_headers, logger, secret, known_mime_types, before_send_file) 3120 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, constant_additional_headers, timeout, redirections, charset, journal_extensions, journal_headers, logger, secret, known_mime_types, before_send_file)
3659 - . 3121 +.
3660 3122
3661 3123
3662 3124
web/controllers_web_site.anubis 0 → 100644
  1 +/*
  2 + * Created by PyramIDE.
  3 + * User: フランスのトトロ aka (David RENÉ)
  4 + * Date: 07/10/2019
  5 + * Time: 10:49
  6 + * © David RENÉ
  7 + */
  8 +
  9 + website with:
  10 + - controllers
  11 + - web session
  12 + - plugin
  13 + - web page renderer
  14 +
  15 +
  16 +transmit CXM_web_session.anubis
  17 +transmit types/controllers_web_site.anubis
  18 +read calexium_lib/web/plugin/plugin.anubis
  19 +read config/logger_config.anubis
  20 +
  21 +
  22 +
  23 +public type WEB_Action:
  24 + web_action(
  25 + WEB_Action_Name name, // name of action
  26 + WEB_Action_Allowed_Protocol allowed_proto,
  27 + (WEB_Session) -> Bool allow, // true if action allowed
  28 + (WEB_Session) -> WEB_Controller_Result do_it
  29 + )
  30 +.
  31 +
  32 +
  33 +public define WEB_Controller_Result
  34 + ajax
  35 + (
  36 + HTTP_Answer http_answer
  37 + )=
  38 + ajax(failure, http_answer)
  39 +.
  40 +
  41 +public define WEB_Controller_Result
  42 + ajax
  43 + (
  44 + WEB_Session session, //modified session
  45 + HTTP_Answer http_answer
  46 + )=
  47 + ajax(success(session), http_answer)
  48 +.
  49 +
  50 +public define WEB_Controller_Result
  51 + ajax
  52 + (
  53 + HTML_Partial_Content content
  54 + )=
  55 + ajax(failure, content, "").
  56 +
  57 +public define WEB_Controller_Result
  58 + ajax
  59 + (
  60 + HTML_Partial_Content content,
  61 + String additional_script
  62 + )=
  63 + ajax(failure, content, additional_script).
  64 +
  65 +public define WEB_Controller_Result
  66 + ajax
  67 + (
  68 + WEB_Session session, //modified session
  69 + HTML_Partial_Content content
  70 + )=
  71 + ajax(success(session), content, "").
  72 +
  73 +public define WEB_Controller_Result
  74 + ajax
  75 + (
  76 + WEB_Session session, //modified session
  77 + HTML_Partial_Content content,
  78 + String additional_script
  79 + )=
  80 + ajax(success(session), content, additional_script).
  81 +
  82 +public define WEB_Controller_Result
  83 + ajax
  84 + (
  85 + Printable_tree content
  86 + )=
  87 + ajax(failure, content, "").
  88 +
  89 +public define WEB_Controller_Result
  90 + ajax
  91 + (
  92 + Printable_tree content,
  93 + String additional_script
  94 + )=
  95 + ajax(failure, content, additional_script).
  96 +
  97 +public define WEB_Controller_Result
  98 + ajax
  99 + (
  100 + WEB_Session session, //modified session
  101 + Printable_tree content
  102 + )=
  103 + ajax(success(session), content, "").
  104 +
  105 +public define WEB_Controller_Result
  106 + ajax
  107 + (
  108 + WEB_Session session, //modified session
  109 + Printable_tree content,
  110 + String additional_script
  111 + )=
  112 + ajax(success(session), content, additional_script).
  113 +
  114 +public define WEB_Controller_Result
  115 + renderer_content(
  116 + HTML_Partial_Content content,
  117 + )=
  118 + renderer_content(failure, content)
  119 +.
  120 +
  121 +public define WEB_Controller_Result
  122 + renderer_content(
  123 + WEB_Session session, //modified session if success else failure
  124 + HTML_Partial_Content content,
  125 + )=
  126 + renderer_content(success(session), content)
  127 +.
  128 +
  129 + public define WEB_Controller_Result
  130 + redraw(
  131 + HTML_Partial_Content content,
  132 + )=
  133 + redraw(failure, content)
  134 +.
  135 +
  136 +public type WEB_Page_Renderer:
  137 + web_page_renderer(
  138 + String app, //application
  139 + String name, //renderer name
  140 + (WEB_Session _session, List(WEB_Plugin), HTML_Partial_Content _content) -> HTTP_Answer page_layout //call back for rendering page
  141 + )
  142 +.
  143 +
  144 +define WEB_Page_Renderer
  145 + default_page_renderer =
  146 + web_page_renderer("AWS", "AWS_DEFAULT_PAGE",
  147 + ( WEB_Session _session,
  148 + List(WEB_Plugin) _plugins,
  149 + HTML_Partial_Content _content
  150 + ) |->
  151 + with _title = get_page_title(_session),
  152 + html_page
  153 + (
  154 + http_ok,
  155 + [ title(_title), ]// title of web site
  156 + ,
  157 + body // body of page
  158 + (
  159 + [], //body options empty
  160 + (HTML_Off_Form)partial(_content)
  161 + )
  162 + )
  163 + )
  164 +.
  165 +
  166 +define WEB_Controller_Result
  167 + apply_action
  168 + (
  169 + WEB_Session _session,
  170 + String requested_action_name,
  171 + List(WEB_Action) actions_list
  172 + ) =
  173 + //println("apply_action ");
  174 + if actions_list is
  175 + {
  176 + [] then http_answer(error_page(http_not_found, "["+requested_action_name+"] Action not found in all controllers", _session)),
  177 + [h . t] then
  178 + if h.name = no_action then
  179 + http_answer( _session, html_content(http_no_content, empty))
  180 + else
  181 + with action_name = if h.name is
  182 + {
  183 + no_action then "",
  184 + controller_action(_, name) then name,
  185 + action_name(name) then name,
  186 + url(url) then url,
  187 + },
  188 + if requested_action_name = action_name then
  189 + with step = get_Int(_session.fields, "AWS_SESSION_STEP", 0) + 1,
  190 + replace_Int(_session.fields, "AWS_SESSION_STEP", step);
  191 + if h.allowed_proto is
  192 + {
  193 + //Action only in HTTP
  194 + http then
  195 + if _session.web_request.is_https then
  196 + http_answer(error_page(http_forbidden, "Only HTTP authorized", _session))
  197 + else
  198 + //ask to the server the authorization to execute that action
  199 + if h.allow(_session) then
  200 + h.do_it(_session)
  201 + else
  202 + http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))
  203 +
  204 + //Action only in HTTPS
  205 + https then
  206 + if _session.web_request.is_https then
  207 + //ask to the server the authorization to execute that action
  208 + if h.allow(_session) then
  209 + h.do_it(_session)
  210 + else
  211 + http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))
  212 + else
  213 + http_answer(error_page(http_forbidden, "Only HTTPS authorized", _session))
  214 + //Action in both HTTP / HTTPS
  215 + http_https then
  216 + //ask to the server the authorization to execute that action
  217 + if h.allow(_session) then
  218 + //println("do_it "+action_name);
  219 + h.do_it(_session)
  220 + else
  221 + http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))
  222 +
  223 + }
  224 + else
  225 + apply_action(_session, requested_action_name, t)
  226 + }
  227 +.
  228 +
  229 +define Maybe(WEB_Controller)
  230 + get_controller
  231 + (
  232 + String controller_name,
  233 + List(WEB_Controller) controllers,
  234 + (LogLevel, String) -> One logger //logger
  235 + )=
  236 + if controllers is
  237 + {
  238 + [] then
  239 + logger(logWarning, "Can't find controller ["+controller_name+"]");
  240 + failure,
  241 + [h . t] then
  242 + if h.name = controller_name then
  243 + //println("Controller ["+controller_name+"] found");
  244 + success(h)
  245 + else
  246 + get_controller(controller_name, t, logger)
  247 + }
  248 +.
  249 +
  250 +define WEB_Page_Renderer
  251 + get_page_renderer
  252 + (
  253 + String renderer_name,
  254 + List(WEB_Page_Renderer) renderers,
  255 + (LogLevel, String) -> One logger //logger
  256 + )=
  257 + if renderers is
  258 + {
  259 + [] then
  260 + logger(logWarning, "Can't find page_renderer ["+renderer_name+"], use the default");
  261 + default_page_renderer,
  262 + [h . t] then
  263 + if h.name = renderer_name then
  264 + //println("renderer_name ["+renderer_name+"] found");
  265 + h
  266 + else
  267 + //println("renderer_name "+renderer_name+" not matching");
  268 + get_page_renderer(renderer_name, t, logger)
  269 + }
  270 +.
  271 +
  272 +define WEB_Page_Renderer
  273 + get_page_renderer
  274 + (
  275 + WEB_Session _session,
  276 + WEB_Page_Renderer _current_page_renderer,
  277 + List(WEB_Page_Renderer) renderers,
  278 + (LogLevel, String) -> One logger //logger
  279 + )=
  280 + //get the renderer page name to use from the session "AWS_PAGE_RENDERER"
  281 + if get_String(_session.fields, "AWS_CURRENT_PAGE_RENDERER") is
  282 + {
  283 + failure then logger(logWarning, "No renderer defined, use the default"); default_page_renderer,
  284 + success(renderer_name) then
  285 + //check if the renderer_page already in cache
  286 + if renderer_name = _current_page_renderer.name then
  287 + _current_page_renderer
  288 + else
  289 + //if not in cache, use the selector function
  290 + get_page_renderer(renderer_name, renderers, logger)
  291 + }
  292 +.
  293 +
  294 +public define JsonValue to_html_ajax_content(Printable_tree content_HTML, String additional_script).
  295 +public define JsonValue to_html_ajax_content(HTML_Partial_Content content_HTML, CommonInfo cinfo, String additional_script).
  296 +
  297 +define (Maybe(WEB_Session), HTTP_Answer)
  298 + apply_controller_action
  299 + (
  300 + WEB_Controller controller,
  301 + List(WEB_Plugin) plugins,
  302 + List(WEB_Controller) controllers,
  303 + WEB_Page_Renderer _current_page_renderer,
  304 + List(WEB_Page_Renderer) page_renderers,
  305 + CommonInfo cinfo,
  306 + WEB_Session _session,
  307 + Maybe(String) _mb_action_name,
  308 + (HTTP_Info,
  309 + Var(List(Web_arg)),
  310 + Bool is_https) -> WEB_Session initial_session,
  311 + (LogLevel, String) -> One logger //logger
  312 + )=
  313 + //get the action name
  314 + with mb_action_name =
  315 + if _mb_action_name is
  316 + {
  317 + failure then get_String(*_session.web_request.lwa, "aws_action"),
  318 + success(_an) then success(_an)
  319 + },
  320 +
  321 + if mb_action_name is
  322 + {
  323 + failure then
  324 + //(failure, error_page(http_not_found, "Action name failure", _session)),
  325 + with new_session = initial_session(_session.web_request.http_info, _session.web_request.lwa, _session.web_request.is_https),
  326 + if get_controller(get_String(*new_session.web_request.lwa, "aws_controller", "root"), controllers, logger) is
  327 + {
  328 + failure then (failure, error_page(http_not_found, "Initial Session Controller not found", new_session)),
  329 + success(new_controller) then apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, failure, initial_session, logger),
  330 + },
  331 + success(action_name) then
  332 + //logger(logInfo, "ACTION_NAME ["+action_name+"] from IP "+get_String(_session.fields, "IP", ""));
  333 + if apply_action(_session, action_name, *controller.controller_actions) is
  334 + {
  335 + http_answer(session, answer) then
  336 + since session is web_session(id, lang, entries, current, previous, _),
  337 + with new_web_session = web_session(id, lang, entries, current, previous, current),
  338 +// println("***** http_answer(session, answer) record new draw point to *****");
  339 +// println("web arguments:"+
  340 +// dump_web_arg_values(*current.lwa));
  341 +// println("************************************");
  342 + (success(new_web_session), answer),
  343 +
  344 + http_answer(answer) then
  345 + since _session is web_session(id, lang, entries, current, previous, _),
  346 + with new_web_session = web_session(id, lang, entries, current, previous, current),
  347 +// println("***** http_answer(answer) record new draw point to *****");
  348 +// println("web arguments:"+
  349 +// dump_web_arg_values(*current.lwa));
  350 +// println("************************************");
  351 + (success(new_web_session), answer),
  352 +
  353 + redirect(new_session) then
  354 + if get_controller(get_String(*new_session.web_request.lwa, "aws_controller", "root"), controllers, logger) is
  355 + {
  356 + failure then (failure, error_page(http_not_found, "Redirect Controller not found", new_session)),
  357 + success(new_controller) then apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, failure, initial_session, logger),
  358 + },
  359 +
  360 + redirect(new_session, r_controller_name, r_action_name) then
  361 + if get_controller(r_controller_name, controllers, logger) is
  362 + {
  363 + failure then (failure, error_page(http_not_found, "Redirect Controller "+r_controller_name+" not found", new_session)),
  364 + success(new_controller) then
  365 + apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, success(r_action_name), initial_session, logger),
  366 + },
  367 +
  368 + redirect_to_previous then
  369 + if get_controller(get_String(*_session.previous_web_request.lwa, "aws_controller", "root"), controllers, logger) is
  370 + {
  371 + failure then (failure, error_page(http_not_found, "Redirect to previous Controller not found", _session)),
  372 + success(new_controller) then
  373 + since _session is web_session(id, lang, entries, _, previous, draw),
  374 + apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, web_session(id, lang, entries, previous, previous, draw), failure, initial_session, logger),
  375 + },
  376 + redirect_to_previous(entries) then
  377 + if get_controller(get_String(*_session.previous_web_request.lwa, "aws_controller", "root"), controllers, logger) is
  378 + {
  379 + failure then (failure, error_page(http_not_found, "Redirect to previous Controller not found", _session)),
  380 + success(new_controller) then
  381 + since _session is web_session(id, lang, _, _, previous, draw),
  382 + apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, web_session(id, lang, entries, previous, previous, draw), failure, initial_session, logger),
  383 + },
  384 + //ajax(answer) then (failure, answer),
  385 + //ajax with modified session that must be saved
  386 + ajax(session, answer) then (session, answer),
  387 +
  388 + //ajax(content, additional_script) then (failure, json(http_ok, to_html_ajax_content(content, cinfo, additional_script))),
  389 + ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, cinfo, additional_script))),
  390 + //ajax(content, additional_script) then (failure, json(http_ok, to_html_ajax_content(content, additional_script))),
  391 + ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, additional_script))),
  392 + send_file(file_path, c_disposition) then (failure, send_file(file_path, c_disposition)),
  393 + renderer_content(session, content) then
  394 + with the_session = if session is {failure then _session, success(__session) then __session},
  395 + since the_session is web_session(id, lang, entries, current, previous, _),
  396 + with new_web_session = web_session(id, lang, entries, current, previous, current),
  397 +// println("***** renderer_content(session, content) record new draw point to *****");
  398 +// println("web arguments:"+
  399 +// dump_web_arg_values(*current.lwa));
  400 +// println("************************************");
  401 + with page_renderer = get_page_renderer(new_web_session, _current_page_renderer, page_renderers, logger),
  402 + (success(new_web_session), page_renderer.page_layout(new_web_session, plugins, content))
  403 + }
  404 + }
  405 +.
  406 +
  407 +
  408 +
  409 +public define Web_Site
  410 + make_web_site_controller_description
  411 + (
  412 + String website_name, // site_UID
  413 + List(String) common_names, // for example: ["www.our-business.com"]
  414 + String site_directory,
  415 + String state_directory,
  416 + One -> One init,
  417 + (HTTP_Info,
  418 + Var(List(Web_arg)),
  419 + Bool is_https) -> WEB_Session initial_session,
  420 + (WEB_Session,
  421 + HTTP_Info,
  422 + Var(List(Web_arg)),
  423 + Bool is_https) -> WEB_Session expired_session,
  424 + Var(List(WEB_Controller)) web_controllers,
  425 + Var(List(WEB_Page_Renderer)) web_page_renderers,
  426 + Var(List(WEB_Plugin)) web_plugins,
  427 + Maybe(WEB_Session) -> List(HTTP_header) additional_headers,
  428 + List(HTTP_header) constant_additional_headers,
  429 + Int timeout,
  430 + Redirections redirections,
  431 + String charset,
  432 + List(String) journal_extensions,
  433 + List(String) journal_headers,
  434 + (LogLevel, String) -> One logger, //logger
  435 + String secret,
  436 + List(MIME) known_mime_types,
  437 + (String action_name,
  438 + List(Web_arg) args) -> One before_send_file
  439 + )=
  440 + //call the initialization function
  441 + init(unique);
  442 +
  443 +
  444 + //
  445 + // make required directories (if needed)
  446 + //
  447 + with //web_sites_directory = (String) make_directory(my_anubis_directory+"/web_sites"),
  448 + base_directory = (String) make_directory(site_directory),
  449 + // state_directory = make_directory(site_directory+"/states"),
  450 + forget((String)make_directory(site_directory+"/public"));
  451 +
  452 + //
  453 + // construct tool functions
  454 + // TODO 'make_separate_web_args_function' must retrieve state_cookies before parsing web_args if using_state_cookies is true
  455 + with save_session = make_save_session_function(timeout, state_directory, logger),
  456 + with current_page_renderer = var((WEB_Page_Renderer)default_page_renderer),
  457 + // with left_menu_list = get_left_menu_from_plugins(*web_plugins),
  458 + // retrieve_session = make_retrieve_session_function(state_directory, website_name),
  459 + //separate_web_args = make_separate_web_args_function(state_directory, retrieve_state),
  460 + //apply_action = make_apply_action_function(actions),
  461 +
  462 + //
  463 + // construct the site handler
  464 + //
  465 + site_handler = (Word32 http_port, Word32 https_port) |->
  466 + ((String host_name,
  467 + HTTP_Info http_info,
  468 + List(Web_arg) _lwa,
  469 + Bool is_https) |->
  470 + //(Printable_tree)
  471 + logger(logTrace,"host_name "+host_name);
  472 + logger(logTrace, dump_http_info(http_info));
  473 + logger(logTrace, dump_web_arg_values(_lwa));
  474 + with cinfo = info(host_name, http_port, https_port, site_directory, secret),
  475 +
  476 + //retrieve the previous session and determine the new one
  477 + with current_session = if retrieve_session(http_info, state_directory, website_name) is
  478 + {
  479 + not_found then
  480 + logger(logInfo, "previous state not found");
  481 + initial_session(http_info, var(_lwa), is_https),
  482 +
  483 + out_of_date(previous_session) then
  484 + logger(logInfo, "previous out_of_date");
  485 + //expired_session(previous_session, http_info, var(_lwa), is_https),
  486 + since previous_session is web_session(id, lang, entries, previous, _, draw),
  487 + replace_String(entries, "IP", http_header_value(http_info.http_headers, "x-forwarded-for", ip_addr_to_string(http_info.ip_address)));
  488 + web_session(id, lang, entries, web_request(http_info, var(_lwa), is_https), previous, draw)
  489 +
  490 + still_valid(previous_session) then
  491 + since previous_session is web_session(id, lang, entries, previous, _, draw),
  492 + replace_String(entries, "IP", http_header_value(http_info.http_headers, "x-forwarded-for", ip_addr_to_string(http_info.ip_address)));
  493 + web_session(id, lang, entries, web_request(http_info, var(_lwa), is_https), previous, draw)
  494 + },
  495 +
  496 +
  497 + //apply the action according to current session
  498 + //since apply_controller_action(get_controller(get_String(lwa, "aws_controller", "root"), *web_controllers), *web_controllers, current_session)
  499 + since if get_controller(get_String(*current_session.web_request.lwa, "aws_controller", "root"), *web_controllers, logger) is
  500 + {
  501 + failure then
  502 + (failure, error_page(http_not_found, "Controller not found", current_session)),
  503 +
  504 + success(new_controller) then
  505 + apply_controller_action(new_controller, *web_plugins, *web_controllers, *current_page_renderer, *web_page_renderers, cinfo, current_session, failure, initial_session, logger),
  506 + }
  507 + is (mb_new_session, http_answer),
  508 +
  509 + //save the session if need and construct the according cookie
  510 + with cookie_headers =
  511 + if mb_new_session is
  512 + {
  513 + failure then [],
  514 + success(new_session) then
  515 + with session_name = save_session(new_session),
  516 + make_session_cookie_headers(website_name, session_name)
  517 + },
  518 +
  519 + //formatting and send http answer because this is the last function
  520 + format(cinfo,
  521 + //state_name,
  522 + additional_headers(mb_new_session) + cookie_headers,
  523 + http_answer,
  524 + is_https,
  525 + charset)
  526 + ),
  527 + //
  528 + // make the delete_out_of_date function
  529 + //
  530 + delete_out_of_date =
  531 + make_delete_out_of_date_sessions_function(site_directory+"/states", logger),
  532 + //
  533 + // construct the web site description
  534 + //
  535 + web_site((Word32 http_port, Word32 https_port) |->
  536 + web_site_description(common_names,
  537 + site_directory,
  538 + redirections,
  539 + charset,
  540 + journal_extensions,
  541 + journal_headers,
  542 + logger,
  543 + secret,
  544 + known_mime_types,
  545 + site_handler(http_port,https_port),
  546 + constant_additional_headers,
  547 + (HTTP_Info http_info, List(Web_arg) lwa) |-> unique
  548 +// if separate_web_args(lwa, http_info ) is
  549 +// swa(mb_previous_state,mb_action_name,operands) then
  550 +// if mb_action_name is
  551 +// {
  552 +// failure then unique
  553 +// success(an) then before_send_file(an,operands)
  554 +// }
  555 + //using_state_cookies
  556 + ),
  557 + delete_out_of_date).
  558 +
  559 +public type WEB_Controller:
  560 + web_controller(
  561 + String name, //controller name
  562 + Var(List(WEB_Action)) controller_actions, //list of all actions of that controller
  563 + (WEB_Session)-> WEB_Controller_Result error //Error renderer
  564 + )
  565 +.
  566 +
  567 +define (WEB_Session)-> WEB_Controller_Result
  568 + web_controller_error
  569 + (
  570 + String name
  571 + )=
  572 + (
  573 + WEB_Session session
  574 + ) |->
  575 + http_answer(session, web_controller_error_page(name)).
  576 +
  577 +public define WEB_Controller
  578 + web_controller
  579 + (
  580 + String name, //controller name
  581 + Var(List(WEB_Action)) controller_actions //list of all actions of that controller
  582 + //(WEB_Session)-> WEB_Controller_Result error //Error renderer
  583 + )=
  584 + web_controller(name, controller_actions, web_controller_error(name))
  585 +.
  586 +
  587 +public type WEB_Page_Renderer:
  588 + web_page_renderer(
  589 + String app, //application
  590 + String name, //renderer name
  591 + (WEB_Session _session, List(WEB_Plugin), HTML_Partial_Content _content) -> HTTP_Answer page_layout //call back for rendering page
  592 + )
  593 +.
  594 +
  595 +define WEB_Page_Renderer
  596 + default_page_renderer =
  597 + web_page_renderer("AWS", "AWS_DEFAULT_PAGE",
  598 + ( WEB_Session _session,
  599 + List(WEB_Plugin) _plugins,
  600 + HTML_Partial_Content _content
  601 + ) |->
  602 + with _title = get_page_title(_session),
  603 + html_page
  604 + (
  605 + http_ok,
  606 + [ title(_title), ]// title of web site
  607 + ,
  608 + body // body of page
  609 + (
  610 + [], //body options empty
  611 + (HTML_Off_Form)partial(_content)
  612 + )
  613 + )
  614 + )
  615 +.
  616 +
  617 +define WEB_Controller_Result
  618 + apply_action
  619 + (
  620 + WEB_Session _session,
  621 + String requested_action_name,
  622 + List(WEB_Action) actions_list
  623 + ) =
  624 + //println("apply_action ");
  625 + if actions_list is
  626 + {
  627 + [] then http_answer(error_page(http_not_found, "["+requested_action_name+"] Action not found in all controllers", _session)),
  628 + [h . t] then
  629 + if h.name = no_action then
  630 + http_answer( _session, html_content(http_no_content, empty))
  631 + else
  632 + with action_name = if h.name is
  633 + {
  634 + no_action then "",
  635 + controller_action(_, name) then name,
  636 + action_name(name) then name,
  637 + url(url) then url,
  638 + },
  639 + if requested_action_name = action_name then
  640 + with step = get_Int(_session.fields, "AWS_SESSION_STEP", 0) + 1,
  641 + replace_Int(_session.fields, "AWS_SESSION_STEP", step);
  642 + if h.allowed_proto is
  643 + {
  644 + //Action only in HTTP
  645 + http then
  646 + if _session.web_request.is_https then
  647 + http_answer(error_page(http_forbidden, "Only HTTP authorized", _session))
  648 + else
  649 + //ask to the server the authorization to execute that action
  650 + if h.allow(_session) then
  651 + h.do_it(_session)
  652 + else
  653 + http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))
  654 +
  655 + //Action only in HTTPS
  656 + https then
  657 + if _session.web_request.is_https then
  658 + //ask to the server the authorization to execute that action
  659 + if h.allow(_session) then
  660 + h.do_it(_session)
  661 + else
  662 + http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))
  663 + else
  664 + http_answer(error_page(http_forbidden, "Only HTTPS authorized", _session))
  665 + //Action in both HTTP / HTTPS
  666 + http_https then
  667 + //ask to the server the authorization to execute that action
  668 + if h.allow(_session) then
  669 + //println("do_it "+action_name);
  670 + h.do_it(_session)
  671 + else
  672 + http_answer(error_page(http_unauthorized, "you are not authorized for this action", _session))
  673 +
  674 + }
  675 + else
  676 + apply_action(_session, requested_action_name, t)
  677 + }
  678 +.
  679 +
  680 +define Maybe(WEB_Controller)
  681 + get_controller
  682 + (
  683 + String controller_name,
  684 + List(WEB_Controller) controllers,
  685 + (LogLevel, String) -> One logger //logger
  686 + )=
  687 + if controllers is
  688 + {
  689 + [] then
  690 + logger(logWarning, "Can't find controller ["+controller_name+"]");
  691 + failure,
  692 + [h . t] then
  693 + if h.name = controller_name then
  694 + //println("Controller ["+controller_name+"] found");
  695 + success(h)
  696 + else
  697 + get_controller(controller_name, t, logger)
  698 + }
  699 +.
  700 +
  701 +define WEB_Page_Renderer
  702 + get_page_renderer
  703 + (
  704 + String renderer_name,
  705 + List(WEB_Page_Renderer) renderers,
  706 + (LogLevel, String) -> One logger //logger
  707 + )=
  708 + if renderers is
  709 + {
  710 + [] then
  711 + logger(logWarning, "Can't find page_renderer ["+renderer_name+"], use the default");
  712 + default_page_renderer,
  713 + [h . t] then
  714 + if h.name = renderer_name then
  715 + //println("renderer_name ["+renderer_name+"] found");
  716 + h
  717 + else
  718 + //println("renderer_name "+renderer_name+" not matching");
  719 + get_page_renderer(renderer_name, t, logger)
  720 + }
  721 +.
  722 +
  723 +define WEB_Page_Renderer
  724 + get_page_renderer
  725 + (
  726 + WEB_Session _session,
  727 + WEB_Page_Renderer _current_page_renderer,
  728 + List(WEB_Page_Renderer) renderers,
  729 + (LogLevel, String) -> One logger //logger
  730 + )=
  731 + //get the renderer page name to use from the session "AWS_PAGE_RENDERER"
  732 + if get_String(_session.fields, "AWS_CURRENT_PAGE_RENDERER") is
  733 + {
  734 + failure then logger(logWarning, "No renderer defined, use the default"); default_page_renderer,
  735 + success(renderer_name) then
  736 + //check if the renderer_page already in cache
  737 + if renderer_name = _current_page_renderer.name then
  738 + _current_page_renderer
  739 + else
  740 + //if not in cache, use the selector function
  741 + get_page_renderer(renderer_name, renderers, logger)
  742 + }
  743 +.
  744 +
  745 +define (Maybe(WEB_Session), HTTP_Answer)
  746 + apply_controller_action
  747 + (
  748 + WEB_Controller controller,
  749 + List(WEB_Plugin) plugins,
  750 + List(WEB_Controller) controllers,
  751 + WEB_Page_Renderer _current_page_renderer,
  752 + List(WEB_Page_Renderer) page_renderers,
  753 + CommonInfo cinfo,
  754 + WEB_Session _session,
  755 + Maybe(String) _mb_action_name,
  756 + (HTTP_Info,
  757 + Var(List(Web_arg)),
  758 + Bool is_https) -> WEB_Session initial_session,
  759 + (LogLevel, String) -> One logger //logger
  760 + )=
  761 + //get the action name
  762 + with mb_action_name =
  763 + if _mb_action_name is
  764 + {
  765 + failure then get_String(*_session.web_request.lwa, "aws_action"),
  766 + success(_an) then success(_an)
  767 + },
  768 +
  769 + if mb_action_name is
  770 + {
  771 + failure then
  772 + //(failure, error_page(http_not_found, "Action name failure", _session)),
  773 + with new_session = initial_session(_session.web_request.http_info, _session.web_request.lwa, _session.web_request.is_https),
  774 + if get_controller(get_String(*new_session.web_request.lwa, "aws_controller", "root"), controllers, logger) is
  775 + {
  776 + failure then (failure, error_page(http_not_found, "Initial Session Controller not found", new_session)),
  777 + success(new_controller) then apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, failure, initial_session, logger),
  778 + },
  779 + success(action_name) then
  780 + //logger(logInfo, "ACTION_NAME ["+action_name+"] from IP "+get_String(_session.fields, "IP", ""));
  781 + if apply_action(_session, action_name, *controller.controller_actions) is
  782 + {
  783 + http_answer(session, answer) then
  784 + since session is web_session(id, lang, entries, current, previous, _),
  785 + with new_web_session = web_session(id, lang, entries, current, previous, current),
  786 +// println("***** http_answer(session, answer) record new draw point to *****");
  787 +// println("web arguments:"+
  788 +// dump_web_arg_values(*current.lwa));
  789 +// println("************************************");
  790 + (success(new_web_session), answer),
  791 +
  792 + http_answer(answer) then
  793 + since _session is web_session(id, lang, entries, current, previous, _),
  794 + with new_web_session = web_session(id, lang, entries, current, previous, current),
  795 +// println("***** http_answer(answer) record new draw point to *****");
  796 +// println("web arguments:"+
  797 +// dump_web_arg_values(*current.lwa));
  798 +// println("************************************");
  799 + (success(new_web_session), answer),
  800 +
  801 + redirect(new_session) then
  802 + if get_controller(get_String(*new_session.web_request.lwa, "aws_controller", "root"), controllers, logger) is
  803 + {
  804 + failure then (failure, error_page(http_not_found, "Redirect Controller not found", new_session)),
  805 + success(new_controller) then apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, failure, initial_session, logger),
  806 + },
  807 +
  808 + redirect(new_session, r_controller_name, r_action_name) then
  809 + if get_controller(r_controller_name, controllers, logger) is
  810 + {
  811 + failure then (failure, error_page(http_not_found, "Redirect Controller "+r_controller_name+" not found", new_session)),
  812 + success(new_controller) then
  813 + apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, new_session, success(r_action_name), initial_session, logger),
  814 + },
  815 +
  816 + redirect_to_previous then
  817 + if get_controller(get_String(*_session.previous_web_request.lwa, "aws_controller", "root"), controllers, logger) is
  818 + {
  819 + failure then (failure, error_page(http_not_found, "Redirect to previous Controller not found", _session)),
  820 + success(new_controller) then
  821 + since _session is web_session(id, lang, entries, _, previous, draw),
  822 + apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, web_session(id, lang, entries, previous, previous, draw), failure, initial_session, logger),
  823 + },
  824 + redirect_to_previous(entries) then
  825 + if get_controller(get_String(*_session.previous_web_request.lwa, "aws_controller", "root"), controllers, logger) is
  826 + {
  827 + failure then (failure, error_page(http_not_found, "Redirect to previous Controller not found", _session)),
  828 + success(new_controller) then
  829 + since _session is web_session(id, lang, _, _, previous, draw),
  830 + apply_controller_action(new_controller, plugins, controllers, _current_page_renderer, page_renderers, cinfo, web_session(id, lang, entries, previous, previous, draw), failure, initial_session, logger),
  831 + },
  832 + //ajax(answer) then (failure, answer),
  833 + //ajax with modified session that must be saved
  834 + ajax(session, answer) then (session, answer),
  835 +
  836 + //ajax(content, additional_script) then (failure, json(http_ok, to_html_ajax_content(content, cinfo, additional_script))),
  837 + ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, cinfo, additional_script))),
  838 + //ajax(content, additional_script) then (failure, json(http_ok, to_html_ajax_content(content, additional_script))),
  839 + ajax(session, content, additional_script) then (session, json(http_ok, to_html_ajax_content(content, additional_script))),
  840 + send_file(file_path, c_disposition) then (failure, send_file(file_path, c_disposition)),
  841 + renderer_content(session, content) then
  842 + with the_session = if session is {failure then _session, success(__session) then __session},
  843 + since the_session is web_session(id, lang, entries, current, previous, _),
  844 + with new_web_session = web_session(id, lang, entries, current, previous, current),
  845 +// println("***** renderer_content(session, content) record new draw point to *****");
  846 +// println("web arguments:"+
  847 +// dump_web_arg_values(*current.lwa));
  848 +// println("************************************");
  849 + with page_renderer = get_page_renderer(new_web_session, _current_page_renderer, page_renderers, logger),
  850 + (success(new_web_session), page_renderer.page_layout(new_web_session, plugins, content))
  851 + }
  852 + }
  853 +.
  854 +
  855 +
  856 +
  857 +public define Web_Site
  858 + make_web_site_controller_description
  859 + (
  860 + String website_name, // site_UID
  861 + List(String) common_names, // for example: ["www.our-business.com"]
  862 + String site_directory,
  863 + String state_directory,
  864 + One -> One init,
  865 + (HTTP_Info,
  866 + Var(List(Web_arg)),
  867 + Bool is_https) -> WEB_Session initial_session,
  868 + (WEB_Session,
  869 + HTTP_Info,
  870 + Var(List(Web_arg)),
  871 + Bool is_https) -> WEB_Session expired_session,
  872 + Var(List(WEB_Controller)) web_controllers,
  873 + Var(List(WEB_Page_Renderer)) web_page_renderers,
  874 + Var(List(WEB_Plugin)) web_plugins,
  875 + Maybe(WEB_Session) -> List(HTTP_header) additional_headers,
  876 + List(HTTP_header) constant_additional_headers,
  877 + Int timeout,
  878 + Redirections redirections,
  879 + String charset,
  880 + List(String) journal_extensions,
  881 + List(String) journal_headers,
  882 + (LogLevel, String) -> One logger, //logger
  883 + String secret,
  884 + List(MIME) known_mime_types,
  885 + (String action_name,
  886 + List(Web_arg) args) -> One before_send_file
  887 + )=
  888 + //call the initialization function
  889 + init(unique);
  890 +
  891 +
  892 + //
  893 + // make required directories (if needed)
  894 + //
  895 + with //web_sites_directory = (String) make_directory(my_anubis_directory+"/web_sites"),
  896 + base_directory = (String) make_directory(site_directory),
  897 + // state_directory = make_directory(site_directory+"/states"),
  898 + forget((String)make_directory(site_directory+"/public"));
  899 +
  900 + //
  901 + // construct tool functions
  902 + // TODO 'make_separate_web_args_function' must retrieve state_cookies before parsing web_args if using_state_cookies is true
  903 + with save_session = make_save_session_function(timeout, state_directory, logger),
  904 + with current_page_renderer = var((WEB_Page_Renderer)default_page_renderer),
  905 + // with left_menu_list = get_left_menu_from_plugins(*web_plugins),
  906 + // retrieve_session = make_retrieve_session_function(state_directory, website_name),
  907 + //separate_web_args = make_separate_web_args_function(state_directory, retrieve_state),
  908 + //apply_action = make_apply_action_function(actions),
  909 +
  910 + //
  911 + // construct the site handler
  912 + //
  913 + site_handler = (Word32 http_port, Word32 https_port) |->
  914 + ((String host_name,
  915 + HTTP_Info http_info,
  916 + List(Web_arg) _lwa,
  917 + Bool is_https) |->
  918 + //(Printable_tree)
  919 + logger(logTrace,"host_name "+host_name);
  920 + logger(logTrace, dump_http_info(http_info));
  921 + logger(logTrace, dump_web_arg_values(_lwa));
  922 + with cinfo = info(host_name, http_port, https_port, site_directory, secret),
  923 +
  924 + //retrieve the previous session and determine the new one
  925 + with current_session = if retrieve_session(http_info, state_directory, website_name) is
  926 + {
  927 + not_found then
  928 + logger(logInfo, "previous state not found");
  929 + initial_session(http_info, var(_lwa), is_https),
  930 +
  931 + out_of_date(previous_session) then
  932 + logger(logInfo, "previous out_of_date");
  933 + //expired_session(previous_session, http_info, var(_lwa), is_https),
  934 + since previous_session is web_session(id, lang, entries, previous, _, draw),
  935 + replace_String(entries, "IP", http_header_value(http_info.http_headers, "x-forwarded-for", ip_addr_to_string(http_info.ip_address)));
  936 + web_session(id, lang, entries, web_request(http_info, var(_lwa), is_https), previous, draw)
  937 +
  938 + still_valid(previous_session) then
  939 + since previous_session is web_session(id, lang, entries, previous, _, draw),
  940 + replace_String(entries, "IP", http_header_value(http_info.http_headers, "x-forwarded-for", ip_addr_to_string(http_info.ip_address)));
  941 + web_session(id, lang, entries, web_request(http_info, var(_lwa), is_https), previous, draw)
  942 + },
  943 +
  944 +
  945 + //apply the action according to current session
  946 + //since apply_controller_action(get_controller(get_String(lwa, "aws_controller", "root"), *web_controllers), *web_controllers, current_session)
  947 + since if get_controller(get_String(*current_session.web_request.lwa, "aws_controller", "root"), *web_controllers, logger) is
  948 + {
  949 + failure then
  950 + (failure, error_page(http_not_found, "Controller not found", current_session)),
  951 +
  952 + success(new_controller) then
  953 + apply_controller_action(new_controller, *web_plugins, *web_controllers, *current_page_renderer, *web_page_renderers, cinfo, current_session, failure, initial_session, logger),
  954 + }
  955 + is (mb_new_session, http_answer),
  956 +
  957 + //save the session if need and construct the according cookie
  958 + with cookie_headers =
  959 + if mb_new_session is
  960 + {
  961 + failure then [],
  962 + success(new_session) then
  963 + with session_name = save_session(new_session),
  964 + make_session_cookie_headers(website_name, session_name)
  965 + },
  966 +
  967 + //formatting and send http answer because this is the last function
  968 + format(cinfo,
  969 + //state_name,
  970 + additional_headers(mb_new_session) + cookie_headers,
  971 + http_answer,
  972 + is_https,
  973 + charset)
  974 + ),
  975 + //
  976 + // make the delete_out_of_date function
  977 + //
  978 + delete_out_of_date =
  979 + make_delete_out_of_date_sessions_function(site_directory+"/states", logger),
  980 + //
  981 + // construct the web site description
  982 + //
  983 + web_site((Word32 http_port, Word32 https_port) |->
  984 + web_site_description(common_names,
  985 + site_directory,
  986 + redirections,
  987 + charset,
  988 + journal_extensions,
  989 + journal_headers,
  990 + logger,
  991 + secret,
  992 + known_mime_types,
  993 + site_handler(http_port,https_port),
  994 + constant_additional_headers,
  995 + (HTTP_Info http_info, List(Web_arg) lwa) |-> unique
  996 +// if separate_web_args(lwa, http_info ) is
  997 +// swa(mb_previous_state,mb_action_name,operands) then
  998 +// if mb_action_name is
  999 +// {
  1000 +// failure then unique
  1001 +// success(an) then before_send_file(an,operands)
  1002 +// }
  1003 + //using_state_cookies
  1004 + ),
  1005 + delete_out_of_date).
  1006 +
web/plugin/plugin.anubis
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 */ 7 */
8 8
9 read system/logger.anubis 9 read system/logger.anubis
10 -read app/app_constants.anubis 10 + read app/app_constants.anubis
11 read calexium_lib/web/widgets/left_menu.anubis 11 read calexium_lib/web/widgets/left_menu.anubis
12 transmit calexium_lib/web/types/making_a_web_site.anubis 12 transmit calexium_lib/web/types/making_a_web_site.anubis
13 read calexium_lib/web/widgets/menu.anubis 13 read calexium_lib/web/widgets/menu.anubis
web/types/controllers_web_site.anubis 0 → 100644
  1 +/*
  2 + * Created by PyramIDE.
  3 + * User: フランスのトトロ aka (David RENÉ)
  4 + * Date: 08/10/2019
  5 + * Time: 05:32
  6 + * © David RENÉ
  7 + */
  8 +
  9 +transmit CXM_web_session.anubis
  10 +
  11 +public type WEB_Controller_Result:
  12 + http_answer(
  13 + WEB_Session session, //modified session
  14 + HTTP_Answer http_answer //http answer
  15 + ),
  16 + http_answer(
  17 + HTTP_Answer http_answer //http answer
  18 + ),
  19 + redirect( //internal redirection, session is modified to call the right controller and action
  20 + WEB_Session session
  21 + ),
  22 + redirect( //internal redirection, session is modified to call the right controller and action
  23 + WEB_Session session,
  24 + String controller,
  25 + String action_name
  26 + ),
  27 + redirect_to_previous,
  28 + redirect_to_previous(
  29 + Var(List(WEB_Session_Field)) fields
  30 + ),
  31 + ajax(
  32 + Maybe(WEB_Session) mb_session, //modified session if success else failure
  33 + HTTP_Answer http_answer //http answer
  34 + ),
  35 + ajax(
  36 + Maybe(WEB_Session) mb_session, //modified session if success else failure
  37 + HTML_Partial_Content content,
  38 + String additional_script
  39 + ),
  40 + ajax(
  41 + Maybe(WEB_Session) mb_session, //modified session if success else failure
  42 + Printable_tree content,
  43 + String additional_script
  44 + ),
  45 + send_file(
  46 + String full_path, //full path with file name of the file to send
  47 + Content_Disposition content_disposition //in which form the file must consider by the client (inline: try to display to user, attachment: save as file)
  48 + ),
  49 + renderer_content(
  50 + Maybe(WEB_Session) mb_session, //modified session if success else failure
  51 + //String title,
  52 + //Left_Menu left_menu,
  53 + HTML_Partial_Content content
  54 + )
  55 + //redraw with the current renderer, the given content
  56 +// redraw(
  57 +// Maybe(WEB_Session) mb_session, //modified session if success else failure
  58 +// HTML_Partial_Content content
  59 +// )
  60 +.
web/types/making_a_web_site.anubis
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 */ 7 */
8 transmit calexium_lib/web/types/web_action_name.anubis 8 transmit calexium_lib/web/types/web_action_name.anubis
9 transmit calexium_lib/web/CXM_common.anubis 9 transmit calexium_lib/web/CXM_common.anubis
10 -transmit calexium_lib/web/CXM_web_session.anubis 10 +
11 transmit calexium_lib/web/CXM_multihost_http_server.anubis 11 transmit calexium_lib/web/CXM_multihost_http_server.anubis
12 transmit calexium_lib/web/CXM_json.anubis 12 transmit calexium_lib/web/CXM_json.anubis
13 transmit calexium_lib/web/widgets/left_menu.anubis 13 transmit calexium_lib/web/widgets/left_menu.anubis
@@ -513,65 +513,6 @@ public type Body_Option: @@ -513,65 +513,6 @@ public type Body_Option:
513 public type HTML_Body: 513 public type HTML_Body:
514 body(List(Body_Option) options, HTML_Off_Form content). 514 body(List(Body_Option) options, HTML_Off_Form content).
515 515
516 -public type WEB_Controller_Result:  
517 - http_answer(  
518 - WEB_Session session, //modified session  
519 - HTTP_Answer http_answer //http answer  
520 - ),  
521 - http_answer(  
522 - HTTP_Answer http_answer //http answer  
523 - ),  
524 - redirect( //internal redirection, session is modified to call the right controller and action  
525 - WEB_Session session  
526 - ),  
527 - redirect( //internal redirection, session is modified to call the right controller and action  
528 - WEB_Session session,  
529 - String controller,  
530 - String action_name  
531 - ),  
532 - redirect_to_previous,  
533 - redirect_to_previous(  
534 - Var(List(WEB_Session_Field)) fields  
535 - ),  
536 - ajax(  
537 - Maybe(WEB_Session) mb_session, //modified session if success else failure  
538 - HTTP_Answer http_answer //http answer  
539 - ),  
540 - ajax(  
541 - Maybe(WEB_Session) mb_session, //modified session if success else failure  
542 - HTML_Partial_Content content,  
543 - String additional_script  
544 - ),  
545 - ajax(  
546 - Maybe(WEB_Session) mb_session, //modified session if success else failure  
547 - Printable_tree content,  
548 - String additional_script  
549 - ),  
550 - send_file(  
551 - String full_path, //full path with file name of the file to send  
552 - Content_Disposition content_disposition //in which form the file must consider by the client (inline: try to display to user, attachment: save as file)  
553 - ),  
554 - renderer_content(  
555 - Maybe(WEB_Session) mb_session, //modified session if success else failure  
556 - //String title,  
557 - //Left_Menu left_menu,  
558 - HTML_Partial_Content content  
559 - )  
560 - //redraw with the current renderer, the given content  
561 -// redraw(  
562 -// Maybe(WEB_Session) mb_session, //modified session if success else failure  
563 -// HTML_Partial_Content content  
564 -// )  
565 -.  
566 -  
567 -public type WEB_Action:  
568 - web_action(  
569 - WEB_Action_Name name, // name of action  
570 - WEB_Action_Allowed_Protocol allowed_proto,  
571 - (WEB_Session) -> Bool allow, // true if action allowed  
572 - (WEB_Session) -> WEB_Controller_Result do_it  
573 - )  
574 -.  
575 516
576 517
577 public type HTML_tooltip: 518 public type HTML_tooltip:
@@ -665,11 +606,4 @@ public type HTTP_Answer: @@ -665,11 +606,4 @@ public type HTTP_Answer:
665 HTML_Partial_Content) 606 HTML_Partial_Content)
666 . 607 .
667 608
668 -public type WEB_Controller:  
669 - web_controller(  
670 - String name, //controller name  
671 - Var(List(WEB_Action)) controller_actions, //list of all actions of that controller  
672 - (WEB_Session)-> WEB_Controller_Result error //Error renderer  
673 - )  
674 -.  
675 609