blob: 0b95309034fbe5b4a6b8368d2bcdcdaa57d5a7b3 [file] [log] [blame]
<section id="commands">
<title>Rivet Tcl Commands and Variables</title>
<section>
<para>
Starting with version 2.1.0 the Rivet command set moved into the
<command>::rivet</command> namespace.
</para>
<para>
In order to preserve out of the box compatibility with existing scripts,
Rivet exports commands by default and makes them available for import
into any namespace (global namespace included).
Rivet's build system can be told not to export the command set by
passing the switch <command>--disable-rivet-commands-export</command>
to 'configure'. In the future we may change this option's default.
</para>
<para>
Commands must be imported into another namespace with the command:
</para>
<para>
<command>namespace import -force ::rivet::*</command>
</para>
<para>
Whenever a new application is being developed and compatibility
issues can be confined within specific files, it is recommended
that commands be specified with their fully qualified names.
</para>
</section>
<refentry id="shorthand">
<refnamediv>
<refname>&lt;?= ... ?&gt;</refname>
<refpurpose>
Shorthand construct for single strings output
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>&lt;?= <arg choice="plain">$string</arg> ?&gt;</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
This construct is a simplified form to print a single string wherever
needed in a <arg>.rvt</arg> template. The contruct is equivalent to
writing the following line of Tcl code
</para>
<programlisting>puts -nonewline $string</programlisting>
<para>
The <arg>string</arg> argument to the shorthand construct can
be any Tcl command returning a value
</para>
<para>
See <xref linkend="hello_world">Hello World</xref> or
<xref linkend="variable_access">Variable Access</xref>
</para>
</refsect1>
</refentry>
<refentry id="abort_code">
<refnamediv>
<refname>abort_code</refname>
<refpurpose>
Returns the code passed to <command>abort_page</command>
earlier during the request processing
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::abort_code</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Usage of this command is meaningful only in a script set as
AbortScript or AfterEveryScript.
<command>abort_code</command> returns the value of the optional
parameter passed to <command>abort_page</command> earlier in
the same request processing.
</para>
</refsect1>
</refentry>
<refentry id="abort_page">
<refnamediv>
<refname>abort_page</refname>
<refpurpose>
Stops outputting data to web page, similar in
purpose to PHP's <command>die</command> command.
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::abort_page</command>
<group choice="req">
<arg><replaceable>abort code</replaceable></arg>
<arg><replaceable>-aborting</replaceable></arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
This command flushes the output buffer and stops the Tcl
script from sending any more data to the client.
A normal Tcl script might use the
<command>exit</command> command, but that cannot be used in
Rivet without actually exiting the apache child
process!
<command>abort_page</command> triggers
the execution of an optional AbortScript that has to be
specified in the configuration. The value of the
argument <arg>abort code</arg> can be retrieved with the
<command>abort_code</command> command during the
execution of <link linkend="directives">AbortScript or
AfterEveryScript</link>,
allowing the script to take appropriate actions in order to deal
with the cause of the abort.
</para>
<para>
The argument <option>-aborting</option> causes <option>abort_page</option>
to return 1 when the current execution is the outcome of an abort condition.
In other words this query is meaningful in code specified as
<link linkend="directives">AfterEveryScript</link> to understand
if an abort condition took place beforehand.
</para>
</refsect1>
</refentry>
<refentry id="apache_log_error">
<refnamediv>
<refname>apache_log_error</refname>
<refpurpose>log messages to the Apache error log</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::apache_log_error</command>
<arg>priority</arg>
<arg>message</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
The apache_log_error command logs a message to the
Apache error log, whose name and location have been
set by the <option>ErrorLog</option> directive.
</para>
<para>
Priority must be one of
<option>debug</option>,
<option>info</option>,
<option>notice</option>,
<option>warning</option>,
<option>err</option>,
<option>crit</option>,
<option>alert</option>, or
<option>emerg</option>.
</para>
</refsect1>
</refentry>
<refentry id="apache_table">
<refnamediv>
<refname>apache_table</refname>
<refpurpose>access and manipulate Apache tables in the request structure.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<group choice="req">
<arg>get</arg>
<arg>set</arg>
<arg>exists</arg>
<arg>unset</arg>
<arg>names</arg>
<arg>array_get</arg>
<arg>clear</arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
The apache_table command is for accessing and manipulating
Apache tables in the request structure.
</para>
<para>
The table name must be one of
<option>notes</option>,
<option>headers_in</option>,
<option>headers_out</option>,
<option>err_headers_out</option>, or
<option>subprocess_env</option>.
</para>
<variablelist>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<arg choice="plain">get</arg>
<arg><replaceable>tablename</replaceable></arg>
<arg><replaceable>key</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
When given the name of an Apache table
<option><replaceable>tablename</replaceable></option>
and the name of a key
<option><replaceable>tablename</replaceable></option>,
returns the value of the key in the table, or an empty
string.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<arg choice="plain">set</arg>
<arg><replaceable>tablename</replaceable></arg>
<arg><replaceable>key</replaceable></arg>
<arg><replaceable>value</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<arg choice="plain">set</arg>
<arg><replaceable>tablename</replaceable></arg>
<arg><replaceable>list</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Stores the <option><replaceable>value</replaceable></option> in
the table <option><replaceable>tablename</replaceable></option>
under the key <option><replaceable>key</replaceable></option>.
</para>
<para>
For the list form,
<option><replaceable>list</replaceable></option> contains
a list of zero or more pairs of key-value pairs to be
set into the table
<option><replaceable>tablename</replaceable></option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<arg choice="plain">exists</arg>
<arg><replaceable>tablename</replaceable></arg>
<arg><replaceable>key</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns 1 if the specified key,
<option><replaceable>key</replaceable></option>,
exists in table
<option><replaceable>tablename</replaceable></option>,
else 0.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<arg choice="plain">unset</arg>
<arg><replaceable>tablename</replaceable></arg>
<arg><replaceable>key</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Removes the key-value pair referenced by
<option><replaceable>key</replaceable></option>
from the table
<option><replaceable>tablename</replaceable></option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<arg choice="plain">names</arg>
<arg><replaceable>tablename</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns a list of all of the keys present in the table
<option><replaceable>tablename</replaceable></option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<arg choice="plain">array_get</arg>
<arg><replaceable>tablename</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns a list of key-value pairs from the table
<option><replaceable>tablename</replaceable></option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::apache_table</command>
<arg choice="plain">clear</arg>
<arg><replaceable>tablename</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Clears the contents of the specified table.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
<refentry id="catch">
<refnamediv>
<refname>catch</refname>
<refpurpose>wraps core command <command>catch</command> </refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::catch</command>
<arg><replaceable>script</replaceable></arg>
<arg><replaceable>error_code_var_name</replaceable></arg>
<arg><replaceable>options_var_name</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>::rivet::catch</command> wraps the core language <command>catch</command>
command adding some extra error handling needed by mod_rivet design.
The rationale for Rivet to have its own <command>::rivet::catch</command> reads
as follows: within mod_rivet a script execution can be interrupted by either calling
<command>::rivet::exit</command>(deprecated) or <command>::rivet::abort_page</command>.
These commands implement a simple internal exception mechanism by
returning a special error code so that execution is in turn handed down to the
<command>AbortScript</command> and eventually to <command>AfterEveryScript</command>
(if any of them is defined). Any code calling one of these commands which runs under
control of the <command>::catch</command> command would need to do this chore itself,
checking the error info and in case throw the error again if it had been originated
by one of mod_rivet's exceptions calls. This is what <command>::rivet::catch</command>
does hiding the implementation details provide a better and more compatibile way to
handle this condition.
</para>
<note>
This command is not meant to replace the core command, thus it's not exported from the
<command>::rivet</command> namespace and therefore has to be fully qualified.
</note>
</refsect1>
</refentry>
<!-- Reference page for command 'clock_to_rfc' -->
<refentry id="clock_to_rfc">
<refnamediv>
<refname>clock_to_rfc850_gmt</refname>
<refpurpose>create a rfc850 time from [clock seconds].</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::clock_to_rfc850_gmt</command>
<arg><replaceable>seconds</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Convert an integer-seconds-since-1970 click value to
RFC850 format, with the additional requirement that it be
GMT only.
</para>
</refsect1>
</refentry>
<!-- Reference page for command 'cookie' -->
<refentry id="cookie">
<refnamediv>
<refname>cookie</refname>
<refpurpose>get, set and delete cookies.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::cookie</command>
<arg>set</arg>
<arg><replaceable>cookieName</replaceable></arg>
<arg><replaceable><optional>cookiValue</optional></replaceable></arg>
<arg>-days <replaceable>expireInDays</replaceable></arg>
<arg>-hours <replaceable>expireInHours</replaceable></arg>
<arg>-minutes <replaceable>expireInMinutes</replaceable></arg>
<arg>-expires <replaceable>Wdy, DD-Mon-YYYY HH:MM:SS GMT</replaceable></arg>
<arg>-path <replaceable>uriPathCookieAppliesTo</replaceable></arg>
<arg>-secure <replaceable>1/0</replaceable></arg>
<arg>-HttpOnly <replaceable>1/0</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>::rivet::cookie</command>
<arg>get</arg>
<arg><replaceable>cookieName</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>::rivet::cookie</command>
<arg>delete</arg>
<arg><replaceable>cookieName</replaceable></arg>
</cmdsynopsis>
<cmdsynopsis>
<command>::rivet::cookie</command>
<arg>unset</arg>
<arg><replaceable>cookieName</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>cookie</command> gets, sets, unsets or deletes a cookie. When you
get a cookie, the command returns the value of the cookie,
or an empty string if no cookie exists.
</para>
<para>
<command>cookie delete</command> will set the timeout value to -1 minutes -
deleting the cookie in the browser.
</para>
<para>
<command>cookie unset</command> will remove the defined cookie in the server
(perhaps preparatory to checking/resetting the cookie).
</para>
<para>
The command has a number of switches setting a cookie attributes
</para>
</refsect1>
</refentry>
<refentry id="debug">
<refnamediv>
<refname>debug</refname>
<refpurpose>
A command to print strings, arrays
and the values of variables as specified by the arguments.
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::debug</command>
<arg choice="plain">-subst</arg><arg>&lt;on|off&gt;</arg>
<arg choice="plain">-separator</arg><arg>&lt;string&gt;</arg>
<arg choice="plain">-option</arg><arg><replaceable>&lt;value&gt;</replaceable></arg>
<arg choice="plain">-option</arg><arg><replaceable>&lt;value&gt;</replaceable></arg>
<arg choice="plain">...</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
A command to make debugging more convenient print strings, arrays
and the values of variables as specified by the arguments.
</para>
<para>
Also allows the setting of an array called debug which will pick up
options for all debug commands.
</para>
</refsect1>
</refentry>
<refentry id="env">
<refnamediv>
<refname>env</refname>
<refpurpose>
Loads a single "environmental variable" into a Tcl variable.
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::env</command>
<arg><replaceable>varName</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
If it is only necessary to load one environmental variable,
this command may be used to avoid the overhead of loading
and storing the entire array.
</para>
</refsect1>
</refentry>
<refentry id="escape_sgml_chars">
<refnamediv>
<refname>escape_sgml_chars</refname>
<refpurpose>escape special SGML characters in a string.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::escape_sgml_chars</command>
<arg>string</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Scans through each character in the specified string looking
for any special (with respect to SGML, and hence HTML) characters
from the specified string, and returns the result.
For example, the right angle bracket is escaped to the corrected
ampersand gt symbol.
</para>
<!--note>
You must require the <command>rivetlib</command> package in order to gain access to this command
</note -->
</refsect1>
</refentry>
<refentry id="escape_shell_command">
<refnamediv>
<refname>escape_shell_command</refname>
<refpurpose>escape shell metacharacters in a string.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::escape_shell_command</command>
<arg>string</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Scans through each character in the specified string looking
for any shell metacharacters, such as asterisk, less than and
greater than, parens, square brackets, curly brackets, angle
brackets, dollar signs, backslashes, semicolons, ampersands,
vertical bars, etc.
</para>
<para>
For each metacharacter found, it is quoted in the result by
prepending it with a backslash, returning the result.
</para>
<!-- note>
You must require the <command>rivetlib</command> package in order to gain access to this command
</note -->
</refsect1>
</refentry>
<refentry id="escape_string">
<refnamediv>
<refname>escape_string</refname>
<refpurpose>convert a string into escaped characters.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::escape_string</command>
<arg>string</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Scans through each character in the specified string looking
for special characters, escaping them as needed, mapping
special characters to a quoted hexadecimal equivalent,
returning the result.
</para>
<para>
This is useful for quoting strings that are going to be
part of a URL.
</para>
<!-- note>
You must require the <command>rivetlib</command> package in order to gain access
to this command
</note -->
</refsect1>
</refentry>
<refentry id="exit">
<refnamediv>
<refname>exit</refname>
<refpurpose>terminate execution and child process</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::exit</command>
<arg>code</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Replaces Tcl's <command>exit</command> core command. <command>::rivet::exit</command>
interrupts execution of the current script and passes execution to AbortScript if
such script is set. After AbortScript has finished and request processing completed
the child process is forced to exit by eventually calling Tcl_Exit producing the same final
effect of the core command.
During an <command>AbortScript</command> execution the
exit condition can be detected
<programlisting>if {[<command>::rivet::abort_page -exiting</command>]} {
...handle exit condition
}</programlisting>
</para>
<para>
<command>::rivet::exit</command> has a single optional argument <arg>code</arg>. This
value must be a positive integer number to be passed to Tcl_Exit. If any other value is
given <arg>code</arg> is set to 0. The exit code can be obtained from the dictionary
returned by <command>::rivet::abort_code</command>
</para>
<programlisting>[::rivet::abort_code]
&lt;== return_code <arg>code</arg> error_code exit</programlisting>
<para>
Rivet's specific implementation prevents any abrupt process termination
that otherwise the <command>exit</command> command would bring about deferring
the call to Tcl_Exit to a later stage when the request processing has finished.
This is always true if the mod_rivet runs the prefork bridge. The behavior with
the worker bridge depends on the <command>SingleThreadExit</command> configuration
directive. By default all the threads of a single process are requested to exit
before the child process exits. Starting with version &version32;
by setting the <command>SingleThreadExit</command> option directive
calling <command>::rivet::exit</command> causes a single thread termination.
Though always accepted this directive is meaningful only if used with the worker
or lazy bridges.
</para>
<note>
Nonetheless we discourage the programmer to use such command, and suggest to focus on proper
application design and avoid such a drastic way to bail out.
If you need to restart the child processes from time to time we recommend to check the
MaxRequests parameter in the
<ulink url="https://httpd.apache.org/docs/2.4/mod/prefork.html">prefork MPM documentation</ulink>
or the
<ulink url="http://httpd.apache.org/docs/2.4/mod/mpm_common.html#maxrequestsperchild">MaxRequestsPerChild</ulink>
configuration parameter
</note>
</refsect1>
</refentry>
<refentry id="headers">
<refnamediv>
<refname>headers</refname>
<refpurpose>set and parse HTTP headers.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::headers</command>
<group choice="req">
<arg>get</arg>
<arg>set</arg>
<arg>redirect</arg>
<arg>add</arg>
<arg>type</arg>
<arg>numeric</arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
The <command>headers</command> command is for setting and
parsing HTTP headers.
</para>
<variablelist>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::headers</command>
<arg choice="plain">get</arg>
<arg><replaceable>headername</replaceable></arg>
<arg><replaceable>value</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Read arbitrary header names and values from output HTTP headers
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::headers</command>
<arg choice="plain">set</arg>
<arg><replaceable>headername</replaceable></arg>
<arg><replaceable>value</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Set arbitrary header names and values into output HTTP headers
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::headers</command>
<arg choice="plain">sent</arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Test internal status of the module and returns 1
if the HTTP headers have been already sent
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::headers</command>
<arg choice="plain">redirect</arg>
<arg><replaceable>uri</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Redirect from the current page to a new
URI. <emphasis>Must</emphasis> be done in the first block
of TCL code.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::headers</command>
<arg choice="plain">add</arg>
<arg><replaceable>headername</replaceable></arg>
<arg><replaceable>value</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>Add text to header
<varname>headername</varname>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::headers</command>
<arg choice="plain">type</arg>
<arg><replaceable>content-type</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
This command sets the <constant>Content-type</constant>
header returned by the script, which is useful if you wish
to send content other than HTML with Rivet - PNG or jpeg
images, for example.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::headers</command>
<arg choice="plain">numeric</arg>
<arg><replaceable>response code</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Set a numeric response code, such as 200, 404 or 500.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
<refentry id="html">
<refnamediv>
<refname>html</refname>
<refpurpose>construct html tagged text.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::html</command>
<arg><replaceable>string</replaceable></arg>
<arg rep="repeat"><replaceable>arg</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Print text with the added ability to pass HTML tags
following the string. Example:
<programlisting>::rivet::html "Test" b i</programlisting>
produces: <computeroutput>&lt;b&gt;&lt;i&gt;Test&lt;/i&gt;&lt;/b&gt;</computeroutput>
</para>
</refsect1>
</refentry>
<refentry id="http_accept">
<refnamediv>
<refname>http_accept</refname>
<refpurpose>Parse HTTP Accept header lines</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::http_accept
<arg><replaceable>-zeroweight</replaceable></arg>
<arg><replaceable>-default</replaceable></arg>
<arg><replaceable>-list</replaceable></arg>
http_accept_line</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Command for parsing HTTP Accept header lines that tell the
server about preferences and/or capabilities of the browser
(e.g. content language,media type, etc.). The following
script
</para>
<para>
<command>::rivet::http_accept</command> returns a dictionary
value in which every content preference is matched to its
precedence value
</para>
<programlisting>load_headers
set language_precedence [::rivet::http_accept $headers(Accept-Language)]
foreach lan [dict keys $language_precedence] {
puts "$lan -> [dict get $language_precedence $lan]"
}</programlisting>
<para>
when run from a browser where 5 languages were chosen
would output
</para>
<programlisting>en-us -> 1
en -> 0.8
it -> 0.6
de-de -> 0.4
fr-fr -> 0.2</programlisting>
<para>
The <replaceable>-list</replaceable> switch would suppress
the precedence values and the accepted fields
are returned listed with decreasing precedence order.
</para>
<programlisting> puts [::rivet::http_accept -list $headers(Accept)]
text/html application/xhtml+xml application/xml */*
</programlisting>
<para>
</para>
</refsect1>
</refentry>
<refentry id="import_keyvalue_pairs">
<refnamediv>
<refname>import_keyvalue_pairs</refname>
<refpurpose>Import an argument list into the named array</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::import_keyvalue_pairs</command>
<arg>arrayName</arg>
<arg>argsList</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
key-value pairs, like "-foo bar" are stored in the array <arg>arrayName</arg>.
In that case, the value "bar" would be stored in the element "foo"
</para>
<para>
If "--" appears or a key doesn't begin with "-", the rest of the arg
list is stored in the special args element of the array.
</para>
<para>
Example:
<programlisting>::rivet::import_keyvalue_pairs keyvalue_map [list -a1 v1 -a2 v2 -a3 v3 -- 1 2 3 4 5]
parray keyvalue_map
keyvalue_map(a1) = v1
keyvalue_map(a2) = v2
keyvalue_map(a3) = v3
keyvalue_map(args) = 1 2 3 4 5</programlisting>
</para>
</refsect1>
</refentry>
<refentry id="include">
<refnamediv>
<refname>include</refname>
<refpurpose>includes a file into the output stream without modification.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::include</command>
<arg><replaceable>filename_name</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Include a file without parsing it for processing tags &lt;?
and ?&gt;. This is the best way to include an HTML file or
any other static content.
</para>
</refsect1>
</refentry>
<refentry id="inspect">
<refnamediv>
<refname>inspect</refname>
<refpurpose>Introspection command for Rivet configuration</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::inspect</command>
<arg><replaceable>configuration_section</replaceable></arg>
<arg><replaceable>configuration_parameter</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>::rivet::inspect</command> provides introspection into the running
configuration of Rivet. Rivet's debug command uses it in order to gain insight
into the configuration, but it can be used in any script.
</para>
<para>
<command>::rivet::inspect</command> can be called in 5 different forms
</para>
<itemizedlist mark="square">
<listitem>
With no argument the command returns a dictionary with 3
keys: server, dir, user. Each key is associated to a subdictionary
carrying the configuration as set for that request. In this form the command is
meant to support compatibility with previous versions of mod_rivet
where three global arrays were created to be internally used by command
<command>::rivet::debug</command>.
</listitem>
<listitem>
With the <arg>-all</arg> argument a dictionary
carrying the whole configuration for that specific request is returned.
If a configuration parameter is not set it's given the
string <emphasis>undefined</emphasis>. Returned configuration paramenters
are<programlisting> "ServerInitScript",
"GlobalInitScript",
"ChildInitScript",
"ChildExitScript",
"BeforeScript",
"AfterScript",
"AfterEveryScript",
"AbortScript",
"ErrorScript",
"UploadMaxSize",
"UploadDirectory",
"UploadFilesToVar",
"SeparateVirtualInterps",
"HonorHeaderOnlyRequests"</programlisting>
</listitem>
<listitem>
With one of the Rivet configuration directives listed above as
single argument <command>::rivet::inspect</command> returns the
current value in the configuration record.
</listitem>
<listitem>
Passing the argument "script" <command>::rivet::inspect</command>
returns a path to the current script in a similar way
core command <command>[info script]</command> does. The basic
difference is that the core command returns a relative path with
respect to the current working directory, whereas mod_rivet's command
returns the full path.
</listitem>
<listitem>
Passing the argument "server" <command>::rivet::inspect</command>
returns a dictionary with these fields taken from the server record
descriptor
<itemizedlist>
<listitem>hostname: The server hostname </listitem>
<listitem>admin: The admin's contact information</listitem>
<listitem>errorlog: The name of the error log</listitem>
<listitem>server_path: Pathname for ServerPath</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</refsect1>
</refentry>
<!-- refentry id="lassign">
<refnamediv>
<refname>lassign</refname>
<refpurpose>Assign a list of values to a list of variables</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::lassign</command>
<arg>value_list</arg>
<arg>variables</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lassign</command> emulates the TclX lassign command. It accepts
a list variables and treats the rest as a list of variable names that will
be assigned with the values in the caller's scope
</para>
<para>
<programlisting># ::rivet::lassign {1 2 3} a b c
# set a
1
# set b
2
# set c
3</programlisting>
</para>
</refsect1>
</refentry -->
<refentry id="lassign_array">
<refnamediv>
<refname>lassign_array</refname>
<refpurpose>Assign a list of values to array variables</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::lassign_array</command>
<arg>value_list</arg>
<arg>array_name</arg>
<arg>array_variables</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lassign_array</command> is an utility command inspired by the same Tclx command and
with a close resemblance with Tcl's <command>lassign</command> for assigning list elements to variables.
<command>lassign_array</command> first argument is a list of values to be assigned to an array that must be
given as second argument. The remaining arguments are the array's variable names which will store
as values the elements of the list. Variables names don't matching values in the list are given an empty string.
Unassigned list elements are returned as a list.
</para>
<programlisting>::rivet::lassign_array {1 2 3 4} assigned_array a b c d
parray assigned_array
<emphasis role="strong">assigned_array</emphasis>
assigned_array(a) = 1
assigned_array(b) = 2
assigned_array(c) = 3
assigned_array(d) = 4
set rem [::rivet::lassign_array {1 2 3 4 5 6 7} assigned_array a b c d]
puts $rem
5 6 7</programlisting>
</refsect1>
</refentry>
<refentry id="lempty">
<refnamediv>
<refname>lempty</refname>
<refpurpose>
Returns 1 if &lt;list&gt; is empty or 0 if it has any elements.
This command emulates the TclX lempty command.
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::lempty</command>
<arg choice="plain">list</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Returns 1 if &lt;list&gt; is empty or 0 if it has any elements.
This command emulates the TclX lempty command.
</para>
</refsect1>
</refentry>
<refentry id="lmatch">
<refnamediv>
<refname>lmatch</refname>
<refpurpose>
Look for elements in &lt;list&gt; that match &lt;pattern&gt;
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::lmatch</command>
<group choice="req">
<arg>-exact</arg>
<arg>-glob</arg>
<arg>-regexp</arg>
</group>
<arg choice="plain">list</arg>
<arg choice="plain">pattern</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Look for elements in &lt;list&gt; that match &lt;pattern&gt;.
This command is a decent replacement for TclX lmatch command when TclX is
not available
</para>
<para>
In the following example a regular expression is matched against
each element in the input list and a list containing the matching
elements is returned
</para>
<para>
<programlisting>::rivet::lmatch -regexp { aaxa bxxb ccxxxxcc } {.+[x]{2}.+}
bxxb ccxxxxcc</programlisting>
</para>
</refsect1>
</refentry>
<refentry id="load_cookies">
<refnamediv>
<refname>load_cookies</refname>
<refpurpose>get any cookie variables sent by the client.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::load_cookies</command>
<arg choice="opt"><replaceable>array_name</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
</refsect1>
<para>
Load the array of cookie variables into the specified
array name. Uses array <option>cookies</option> by
default.
</para>
</refentry>
<refentry id="load_env">
<refnamediv>
<refname>load_env</refname>
<refpurpose>get the request's environment variables.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::load_env</command>
<arg choice="opt"><replaceable>array_name</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Load the array of environment variables into the specified
array name. Uses array <option>::request::env</option> by
default.
</para>
<para>
As Rivet pages are run in the <option>::request</option>
namespace, it isn't necessary to qualify the array name
for most uses - it's ok to access it as
<option>env</option>.
</para>
</refsect1>
</refentry>
<refentry id="load_headers">
<refnamediv>
<refname>load_headers</refname>
<refpurpose>get client request's headers.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::load_headers</command>
<arg><replaceable>array_name</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Load the headers that come from a client request into the
provided array name, or use <option>headers</option> if no
name is provided.
</para>
</refsect1>
</refentry>
<refentry id="load_response">
<refnamediv>
<refname>load_response</refname>
<refpurpose>load form variables into an array.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::load_response</command>
<arg><replaceable>arrayName</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Load any form variables passed to this page into an
array. If <command>load_response</command> is called without
arguments the array <option>response</option> is created in
the scope of the caller. If the variables var1,var2,var3...
having values val1,val2,val3... are passed to the page, the
resulting array will be a collection mapping var1,var2,var3...
to their corresponding values. <command>load_response</command>
was inspired by the same NeoWebScript procedure in the way
it deals with multiple assignments: if a variable
is assigned more than once the corresponding array element will be a
list of the values for the variable. This can be useful in the case
of forms with checkbox options that are given the same name.
This condition is signalled by the presence of an auxiliary array
variable.
</para>
<para>
Example: if a group of checkboxes are associated to the <option>var1</option>
variable then <command>response(var1)</command> will store
the list of their values and the array will also have the extra variable
<option>response(__var1)</option> which can be tested with
the usual <command>[info exists response(<option>__var1</option>)]</command>
</para>
<para>
Calling <command>load_response</command> several times for the same
array results in adding more values to the array at every call.
When needed it is left to the caller to empty the array between
two subsequent calls.
</para>
</refsect1>
</refentry>
<refentry id="lremove">
<refnamediv>
<refname>lremove</refname>
<refpurpose>remove from a list elements matching one or more patterns</refpurpose>
</refnamediv>
<refsynopsisdiv>
<command>::rivet::lremove</command>
<group choice="req">
<arg>-regexp | -glob | -exact</arg></group>
<arg choice="plain">list</arg>
<arg choice="plain">pattern</arg>
<arg><replaceable>pattern</replaceable></arg>
<arg><replaceable>pattern</replaceable></arg>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lremove</command> removes from list <arg>list</arg> the first occurrence
of an element matching one of the patterns listed in the command line. By specifying the
<option>-all</option> option every occurrence of one the patterns is removed
</para>
<para>
Pattern matching can be <option>-exact</option>,<option>-glob</option> style or following
regular expressions (<option>-regexp</option>). These options are globally valid across the
whole pattern list (default is glob style matching)
</para>
<programlisting>::rivet::lremove -all -regexp {aa e111 bab aa} aa e111 bab
e111 bab
::rivet::lremove -all -regexp {aa e111 bab aa} aa "e\\d+"
bab</programlisting>
</refsect1>
</refentry>
<refentry id="makeurl">
<refnamediv>
<refname>makeurl</refname>
<refpurpose>construct url's based on hostname, port.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::makeurl</command>
<arg><replaceable>filename</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Create a self referencing URL from a filename. <command>makeurl</command>
can be used in three ways
<itemizedlist>
<listitem>With no arguments the current script URL is returned</listitem>
<listitem>
The argument is a relative path: the command returns
the argument prefixed with the current script's URL
</listitem>
<listitem>
The argument is an absolute path: the full URL to the resource is returned
</listitem>
</itemizedlist>
</para>
<para>
Example with an absolute path:
<programlisting>::rivet::makeurl /tclp.gif</programlisting> returns
<computeroutput>http://[hostname]:[port]/tclp.gif</computeroutput>.
where hostname and port are the hostname and port of the
server in question. The protocol prefix is inferred from the protocol
in the URL referencing the script.
</para>
</refsect1>
</refentry>
<refentry id="no_body">
<refnamediv>
<refname>no_body</refname>
<refpurpose>Prevents Rivet from sending any content.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::no_body</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
This command is useful for situations where it is necessary
to only return HTTP headers and no actual content. For
instance, when returning a 304 redirect.
</para>
</refsect1>
</refentry>
<refentry id="parray">
<refnamediv>
<refname>parray</refname>
<refpurpose>Tcl's <command>parray</command> with html formatting.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::parray</command>
<arg><replaceable>arrayName</replaceable></arg>
<arg><replaceable><optional>pattern</optional></replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
An html version of the standard Tcl
<command>parray</command> command. Displays the entire
contents of an array in a sorted, nicely-formatted way.
Mostly used for debugging purposes.
</para>
</refsect1>
</refentry>
<refentry id="parse">
<refnamediv>
<refname>parse</refname>
<refpurpose>parses a Rivet template file.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::parse</command>
<arg><replaceable>filename</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Like the Tcl <command>source</command> command, but also
parses for Rivet &lt;? and ?&gt; processing tags. Using
this command, you can use one .rvt file from another.
</para>
</refsect1>
</refentry>
<refentry id="raw_post">
<refnamediv>
<refname>raw_post</refname>
<refpurpose>get the unmodified body of a POST request sent by the client.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::raw_post</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
</refsect1>
<para>
Returns the raw POST data from the request. If the request was
not a POST or there is no data, then "" - an empty string - is returned.
</para>
</refentry>
<refentry id="redirect">
<refnamediv>
<refname>redirect</refname>
<refpurpose>Interrupt processing and divert to a new URL</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::redirect</command>
<arg>URL</arg>
<arg>permanent</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>::rivet::redirect</command> diverts the browser to a new URL and marks
the redirection as either permanent in the browser local cache or
non permanent (default).
Calling <command>::rivet::redirect</command> causes the script execution to interrupt
and control passes to <command>AbortScript</command>, if such script is
set, by calling <command>::rivet::abort_page</command> and passing as abort
code a dictionary with 2 keys:
<itemizedlist>
<listitem><command>error_code</command>: string literal 'redirect'</listitem>
<listitem><command>location</command>: the URL the browser will be redirected to</listitem>
</itemizedlist>
</para>
<para>
<command>::rivet::redirect</command> drives the redirection by setting the
301 (permanent = 1: permanent redirect) or 302 (permanent = 0: non permanent redirect) and
attempts to discard the output the script might have already placed in the
stdout channel buffer. The <quote>permanent</quote> argument can also be any of the
other HTTP status codes. This is handy for returning one the 3xx status codes
dedicated to the HTTP request redirection
The command can fail if
<itemizedlist>
<listitem>A <command>flush stdout</command> has already been called before
<command>::rivet::redirect</command> thus causing the HTTP headers to be sent</listitem>
<listitem>The channel buffer has been flushed already by calling <command>flush stdout</command>
or because the Rivet channel internal buffer was full</listitem>
</itemizedlist>
The <command>stdout</command> channel, like any Tcl channels, can be manipulated
and if needed its internal buffer stretched.
</para>
</refsect1>
</refentry>
<refentry id="read_file">
<refnamediv>
<refname>read_file</refname>
<refpurpose>
Read the entire contents of a file and return it as a string.
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::read_file</command>
<arg>file name</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
This is a utility command which loads the entire content of
a file and returns it as a result.
</para>
</refsect1>
</refentry>
<refentry id="thread_id">
<refnamediv>
<refname>thread_id</refname>
<refpurpose>Returns the Tcl interpreter current thread id</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::thread_id</command>
<arg>-decimal | -hex</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>::rivet::threadid</command> returns is either hexadecimal
(default) or decimal representation the current thread id. This command
is useful because allows for precise identification of an execution thread
when Apache runs a threaded MPM. Calling the command with <arg>-decimal</arg>
prints the thread id in a form that makes it comparable with the <command>tid</command>
information printed in the error log.
</para>
</refsect1>
</refentry>
<refentry id="try">
<refnamediv>
<refname>try</refname>
<refpurpose>
Catch error and exception conditions
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::try</command>
<arg>script</arg>
<arg>script</arg>
<arg><replaceable>handlers</replaceable></arg>
<arg><replaceable>finally script</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>::rivet::try</command> wraps the core language
command and simply traps exceptions that might have raised
by <command>::rivet::abort_page</command> and
<command>::rivet::exit</command> to throw them again and
thus causing <command>AbortScript</command> to be executed.
</para>
<para>
If neither <command>::rivet::abort_page</command> nor
<command>::rivet::exit</command> are called from <arg>script</arg>
then any handlers specified in the command are tested for execution.
Thus <command>::rivet::try</command> can transparently be used
as a replacement for Tcl's own <command>try</command> and it's needed
if you want <arg>script</arg> to safely bail out to <command>AbortScript</command>
</para>
<note>
This command is not exported from the <command>::rivet</command> namespace and therefore has
to be fully qualified.
</note>
<para>
This script shows how <command>::rivet:try</command>
handles different exceptions or errors. You can drive this script
within mod_rivet adding the arguments fail or abort or exit to its URL.
You can handle the <quote>exit</quote> and <quote>abort</quote> cases with
an <command>AbortScript</command>.
See <xref linkend="directives"><command>AbortScript</command></xref>
</para>
<programlisting>&lt;html&gt;&lt;?
::rivet::try {
if {[::rivet::var_qs exists exit]} {
::rivet::exit [::rivet::var_qs get exit]
} elseif {[::rivet::var_qs exists abort]} {
::rivet::abort_page [::rivet::var_qs get abort]
} elseif {[::rivet::var_qs exists fail]} {
# this is just a non existent command
wrong_command
} else {
puts "&lt;b&gt;OK&lt;/b&gt;"
}
} on error {e o} {
puts "catching error -&amp;gt; $e&lt;br/&gt;"
dict for {fd fv} $o {
puts "$fd --&amp;gt;&amp;gt; $fv&lt;br/&gt;"
}
}
?>&lt;/html&gt;</programlisting>
<para>
Placing this code in a file (try.rvt) on the
web server <emphasis>DocumentRoot</emphasis>
directory and setting for example the browser
to <command>http://localhost/try.rvt?fail=1</command>.
</para>
<programlisting>catching error -> invalid command name "wrong_command"
-errorcode -->> TCL LOOKUP COMMAND wrong_command
-code -->> 1
-level -->> 0
-errorstack -->> INNER {invokeStk1 wrong_command} UP 1
-errorinfo -->> invalid command name "wrong_command" while executing "wrong_command" ("::try" body line 9)
-errorline -->> 9</programlisting>
</refsect1>
</refentry>
<refentry id="unescape_string">
<refnamediv>
<refname>unescape_string</refname>
<refpurpose>unescape escaped characters in a string.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::unescape_string</command>
<arg>string</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Scans through each character in the specified string looking
for escaped character sequences (characters containing a
percent sign and two hexadecimal characters), unescaping them
back to their original character values, as needed, also mapping
plus signs to spaces, and returning the result.
</para>
<para>
This is useful for unquoting strings that have been quoted to
be part of a URL.
</para>
<!-- note>
You must require the <command>rivetlib</command> package in order to gain
access to this command
</note -->
</refsect1>
</refentry>
<refentry id="upload">
<refnamediv>
<refname>upload</refname>
<refpurpose>handle a file uploaded by a client.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::upload</command>
<group choice="req">
<arg>channel</arg>
<arg>save</arg>
<arg>data</arg>
<arg>exists</arg>
<arg>size</arg>
<arg>type</arg>
<arg>filename</arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
The upload command is for file upload manipulation.
See the relevant Apache Directives to further configure the
behavior of this Rivet feature.
</para>
<variablelist>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">channel</arg>
<arg><replaceable>uploadname</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
When given the name of a file upload
<option><replaceable>uploadname</replaceable></option>,
returns a Tcl channel that can be used to access the
uploaded file.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">save</arg>
<arg><replaceable>uploadname</replaceable></arg>
<arg><replaceable>filename</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Saves the <option><replaceable>uploadname</replaceable></option> in
the file <option><replaceable>filename</replaceable></option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">data</arg>
<arg><replaceable>uploadname</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns data uploaded to the server. This is binary clean
- in other words, it will work even with files like
images, executables, compressed files, and so on.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">exists</arg>
<arg><replaceable>uploadname</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns true if an upload named <arg>uploadname</arg>
exists. This can be used in scripts that are meant to
be run by different forms that send over uploads that
might need specific processing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">size</arg>
<arg><replaceable>uploadname</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns the size of the file uploaded.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">type</arg>
</cmdsynopsis>
</term>
<listitem>
<para>
If the <varname>Content-type</varname> is set, it is
returned, otherwise, an empty string.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">filename</arg>
<arg><replaceable>uploadname</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns the filename on the remote host that uploaded the file.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">tempname</arg>
<arg><replaceable>uploadname</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns the name of the temporary file on the local host that the file was uploaded into.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::upload</command>
<arg choice="plain">names</arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns the variable names, as a list, of all the files uploaded.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
See <xref linkend="file_upload"/>.
</para>
</refsect1>
</refentry>
<refentry id="url_script">
<refnamediv>
<refname>url_script</refname>
<refpurpose>get the code of the URL referenced Tcl script or Rivet template</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::url_script</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
This command is used internally by the rivet central Tcl
procedure (::Rivet::request_handling) executed by
the default traditional code for HTTP requests processing.
Unless you're implementing your own ::Rivet::request_handling
procedure it's unlikely it can be of any use.
</para>
</refsect1>
</refentry>
<refentry id="var">
<refnamediv>
<refname>var</refname>
<refname>var_qs</refname>
<refname>var_post</refname>
<refpurpose>get the value of a form variable.</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::var</command>
<group choice="req">
<arg>get</arg>
<arg>list</arg>
<arg>exists</arg>
<arg>number</arg>
<arg>all</arg>
</group>
</cmdsynopsis>
<cmdsynopsis>
<command>::rivet::var_qs</command>
<group choice="req">
<arg>get</arg>
<arg>list</arg>
<arg>exists</arg>
<arg>number</arg>
<arg>all</arg>
</group>
</cmdsynopsis>
<cmdsynopsis>
<command>::rivet::var_post</command>
<group choice="req">
<arg>get</arg>
<arg>list</arg>
<arg>exists</arg>
<arg>number</arg>
<arg>all</arg>
</group>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
The <command>var</command> command retrieves information
about GET or POST variables sent to the script via client
request. It treats both GET and POST variables the same,
regardless of their origin. Note that there are two
additional forms of <command>::rivet::var</command>:
<command>rivet::var_qs</command> and
<command>::rivet::var_post</command>.
These two restrict the retrieval of information to
parameters arriving via the querystring
(?foo=bar&amp;bee=bop) or POSTing, respectively.
</para>
<variablelist>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::var</command>
<arg choice="plain">get</arg>
<arg><replaceable>varname</replaceable></arg>
<arg><replaceable><optional>default</optional></replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns the value of variable
<option><replaceable>varname</replaceable></option>
as a string (even if there are multiple values). If
the variable doesn't exist as a GET or POST
variable, the
<option><replaceable><optional>default</optional></replaceable></option>
value is returned, otherwise "" - an empty string -
is returned.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::var</command>
<arg choice="plain">list</arg>
<arg><replaceable>varname</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns the value of variable
<option><replaceable>varname</replaceable></option> as a list,
one list element per reference. Radiobuttons or multiple
selection listboxes are suited widgets which may
return list data.
</para>
<para>
If the result list is passed as a default value to the form package, one
could also set index "__varname" to get it interpreted as a list.
</para>
<programlisting>set response(countries) [::rivet::var list countries]
set response(__countries) ""
form form_request -defaults response
form_request select countries -multiple 1 -values {USA Canada Mexico}
form_request end</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::var</command>
<arg choice="plain">exists</arg>
<arg><replaceable>varname</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns 1 if
<option><replaceable>varname</replaceable></option>
exists, 0 if it doesn't.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::var</command>
<arg choice="plain">number</arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Returns the number of variables.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<cmdsynopsis>
<command>::rivet::var</command>
<arg choice="plain">all</arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Return a list of variable names and values.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>See <xref linkend="variable_access"/>.</para>
</refsect1>
</refentry>
<refentry id="wrap">
<refnamediv>
<refname>wrap</refname>
<refpurpose>
Split a string on newlines.
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::wrap</command>
<arg>string</arg>
<arg>maxlen</arg>
<arg choice="plan">html</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
For each line, wrap the line at a space character to be
equal to or shorter than the maximum length value passed.
</para>
<para>
If a third argument called "-html" is present, the string is put together
with html &lt;br&gt; line breaks, otherwise it's broken with newlines.
</para>
</refsect1>
</refentry>
<refentry id="wrapline">
<refnamediv>
<refname>wrapline</refname>
<refpurpose>
Split the line into multiple lines by splitting on space characters
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::wrapline</command>
<arg>string</arg>
<arg>maxlen</arg>
<arg choice="plan">html</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Given a line and a maximum length and option "-html" argument, split the line
into multiple lines by splitting on space characters and making sure each line
is less than maximum length.
</para>
<para>
If the third argument, "-html", is present, return the result with the lines
separated by html &lt;br&gt; line breaks, otherwise the lines are returned
separated by newline characters.
</para>
</refsect1>
</refentry>
<refentry id="xml">
<refnamediv>
<refname>xml</refname>
<refpurpose>
XML Fragments creation
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>::rivet::xml</command>
<arg>string</arg>
<arg>tag descriptor</arg>
<arg>tag descriptor</arg>
<arg>...</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
Given a string and a variable number of tag descriptors return XML fragment made
by nesting the tags with the same hierarchical order they are listed on the command
line. The tag descriptors can be a one element list (the tag) or an odd-length list whose
first argument is the tag namme and the remaining elements are interpreted as
attribute name-attribute value pairs.
</para>
<para>
<command>::rivet::xml</command> can work as a replacement of <command>::rivet::html</command>
provided you take care of sending the string with command <command>puts</command>
</para>
<programlisting>::rivet::xml "a string" b u
&lt;== &lt;b&gt;&lt;u&gt;a string&lt;/u&gt;&lt;/b&gt;</programlisting>
<para>
You can specify the tags attributes by replacing a tag specification
with a odd-length list containing the tag name and a series of
attribute-value pairs
</para>
<programlisting><command>::rivet::xml "a string" [list div class box id testbox] b i</command>
&lt;== &lt;div class=&quot;box&quot; id=&quot;testbox&quot;&gt;&lt;b&gt;&lt;i&gt;a string&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;</programlisting>
<programlisting><command>::rivet::xml "text to be wrapped in XML" div [list a href http://..../ title "info message"]</command>
&lt;== &lt;div&gt;&lt;a href=&quot;http://..../&quot; title=&quot;info message&quot;&gt;text to be wrapped in XML&lt;/a&gt;&lt;/div&gt;</programlisting>
<para>
A single argument is interpreted as a list of tag name and attributes to be
coded as a self closing element
</para>
<programlisting><command>::rivet::xml [list b a1 v1 a2 v2]</command>
&lt;== &lt;b a1=&quot;v1&quot; a2=&quot;v2&quot; /&gt;</programlisting>
<para>
Unless the string is literally an empty string
</para>
<programlisting><command>::rivet::xml "" [list b a1 v1 a2 v2]</command>
&lt;== &lt;b a1=&quot;v1&quot; a2=&quot;v2&quot;&gt;&lt;/b&gt;</programlisting>
<para>which is useful for generating 'script' elements in an HTML page header that wouldn't be understood
as single closing element</para>
<programlisting><command>::rivet::xml "" [list script type "text/javascript" src js/myscripts.js]</command>
&lt;== &lt;script type=&quot;text/javascript&quot; src=&quot;js/myscripts.js&quot;&gt;&lt;/script&gt;</programlisting>
</refsect1>
</refentry>
</section>