NaviServer - programmable web server

[ Main Table Of Contents | Table Of Contents | Keyword Index ]

# ns_adp(n) 4.99.8 naviserver "NaviServer Built-in Commands"

## Name

ns_adp - ADP introduction and operation

## Table Of Contents

## Description

Several commands, normally beginning with the ns_adp prefix, are used to support Naviserver Dynamic Pages , or ADPs . ADPs are a server-side environment for embedding Tcl code within static text blocks (typically HTML or XML). The Tcl code is normally delimited within <% and %> or <%= and %> tags and can be used to generate additional text or for any other purpose, e.g., updating a database.

The <% ...script... %> is used for cases where the result of the Tcl script is ignored while the <%=...script %> syntax is used to append the script result to the output buffer. In either case, the ns_adp_puts command can be used to add content to the output buffer. A simple ADP file could contain:

    <html>
    <head><title>Hello from <%=[ns_info hostname]%></title></head>
    <body>
    Time is: <%=[clock format [clock seconds]]%>
    Four links:
    <% for {set i 0} {$i < 4} {incr i} { ns_adp_puts "<a href=/link/$i.htm>Link $i</a><br>" } %>
    </body>
    </html>

Accessing this page would generate output similar to:

    <html>
    <head><title>Hello from jgdavidson.local</title></head>
    <body>
    Time is: Mon Aug 01 22:15:18 EDT 2005
    Four links: <a href=/link/0.htm>Link 0</a><br>
    <a href=/link/1.htm>Link 1</a><br>
    <a href=/link/2.htm>Link 2</a><br>
    <a href=/link/3.htm>Link 3</a><br>
    </body>
    </html>

ADP processing normally occurs in the context of an HTTP transaction when an URL request is mapped to an ADP file in the server's page root. (see ADP CONFIGURATION below for details on configuring this mapping). The ADP request processing code allocates a Tcl interpreter and includes the cooresponding ADP file. Output generated during execution of the ADP is sent as a normal HTTP response, using default status code of "200 OK" and the mime type which corresponds to the ADP file extensions, normally .adp and text/html (commands such as ns_adp_mimetype can be used to control the eventual response type).

An ADP can include additional ADP files with the ns_adp_include command or evaluate ADP text/script code directly with ns_adp_eval . This capability enables are large degree of reuse of presentation and code between applications. Each such included file or ADP string evaluation is performed in it's own call frame similar to a Tcl procedure with a local variable namespace. Arguments can be passed to new call frames and then accessed with commands such as ns_adp_argv . When necessary, commands such as ns_adp_abort provide limited support to interrupt and/or return from within an ADP, unwinding the ADP call stack to the underyling C-level request processing code.

Naviserver can be configured to execute ADP's placed with other static files within a virtual server's pages directory via the map parameter in the adp server config section, for example:

    ns_section ns/server/server1/adp
    ns_param map /*.adp ns_param map {/stories/*.adp 60}

The first map will evaluate all files which end in .adp and do not have more specific mappings (such as the second map). The second config map will execute files which end with .adp located under the /stories directly and also specifies a cache timeout in seconds. In this case, results will be retained and returned to subsequent requests without re-executing the ADP for up to 60 seconds (see the -cache paramter to the ns_adp_include command for more details).

Alternatively, arbitrary URL's may be mapped to individual ADP files using the ns_register_adp command. This command would normally be included in a virtual-server initialization scripts within the modules/tcl/ server subdirectory.

By default, errors within an ADP script block are reported in the server log and interrupt execution of the current block only; subsequent text and script blocks continue to be processed and and no error message is included in the output. This approach is highly defensive and has the benefit of generating a valid, if partial, responses after minor errors. A negative aspect of this approach is that, without careful monitoring of the server log, such errors can easily be ignored.

The default error handling behavior can be modified by settings one or more virtual-server configuration flags:

    ns_section ns/server/server1/adp
    ns_param stricterror false; # Interrupt execution on any error.
    ns_param displayerror false; # Include error message in output.
    ns_param detailerror true; # Include connection details messages.

These flags, along with other options, can be queried or modified for an individual ADP execution stream via the ns_adp_ctl.

By default, each Tcl block is independent of other blocks and must be a complete script. In particular, this means that conditional code cannot span blocks, e.g., the following does not work by default:

    <% foreach elem $list { %> Here is an <%=$elem%> element. <% } %>

This behavior can be changed with the singlescript config option or via the ns_adp_ctl command which instructs the ADP parser to converts all text/code blocks within an ADP into a single Tcl script block:

    ns_section ns/server/server1/adp
    ns_param singlescript false; # Combine code blocks into one scripts.

Setting this option would covert the script above into the following equivalent:

    <%
      foreach elem $list {
        ns_adp_puts -nonewline "\n Here is an"
        ns_adp_puts -nonewline $elem
        ns_adp_puts -nonewline " element.\n"
      }
    %>

Note that this option combines scripts within a particular ADP file, it does not combine scripts which span multiple included ADP's. In addition, error semantics described above apply to the combined script and any error within any block combined into a single script will stop execution of the entire included page.

Output including accumulated text blocks and output generated by Tcl script blocks is normally buffered internally until the end of the connection. Once complete, a single response is generated which follows HTTP response headers indicating the resulting content length. The content may optionally be gzip compressed first.

Alternatively, an incremental response can be be generated either in response to calling the ns_adp_stream or ns_adp_flush commands or automatically due to buffer overflow. In this case, an HTTP response will be generated on the first flush which specifies incremental content using HTTP/1.1 chunked-encoding. Forcing a connection into streaming mode can be useful for certain long running requests where it's reasonable to expect the browser can render incremental respnoses.

The size of the internal buffer and gzip compression options can be set with corresponding server and ADP config options. Note both the virtual-server wide gzip and ADP gzip options must be enabled to support compression of ADP output.

       ns_section ns/server/server1/adp
       ns_param gzip true ;# Enable ADP output compression.
       ns_param bufsize 102400; # Buffer size, 1meg default.

The ADP interface uses the server's mimetype configuration to map file extensions to charsets and cooresponding encoding. This configuration is necessary to ensure the file text and script blocks are properly coverted to UTF-8 for use internally. This mimetype is also used to set the character output encoding although the ns_conn encoding option can be used to override the encoding if necessary.

## CONFIGURATION

ADP pages can be enabled per-virtual-server in the configuration file.

       ns_section "ns/server/server1/adp"
       ns_param   map     /*.adp
       ...

A map entry is used to register the ADP page handler for each of the GET, HEAD and POST methods on the given URL. There may be zero or more map entries.

The following parameters provide a hook for running common code for each ADP either at the beginning of processing or for handling errors.

startpage

  The path of an ADP page which is run before the requested ADP page. Default: none.

errorpage

  The path of an ADP page which is run when an code within an ADP raises an error which is not caught. Default: none.

The following parameters control memory usage.

cachesize

  The size in bytes of the per-virtual-server page cache. This is the cache of ADP pages as read from disk and converted to an efficient form for evaluation. In addition, a separate cache of script blocks is kept per-thread, which is not controlled by this parameter. Default: 5MB.

bufsize

  The size in bytes of the ADP output buffer. The buffer is flushed to the client when full, or each time a new chunk is appended when streaming is enabled. Default: 1MB.

tracesize

  The number of bytes of each text and script block which will be dumped to the error log when the trace option is enabled. Default: 40.

The following parameters set the default options for the ADP engine. They can be customised per-URL using the -options flag of the ns_register_adp command, or at run-time for each page using the ns_adp_ctl command.

See ns_adp_ctl for details on each option.

cache

  Default: off.

stream

  Default: off.

enablexpire

  Default: off.

enabledebug

  Default: off.

safeeval

  Default: off.

singlescript

  Default: off.

trace

  Log each text and script block of each ADP page as it is executed. The first n bytes will be logged, as determined by the tracesize parameter. Default: off.

detailerror

  Default: on.

stricterror

  Default: off.

displayerror

  Default: off.

trimspace

  Default: off.

autoabort

  Default: enabled.

The following parameter...

debuginit

  The command which is called when ADP page debugging is initiated. The parameter enabledebug must be on for this to take effect. Default: ns_adp_debuginit.

## See Also

ns_adp_ctl, ns_adp_include, ns_adp_puts

## Keywords

ADP, configuration, gzip, ns_conn