doc/quickref.xml (3,244 lines of code) (raw):

<?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>