% This LaTeX document was generated using the LaTeX backend of PlDoc, % The SWI-Prolog documentation system \subsection{library(http/http_session): HTTP Session management} \label{sec:httpsession} This library defines session management based on HTTP cookies. Session management is enabled simply by loading this module. Details can be modified using \predref{http_set_session_options}{1}. By default, this module creates a session whenever a request is processes that is inside the hierarchy defined for session handling (see path option in \predref{http_set_session_options}{1}). Automatic creation of a session can be stopped using the option \verb$create(noauto)$. The predicate \predref{http_open_session}{2} must be used to create a session if \const{noauto} is enabled. Sessions can be closed using \predref{http_close_session}{1}. If a session is active, \predref{http_in_session}{1} returns the current session and \predref{http_session_assert}{1} and friends maintain data about the session. If the session is reclaimed, all associated data is reclaimed too. Begin and end of sessions can be monitored using \file{library(broadcast)}. The broadcasted messages are: \begin{description} \termitem{http_session}{begin(SessionID,Peer)} Broadcasted if a session is started \termitem{http_session}{end(SessionId,Peer)} Broadcasted if a session is ended. See \predref{http_close_session}{1}. \end{description} For example, the following calls \verb$end_session(SessionId)$ whenever a session terminates. Please note that sessions ends are not scheduled to happen at the actual timeout moment of the session. Instead, creating a new session scans the active list for timed-out sessions. This may change in future versions of this library. \begin{code} :- listen(http_session(end(SessionId, Peer)), end_session(SessionId)). \end{code} \vspace{0.7cm} \begin{description} \predicate[det]{http_set_session_options}{1}{+Options} Set options for the session library. Provided options are: \begin{description} \termitem{timeout}{+Seconds} Session timeout in seconds. Default is 600 (10 min). A timeout of \verb$0$ (zero) disables timeout. \termitem{cookie}{+Cookiekname} Name to use for the cookie to identify the session. Default \verb$swipl_session$. \termitem{path}{+Path} \arg{Path} to which the cookie is associated. Default is \verb$/$. Cookies are only sent if the HTTP request path is a refinement of \arg{Path}. \termitem{route}{+Route} Set the route name. Default is the unqualified hostname. To cancel adding a route, use the empty atom. See \predref{route}{1}. \termitem{enabled}{+Boolean} Enable/disable session management. Sesion management is enabled by default after loading this file. \termitem{create}{+Atom} Defines when a session is created. This is one of \const{auto} (default), which creates a session if there is a request whose path matches the defined session path or \const{noauto}, in which cases sessions are only created by calling \predref{http_open_session}{2} explicitely. \termitem{proxy_enabled}{+Boolean} Enable/disable proxy session management. Proxy session management associates the \textit{originating} IP address of the client to the session rather than the \textit{proxy} IP address. Default is false. \termitem{gc}{+When} \arg{When} is one of \const{active}, which starts a thread that performs session cleanup at close to the moment of the timeout or \const{passive}, which runs session GC when a new session is created. \termitem{samesite}{+Restriction} One of \const{none}, \const{lax} (default), or \const{strict} - The SameSite attribute prevents the CSRF vulnerability. strict has best security, but prevents links from external sites from operating properly. lax stops most CSRF attacks against REST endpoints but rarely interferes with legitimage operations. \const{none} removes the samesite attribute entirely. \textbf{Caution: The value \const{none} exposes the entire site to CSRF attacks.} \end{description} In addition, extension libraries can define \predref{session_option}{2} to make this predicate support more options. In particular, \file{library(http/http_redis_plugin)} defines the following additional options: \begin{description} \termitem{redis_db}{+DB} Alias name of the redis database to access. See \predref{redis_server}{3}. \termitem{redis_prefix}{+Atom} Prefix to use for all HTTP session related keys. Default is \verb$'swipl:http:session'$ \end{description} \predicate[nondet]{http_session_option}{1}{?Option} True if \arg{Option} is a current option of the session system. \predicate[semidet]{session_setting}{2}{+SessionID, ?Setting} Find setting for \arg{SessionID}. It is possible to overrule some session settings using \verb$http_session_set(Setting)$. \predicate[det]{http_set_session}{1}{Setting} \nodescription \predicate[det]{http_set_session}{2}{SessionId, Setting} Overrule a setting for the current or specified session. Currently, the only setting that can be overruled is \const{timeout}. \begin{tags} \tag{Errors} \verb$permission_error(set, http_session, Setting)$ if setting a setting that is not supported on per-session basis. \end{tags} \predicate[det]{http_session_id}{1}{-SessionId} True if \arg{SessionId} is an identifier for the current session. \begin{arguments} \arg{SessionId} & is an atom. \\ \end{arguments} \begin{tags} \tag{Errors} \verb$existence_error(http_session, _)$ \tag{See also} \predref{http_in_session}{1} for a version that fails if there is no session. \end{tags} \predicate[semidet]{http_in_session}{1}{-SessionId} True if \arg{SessionId} is an identifier for the current session. The current session is extracted from \verb$session(ID)$ from the current HTTP request (see \predref{http_current_request}{1}). The value is cached in a backtrackable global variable \verb$http_session_id$. Using a backtrackable global variable is safe because continuous worker threads use a failure driven loop and spawned threads start without any global variables. This variable can be set from the commandline to fake running a goal from the commandline in the context of a session. \begin{tags} \tag{See also} \predref{http_session_id}{1} \end{tags} \predicate[det]{http_open_session}{2}{-SessionID, +Options} Establish a new session. This is normally used if the create option is set to \const{noauto}. \arg{Options}: \begin{description} \termitem{renew}{+Boolean} If \const{true} (default \const{false}) and the current request is part of a session, generate a new session-id. By default, this predicate returns the current session as obtained with \predref{http_in_session}{1}. \end{description} \begin{tags} \tag{Errors} \verb$permission_error(open, http_session, CGI)$ if this call is used after closing the CGI header.\mtag{See also}- \predref{http_set_session_options}{1} to control the \const{create} option. \\- \predref{http_close_session}{1} for closing the session. \end{tags} \predicate[det]{http_session_asserta}{1}{+Data} \nodescription \predicate[det]{http_session_assert}{1}{+Data} \nodescription \predicate[nondet]{http_session_retract}{1}{?Data} \nodescription \predicate[det]{http_session_retractall}{1}{?Data} Versions of \predref{assert}{1}, \predref{retract}{1} and \predref{retractall}{1} that associate data with the current HTTP session. \predicate[nondet]{http_session_data}{1}{?Data} True if \arg{Data} is associated using \predref{http_session_assert}{1} to the current HTTP session. \begin{tags} \tag{Errors} \verb$existence_error(http_session,_)$ \end{tags} \predicate[det]{http_session_asserta}{2}{+Data, +SessionID} \nodescription \predicate[det]{http_session_assert}{2}{+Data, +SessionID} \nodescription \predicate[nondet]{http_session_retract}{2}{?Data, +SessionID} \nodescription \predicate[det]{http_session_retractall}{2}{@Data, +SessionID} \nodescription \predicate[det]{http_session_data}{2}{?Data, +SessionID} Versions of \predref{assert}{1}, \predref{retract}{1} and \predref{retractall}{1} that associate data with an explicit HTTP session. \begin{tags} \tag{See also} \predref{http_current_session}{2}. \end{tags} \predicate[nondet]{http_current_session}{2}{?SessionID, ?Data} Enumerate the current sessions and associated data. There are two \textit{pseudo} data elements: \begin{description} \termitem{idle}{Seconds} Session has been idle for \arg{Seconds}. \termitem{peer}{Peer} \arg{Peer} of the connection. \end{description} \predicate[det]{http_close_session}{1}{+SessionID} Closes an HTTP session. This predicate can be called from any thread to terminate a session. It uses the \predref{broadcast}{1} service with the message below. \begin{code} http_session(end(SessionId, Peer)) \end{code} The broadcast is done \textbf{before} the session data is destroyed and the listen-handlers are executed in context of the session that is being closed. Here is an example that destroys a Prolog thread that is associated to a thread: \begin{code} :- listen(http_session(end(SessionId, _Peer)), kill_session_thread(SessionID)). kill_session_thread(SessionID) :- http_session_data(thread(ThreadID)), thread_signal(ThreadID, throw(session_closed)). \end{code} Succeed without any effect if \arg{SessionID} does not refer to an active session. If \predref{http_close_session}{1} is called from a handler operating in the current session and the CGI stream is still in state \const{header}, this predicate emits a \verb$Set-Cookie$ to expire the cookie. \begin{tags} \tag{Errors} \verb$type_error(atom, SessionID)$ \tag{See also} \predref{listen}{2} for acting upon closed sessions \end{tags} \predicate[det]{http_session_cookie}{1}{-Cookie} Generate a random cookie that can be used by a browser to identify the current session. The cookie has the format XXXX-XXXX-XXXX-XXXX[.$<$route$>$], where XXXX are random hexadecimal numbers and [.$<$route$>$] is the optionally added routing information. \predicate[semidet,multifile]{hooked}{0}{} \nodescription \predicate[multifile]{hook}{1}{+Goal} These multifile predicates may be used to hook the data storage of this library. An example is implemented by \file{library(http/http_redis_plugin)}, storing all session data in a redis database. \end{description}