123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233(* Ocsigen
* http://www.ocsigen.org
* Copyright (C) 2007 Vincent Balat
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)(*****************************************************************************)(*****************************************************************************)(** Internal functions used by Eliom: *)(** Service sessions *)(*****************************************************************************)(*****************************************************************************)openEliom_libletcompute_cookie_infositedatasecure_osecure_cicookie_info=letsecure=Eliom_common.get_secure~secure_o~sitedata()inifsecurethenletc,_,_=secure_ciinc,trueelsecookie_info,false(*****************************************************************************)letclose_service_state~scope~secure_o?sp()=letsp=Eliom_common.sp_of_optionspintryletcookie_level=Eliom_common.cookie_level_of_user_scopescopeinlet(cookie_info,_,_),secure_ci=Eliom_common.get_cookie_infospcookie_levelinletsitedata=Eliom_request_info.get_sitedata_sp~spinletcookie_info,secure=compute_cookie_infositedatasecure_osecure_cicookie_infoinletfull_st_name=Eliom_common.make_full_state_name~sp~secure~scopeinlet_,ior=Eliom_common.Full_state_name_table.findfull_st_name!cookie_infoinmatch!iorwith|Eliom_common.SCc->(* there is only one way to close a session:
remove it from the session group table.
It will remove the entry in the session table *)(matchscopewith|`Session_group_->((* If we want to close all the group of browser sessions,
the node is found in the group table: *)matchEliommod_sessiongroups.Serv.find_node_in_group_of_groups!(c.Eliom_common.sc_session_group)with|None->Lwt_log.ign_error~section:Lwt_log.eliom"No group of groups. Please report this problem."|Some(_service_table,g)->Eliommod_sessiongroups.Serv.removeg)|`Session_|`Client_process_->Eliommod_sessiongroups.Serv.removec.Eliom_common.sc_session_group_node);ior:=Eliom_common.SCNo_data|_->()withNot_found->()letfullsessgrp~cookie_level~spset_session_group=letsitedata=Eliom_request_info.get_sitedata_sp~spinEliommod_sessiongroups.make_full_group_name~cookie_level(Eliom_request_info.get_request_spsp).Ocsigen_extensions.request_info(Eliom_common.get_site_dir_stringsitedata)(Eliom_common.get_mask4sitedata)(Eliom_common.get_mask6sitedata)set_session_groupletrecfind_or_create_service_cookie_?set_session_group~(cookie_scope:Eliom_common.cookie_scope)~secure_o~sp()=(* If the cookie does not exist, create it.
Returns the cookie info for the cookie *)letcookie_level=Eliom_common.cookie_level_of_user_scopecookie_scopeinletnew_service_cookiesitedatafull_state_nametable=letset_session_group=matchcookie_scopewith|`Client_processn->(* We create a group whose name is the
browser session cookie
and put the tab session into it. *)letv=find_or_create_service_cookie_~cookie_scope:(`Sessionn)~secure_o~sp()inSomeEliom_common.(Hashed_cookies.to_stringv.sc_hvalue)|_->set_session_groupinletfullsessgrp=fullsessgrp~cookie_level~spset_session_groupinletc=Eliommod_cookies.make_new_session_id()inlethc=Eliom_common.Hashed_cookies.hashcinlethc_string=Eliom_common.Hashed_cookies.to_stringhcinletstr=ref(Eliom_common.new_service_session_tablessitedata)inlettimeout=refEliom_common.TGlobal(* See global table *)inletexpiry=refNone(*Some 0.*)(* None = never. We'll change it later. *)inletsession_group=reffullsessgrpinletsession_group_node=Eliommod_sessiongroups.Serv.addsitedatahc_stringfullsessgrpinEliom_common.SessionCookies.replace(* actually it will add the cookie *)tablehc_string{Eliom_common.Service_cookie.full_state_name;session_table=!str;expiry;timeout;session_group;session_group_node};{Eliom_common.sc_hvalue=hc;Eliom_common.sc_set_value=Somec;Eliom_common.sc_table=str;Eliom_common.sc_timeout=timeout;Eliom_common.sc_exp=expiry;Eliom_common.sc_cookie_exp=ref(Eliom_common.default_client_cookie_exp());Eliom_common.sc_session_group=session_group;Eliom_common.sc_session_group_node=session_group_node}inlet(cookie_info,_,_),secure_ci=Eliom_common.get_cookie_infospcookie_levelinletsitedata=Eliom_request_info.get_sitedata_sp~spinletcookie_info,secure=compute_cookie_infositedatasecure_osecure_cicookie_infoinletfull_st_name=Eliom_common.make_full_state_name~sp~secure~scope:cookie_scopeintrylet_old,ior=Eliom_common.Full_state_name_table.findfull_st_name!cookie_infoinmatch!iorwith|Eliom_common.SCData_session_expired(* We do not trust the value sent by the client,
for security reasons *)|Eliom_common.SCNo_data->letv=new_service_cookiesitedatafull_st_namesitedata.Eliom_common.session_servicesinior:=Eliom_common.SCv;v|Eliom_common.SCc->(matchset_session_groupwith|None->()|Some_session_group->letfullsessgrp=fullsessgrp~cookie_level~spset_session_groupinletnode=Eliommod_sessiongroups.Serv.movesitedatac.Eliom_common.sc_session_group_nodefullsessgrpinc.Eliom_common.sc_session_group_node<-node;c.Eliom_common.sc_session_group:=fullsessgrp);cwithNot_found->letv=new_service_cookiesitedatafull_st_namesitedata.Eliom_common.session_servicesincookie_info:=Eliom_common.Full_state_name_table.addfull_st_name(None,ref(Eliom_common.SCv))!cookie_info;vletfind_or_create_service_cookie_=(find_or_create_service_cookie_:?set_session_group:string->cookie_scope:Eliom_common.cookie_scope->secure_o:booloption->sp:Eliom_common.server_params->unit->Eliom_common.tablesEliom_common.one_service_cookie_info:>?set_session_group:string->cookie_scope:[<Eliom_common.cookie_scope]->secure_o:booloption->sp:Eliom_common.server_params->unit->Eliom_common.tablesEliom_common.one_service_cookie_info)letfind_or_create_service_cookie?set_session_group~cookie_scope~secure_o?sp()=letsp=Eliom_common.sp_of_optionspinfind_or_create_service_cookie_?set_session_group~cookie_scope~secure_o~sp()letfind_service_cookie_only~cookie_scope~secure_o?sp()=(* If the cookie does not exist, do not create it, raise Not_found.
Returns the cookie info for the cookie *)letsp=Eliom_common.sp_of_optionspinlet(cookie_info,_,_),secure_ci=Eliom_common.get_cookie_infosp(Eliom_common.cookie_level_of_user_scopecookie_scope)inletsitedata=Eliom_request_info.get_sitedata_sp~spinletcookie_info,secure=compute_cookie_infositedatasecure_osecure_cicookie_infoinletfull_st_name=Eliom_common.make_full_state_name~sp~secure~scope:cookie_scopeinlet_,ior=Eliom_common.Full_state_name_table.findfull_st_name!cookie_infoinmatch!iorwith|Eliom_common.SCNo_data->raiseNot_found|Eliom_common.SCData_session_expired->raiseEliom_common.Eliom_Session_expired|Eliom_common.SCv->v