123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380# 1 "src/lib/eliom_route.server.ml"openEliom_libopenLwtopenOcsigen_extensionsincludeEliom_route_baseincludeEliom_route_base.Make(structtypesite_data=Eliom_common.sitedatatypeinfo=Eliom_common.infoletsess_info_of_info{Eliom_common.session_info;_}=session_infoletmeth_of_info{Eliom_common.request;_}=matchOcsigen_request.methrequest.request_infowith|`GET->`Get|`POST->`Post|`PUT->`Put|`DELETE->`Delete|_->`Otherletsubpath_of_info{Eliom_common.request;_}=Ocsigen_request.sub_pathrequest.request_infomoduleContainer=structtypet=Eliom_common.tablesletsettv=t.Eliom_common.table_services<-vletget{Eliom_common.table_services;_}=table_servicesletdlist_add?sptableslr=tables.Eliom_common.service_dlist_add?splrletset_contains_timeouttablesb=tables.Eliom_common.table_contains_services_with_timeout<-bendtypeparams=Eliom_common.server_paramstyperesult=Ocsigen_response.tmoduleNode=structtypet=(Eliom_common.page_tableref*Eliom_common.page_table_key,Eliom_common.na_key_serv)leftrightOcsigen_cache.Dlist.nodeletup=Ocsigen_cache.Dlist.upletremove=Ocsigen_cache.Dlist.removeendmoduleTable=structtypet=Eliom_common.page_tableletremove=Eliom_common.Serv_Table.removeletaddkvt=Eliom_common.Serv_Table.addk(`Ptcv)tletfindkt=let(`Ptcv)=Eliom_common.Serv_Table.findktinvletempty()=Eliom_common.Serv_Table.emptyendletmake_params=Eliom_common.make_server_paramslethandle_directory{Eliom_common.request=r;_}=Lwt.fail@@Ocsigen_extensions.Ocsigen_is_dir(Ocsigen_extensions.new_url_of_directory_requestr)letget_number_of_reloads()=Ocsigen_extensions.get_numberofreloads()end)letfind_auxnowsitedatainfo_sci:Ocsigen_response.tLwt.t=Eliom_common.Full_state_name_table.fold(funfullsessname(_,r)beg->try%lwtbegwith|Eliom_common.Eliom_404|Eliom_common.Eliom_Wrong_parameter->(match!rwith|Eliom_common.SCData_session_expired|Eliom_common.SCNo_data(* cookie removed *)->beg|Eliom_common.SCc->find_servicenow!(c.Eliom_common.sc_table)(Somefullsessname)sitedatainfo)|e->faile)sci(failEliom_common.Eliom_404)letsession_tables{Eliom_common.all_cookie_info;tab_cookie_info;_}=let(service_cookies_info,_,_),(secure_service_cookies_info,_,_)=all_cookie_infoand(service_cookies_info_tab,_,_),(secure_service_cookies_info_tab,_,_)=tab_cookie_infoin[!secure_service_cookies_info_tab,"secure tab session table";!service_cookies_info_tab,"tab session table";!secure_service_cookies_info,"secure session table";!service_cookies_info,"session table"]letdrop_most_paramsrisi=Ocsigen_request.updateri~post_data:None~meth:`GET~get_params_flat:si.Eliom_common.si_other_get_paramsletget_pagenow({Eliom_common.request=ri;session_info=si;_}asinfo)sitedata:Ocsigen_response.tLwt.t=lettables=session_tablesinfoincatch(fun()->List.fold_left(funbeg(table,table_name)->Lwt.catch(fun()->beg)(function|Eliom_common.Eliom_404|Eliom_common.Eliom_Wrong_parameter->Lwt_log.ign_info_f~section"Looking for %a in the %s:"(fun_ri->Url.string_of_url_path~encode:true(Ocsigen_request.sub_pathri.request_info))ritable_name;find_auxnowsitedatainfoEliom_common.Eliom_404table|e->Lwt.faile))(Lwt.failEliom_common.Eliom_404)tables)(function|Eliom_common.Eliom_404|Eliom_common.Eliom_Wrong_parameter->catch(* ensuite dans la table globale *)(fun()->Lwt_log.ign_info~section"Searching in the global table:";find_servicenowsitedata.Eliom_common.global_servicesNonesitedatainfo)(function|(Eliom_common.Eliom_404|Eliom_common.Eliom_Wrong_parameter)asexn->((* si pas trouvé avec, on essaie sans l'état *)matchsi.Eliom_common.si_state_infowith|Eliom_common.RAtt_no,Eliom_common.RAtt_no->failexn|g,Eliom_common.RAtt_anon_|g,Eliom_common.RAtt_named_->(* There was a POST state.
We remove it, and remove POST parameters.
*)Lwt_log.ign_info~section"Link too old. Try without POST parameters:";Polytables.set~table:(Ocsigen_request.request_cacheri.request_info)~key:Eliom_common.eliom_link_too_old~value:true;letrequest={riwithrequest_info=Ocsigen_request.updateri.request_info~post_data:None~meth:`GET}andsession_info={siwithEliom_common.si_nonatt_info=Eliom_common.RNa_no;Eliom_common.si_state_info=g,Eliom_common.RAtt_no}infail@@Eliom_common.Eliom_retry_with{infowithEliom_common.request;session_info}|Eliom_common.RAtt_named_,Eliom_common.RAtt_no|Eliom_common.RAtt_anon_,Eliom_common.RAtt_no->(* There was a GET state, but no POST state.
We remove it with its parameters,
and remove POST parameters.
*)Lwt_log.ign_info~section"Link to old. Trying without GET state parameters and POST parameters:";Polytables.set~table:(Ocsigen_request.request_cacheri.request_info)~key:Eliom_common.eliom_link_too_old~value:true;letrequest={riwithrequest_info=drop_most_paramsri.request_infosi}andsession_info=letopenEliom_commonin{siwithsi_nonatt_info=RNa_no;si_state_info=RAtt_no,RAtt_no;si_other_get_params=[]}infail@@Eliom_common.Eliom_retry_with{infowithEliom_common.request;session_info})|e->faile)|e->faile)letadd_naservice_tableat(key,elt)=matchatwith|Eliom_common.AVide->Eliom_common.ATable(Eliom_common.NAserv_Table.addkeyeltEliom_common.NAserv_Table.empty)|Eliom_common.ATablet->Eliom_common.ATable(Eliom_common.NAserv_Table.addkeyeltt)letfind_naservice_tableatk=matchatwith|Eliom_common.AVide->raiseNot_found|Eliom_common.ATablet->Eliom_common.NAserv_Table.findktletadd_naservicetablesname(max_use,expdate,naservice)=letsp=Eliom_common.get_sp_option()inletgeneration=Ocsigen_extensions.get_numberofreloads()in(ifsp=None(* not duringsession *)thentryletg,_,_,_,_=find_naservice_table!(tables.Eliom_common.table_naservices)nameinifg=generationthenmatchnamewith|Eliom_common.SNa_no|Eliom_common.SNa_get'_|Eliom_common.SNa_post'_->raise(Eliom_common.Eliom_duplicate_registration"<non-attached coservice>")|Eliom_common.SNa_get_n->raise(Eliom_common.Eliom_duplicate_registration("GET non-attached service "^n))|Eliom_common.SNa_post_n->raise(Eliom_common.Eliom_duplicate_registration("POST non-attached service "^n))|Eliom_common.SNa_void_dontkeep|Eliom_common.SNa_void_keep->raise(Eliom_common.Eliom_duplicate_registration"<void coservice>")|Eliom_common.SNa_get_csrf_safe_|Eliom_common.SNa_post_csrf_safe_->assertfalsewithNot_found->());(matchexpdatewith|Some_->tables.Eliom_common.table_contains_naservices_with_timeout<-true|_->());letnode=matchnamewith|Eliom_common.SNa_get'_|Eliom_common.SNa_post'_->Some(tables.Eliom_common.service_dlist_add?sp(Rightname))|_->Noneintables.Eliom_common.table_naservices:=add_naservice_table!(tables.Eliom_common.table_naservices)(name,(generation,max_use,expdate,naservice,node))letremove_naservice_tablesnamenodeopt=matchnodeoptwith|None->tables.Eliom_common.table_naservices:=Eliom_common.remove_naservice_table!(tables.Eliom_common.table_naservices)name|Somenode->Ocsigen_cache.Dlist.removenodeletfind_naservicenowtablesname=let((_,_,expdate,_,nodeopt)asp)=find_naservice_table!(tables.Eliom_common.table_naservices)nameinmatchexpdatewith|Some(_,e)when!e<now->(* Service expired. Removing it. *)Lwt_log.ign_info~section"Non attached service expired. Removing it";remove_naservice_tablesnamenodeopt;raiseNot_found|_->(matchnodeoptwith|Somenode->Ocsigen_cache.Dlist.upnode|None->());pletremove_naservicetablesname=let_,_,_,_,nodeopt=find_naservice_table!(tables.Eliom_common.table_naservices)nameinremove_naservice_tablesnamenodeoptletmake_naservicenow({Eliom_common.request=ri;session_info=si;_}asinfo)sitedata=letfind_auxsci=matchEliom_common.Full_state_name_table.fold(funfullsessname(_,r)beg->matchbegwith|Eliom_common.Found_->beg|Eliom_common.Notfound_->(match!rwith|Eliom_common.SCNo_data|Eliom_common.SCData_session_expired->beg|Eliom_common.SCc->(tryEliom_common.Found(find_naservicenow!(c.Eliom_common.sc_table)(Eliom_common.na_key_serv_of_reqsi.Eliom_common.si_nonatt_info),!(c.Eliom_common.sc_table),Somefullsessname)withNot_found->beg)))sci(Eliom_common.Notfound())with|Eliom_common.Foundv->v|Eliom_common.Notfound_->raiseNot_foundinlettables=session_tablesinfoin(trytryletrecf=function|[]->raiseNot_found|(table,table_name)::l->(Lwt_log.ign_info_f~section"Looking for a non attached service in the %s:"table_name;tryreturn(find_auxtable)withNot_found->fl)inftableswithNot_found->Lwt_log.ign_info~section"Looking for a non attached service in the global table";return(find_naservicenowsitedata.Eliom_common.global_services(Eliom_common.na_key_serv_of_reqsi.Eliom_common.si_nonatt_info),sitedata.Eliom_common.global_services,None)withNot_found->((* The non-attached service has not been found.
We call the same URL without non-attached parameters.
*)matchsi.Eliom_common.si_nonatt_infowith|Eliom_common.RNa_no->assertfalse|Eliom_common.RNa_post__|Eliom_common.RNa_post'_->(*VVV (Some, Some) or (_, Some)? *)Lwt_log.ign_info~section"Link too old to a non-attached POST coservice. Try without POST parameters:";Polytables.set~table:(Ocsigen_request.request_cacheri.request_info)~key:Eliom_common.eliom_link_too_old~value:true;Eliom_common.get_session_info~sitedata~req:{riwithOcsigen_extensions.request_info=drop_most_paramsri.request_infosi}si.Eliom_common.si_previous_extension_error>>=fun(ri',si',_previous_tab_cookies_info)->Lwt.fail@@Eliom_common.Eliom_retry_with{infowithrequest=ri';session_info=si'}|Eliom_common.RNa_get__|Eliom_common.RNa_get'_->Lwt_log.ign_info~section"Link too old. Try without non-attached parameters:";Polytables.set~table:(Ocsigen_request.request_cacheri.request_info)~key:Eliom_common.eliom_link_too_old~value:true;Eliom_common.get_session_info~sitedata~req:{riwithOcsigen_extensions.request_info=drop_most_paramsri.request_infosi}si.Eliom_common.si_previous_extension_error>>=fun(ri',si',_previous_tab_cookies_info)->Lwt.fail@@Eliom_common.Eliom_retry_with{infowithrequest=ri';session_info=si'}))>>=fun((_,max_use,expdate,naservice,node),tablewhereithasbeenfound,fullsessname)->letsp=Eliom_common.make_server_paramssitedatainfoNonefullsessnameinnaservicesp>>=funr->Lwt_log.ign_info~section"Non attached page found and generated successfully";(matchexpdatewithSome(timeout,e)->e:=timeout+.now|None->());(matchmax_usewith|None->()|Somer->if!r=1thenremove_naservice_tablewhereithasbeenfound(Eliom_common.na_key_serv_of_reqsi.Eliom_common.si_nonatt_info)nodeelser:=!r-1);returnr