blob: 87680d545e3588a1193fcd340d603be96422aeb2 [file] [log] [blame]
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
$Id$
-->
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/committees/docbook/xml/4.1.2/docbookx.dtd">
<article lang="en">
<title>Websh Reference 3.6.0b5</title>
<articleinfo>
<releaseinfo>
$Id$
</releaseinfo>
</articleinfo>
<section id="intro">
<title>Introduction</title>
<section id="general_remarks">
<title>General remarks</title>
<para>
Websh 3.6 (pronounced "web shell") embeds a Tcl interpreter,
(version 8.3 or higher) and all Tcl commands are available.
</para>
<para>
Typically, Websh commands have the following syntax:
<cmdsynopsis>
<command>web::acommand</command>
<arg choice="opt">options</arg>
<arg choice="opt">subcommands</arg>
<arg choice="opt">arguments</arg>
</cmdsynopsis>
Options start with a dash (&quot;-&quot;). As usual, dash-dash
(&quot;--&quot;) indicates the
&quot;end-of-options&quot;. Thus,
<programlisting>web::acommand -o1 a1 -- -o2</programlisting>
takes &quot;-o2&quot; as the first argument.
</para>
<para>
Instead of the normal Tcl behaviour, Websh configuration
commands normally return the previous value when a new value
is set.
</para>
<para>
In addition to the examples given here, you might find <ulink
url="http://tcl.apache.org/websh/examples/">http://tcl.apache.org/websh/examples/</ulink>
a useful source of information.
</para>
</section>
<section id="about">
<title>About this document</title>
<para>
The original version of this document can always be found at
<ulink
url="http://tcl.apache.org/websh/download/">http://tcl.apache.org/websh/download/</ulink>.
</para>
<note>
<para>
We try to keep this quick reference up-to-date and hope that
it will be useful. We do not guarantee that it is suitable for
any particular purpose whatsoever. The authors accept no
liability with regards to this information or its use.
</para>
</note>
</section>
</section>
<section id="configuration">
<title>Configuration</title>
<section id="web::config">
<title><command>web::config</command></title>
<cmdsynopsis>
<command>web::config</command>
<arg choice="req"><replaceable>key</replaceable></arg>
<arg choice="opt"><replaceable>value</replaceable></arg>
</cmdsynopsis>
<para>
If <option><replaceable>value</replaceable></option> is
ommitted, the current value of
<option><replaceable>key</replaceable></option> is returned. Note that
unlike the <command>set</command> command
<command>web::config</command> always returns the value
for the given key <emphasis>before</emphasis> the new value is set.
This allows to keep the old value and set it back later.
</para>
<variablelist>
<varlistentry>
<term><option>uploadfilesize</option>
<optional><option><replaceable>size</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets the maximum number of bytes that will be saved, when
files are uploaded in a multipart form. Default: 0.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>cmdparam</option> <optional><option><replaceable>name</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets name of the command parameter in
the URL used to dispatch to <command>web::command</command>
using <command>web::dispatch</command>. Default: &quot;cmd&quot;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>timeparam</option> <optional><option><replaceable>name</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets name of the timestamp parameter in the URL. Default:
&quot;t&quot;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>cmdurltimestamp</option> <optional><option>0|1</option></optional></term>
<listitem>
<para>
Defines whether the timestamp should be included in URLs
generated by <command>web::cmdurl</command>. Default: 1 (yes)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>logsubst</option> <optional><option>0|1</option></optional></term>
<listitem>
<para>
Turns substitution of log messages on (1) or off (0). Default:
0 (off).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>safelog</option> <optional><option>0|1</option></optional></term>
<listitem>
<para>
Makes <command>web::log</command> &quot;safe&quot; if set to 1
(i.e. it never throws an error even if corresponding I/O to
file, channel or command etc. fails). Default: 1 (on).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>putxmarkup</option>
<optional><option>brace|tag</option></optional></term>
<listitem>
<para>
Sets or gets the markup characters for sections to be eval'd in
<command>web::putx</command> and <command>web::putxfile</command>
commands to either curly braces ({ ... }) or special tags (&lt;?
... ?&gt;). Default: &quot;brace&quot;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>encryptchain</option> <optional><option><replaceable>list</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets the list of commands that should be tried, in
sequence, to encrypt a message.
Default: &quot;web::encryptd&quot;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>decryptchain</option> <optional><option><replaceable>list</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets the list of commands that should be tried, in
sequence, to decrypt a message.
Default: &quot;web::decryptd&quot;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>filepermissions</option> <optional><option><replaceable>permissions</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets the file permissions of files that Websh creates.
This affects the creation of log files, filecounters, session
files, and temporary files created when files are uploaded in
multipart forms (see <command>web::formvar</command>). Default:
0644.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The following special subcommand is used to reset all configuration
options to their default values:
</para>
<variablelist>
<varlistentry>
<term><option>reset</option></term>
<listitem>
<para>
Resets all values to their defaults.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The following two subcommands are read-only and just return their
predefined values:
</para>
<variablelist>
<varlistentry>
<term><option>version</option></term>
<listitem>
<para>
Returns the version info string.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>copyright</option></term>
<listitem>
<para>
Returns a copyright message string.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The following subcommands are also read-only. They return the
current request environment within mod_websh (and if applicable
in CGI mode):
</para>
<variablelist>
<varlistentry>
<term><option>script</option></term>
<listitem>
<para>
Returns the path to the currently requestes Websh script.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>server_root</option></term>
<listitem>
<para>
Returns the Apache ServerRoot configuration path.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>document_root</option></term>
<listitem>
<para>
Returns the Apache DocumentRoot configuration path.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>interpclass</option></term>
<listitem>
<para>
Returns the interpclass the current request was mapped to
(see <command>web::interpmap</command> command).
</para>
</listitem>
</varlistentry>
</variablelist>
<example>
<title><command>web::config</command></title>
<programlisting>
% web::config decryptchain
web::encryptd
% web::config filepermissions 0666
0644
% web::config filepermissions
0666
% web::config putxmarkup tag
brace
% web::config reset
% web::config filepermissions
0644
% web::config putxmarkup
brace
% </programlisting>
</example>
</section>
</section>
<section id="command_dispatching_and_session_management">
<title>Command dispatching and session management</title>
<para>
Websh provides a command dispatching mechanism to produce,
for example, different HTML pages within one "application",
which is most likely one file on the file system. The name of
the command to be used for a particular page is encoded in the
querystring (see <command>web::cmdurl</command> for details on
how to produce such querystrings). Command dispatching is
initiated with the command <command>web::dispatch</command>.
Commands are defined with <command>web::command</command>.
</para>
<section id="web::command">
<title><command>web::command</command></title>
<para>
<cmdsynopsis>
<command>web::command</command>
<arg choice="opt"><replaceable>cmdName</replaceable></arg>
<arg choice="req"><replaceable>cmdBody</replaceable></arg>
</cmdsynopsis>
Registers <option>cmdBody</option> as
<option>cmdName</option>. If <option>cmdName</option> is
omitted, "default" is used.
<example>
<title>Simple command dispatching</title>
<programlisting>
proc page {title code} {
web::put &quot;&lt;html&gt;&lt;title&gt;[web::htmlify $title]&lt;/title&gt;&lt;body&gt;&quot;
web::put &quot;&lt;h1&gt;[web::htmlify $title]&lt;/h1&gt;&quot;
uplevel 1 $code
web::put {&lt;/body&gt;&lt;/html&gt;}
}
web::command default {
page &quot;Home&quot; {
web::put &quot;&lt;a href=\&quot;[web::cmdurl page1]\&quot;&gt;Link to Page 1&lt;/a&gt;&quot;
web::put &quot;&lt;br/&gt;&quot;
web::put &quot;&lt;a href=\&quot;[web::cmdurl page2]\&quot;&gt;Link to Page 2&lt;/a&gt;&quot;
}
}
web::command page1 {
page &quot;Page 1&quot; {
web::put &quot;&lt;a href=\&quot;[web::cmdurl default]\&quot;&gt;Home&lt;/a&gt;&quot;
}
}
web::command page2 {
page &quot;Page 2&quot; {
web::put &quot;&lt;a href=\&quot;[web::cmdurl default]\&quot;&gt;Home&lt;/a&gt;&quot;
}
}
web::dispatch</programlisting>
</example>
</para>
</section>
<section id="web::getcommand">
<title><command>web::getcommand</command></title>
<para>
<cmdsynopsis>
<command>web::getcommand</command>
<arg choice="opt"><replaceable>cmdName</replaceable></arg>
</cmdsynopsis>
Retrieves the body of the command <option>commandName</option>
or of the command &quot;default&quot; if
<option>cmdName</option> is omitted.
</para>
</section>
<section id="web::cmdurl">
<title><command>web::cmdurl</command></title>
<para>
<cmdsynopsis>
<command>web::cmdurl</command>
<arg choice="opt"><replaceable>options</replaceable></arg>
<arg choice="req"><replaceable>cmdName</replaceable></arg>
<arg choice="opt"><replaceable>key-value-list</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>web::cmdurl</command>
<arg choice="opt"><replaceable>options</replaceable></arg>
<arg choice="req"><replaceable>cmdName</replaceable></arg>
<arg choice="opt"><replaceable>k1 v1 ... kN vN</replaceable></arg>
</cmdsynopsis>
</para>
<para>
Options are: <option>-notimestamp</option>, and
<option>-urlformat</option>
</para>
<para>
Generate URLs including querystring. By default, URLs are
self-referencing, but the exact output is subject to
configuration. The querystring is encrypted, using the
encryption method specified by configuration (see
<command>web::config</command>). If <option>cmdName</option>
is &quot;&quot;, no command parameter is produced in the query
string.
<variablelist>
<varlistentry>
<term><option>-notimestamp</option></term>
<listitem>
<para>
Tells Websh not to add a timestamp to URLs.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-urlformat</option> <option><replaceable>list</replaceable></option></term>
<listitem>
<para>
Specifies which items will be used to format just this
URL. Default: <command>{scriptname pathinfo
querystring}</command>.
</para>
<para>
Note: Use <command>web::cmdurlcfg</command> to define the
url format for all URLs produced by
<command>web::cmdurl</command> in one request.
</para>
<para>
<variablelist>
<varlistentry>
<term><option>scheme</option></term>
<listitem>
<para>
Includes the protocol, only &quot;http&quot;
and &quot;https&quot; are currently supported.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>host</option></term>
<listitem>
<para>
Includes the host name,
e.g. &quot;websh.com&quot;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>port</option></term>
<listitem>
<para>
Includes the port,
e.g. &quot;80&quot;</para><para> Trying to set
this item without host will throw an error.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>scriptname</option></term>
<listitem>
<para>
Includes scriptname,
e.g. &quot;/cgi-bin/orderbooks&quot;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>pathinfo</option></term>
<listitem>
<para>
Includes pathinfo,
e.g. &quot;/merchants/shop1&quot;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>querystring</option></term>
<listitem>
<para>
Includes the querystring,
e.g. &quot;select=download&quot;.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
<note>
Note that there are two more commands that control
the output of <command>web::cmdurl</command>:
<command>web::config</command> <option>cmdparam</option>
and
<command>web::config</command> <option>timeparam</option>.
</note>
</para>
<example>
<title><command>web::cmdurl</command></title>
<programlisting>
% web::cmdurl -notimestamp -urlformat [list scheme host scriptname pathinfo querystring] &quot;test&quot;
http://websh.com/bin/returnmail/member?XDZuRD2rnsfHjFH
% </programlisting>
</example>
</section>
<section id="web::cmdurlcfg">
<title><command>web::cmdurlcfg</command></title>
<para>
<cmdsynopsis>
<command>web::cmdurlcfg</command>
<arg choice="opt"><replaceable>option</replaceable></arg>
<arg choice="opt"><replaceable>key</replaceable></arg>
<arg choice="opt"><replaceable>value</replaceable></arg>
</cmdsynopsis>
</para>
<para>
Command options are exactly like those of
<command>web::param</command>.
</para>
<para>
<cmdsynopsis>
<command>web::cmdurlcfg</command>
<arg choice="req"><replaceable>option</replaceable></arg>
<arg choice="opt"><replaceable>value</replaceable></arg>
</cmdsynopsis>
</para>
<para>
Options are <option>-scheme</option>,
<option>-host</option>, <option>-port</option>,
<option>-scriptname</option>,
<option>-pathinfo</option>,
<option>-querystring</option>,
<option>-urlformat</option></para><para> If
<option>value</option> is omitted, the current value is
returned. Otherwise, the <option>value</option> is stored.
Configuration for <command>web::cmdurl</command>.
This command serves two purposes:
<orderedlist>
<listitem><para>Management of static parameters</para></listitem>
<listitem><para>Configuration for
<command>web::cmdurl</command></para></listitem>
</orderedlist>
By "static parameters", we mean those which are set for every
page, instead of set on a per-page basis.
</para>
</section>
<section id="management_of_static_parameters">
<title>Management of static parameters</title>
<para>
In addition to the easy way of tracking parameters using
<command>web::dispatch -track ...</command>, specific values
for parameters can be set using <command>web::cmdurlcfg</command>:
In order to explicitly set, retrieve, append or unset static
parameters, use the syntax of the <command>web::param</command>
command, for example:
<variablelist>
<varlistentry>
<term><command>web::cmdurlcfg</command> -set
<option><replaceable>key</replaceable></option>
<option><replaceable>value</replaceable></option></term>
<listitem>
<para>
Adds the static parameter <option>key</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::cmdurlcfg</command> -names</term>
<listitem>
<para>
Returns a list of all known static parameters.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
<emphasis>Important</emphasis>: <command>web::cmdurl</command>
compares every key from the static parameters (see
<command>web::cmdurlcfg</command>) against the keys from the
command line. The static parameter is only used if there is no
parameter of the same name given on the command line.
</para>
</section>
<section id="configuration_for_web_cmdurl">
<title>Configuration for <command>web::cmdurl</command></title>
<para>
<variablelist>
<varlistentry>
<term><option>-scheme</option> <optional><option><replaceable>value</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets protocol to be used. Defaults to the scheme used
to access the page, which is overridden if the user
sets a value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-host</option> <optional><option><replaceable>value</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets server name to be used. Default: taken from
request.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-port</option></term>
<listitem>
<para>
Sets or gets port number to be used. Default: taken from
request, 80 if not available.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-scriptname</option></term>
<listitem>
<para>
Sets or gets name of CGI executable. Default: taken from
request.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-pathinfo</option></term>
<listitem>
<para>
Sets or gets path info (path after scriptname). Default:
taken from request.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-urlformat</option> <option><replaceable>list</replaceable></option></term>
<listitem>
<para>
Sets or gets the urlformat permanently. See
<command>web::cmdurl</command> for the description of
this option.
</para>
</listitem>
</varlistentry>
</variablelist>
In all these cases, &quot;<command>web::cmdurlcfg -option
<option>value</option></command>&quot; sets the value of the given
option and returns the value that was used before the change,
while &quot;<command>web::cmdurlcfg -option</command>&quot; returns
the current value. If no value has been set using
<command>web::cmdurlcfg</command>, but is
requested for the URL generation, the value from the request
will be used. This value, however, can not be retrieved using
<command>web::cmdurlcfg</command>.
<variablelist>
<varlistentry>
<term><option>-reset</option></term>
<listitem>
<para>
Resets the <command>web::cmdurlcfg</command> configuration.
Note however, that static parameters will not be reset by this
option. To get rid of static parameters configured with the
<command>-set</command> option, use <command>-unset</command>
with (for a specific parameter) or without (for all parameters)
key.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
<emphasis>Note</emphasis> that setting a value to an empty string
is the same as using <command>-unset</command>.
</para>
<para>
<emphasis>Also note</emphasis>: <command>web::cmdurl</command>
compares every key from the static parameters against
the keys from the command line. The static parameter is only
used if there is no such parameter on the command line.
</para>
<example>
<title><command>web::cmdurl</command> and <command>web::cmdurlcfg</command></title>
<programlisting>
% web::cmdurl &quot;&quot;
?XDqPtk34XvyPh41gUBo
% web::cmdurlcfg -scriptname bin/test_script
% web::cmdurl &quot;&quot;
bin/test_script?XDqPtk34XvyPh41gUBo
% web::cmdurlcfg -scriptname &quot;&quot;
% web::cmdurl &quot;&quot;
?XDqPtk34XvyPh41gUBo
% web::cmdurlcfg -urlformat {scheme host port querystring}
scriptname pathinfo querystring
% # for clearer view on what happens: disable querystring encryption
% web::config encryptchain {}
web::encryptd
% web::cmdurlcfg -set foo bar
bar
% web::cmdurlcfg -host tcl.apache.org
% web::cmdurl zoo
http://tcl.apache.org:80?foo=bar&amp;cmd=zoo&amp;t=1141776460
% web::cmdurlcfg -reset
% web::cmdurl zoo
?foo=bar&amp;cmd=zoo&amp;t=1141776496
% web::config cmdurltimestamp 0
1
% web::config cmdparam page
cmd
% web::cmdurl zoo
?foo=bar&amp;page=zoo
% </programlisting>
</example>
</section>
<section id="web::dispatch">
<title><command>web::dispatch</command></title>
<para>
<cmdsynopsis>
<command>web::dispatch</command>
<arg choice="opt"><replaceable>options</replaceable></arg>
</cmdsynopsis>
Options are: <option>-cmd</option>,
<option>-querystring</option>, <option>-postdata</option>,
<option>-track</option> and <option>-hook</option>.
</para>
<para>
Parse information and call a command.
</para>
<para>
<variablelist>
<varlistentry>
<term><option>-cmd</option> <option><replaceable>cmdName</replaceable></option></term>
<listitem>
<para>
Switches to command <option>cmdName</option>. If
<option>cmdName</option> is an empty string, no
command is called. By default,
<option>cmdName</option> is taken from the
querystring.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-querystring</option>
<option><replaceable>string</replaceable></option></term>
<listitem>
<para>
Parses <option>string</option> as the querystring. If
<option>string</option> is an empty string,
querystring parsing is turned off. By default,
querystring is taken from the request data (CGI
environment or apache module request object).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-postdata</option> <option>&quot;&quot;</option></term>
<listitem>
<para>
Do not parse any post data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-postdata</option> <optional><option>#</option></optional><option><replaceable>channelName</replaceable></option>
<option><replaceable><optional>content_length</optional></replaceable></option>
<option><replaceable><optional>content_type</optional></replaceable></option>
</term>
<listitem>
<para>
Parse channel <option>channelName</option> (or variable
named <option>channelName</option> if <option>#</option> is
given) as POST data input with length
<option>content_length</option> and type
<option>content_type</option>. <option>content_type</option>
can be <literal
remap="tt">application/x-www-form-urlencoded</literal>
or <literal remap="tt">multipart/form-data;
boundary=xxx</literal>.
In the case of multipat form data,
<option>content-type</option> must specify the
boundary as well. By default, POST data is taken from
the request data.</para><para> Default for
<option>content_type</option> is <literal
remap="tt">application/x-www-form-urlencoded</literal>.
Default for <option>content_length</option> is to read a
channel up to EOF or the full content of the variable.
</para>
<para>
Use the keyword <literal remap="tt">end</literal> for
<option>content_length</option> to indicate that
Websh should read all content.</para><para>
Supported content types are:
<itemizedlist>
<listitem><para><literal remap="tt">multipart/form-data; boundary=xxxx</literal></para></listitem>
<listitem><para><literal remap="tt">application/x-www-form-urlencoded</literal> (default)</para></listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-track</option> <option><replaceable>paramKeyList</replaceable></option></term>
<listitem>
<para>
Track a parameter: register it as &quot;static&quot;
for the generation of URLs with
<command>web::cmdurl</command>. Thus,
each parameter with the key in
<option>paramKeyList</option> will be repeated in
every URL generated with <command>web::cmdurl</command>.
See the documentation of <command>web::cmdurl</command> for
details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-hook</option> <option><replaceable>code</replaceable></option></term>
<listitem>
<para>
Causes <command>web::dispatch</command> to eval
<option>code</option>
just before the command (from any source) is
evaluated. When <option>code</option> is evaluated,
the full request information has been parsed. That
is, <command>web::param</command>,
<command>web::formvar</command> etc. will have up-to-date
information when <option>code</option> is evaluated.
</para>
</listitem>
</varlistentry>
</variablelist>
<emphasis>Note</emphasis>: If no command is passed to
<command>web::dispatch</command> either in the querystring or with the
<option>-cmd</option> option, <command>web::dispatch</command> will
call the command &quot;default&quot;.
</para>
<example>
<title><command>web::command</command> and <command>web::dispatch</command></title>
<programlisting>
% set tst {puts &quot;On the hook&quot;}
puts &quot;On the hook&quot;
% web::command acmd {puts &quot;this is acmd&quot;}
% web::dispatch -cmd acmd -querystring &quot;&quot; -postdata &quot;&quot;
this is acmd
% web::dispatch -cmd acmd -querystring &quot;&quot; -postdata &quot;&quot; -hook $tst
On the hook
this is acmd
% set data &quot;a=b&amp;c=d&quot;
a=b&amp;c=d
% web::dispatch -cmd &quot;&quot; -querystring &quot;&quot; -postdata #data
% web::formvar a
b
% web::formvar c
d
% </programlisting>
</example>
</section>
<section id="session_management">
<title>Session management</title>
<para>
Websh session management consits of two parts:
<itemizedlist>
<listitem><para>Session id tracking</para></listitem>
<listitem><para>Session context management</para></listitem>
</itemizedlist>
</para>
<para>
Session context managers are described in detail below
(<command>web::filecontext</command>,
<command>web::cookiecontext</command>). Session id tracking is
managed by <command>web::dispatch -track</command>. The two
parts are connected with the <option>-attachto</option> option
of the session context manager. The control is as follows:
</para>
<para>
<itemizedlist>
<listitem>
<para>
A user uses the Websh script for the first
time.<command>web::dispatch -track</command> will not
see any session id, and, consequently, not set the
static parameter <literal remap="tt">id</literal>.
</para>
</listitem>
<listitem>
<para>
Within the application, the session is initialized using
<command>mgr::init</command>. <command>init</command>
will find no static parameter <literal
remap="tt">id</literal> (which has been specified at
creation time of the session manager using the
<option>-attachto</option> option). Now, it tries to
create a new session id. This will be possible if a
session id generator has been specified when the manager
was created using the <option>-idgen</option> option.
From now, on the session id will be a static parameter,
and will therefore be present in every URL generated
with <command>web::cmdurl</command>.
</para>
</listitem>
<listitem>
<para>
The next time the user visits the Websh application
using one of these URLs,
<command>web::dispatch</command> will detect the
session id, and <command>mgr::init</command> will directly load
the corresponding session context without generating a
new session id.
</para>
</listitem>
</itemizedlist>
</para>
<example>
<title>Examples</title>
<para>
See <ulink
url="http://tcl.apache.org/websh/examples/">http://tcl.apache.org/websh/examples/</ulink>
for several sample application demonstrating Websh's
session management facilities.
</para>
</example>
</section>
</section>
<section id="request_data_handling">
<title>Request data handling</title>
<section id="web::request">
<title><command>web::request</command></title>
<para>
<cmdsynopsis>
<command>web::request</command>
<arg choice="opt"><replaceable>options</replaceable></arg>
<arg choice="opt"><replaceable>key</replaceable></arg>
<arg choice="opt"><replaceable>value</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>web::request</command>
<arg choice="opt"><replaceable>key</replaceable></arg>
<arg choice="opt"><replaceable>default</replaceable></arg>
</cmdsynopsis>
</para>
<para>
Options are: <option>-count</option>, <option>-set</option>,
<option>-lappend</option>, <option>-names</option>,
<option>-unset</option>, <option>-reset</option> and
<option>-channel</option>
</para>
<para>
<command>web::request</command> is an accessor to request
specific information: either CGI related (stand alone
Websh) or Apache related (mod_websh).
<variablelist>
<varlistentry>
<term><command>web::request</command> <option>-names</option></term>
<listitem>
<para>
Returns a list of all known keys.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command> <option><replaceable>key</replaceable></option>
<optional><option><replaceable>default</replaceable></option></optional></term>
<listitem>
<para>
Returns the value for <option>key</option>. Can be a
list. In case that <option>key</option> does not
exist, return <option>default</option>, if it is
given, or an empty string.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command>
<option>-count</option> <option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Returns number of items in list for
<option>key</option>; returns 0 if
<option>key</option> does not exist.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command>
<option>-set</option> <option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Does the same as <command>web::request</command>
<option>key</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command>
<option>-set</option> <option><replaceable>key</replaceable></option>
<option><replaceable>value</replaceable></option>
<optional><option><replaceable>value</replaceable></option></optional>
<optional><option><replaceable>...</replaceable></option></optional></term>
<listitem>
<para>
Adds the parameter <option>key</option> to the
<command>web::request</command> data. Any existing parameters
with <option>key</option> are overwritten.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command>
<option>-lappend</option> <option><replaceable>key</replaceable></option>
<option><replaceable>value</replaceable></option>
<optional><option><replaceable>value</replaceable></option></optional>
<optional><option><replaceable>...</replaceable></option></optional></term>
<listitem>
<para>
Appends parameters with the same <option>key</option>
to the <command>web::request</command> data. In this case
the existing <option>value</option> is not overwritten.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command>
<option>-unset</option></term>
<listitem>
<para>
Deletes all parameters from the <command>web::request</command> data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command>
<option>-unset</option> <option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Deletes a parameter from the <command>web::request</command> data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command>
<option>-reset</option></term>
<listitem>
<para>
Deletes all parameters from the <command>web::request</command>
data (like '<command>web::request -unset</command>'),
removes all static parameters (like
'<command>web::cmdurlcfg -unset</command>'), all form
variables (like '<command>web::formvar -unset</command>'),
all query string parameters (like
'<command>web::param -unset</command>'), and all
temporary files created by HTTP form upload.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command>
<option>-channel</option></term>
<listitem>
<para>
Returns the preset default channel for the current request.
(Note that this is not necessarily the currently selected
channel.)
</para>
</listitem>
</varlistentry>
</variablelist>
Special case for handling Basic Auth:
<variablelist>
<varlistentry>
<term><command>web::request</command> <option>AUTH_USER</option></term>
<listitem>
<para>
Returns the username provided by the user when Basic Auth is
requested and Apache does not handle it (i.e. if Apache does
not provide REMOTE_USER).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::request</command> <option>AUTH_PW</option></term>
<listitem>
<para>
Returns the password provided by the user when Basic Auth is
requested and Apache does not handle it (i.e. if Apache does
not provide REMOTE_USER).
</para>
</listitem>
</varlistentry>
</variablelist>
The following example provides a basic app that requires Basic Auth and
completely bypasses Apache's auth mechanisms.
<example>
<title><command>web::request AUTH_USER</command> and <command>web::request AUTH_PW</command></title>
<programlisting>
# returns 1 if user/pass provided is websh/websh
proc isAuthenticated {} {
if {[web::request -count AUTH_USER]} {
set user [web::request AUTH_USER]
set pass [web::request AUTH_PW]
if {[string eq $user "websh"] &amp;&amp; [string eq $pass "websh"]} {
return 1
}
}
return 0
}
# the default command requests Basic Auth unless provided correctly
web::command default {
if {![isAuthenticated]} {
web::response -set Status {401 Authorization Required}
web::response -set WWW-Authenticate {Basic realm="Websh auth"}
web::put "Sorry, you're out"
} else {
web::put "You're in"
}
}
# command dispath
web::dispatch
</programlisting>
</example>
<emphasis>Note:</emphasis> CGI usually does not expose the Basic Auth
Authorization header for security reasons. The following configuration
for Apache (as of version 2.0.51) will allow Websh to also provide the
same functionality when running in CGI (requires mod_setenvif):
<example>
<title>Apache configuration for AUTH_USER and AUTH_PW to work under CGI</title>
<programlisting>
SetEnvIf Authorization "^(Basic .+)$" AUTH_BASIC=$1
</programlisting>
</example>
<emphasis>Important security consideration:</emphasis> This
configuration will also expose the authentication information to
Websh when Apache does handle the authentication. Although Websh
hides the information in that case, it is always available in the
CGI environment. Use this configuration carefully!
</para>
</section>
<section id="web::param">
<title><command>web::param</command></title>
<para>
<cmdsynopsis>
<command>web::param</command>
<arg choice="opt"><replaceable>option</replaceable></arg>
<arg choice="opt"><replaceable>key</replaceable></arg>
<arg choice="opt"><replaceable>value</replaceable></arg>
<arg choice="opt"><replaceable>...</replaceable></arg>
</cmdsynopsis>
Options are: <option>-count</option>, <option>-set</option>,
<option>-lappend</option>, <option>-names</option>, and
<option>-unset</option>
</para>
<para>
<command>web::param</command> is an accessor to state information
from the querystring. Suppose the querystring is &quot;lang=EN&quot;.
After <command>web::dispatch</command> has parsed the querystring,
<command>web::param</command> <option>lang</option> will
report <literal remap="tt">EN</literal>. Additionaly,
<command>web::param</command> can manage this data and add, append,
and delete parameters as needed.
<variablelist>
<varlistentry>
<term><command>web::param</command> <option>-names</option></term>
<listitem>
<para>
Returns a list of all known keys.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::param</command> <option><replaceable>key</replaceable></option>
<optional><option><replaceable>default</replaceable></option></optional></term>
<listitem>
<para>
Returns the value for <option>key</option>. Can be a
list. In case that <option>key</option> does not
exist, return <option>default</option>, if it is
given, or an empty string.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::param</command>
<option>-count</option> <option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Returns number of items in list of
<option>key</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::param</command> <option>-set</option>
<option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Does the same as <command>web::param</command>
<option>key</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::param</command> <option>-set</option>
<option><replaceable>key</replaceable></option> <option><replaceable>value</replaceable></option>
<optional><option><replaceable>value</replaceable></option></optional>
<optional><option><replaceable>...</replaceable></option></optional></term>
<listitem>
<para>
Adds the parameter <option>key</option> to the
<command>web::param</command> data. Any existing
parameters with <option>key</option> are overwritten.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::param</command>
<option>-lappend</option> <option><replaceable>key</replaceable></option>
<option><replaceable>value</replaceable></option>
<optional><option><replaceable>value</replaceable></option></optional>
<optional><option><replaceable>...</replaceable></option></optional></term>
<listitem>
<para>
Appends parameters with the same <option>key</option>
to the <command>web::param</command> data.
In this case the existing <option>value</option> is not
overwritten.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::param</command> <option>-unset</option></term>
<listitem>
<para>
Deletes all parameters from the <command>web::param</command>
data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::param</command>
<option>-unset</option> <option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Deletes a parameter from the <command>web::param</command>
data.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>
<section id="web::formvar">
<title><command>web::formvar</command></title>
<para>
<cmdsynopsis>
<command>web::formvar</command>
<arg choice="opt"><replaceable>options</replaceable></arg>
<arg choice="opt"><replaceable>key</replaceable></arg>
<arg choice="opt"><replaceable>value</replaceable></arg>
</cmdsynopsis>
</para>
<para>
Exactly like <command>web::param</command>.
</para>
<para>
<command>web::formvar</command> is an accessor to HTML FORM
data. After <command>web::dispatch</command> has parsed the
POST data, you can access all form fields using
<command>web::formvar</command>.
</para>
<para>
In addition to this, <command>web::formvar</command> can also
handle files uploaded
via Netscape 2.0 file upload mechanism. In this case, the result of
<command>web::formvar</command> is a list with four elements:
The first element contains the name of the locally saved file;
the second element contains the remote file name; the third element
is set to 0 if the upload was successful, -1 if upload is disabled
(see <command>web::config uploadfilesize</command>) and n > 0 if n
Bytes have been truncated, because the file was too big. The last
element contains the mime type of the file.
</para>
<para>
Note that the temporary files are created with the permissions
configured by <command>web::config filepermissions</command>,
which defaults to 0644.
</para>
<example>
<title><command>web::param</command></title>
<programlisting>
% web::request CONTENT_LENGTH
% web::dispatch -querystring &quot;cmd=default&amp;t=100&quot; -postdata &quot;&quot; -cmd &quot;&quot;
% web::param -names
t cmd
% web::param cmd
default
% web::param -set k v
v
% web::param -names
t cmd k
% </programlisting>
</example>
</section>
</section>
<section id="response_data_handling">
<title>Response data handling</title>
<para>
Websh can send output to any Tcl channel and to global
variables (<command>web::put</command>). Optionally, data is
scanned for Tcl code before it is output to a channel
(<command>web::putx</command>). Websh manages
<emphasis>response objects</emphasis> that are related to Tcl
channels and are identified using the name of the corresponding
Tcl channel. Configuration is achieved with
<command>web::response</command>.
</para>
<section id="web::response">
<title><command>web::response</command></title>
<para>
<cmdsynopsis>
<command>web::response</command>
</cmdsynopsis>
<cmdsynopsis>
<command>web::response</command>
<arg choice="opt"><replaceable>option</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>web::response</command>
<arg choice="opt"><replaceable>subcommand</replaceable></arg>
<arg choice="req"><replaceable>args</replaceable></arg>
</cmdsynopsis>
Subcommands are <option>-select</option>,
<option>-set</option>, <option>-lappend</option>,
<option>-names</option>, <option>-count</option>,
<option>-unset</option>, <option>-reset</option>, and
<option>-resetall</option> Options are
<option>-sendheader</option>, <option>-httpresponse</option>,
and <option>-bytessent</option>.</para><para>
Selects the default response object and sets and accesses
properties of the response object, and returns the name of the
response object.
</para>
<para>
<variablelist>
<varlistentry>
<term><command>web::response</command></term>
<listitem>
<para>
Returns the name of the currently selected response object.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-select</option>
<optional><option>#</option></optional><replaceable>channelName</replaceable>
</term>
<listitem>
<para>
Selects <option><replaceable>channelName</replaceable></option>
as new response object. If the
<option><replaceable>channelName</replaceable></option> is
prepended by a <option>#</option>, it refers to a global
variable named
<option><replaceable>channelName</replaceable></option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-set</option> <option><replaceable>key</replaceable></option>
<optional><option><replaceable>value</replaceable></option></optional></term>
<listitem>
<para>
Sets property <option>key</option> to
<option>value</option>, or returns current value if
<option>value</option> is omitted. The
<option>keys</option> are names of HTTP header fields
(do not include ':' at the end of the header field
name) and <option>value</option> the corresponding
value of the field (like Content-Type) and their
values (like text/html).</para><para>
Example:</para><para> <literal
remap="tt"><command>web::response</command> -set Content-Type text/plain</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-names</option></term>
<listitem>
<para>
Returns the list of known keys.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-count</option> <option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Returns number of items in list of <option>key</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-unset</option>
<optional><option><replaceable>key</replaceable></option></optional></term>
<listitem>
<para>
Deletes the value of <option>key</option>, if
<option>key</option> is given, or all keys.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-sendheader</option>
<optional><option>boolean</option></optional></term>
<listitem>
<para>
Sets or gets the sendheader flag which indicates and controls
whether the HTTP headers have been or should be sent.
It is initially set to 1 and set to 0 after the first
call of <command>web::put</command> or
<command>web::putx</command>. If
<option>boolean</option> is omitted, returns the
current value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-httpresponse</option>
<optional><option><replaceable>value</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets the HTTP response like &quot;HTTP/1.0 200
OK&quot; for the given (or default) channel. If no
<option>value</option> given, returns the the current
HTTP response set. In the case of the Apache module
mod_websh, Apache replaces the protocol
&quot;HTTP/??&quot; in the reponse with
&quot;HTTP/1.1&quot;.
</para>
<para>
<emphasis>Note</emphasis>: Depending on the CGI
implementation of your web
server, this does not always work. A working alternative
for newer versions of Apache is to set a Status header
in the response as follows:
</para>
<para> <literal
remap="tt"><command>web::response</command> -set Status &quot;400 Bad Request&quot;</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-bytessent</option></term>
<listitem>
<para>
Returns the number of bytes that have already been sent to this
channel.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-reset</option></term>
<listitem>
<para>
Resets the 'sendheader' flag for the channel to true,
the HTTP response to the default &quot;HTTP/?? 200
OK&quot;, removes any HTTP headers set, and resets the
names of the query string parameters for the timestamp
and the command to their default values (&quot;t&quot;
and &quot;cmd&quot;, respectively).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::response</command>
<option>-resetall</option></term>
<listitem>
<para>
Performs a <command>web::response -reset</command> on all
registered channels.
</para>
</listitem>
</varlistentry>
</variablelist>
<example>
<title><command>web::response</command></title>
<programlisting>
% web::response
stdout
% web::response -select stderr
stdout
% web::response
stderr
% web::response -sendheader
1
% web::response -names
Content-Type Generator
% web::response Content-Type
text/html
% web::response -bytessent
0
% web::response -set Set-Cookie &quot;my cookie that contains data&quot;
% web::put &quot;Hello, world\n&quot;
Content-Type: text/html
Set-Cookie: my cookie that contains data
Generator: websh3.6.0
Hello, world
% </programlisting>
</example>
</para>
</section>
<section id="web::put">
<title><command>web::put</command></title>
<para>
<cmdsynopsis>
<command>web::put</command>
<arg choice="opt">
<arg choice="opt">#</arg>
<replaceable>channel</replaceable>
</arg>
<arg choice="req"><replaceable>text</replaceable></arg>
</cmdsynopsis>
Sends output to a Tcl channel. No newline is added to
output. If
<optional><option><replaceable>channel</replaceable></option></optional>
is ommitted, output is sent to the current default
channel. The default channel can be changed with
<command>web::response <option>-select</option>
<optional><option>#</option></optional><option><replaceable>channel</replaceable></option></command>.
The optional hash (&quot;#&quot;) denotes that output should be
sent to a global variable named
<option><replaceable>channel</replaceable></option> instead of
a Tcl channel.
</para>
</section>
<section id="web::putx">
<title><command>web::putx</command></title>
<para>
<cmdsynopsis>
<command>web::putx</command>
<arg choice="opt">
<arg choice="opt">#</arg>
<replaceable>channel</replaceable>
</arg>
<arg choice="req"><replaceable>text</replaceable></arg>
</cmdsynopsis>
Writes <option>text</option> to the specified channel. Code in
curly brackets is eval'd, unless the brackets are escaped by
&quot;\&quot;. These markup characters '{...}' can be changed
to '&lt;? ... ?&gt;' with
'<command>web::config putxmarkup tag</command>'. The optional hash
(&quot;#&quot;) denotes that output should be sent to a global
variable named <option><replaceable>channel</replaceable></option>
instead of a Tcl channel.
</para>
</section>
<section id="web::putxfile">
<title><command>web::putxfile</command></title>
<para>
<cmdsynopsis>
<command>web::putxfile</command>
<arg choice="opt">
<arg choice="opt">#</arg>
<replaceable>channel</replaceable>
</arg>
<arg choice="req"><replaceable>file</replaceable></arg>
<arg choice="opt"><replaceable>msg</replaceable></arg>
</cmdsynopsis>
Like <command>web::putx</command>, but takes input from a file.
</para>
<para>
Returns 0 on success, 1 otherwise. If an error occurs, an
error message is written to <option>msg</option>. If only two
arguments are passed, then <option>channel</option> takes
precedence. The optional hash (&quot;#&quot;) denotes that output
should be sent to a global variable named
<option><replaceable>channel</replaceable></option> instead
of a Tcl channel.
</para>
</section>
</section>
<section id="logging">
<title>Logging</title>
<para>
Logging consists of two parts. <command>web::log</command>
issues a logging message, while
<command>web::loglevel</command> and
<command>web::logdest</command> determine where to send a
message. Websh uses a two-step filtering. First, Websh
determines whether it should handle a message, or not, using the
levels configured with <command>web::loglevel</command>. Then,
Websh determines which message is to be sent where, using the
the additional filters and destinations configured with
<command>web::logdest</command>. There is no logging per default.
Setting levels with <command>web::loglevel</command> is mandatory.
</para>
<para>
A filter consists of a tag and a level, separated by a
&quot;.&quot;. The tag is free text. Typically, it is the name
of the application, say &quot;foo&quot;. Example:
&quot;ws3.debug&quot;. Levels are, in order:
<itemizedlist>
<listitem><para>alert</para></listitem>
<listitem><para>error</para></listitem>
<listitem><para>warning</para></listitem>
<listitem><para>info</para></listitem>
<listitem><para>debug</para></listitem>
</itemizedlist>
</para>
<section id="web::logdest">
<title><command>web::logdest</command></title>
<para>
<cmdsynopsis>
<command>web::logdest</command>
<arg choice="req"><replaceable>subcommand</replaceable></arg> <arg
choice="opt"><replaceable>options</replaceable></arg>
<arg choice="req"><replaceable>args</replaceable></arg>
</cmdsynopsis>
Subcommands are: <option>add</option>,
<option>delete</option>, <option>names</option>, and
<option>levels</option>.
</para>
<variablelist>
<varlistentry>
<term><command>web::logdest</command> <option>add</option> <optional><option><replaceable>options</replaceable></option></optional>
<option><replaceable>level</replaceable></option> <option><replaceable>plugin</replaceable></option> <optional><option><replaceable>plugin-specific options</replaceable></option></optional></term>
<listitem>
<para>
Options are: <option>-maxchar n</option>, and
<option>-format &quot;format string&quot;</option>.
<literal>-maxchar n</literal> truncates the message to a
maximum of <literal>n</literal> characters.
</para>
<para>
The format string consists of time format specifications for
<function>strftime()</function> plus: <literal
remap="tt">$p</literal> (process id), <literal
remap="tt">$t</literal> (thread id), <literal
remap="tt">$l</literal> (log level), <literal
remap="tt">$n</literal> (numerical log level), <literal
remap="tt">$f</literal> (log facility), <literal
remap="tt">$m</literal> (the message), and <literal
remap="tt">$$</literal> (dollar sign).
</para>
<para>
Default format: <literal>&quot;%x %X [\$p] \$f.\$l: \$m\n&quot;</literal>
</para>
<para>
Known plug-ins are: <option>file</option>,
<option>syslog</option> (Unix only), <option>command</option>,
<option>channel</option>, and
<option>apache</option> (mod_websh only).
<emphasis>Note</emphasis>: plug-ins may have indiviudal options
(such as <option>-unbuffered</option>), see documentation below.
</para>
<para>
<programlisting>
web::logdest add -maxchar 25 -format &quot;%x %X \$l \$m\n&quot; *.-debug command logTest</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::logdest</command>
<option>delete</option>
<optional><option><replaceable>name</replaceable></option></optional></term>
<listitem>
<para>
Removes destination <option>name</option> from list, or
removes all destinations if <option>name</option> is omitted.
(The special case <literal remap="tt">-requests</literal>
to delete all destinations except the one defined from
within <command>web::initializer</command> code is only
used internally.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::logdest</command>
<option><replaceable>names</replaceable></option></term>
<listitem>
<para>
Returns a list of all destination ids that have been set.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::loglevel</command>
<option><replaceable>levels</replaceable></option></term>
<listitem>
<para>
Lists all destination ids and their actual log levels in a
readable format
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="web::loglevel">
<title><command>web::loglevel</command></title>
<para>
<cmdsynopsis>
<command>web::loglevel</command>
<arg choice="req">subcommand</arg>
<arg choice="req">args</arg>
</cmdsynopsis>
Subcommands are: <option>add</option>,
<option>delete</option>, <option>names</option>,
and <option>levels</option>.
Levels defined using <command>web::loglevel</command> act as a
filter for log messages sent by Websh. Only messages that pass
at least one level defined using this command are passed to the
log destinations configured using <command>web::logdest</command>
</para>
<para>
<variablelist>
<varlistentry>
<term><command>web::loglevel</command>
<option>add</option> <option><replaceable>level</replaceable></option></term>
<listitem>
<para>
Adds a level to the list.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::loglevel</command>
<option>delete</option>
<optional><option><replaceable>name</replaceable></option></optional></term>
<listitem>
<para>
Removes level <option>name</option> from list, or removes all
levels if <option>name</option> is omitted.
(The special case <literal remap="tt">-requests</literal>
to delete all levels except the one defined from within
<command>web::initializer</command> code is only used
internally.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::loglevel</command>
<option><replaceable>names</replaceable></option></term>
<listitem>
<para>
Returns a list of all level ids that have been set.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::loglevel</command>
<option><replaceable>levels</replaceable></option></term>
<listitem>
<para>
Lists all level ids and their actual log levels in a
readable format.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>
<section id="web::log">
<title><command>web::log</command></title>
<para>
<cmdsynopsis>
<command>web::log</command> <arg choice="req"><replaceable>level</replaceable></arg>
<arg choice="req"><replaceable>msg</replaceable></arg>
</cmdsynopsis>
Issues a log message. It is possible, should the user so
desire, to have the <command>web::log</command> run
<command>subst</command> on its arguments. This behaviour is
turned off by default, and can be turned on by doing:
<programlisting>web::config logsubst 1</programlisting>.
</para>
</section>
<section id="log_plug-ins">
<title>Log plug-ins</title>
<section id="file">
<title>File</title>
<para>
<cmdsynopsis>
<command>web::logdest</command>
<arg choice="plain">add</arg>
<arg choice="req"><replaceable>destination</replaceable>.-<replaceable>level</replaceable></arg>
<arg choice="req">file</arg>
<arg choice="opt"><replaceable>options</replaceable></arg>
<arg choice="req"><replaceable>filename</replaceable></arg>
</cmdsynopsis>
Option is: <option>-unbuffered</option>
</para>
<para>
Log messages are sent to the file <option>filename</option>,
which is opened in append mode at the time of this call and
stays open until this destination is deleted. This is either
at the end of the request (mod_websh) or when the interpreter
is deleted.
</para>
<para>
The file opened using the permissions configured with
<command>web::config filepermissions</command>. Default: 0644.
</para>
</section>
<section id="syslog">
<title>Syslog</title>
<para>
<cmdsynopsis>
<command>web::logdest</command>
<arg choice="plain">add</arg>
<arg choice="req">*.-debug</arg>
<arg choice="req">syslog</arg>
<arg choice="opt"><replaceable>level</replaceable></arg>
</cmdsynopsis>
See the man page for syslog for levels on your system. Typical: 10.
Available under Unix only.
</para>
</section>
<section id="command">
<title>Command</title>
<para>
<cmdsynopsis>
<command>web::logdest</command>
<arg choice="plain">add</arg>
<arg choice="req">*.-debug</arg>
<arg choice="plain">command</arg>
<arg choice="req"><replaceable>cmdName</replaceable></arg>
</cmdsynopsis>
</para>
<para>
The log message is sent to a Tcl command taking the message
as an argument. E.g.
<programlisting>
% proc logCommand {msg} {
puts "---- here comes the message ----"
puts -nonewline $msg
puts "----- that was the message -----"
}
%
% web::loglevel add *.-debug
loglevel0
% web::logdest add *.-debug command logCommand
logdest0
% web::log debug "a log message"
---- here comes the message ----
10/28/05 13:44:26 [20596] user.debug: a log message
----- that was the message -----
% </programlisting>
</para>
</section>
<section id="channel">
<title>Channel</title>
<para>
<cmdsynopsis>
<command>web::logdest</command>
<arg choice="plain">add</arg>
<arg choice="req">*.-debug</arg>
<arg choice="plain">channel</arg>
<arg choice="opt"><replaceable>options</replaceable></arg>
<arg choice="req"><replaceable>channel</replaceable></arg>
</cmdsynopsis>
Option is: <option>-unbuffered</option>
</para>
<para>
Writes the message to the Tcl channel <option>channel</option>.
</para>
</section>
<section id="apache">
<title>Apache</title>
<cmdsynopsis>
<command>web::logdest</command>
<arg choice="plain">add</arg>
<arg choice="req">*.-debug</arg>
<arg choice="plain">apache</arg>
</cmdsynopsis>
<para>
Sends the message to the Apache ErrorLog file. Available within
mod_websh only.
</para>
</section>
<section>
<example>
<title><command>web::log</command>, <command>web::loglevel</command>, and <command>web::logdest</command></title>
<programlisting>
% web::loglevel add *.-debug
loglevel0
% web::logdest add *.-debug channel stdout
logdest0
% web::log info {Websh is cool}
03/01/00 00:00:00 [111] user.info: Websh is cool
% web::logdest delete
% web::logdest add -format &quot;--&gt; \$m\n&quot; *.-debug channel stdout
logdest0
% web::log info {Websh is cool}
--&gt; Websh is cool
% web::logdest delete
% web::logdest add -maxchar 5 *.-debug channel stdout
% web::log info {Websh is cool}
03/01/00 00:00:00 [111] user.info: Websh
% </programlisting>
</example>
</section>
</section>
</section>
<section id="context_handling">
<title>Context handling</title>
<section id="web::context">
<title><command>web::context</command></title>
<para>
Creation
<cmdsynopsis>
<command>web::context</command> <arg choice="req"><replaceable>name</replaceable></arg>
</cmdsynopsis>
Creates a namespace <option>name</option> with the following
commands:
<cmdsynopsis>
<command><replaceable>name</replaceable>::subcommand</command>
<arg choice="req"><replaceable>args</replaceable></arg>
</cmdsynopsis>
Subcommands are: <option>cset</option>,
<option>cappend</option>, <option>clappend</option>,
<option>cget</option>, <option>cexists</option>,
<option>cunset</option>, <option>carray</option>,
<option>cnames</option>, <option>delete</option>,
and <option>dump</option>.
Manages data of the context. The subcommands behave like the
Tcl commands with similar names.
<variablelist>
<varlistentry>
<term><command><replaceable>name</replaceable>::cset</command>
<option><replaceable>key</replaceable></option> <option><replaceable>value</replaceable></option></term>
<listitem>
<para>
Set <option>key</option> to <option>value</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::cappend</command>
<option><replaceable>key</replaceable></option> <option><replaceable>value</replaceable></option>
<optional><option><replaceable>value</replaceable></option></optional>
<optional><option><replaceable>...</replaceable></option></optional></term>
<listitem>
<para>
Appends <option>value</option> to existing value for
<option>key</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::clappend</command>
<option><replaceable>key</replaceable></option> <option><replaceable>value</replaceable></option>
<optional><option><replaceable>value</replaceable></option></optional>
<optional><option><replaceable>...</replaceable></option></optional></term>
<listitem>
<para>
Appends <option>value</option> to existing list of
values for <option>key</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::cget</command>
<option><replaceable>key</replaceable></option>
<optional><option><replaceable>default</replaceable></option></optional></term>
<listitem>
<para>
Accesses the value for key <option>key</option>, or
returns <option>default</option> if
<option>key</option> does not exist in the context. If
<option>default</option> is omitted, an empty string
is returned if <option>key</option> is unknown.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::cexists</command>
<option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Returns true (1) if <option>key</option> exists in
context, false (0) otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::cunset</command>
<option><replaceable>key</replaceable></option></term>
<listitem>
<para>
Removes <option>key</option> from context.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::carray</command>
<option><replaceable>option</replaceable></option> <option><replaceable>key</replaceable></option>
<option><replaceable>arg</replaceable></option></term>
<listitem>
<para>
Array manipulation as known from the Tcl command
<emphasis>array</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::cnames</command>
<optional><option><replaceable>pattern</replaceable></option></optional></term>
<listitem>
<para>
Lists existing keys of context matching
<option>pattern</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::delete</command></term>
<listitem>
<para>
Deletes the context (same as <command>namespace delete
<replaceable>name</replaceable></command>)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::dump</command></term>
<listitem>
<para>
Serializes context in a &quot;source&quot;-able format.
</para>
</listitem>
</varlistentry>
</variablelist>
<example>
<title><command>web::context</command></title>
<programlisting>
% web::context sc
% sc::cset lang FR
FR
% # ... some code ...
% set lang [sc::cget lang EN]
FR
% </programlisting>
</example>
</para>
</section>
<section id="web::filecontext">
<title><command>web::filecontext</command></title>
<para>
Creation:
<cmdsynopsis>
<command>web::filecontext</command>
<arg choice="req"><replaceable>name</replaceable></arg>
<arg choice="opt"><replaceable>options</replaceable></arg>
</cmdsynopsis>
Options are: <option>-perm</option>, <option>-path</option>,
<option>-crypt</option>, <option>-idgen</option>, and
<option>-attachto</option>.
Creates a namespace <option>name</option> to manage file-based
context data:
<cmdsynopsis>
<command><replaceable>name</replaceable>::subcommand</command>
<arg choice="req"><replaceable>args</replaceable></arg>
</cmdsynopsis>
Subcommands are: <option>cset</option>,
<option>cappend</option>, <option>clappend</option>,
<option>cget</option>, <option>cexists</option>,
<option>cunset</option>, <option>carray</option>,
<option>cnames</option>, <option>init</option>,
<option>new</option>, <option>commit</option>,
<option>invalidate</option>, and <option>id</option>.
Manages file-based context data. The subcommands have their
familiar behaviour of the Tcl commands with similar
names. Please refer to the section <link
linkend="context_handling">context management</link> for a
description of the commands <option>cset</option>,
<option>cappend</option>, <option>clappend</option>,
<option>cget</option>, <option>cexists</option>,
<option>cunset</option>, <option>carray</option>, and
<option>cnames</option>.
<variablelist>
<varlistentry>
<term>
<command><replaceable>name</replaceable>::init</command>
<optional><option><replaceable>id</replaceable></option></optional>
</term>
<listitem>
<para>
Loads an existing session context with id
<option>id</option>, or creates a new one, if
possible. Automation depends on the settings of the
actual context manager settings, see
below.</para><para> If you specify an
<option>id</option>, you must decide when to create a
new file and when to use the old one, if any, by
yourself.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::new</command>
<optional><option><replaceable>id</replaceable></option></optional></term>
<listitem>
<para>
Creates a new session context. Automation depends on
the settings of the actual context manager settings,
see below.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::commit</command></term>
<listitem>
<para>
Makes session context persistent.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::id</command></term>
<listitem>
<para>
Returns id of session.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::invalidate</command></term>
<listitem>
<para>
Deletes session in memory and on file system.
</para>
</listitem>
</varlistentry>
</variablelist>
Options:
<cmdsynopsis>
<command>web::filecontext</command>
<arg choice="req"><replaceable>name</replaceable></arg>
<arg choice="req">-perm</arg>
<arg choice="req"><replaceable>perm</replaceable></arg>
</cmdsynopsis>
Sets the file permissions of the session context files
<option>perm</option> is an unix-like octal value like 0644.
If not specified, files are created with the permissions defined
in <command>web::config filepermissions</command>,
which again defaults to 0644.
<variablelist>
<varlistentry>
<term><command>web::filecontext</command>
<option><replaceable>name</replaceable></option> <option>-path</option>
<option><replaceable>path</replaceable></option>
</term>
<listitem>
<para>
Specifies where to store session context files and how
to name them. Suppose that the session id is 99.
<emphasis>-path [file join .. data s%d.dat]</emphasis>
would then cause filecontext to save the session
context as <literal
remap="tt">../data/s99.dat</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::filecontext</command>
<option><replaceable>name</replaceable></option> <option>-crypt</option>
<option>boolean</option></term>
<listitem>
<para>
Sets crypting of session context on or off.
Default: on.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::filecontext</command>
<option><replaceable>name</replaceable></option> <option>-idgen</option>
<option><replaceable>idgen</replaceable></option></term>
<listitem>
<para>
Sets command <option>idgen</option> to find a new
session id. See doc of
<command>web::filecounter</command> below for an
implementation provided by Websh.
</para>
<para>
<option>idgen</option> is used in case that no
<option>id</option> argument has been passed to
<option>init</option> or <option>new</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::filecontext</command>
<option><replaceable>name</replaceable></option> <option>-attachto</option>
<option><replaceable>idparam</replaceable></option>
</term>
<listitem>
<para>
Causes <command><replaceable>name</replaceable>::init</command>
to initialize with the id given in the querystring parameter
<option>idparam</option>. (This is one important reason why
the querystring should be encrypted). After
<command>web::dispatch</command> has
parsed the querystring, <command>web::param</command>
will report the current session id in
<option>idparam</option>, if any. <emphasis>Note</emphasis>
that you can maintain several sessions in parallel,
and attach every session to its own
<option>idparam</option>.
</para>
<para>
Using
<emphasis><command>web::dispatch -track</command></emphasis>
further automates the passing of session ids from
request to request.
</para>
</listitem>
</varlistentry>
</variablelist>
<emphasis>Note:</emphasis> Whenever you create a new
file-based context, the context is initialized and you loose
whatever information that you might have stored in the context
before you initialized it as a file-based session context.
</para>
</section>
<section id="web::cookiecontext">
<title><command>web::cookiecontext</command></title>
<para>
Creation:
<cmdsynopsis>
<command>web::cookiecontext</command>
<arg choice="req"><replaceable>name</replaceable></arg> <arg
choice="opt"><replaceable>options</replaceable></arg>
</cmdsynopsis>
Options are: <option>-expires</option>,
<option>-path</option>, <option>-domain</option>,
<option>-secure</option>, <option>-crypt</option>, and
<option>-channel</option>.
Creates a namespace <option>name</option> to manage
cookie-based context data:
<variablelist>
<varlistentry>
<term><command><replaceable>name</replaceable>::subcommand</command>
<option><replaceable>args</replaceable></option></term>
<listitem>
<para>
Subcommands are: <option>cset</option>,
<option>cappend</option>, <option>clappend</option>,
<option>cget</option>, <option>cexists</option>,
<option>cunset</option>, <option>carray</option>,
<option>cnames</option>, <option>init</option>,
<option>new</option>, <option>commit</option>,
<option>invalidate</option>, and <option>id</option>.
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term><command><replaceable>name</replaceable>::init</command>
<optional><option><replaceable>id</replaceable></option></optional></term>
<listitem>
<para>
Loads an existing session context (cookie must have
been sent by the client).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::new</command>
<optional><option><replaceable>id</replaceable></option></optional></term>
<listitem>
<para>
Creates a new session context.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::commit</command></term>
<listitem>
<para>
Sends a cookie (if no output to the page has been sent yet).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::id</command></term>
<listitem>
<para>
Returns id of session.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command><replaceable>name</replaceable>::invalidate</command></term>
<listitem>
<para>
Deletes session in memory and on client side.
</para>
</listitem>
</varlistentry>
</variablelist>
Options:
<variablelist>
<varlistentry>
<term><command>web::cookiecontext</command>
<option><replaceable>name</replaceable></option> <option>-expires</option>
<option><replaceable>time</replaceable></option></term>
<listitem>
<para>
Sets the expiration date of the cookie. Possible values
for <option>time</option> are
<emphasis>seconds</emphasis> (time in seconds since
1970-01-01) or <emphasis>date-string</emphasis> (any
time string that Tcl can scan. Note that therefore many
relative times, such as <emphasis>24 hours</emphasis>,
<emphasis>week</emphasis>, <emphasis>2 weeks</emphasis>,
<emphasis>tomorrow</emphasis>, etc.
are possible. Default is <emphasis>now + 24 hours</emphasis>
(i.e. cookie expires in 24 hours. (Please note that the
behavior of some of these relative time specifiers changed
from Tcl8.4 to Tcl8.5.) Use
<emphasis>-expires &quot;&quot;</emphasis> to
send a cookie without an expires parameter.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::cookiecontext</command>
<option><replaceable>name</replaceable></option> <option>-path</option>
<option><replaceable>path</replaceable></option></term>
<listitem>
<para>
Sets the <option>path</option> property of the cookie.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::cookiecontext</command>
<option><replaceable>name</replaceable></option> <option>-domain</option>
<option><replaceable>domain</replaceable></option></term>
<listitem>
<para>
Sets the <option>domain</option> property of the cookie.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::cookiecontext</command>
<option><replaceable>name</replaceable></option>
<option>-secure</option> <option>boolean</option></term>
<listitem>
<para>
Sets the <option>secure</option> property of the cookie.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::cookiecontext</command>
<option><replaceable>name</replaceable></option> <option>-crypt</option>
<option>boolean</option></term>
<listitem>
<para>
Sets crypting of cookie context on or off.
Default: on.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::cookiecontext</command>
<option><replaceable>name</replaceable></option> <option>-channel</option>
<option><replaceable>channelName</replaceable></option></term>
<listitem>
<para>
Sets the response object to send the cookie to (see also
<command>web::response</command>).
</para>
</listitem>
</varlistentry>
</variablelist>
Because cookies are client-based, in principle no id is
needed. Websh uses <option>id</option> to name the cookie,
however, and the <command>new</command>,
<command>init</command>, and <command>load</command> commands
still require the <option>id</option> argument. (fixme: any
changes?) Please note that property settings of a cookie
context can only be changed <emphasis>before</emphasis>
anything is output on the respective channel.
</para>
</section>
<section id="web::filecounter">
<title><command>web::filecounter</command></title>
<para>
This is a numeric sequence-number generator which stores its
state in a file. Basic usage:
<variablelist>
<varlistentry>
<term>Creation:</term>
<listitem>
<para>
<command>web::filecounter</command>
<option><replaceable>name</replaceable></option> <option>-filename</option>
<option><replaceable>fname</replaceable></option>
<optional><option><replaceable>options</replaceable></option></optional>
</para>
<para>
Options are: <option>-min</option>,
<option>-max</option>, <option>-seed</option>,
<option>-incr</option>, <option>-mask</option>,
<option>-wrap</option>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-filename</option>
<option><replaceable>filename</replaceable></option></term>
<listitem>
<para>
Uses <option>filename</option> to store the current
value (no default).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-min</option> <option><replaceable>value</replaceable></option></term>
<listitem>
<para>
Uses this value as a minimum at start and after wrap,
if wrap is true. Default: 0.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-max</option> <option><replaceable>value</replaceable></option></term>
<listitem>
<para>
Uses this value as a maximum, if wrap is true. Default: 2147483647.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-seed</option> <option><replaceable>value</replaceable></option></term>
<listitem>
<para>
Usea this value as a starting point if persistent file does
not exist yet. Default: 0.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-incr</option> <option><replaceable>value</replaceable></option></term>
<listitem>
<para>
Uses this value as an increment for each 'nextval'.
Default: 1.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-perms</option>
<option><replaceable>value</replaceable></option></term>
<listitem>
<para>
Sets the permissions on the newly created files.
Default is configured in <command>web::config filepermissions</command>, which defaults to 0644.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-wrap</option>
<option>boolean</option></term>
<listitem>
<para>
Indicates whether this counter should wrap around its
values (back to min from max). Default: false.
</para>
</listitem>
</varlistentry>
</variablelist>
After creation, a new command <option>name</option> is
registered with the following subcommands:
<variablelist>
<varlistentry>
<term><option><replaceable>name</replaceable></option> config</term>
<listitem>
<para>
Returns a flat list of key value pairs with the
filecounter's configuration.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option><replaceable>name</replaceable></option> nextval</term>
<listitem>
<para>
Returns the next value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option><replaceable>name</replaceable></option> curval</term>
<listitem>
<para>
Returns the current value, that is, the value that the
last call to &quot;nextval&quot; or &quot;getval&quot;
reported (as opposed to the current value in the file).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option><replaceable>name</replaceable></option> getval</term>
<listitem>
<para>
Returns the current value in the file. (Does not increment
file as in &quot;nextval&quot;.)
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<example>
<title><command>web::filecounter</command></title>
<programlisting>
% web::filecounter fc1 -filename test.dat
fc1
% fc1 config
file test.dat handle fc1 seed 0 min 0 max 2147483647 incr 1 perms 0644 wrap false curr {not valid}
% fc1 curval
web::filecounter: no current value available
% fc1 nextval
0
% fc1 config
file test.dat handle fc1 seed 0 min 0 max 2147483647 incr 1 perms 0644 wrap false curr 0
% fc1 nextval
1
% web::filecounter fc2 -filename test.dat
fc2
% fc2 curval
web::filecounter: no current value available
% fc2 getval
1
% fc2 nextval
2
% fc2 curval
2
% fc1 curval
1
% fc1 nextval
3
% fc2 getval
3
% web::filecounter fc3 -filename othertest.dat -min 1 -max 10 -seed 1 -incr 2 -wrap 1
fc3
% fc3 config
file othertest.dat handle fc3 seed 1 min 1 max 10 incr 2 perms 0644 wrap true curr {not valid}
% fc3 nextval
1
% fc3 nextval
3
% </programlisting>
</example>
</section>
</section>
<section id="file_handling_and_file_IO">
<title>File handling and file I/O</title>
<section id="web::include">
<title><command>web::include</command></title>
<para>
<cmdsynopsis>
<command>web::include</command>
<arg choice="req"><replaceable>fileName</replaceable></arg>
<arg choice="opt"><replaceable>msg</replaceable></arg>
</cmdsynopsis>
If the file <option>fileName</option> exists, it is sourced (must be a
script). Otherwise if the library fileName+&quot;shared lib
extension&quot; exists, it is loaded (must be a shared library).
Returns 0 on success, 1 otherwise. If an error occurs, an error
message is written to <option>msg</option>.
</para>
</section>
<section id="web::readfile">
<title><command>web::readfile</command></title>
<para>
<cmdsynopsis>
<command>web::readfile</command> <arg choice="req"><replaceable>file</replaceable></arg>
<arg choice="req"><replaceable>varName</replaceable></arg> <arg choice="req"><replaceable>msg</replaceable></arg>
</cmdsynopsis>
Reads <option>file</option> and writes it to
<option>varName</option>. Returns 0 on success, 1
otherwise. If an error occurs, an error message is written to
the variable <option>msg</option>.
</para>
</section>
<section id="web::lockfile_and_web::unlockfile">
<title><command>web::lockfile</command> and <command>web::unlockfile</command></title>
<para>
<cmdsynopsis>
<command>web::lockfile</command> <arg choice="req"><replaceable>fh</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>web::unlockfile</command> <arg choice="req"><replaceable>fh</replaceable></arg>
</cmdsynopsis>
Interfaces <function>lockf()</function>. <function>lockf()</function>
works best on local filesystems.
Please read the documentation of <function>lockf()</function> on your
system to learn about the problems and limitations of file locking.
Note that
<command>web::lockfile</command> also performs a
<function>seek()</function> and
resets the file cursor to the beginning of the file.
<emphasis>Note</emphasis> that the file needs to be open for
writing.
</para>
</section>
<section id="web::truncatefile">
<title><command>web::truncatefile</command></title>
<para>
<cmdsynopsis>
<command>web::truncatefile</command>
<arg choice="req"><replaceable>fh</replaceable></arg>
</cmdsynopsis>
Interfaces <function>truncate()</function>. Truncates a file based on
the file handle, while Tcl's file commands are based on file
names. This is used to truncate a file while holding the lock.
</para>
<example>
<title><command>web::lockfile</command></title>
<programlisting>
set fh [open [web::tempfile] w]
web::lockfile $fh
puts $fh foo
web::unlockfile $fh
close $fh </programlisting>
</example>
</section>
</section>
<section id="data_encryption">
<title>Data encryption</title>
<para>
Encrypts (<command>web::encrypt</command>) and decrypts
(<command>web::decrypt</command>) data. By default, the
built-in, weak encryption is used. Encryption is extensible by
plug-ins. The encryption module tries all plug-ins from a list
until the first plug-in was able to en-/decrypt the input. See
<command>web::config</command> for the configuration of the
plug-ins to be used.
</para>
<section id="web::encrypt">
<title><command>web::encrypt</command></title>
<para>
<cmdsynopsis>
<command>web::encrypt</command> <arg choice="req"><replaceable>data</replaceable></arg>
</cmdsynopsis>
Returns encrypted data.
</para>
</section>
<section id="web::decrypt">
<title><command>web::decrypt</command></title>
<para>
<cmdsynopsis>
<command>web::decrypt</command> <arg choice="req"><replaceable>data</replaceable></arg>
</cmdsynopsis>
Returns decrypted data.
<example>
<title><command>web::encrypt</command></title>
<programlisting>
% web::encrypt &quot;Hello, world!&quot;
XDIVAhkgkxRjcfA7UTwpD7
% web::decrypt [web::encrypt &quot;Hello, world!&quot;]
Hello, world!
% </programlisting>
</example>
</para>
</section>
<section id="encryption_plug-in_D">
<title>Encryption plug-in D</title>
<para>
</para>
</section>
<section id="web::encryptd">
<title><command>web::encryptd</command></title>
<para>
By default, Websh uses this plug-in for (very) weak data
encryption (<command>web::encryptd</command>)
and decryption (<command>web::decryptd</command>). The
encryption key is managed with
<command>web::crpytdkey</command>.
</para>
<para>
<cmdsynopsis>
<command>web::encryptd</command> <arg choice="req"><replaceable>data</replaceable></arg>
</cmdsynopsis>
Returns encrypted <option><replaceable>data</replaceable></option>.
</para>
</section>
<section id="web::decryptd">
<title><command>web::decryptd</command></title>
<para>
<cmdsynopsis>
<command>web::decryptd</command> <arg choice="req"><replaceable>data</replaceable></arg>
</cmdsynopsis>
Returns decrypted <option><replaceable>data</replaceable></option>.
</para>
</section>
<section id="web::cryptdkey">
<title><command>web::cryptdkey</command></title>
<para>
<cmdsynopsis>
<command>web::cryptdkey</command>
<arg choice="opt"><replaceable>key</replaceable></arg>
</cmdsynopsis>
Sets a new key for encryption. If no argument is given,
resets to the default key. This command does not return the
currently active key, in difference to other configuration
commands of Websh.
</para>
</section>
<section id="encryption_plug-in_interface_">
<title>Encryption plug-in interface</title>
<para>
<emphasis>For plug-in developers only</emphasis>
</para>
<para>
The encryption plug-in is required to implement the interface
described below (note that to activate your plug-in, use
<command>web::config encryptchain</command> and
<command>web::config decryptchain</command> respectively):
<itemizedlist>
<listitem>
<para>
<command>web::yourencrypt</command> accepts one argument
<command>web::yourencrypt</command> takes a string as
input and generates a string which must be URI compliant.
</para>
</listitem>
<listitem>
<para>
<command>web::yourdecrypt</command> accepts one argument
<command>web::yourdecrypt</command> takes a string as input
and returns a string.
</para>
</listitem>
<listitem>
<para>Symmetry: <emphasis><command>$in ==
[web::yourdecrypt [web::yourencrypt
$in]]</command></emphasis>
</para>
</listitem>
<listitem>
<para>
Error messaging: <emphasis>TCL_OK</emphasis> for
success. <emphasis>TCL_ERROR</emphasis> for any error
during en-/decryption. <emphasis>TCL_CONTINUE</emphasis>
for unknown encryption type (pass on to next method).
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="uri-html-_en-decoding">
<title>Uri-/html- en-/decoding</title>
<section id="web::htmlify">
<title><command>web::htmlify</command></title>
<para>
<cmdsynopsis>
<command>web::htmlify</command>
<arg choice="opt">-options</arg>
<arg choice="req"><replaceable>text</replaceable></arg>
</cmdsynopsis>
</para>
<para>
Options: <option>-numeric</option>.
</para>
<para>
Returns HTML-compliant <option>text</option> with HTML
encoded entities in mnemonic form (e.g. &amp;auml;) or in numeric
form (e.g. &amp;#228;) if the option <option>-numeric</option>
is specified. Multibyte characters are encoded as
&amp;#&lt;numeric&gt;;.
</para>
</section>
<section id="web::dehtmlify">
<title><command>web::dehtmlify</command></title>
<para>
<cmdsynopsis>
<command>web::dehtmlify</command>
<arg choice="req"><replaceable>text</replaceable></arg>
</cmdsynopsis>
</para>
<para>
Removes all HTML-tags from <option>text</option> and translates
all HTML entities to their corresponding characters (also
handles encoded multibyte characters encoded with
&amp;#&lt;numeric&gt;;).
</para>
</section>
<section id="web::uriencode">
<title><command>web::uriencode</command></title>
<para>
<cmdsynopsis>
<command>web::uriencode</command>
<arg choice="req"><replaceable>text</replaceable></arg>
</cmdsynopsis>
</para>
<para>
Returns URI-compliant <option>text</option>.
</para>
</section>
<section id="web::uridecode">
<title><command>web::uridecode</command></title>
<para>
<cmdsynopsis>
<command>web::uridecode</command>
<arg choice="req"><replaceable>text</replaceable></arg>
</cmdsynopsis>
</para>
<para>Decodes URI-compliant <option>text</option>.
</para>
<example>
<title><command>web::htmlify</command></title>
<programlisting>
% web::htmlify &lt;
&amp;lt;
% web::htmlify -numeric &lt;
&amp;#60;
% web::dehtmlify &quot;&amp;lt; &amp;#60;&quot;
&lt; &lt;
% web::uriencode &quot;Hello, world!&quot;
Hello%2c+world%21
% web::uridecode &quot;Hello%2c+world%21&quot;
Hello, world!
% </programlisting>
</example>
</section>
</section>
<section id="inter-process_and_-system_communication">
<title>Inter-process/-system communication</title>
<para>
Sends to and receives from sockets.
</para>
<section id="web::send">
<title><command>web::send</command></title>
<para>
<cmdsynopsis>
<command>web::send</command>
<arg choice="req"><replaceable>channel</replaceable></arg>
<arg choice="req"><replaceable>cmdNr</replaceable></arg>
<arg choice="req"><replaceable>message</replaceable></arg>
<arg choice="opt"><replaceable>flags</replaceable></arg>
</cmdsynopsis>
Sends the command
<option><replaceable>cmdNr</replaceable></option> and the
message <option><replaceable>message</replaceable></option> to
channel
<option><replaceable>channelName</replaceable></option> using
the flags
<option><replaceable>flags</replaceable></option>. The command
numbers are application specific. If
<option>#<replaceable>flags</replaceable></option> is used,
flags is the numeric (integer) representation of the flags is
to be set. If the # is omitted,
<option><replaceable>flags</replaceable></option> is a list of
symbolic flags. Currently, there is only one flag:
<option>multiple</option> or <option>noflush</option> with the
same meaning, indicating that there is more to follow and no
automatic flush on the channel should be done.
</para>
</section>
<section id="web::recv">
<title><command>web::recv</command></title>
<para>
<cmdsynopsis>
<command>web::recv</command>
<arg choice="req"><replaceable>channel</replaceable></arg>
<arg choice="req"><replaceable>cmdVarName</replaceable></arg>
<arg choice="req"><replaceable>msgVarName</replaceable></arg>
<arg choice="req"><replaceable>flagVarName</replaceable></arg>
</cmdsynopsis>
Receives a message from <option>channelName</option>. The
other arguments are the names of the corresponding variables
which will contain the message. The flags are returned
numeric. (To handle these flags, use the
<command>web::msgflag</command> function).
</para>
</section>
<section id="web::msgflag">
<title><command>web::msgflag</command></title>
<para>
<cmdsynopsis>
<command>web::msgflag</command>
<arg choice="opt"><replaceable>flags</replaceable></arg>
<arg choice="opt"><replaceable>testflags</replaceable></arg>
</cmdsynopsis>
Sets or tests flags.
<variablelist>
<varlistentry>
<term><command>web::msgflag</command></term>
<listitem>
<para>
Returns a list of all known message flags.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::msgflag</command>
<option><replaceable>flags</replaceable></option></term>
<listitem>
<para>
Returns the integer representation of the flags listed
in <option>flags</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::msgflag</command>
<option><replaceable>flags</replaceable></option>
<option><replaceable>testflags</replaceable></option></term>
<listitem>
<para>
Returns 1, if the flags in <option>testflags</option>
are set in <option>flags</option>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para><para>
</para>
</section>
</section>
<section id="apache_module_specific_commands">
<title>Apache module specific commands</title>
<para>
Note that these commands are implemented as dummies in the CGI
version of Websh only. They don't do anything except for
<command>web::initializer</command> and
<command>web::finalizer</command>, which just evaluate the
code provided in the argument.
</para>
<section id="web::initializer">
<title><command>web::initializer</command></title>
<para>
<cmdsynopsis>
<command>web::initializer</command> <arg choice="req"><replaceable>code</replaceable></arg>
</cmdsynopsis>
This code is executed only when a new interpreter is created.
Note that the &quot;main&quot; Websh script can
<command>source</command> several modules which each call
their initialization code.
Also note that this code eval'd when it is first requested and
read in its normal script sequence, and not prior to any other
code in the script.
</para>
<para>
Calling <command>web::loglevel</command> and
<command>web::logdest</command> in any
<command>web::initializer</command> will tag these log levels
and destinations as not to be deleted, after the request ends.
This log condifguration will therefore also be available in
the finalizer code, which is only eval'd after the last request
in the interpreter has been cleaned up.
</para>
<example>
<title>logging in <command>web::initializer</command></title>
<programlisting>
&gt; cat test.ws3
web::initializer {
web::logdest add user.-debug file -unbuffered /tmp/test.log
web::logfilter add *.-debug
web::log info "initializing interp"
}
web::command default {
web::log info "command default call number [web::interpcfg numreq]"
web::putxfile /tmp/dummypage.html
}
web::finalizer {
web::log info "shutting down interp"
}
web::dispatch
&gt; # requesting test.ws3 three times over mod_websh:
&gt; more /tmp/test.log
10/28/05 14:13:45 [20639] user.info: initializing interp
10/28/05 14:13:45 [20639] user.info: command default call number 0
10/28/05 14:13:46 [20639] user.info: command default call number 1
10/28/05 14:13:47 [20639] user.info: command default call number 2
10/28/05 14:13:47 [20639] user.info: shutting down interp</programlisting>
</example>
<para>
Note that in the above example the lifetime of the interpreter class is set to 3 requests. (See command <command>web::interpclasscfg</command>.)
</para>
</section>
<section id="web::finalizer">
<title><command>web::finalizer</command></title>
<para>
<cmdsynopsis>
<command>web::finalizer</command> <arg choice="req"><replaceable>code</replaceable></arg>
</cmdsynopsis>
Registers code to be exectuted when the interpreter for this
Websh script is deleted. <command>web::finalize</command>
will then call each <option>code</option> block that has been
registered, starting with the most recently added
<option>code</option>.
</para>
</section>
<section id="web::finalize">
<title><command>web::finalize</command></title>
<para>
<cmdsynopsis>
<command>web::finalize</command>
</cmdsynopsis>
Executes finalizer code that has been registered using
<command>web::finalizer</command>, starting with the most
recently added <option>code</option>. Note that this command
is executed automatically and does not have to be called
manually. However, it can be used as a hook, when the
interpreter is deleted:
<example>
<title><command>web::finalize</command> hook</title>
<programlisting>
rename web::finalize web::finalize.orig
proc web::myFinalize {} {
# code to eval before finalize.orig
finalize.orig
# code to eval after finalize.orig
} </programlisting>
</example>
</para>
</section>
<section id="web::maineval">
<title><command>web::maineval</command></title>
<para>
<cmdsynopsis>
<command>web::maineval</command> <arg choice="req"><replaceable>code</replaceable></arg>
</cmdsynopsis>
Executes code in the &quot;main&quot; interpreter of mod_websh. (Note
that this is synchronized, i.e. the main interpreter is locked for
exclusive access by the current thread within the process. However,
running Apache in a prefork setting sets up a main interpreter per
child, so the exclusive access does not refer to server wide
exclusivity, but only to child process wide exclusiveity.)
</para>
</section>
<section id="web::interpclasscfg">
<title><command>web::interpclasscfg</command></title>
<para>
<cmdsynopsis>
<command>web::interpclasscfg</command>
<arg choice="req"><replaceable>classid</replaceable></arg>
<arg choice="req"><replaceable>property</replaceable></arg>
<arg choice="opt"><replaceable>value</replaceable></arg>
</cmdsynopsis>
Properties are: <option>maxrequests</option>,
<option>maxttl</option>, <option>maxidletime</option>
Sets or accesses properties of the interpreter class
<option>classid</option>.
<variablelist>
<varlistentry>
<term>
<command>web::interpclasscfg</command>
<option><replaceable>classid</replaceable></option>
<option>maxrequests</option>
<optional><option><replaceable>value</replaceable></option></optional>
</term>
<listitem>
<para>
Sets or gets the maximum number of requests
interpreters of this class should handle. If
<option>value</option> is 0, handle an unlimited
number of requests. Default: 1.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::interpclasscfg</command>
<option><replaceable>classid</replaceable></option>
<option>maxttl</option>
<optional><option><replaceable>value</replaceable></option></optional></term>
<listitem>
<para>
Sets or gets the maximum number of seconds
interpreters of this class should live. If
<option>value</option> is 0, it lives
forever. Default: 0.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::interpclasscfg</command>
<option><replaceable>classid</replaceable></option> <option>maxidletime</option>
<optional><option><replaceable>value</replaceable></option></optional>
</term>
<listitem>
<para>
Sets or gets the maximum number of seconds
interpreters of this class should live beeing idle. If
<option>value</option> is 0, no idle timeout is
assumed. Default: 0.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>
<section id="web::interpcfg">
<title><command>web::interpcfg</command></title>
<para>
<cmdsynopsis>
<command>web::interpcfg</command>
<arg choice="opt"><replaceable>property</replaceable></arg>
<arg choice="opt"><replaceable>value</replaceable></arg>
</cmdsynopsis>
Properties are: <option>numreq</option>,
<option>retire</option>, <option>starttime</option>,
<option>lastusedtime</option>
Sets or accesses properties of the current interpreter.
<variablelist>
<varlistentry>
<term><command>web::interpcfg</command></term>
<listitem>
<para>
Returns <option>classid</option> of current
interpreter.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::interpcfg</command>
<option>numreq</option></term>
<listitem>
<para>
Returns the number of requests handled by this
interpreter.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::interpcfg</command>
<option>retire</option>
<optional><option>boolean</option></optional></term>
<listitem>
<para>
Sets or gets the flag indicating this interpreter
should be removed after handling the current request.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::interpcfg</command>
<option>starttime</option></term>
<listitem>
<para>
Returns the time in seconds since the epoch, this
interpreter was started.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>web::interpcfg</command>
<option>lastusedtime</option></term>
<listitem>
<para>
Returns the time in seconds since the epoch, this
interpreter was last used (starttime in case of first
request).
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>
<section id="web::interpmap">
<title><command>web::interpmap</command></title>
<para>
<cmdsynopsis>
<command>web::interpmap</command>
<arg choice="req"><replaceable>filename</replaceable></arg>
</cmdsynopsis>
Hook to define interpreter classes depending on the requested file.
Note that this hook must be defined in the Websh configuration file
(WebshConfig directive of mod_websh).
</para>
<para>
When a request is directed to mod_websh, Websh needs to determine the
interpreter class for that reqest. It does that by calling
<command>web::interpmap</command> with the requested file as argument.
The return value of that command is the name of the interpreter class
and at the same time the filename of the script for this interpreter
class.
<example>
<title><command>web::interpmap</command></title>
<programlisting>
proc web::interpmap {filename} {
if {[string match "/path/to/myApp" $filename]} {
# this is my special app
return /real/path/to/myApp
}
if {[string match "*.ws3"]} {
# scripts have their own interp class
return $filename
}
# default: all templates are handled by my handler
return /my/special/template/handler
} </programlisting>
</example>
The default implementation of <command>web::interpmap</command> is
<programlisting>proc web::interpmap {filename} {return $filename}</programlisting>
This sets up a separate interpreter class for every requested URL
and takes the file itself as script.
</para>
</section>
</section>
<section id="misc_commands">
<title>Miscellaneous commands</title>
<section id="web::match">
<title><command>web::match</command></title>
<para>
<cmdsynopsis>
<command>web::match</command>
<arg choice="req"><replaceable>result</replaceable></arg>
<arg choice="req"><replaceable>listToBeSearched</replaceable></arg>
<arg choice="req"><replaceable>searchFor</replaceable></arg>
</cmdsynopsis>
In case <option><replaceable>searchFor</replaceable></option> exists in
<option><replaceable>listToBeSearched</replaceable></option>,
<command>web::match</command> returns
<option><replaceable>result</replaceable></option>, otherwise an empty string.
</para>
<para>
<command>web::match</command> treats listToBeSearched as a list.
Thus, <emphasis><command>web::match &quot;ok&quot; {tv dvd vcr} dvd</command></emphasis>
will return <emphasis>ok</emphasis>.
</para>
</section>
<section id="web::tempfile">
<title><command>web::tempfile</command></title>
<para>
<cmdsynopsis>
<command>web::tempfile</command>
<arg choice="opt"><replaceable>options</replaceable></arg>
</cmdsynopsis>
Options are <option>-path <replaceable>path</replaceable></option>,
<option>-prefix <replaceable>prefix</replaceable></option>, and <option>-remove</option>.
<cmdsynopsis><command>web::tempfile</command>
<arg choice="opt">-path
<replaceable>path</replaceable>
</arg>
<arg choice="opt">-prefix
<replaceable>prefix</replaceable>
</arg>
</cmdsynopsis>
Returns a unique name of a temporary file in the default
temp directory or the directory given with
<replaceable>path</replaceable>.
The name can be prefixed with <replaceable>prefix</replaceable>.
The maximum of guaranteed unique names per application is system
dependent. This command just returns the name of a file. It is the
programmers job to handle the file, for example to open
it. Note that Websh keeps an internal list of all file
names generated with <command>web::tempfile</command> and will
attempt to delete all files when the interpreter dies.
<cmdsynopsis><command>web::tempfile</command>
<arg choice="req">-remove</arg>
</cmdsynopsis>
Attempts to clean up all temporary
files previously created using <command>web::tempfile</command> and
resets the internal list of these file names.
</para>
</section>
</section>
</article>