% 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 \verb$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.
\end{description}

    \predicate[nondet]{http_session_option}{1}{?Option}
True if \arg{Option} is a current option of the session system.

    \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.
\end{description}

