debian compat 9
[yazproxy-moved-to-github.git] / doc / reference.xml
index 2bd922d..2ef809c 100644 (file)
@@ -3,7 +3,7 @@
   <section id="proxy-operation">
    <title>Operating Environment</title>
    <para>
-    The YAZ proxy is a single program. After startup it spawns 
+    The YAZ proxy is a console program. After startup it spawns 
     a child process (except on Windows or if option -X is given). 
     The child process is the core of the proxy and it handles all
     communication with clients and servers. The parent process
     see <xref linkend="proxy-usage"/>.
    </para>
    <para>
-    As an option the proxy may change user identity to a less priviledged
+    As an option, the proxy may change user identity to a less privileged
     user.
    </para>
   </section>
   <section id="proxy-target">
-   <title>Specifying the Backend Server</title>
+   <title>Choosing the Backend Server</title>
    <para>
     When the proxy receives a Z39.50 Initialize Request from a Z39.50
     client, it determines the backend server by the following rules:
@@ -32,7 +32,7 @@
        usual YAZ address format (typically
        <literal>tcp:<parameter>hostname</parameter>:<parameter>port</parameter></literal>)
        as described in
-       <ulink url="http://www.indexdata.dk/yaz/doc/comstack.addresses.tkl"
+       <ulink url="&url.yaz.comstack.addresses;"
        >the Addresses section of the YAZ manual</ulink>.
       </para>
      </listitem>
      </listitem>
     </orderedlist>
    </para>
+   <para>
+    If the proxy receives an SRU request, the following rules are used.
+    <orderedlist>
+     <listitem>
+      <para>If default target has Explain information with a
+       <literal>database</literal> that matches the path of the
+       HTTP request of SRU that backend server is used for SRU operation.
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       Otherwise the service will return HTTP 404 (Not found).
+      </para>
+     </listitem>
+    </orderedlist>
+   </para>
   </section>
   <section id="proxy-keepalive">
    <title>Keep-alive Facility</title>
     </para>
   </section>
   
+  
+  <section id="query-cache">
+   <title>Query Caching</title>
+   <para>
+    Simple stateless clients often send identical Z39.50 searches
+    in a relatively short period of time (e.g. in order to produce a
+    results-list page, the next page,
+    a single full-record, etc). And for many targets, it's
+    much more expensive to produce a new result set than to
+    reuse an existing one.
+   </para>
+   <para>
+    The proxy tries to solve that by remembering the last query for each
+    backend target, so that if an identical query is received next, it
+    is turned into Present Requests rather than new Search Requests.
+   </para>
+   <note>
+    <para>
+     In a future we release will will probably allows for
+     an arbitrary-sized cache for targets supporting named result sets.
+    </para>
+   </note>
+   <para>
+    You can enable/disable query caching using option -o.
+   </para>
+  </section>
+  
+  <section id="record-cache">
+   <title>Record Caching</title>
+   <para>
+    As an option, the proxy may also cache result set records for the
+    last search.
+    The proxy takes into account the Record Syntax and CompSpec.
+    The CompSpec includes simple element set names as well.
+    By default the cache is 200000 bytes per session.
+   </para>
+  </section>
+  
+  <section id="query-validation">
+   <title>Query Validation</title>
+   <para>
+    The Proxy may also be configured to trap particular attributes in
+    Type-1 queries and send Bib-1 diagnostics back to the client without
+    even consulting the backend target. This facility may be useful if
+    a target does not properly issue diagnostics when unsupported attributes
+    are send to it.
+   </para>
+  </section>
+  
+   <section id="record-validation">
+   <title>Record Syntax Validation</title>
+   <para>
+    The proxy may be configured to accept, reject or convert records.
+    When accepted, the target passes search/present requests to the
+    backend target under the assumption that the target can honor the
+    request (In fact it may not do that). When a record is rejected because
+    the record syntax is "unsupported" the proxy returns a diagnostic to the
+    client. Finally, the proxy may convert records.
+   </para>
+   <para>
+    The proxy can convert from MARC to MARCXML and thereby offer an
+    XML version of any MARC record as long as it is ISO2709 encoded.
+    If the proxy is compiled with libXSLT support it can also
+    perform XSLT on XML.
+   </para>
+  </section>
+  
+  <section id="other-optimizations">
+   <title>Other Optimizations</title>
+   <para>
+    We've had some plans to support global caching of result set records,
+    but this has not yet been implemented.
+   </para>
+  </section>
+   
   <section id="proxy-config-file">
    <title>Proxy Configuration File</title>
    <para>
    </para>
    <para>
     The config file is XML based. The YAZ proxy must be compiled 
-    with <ulink url="http://www.xmlsoft.org/">libxml2</ulink> and
-    <ulink url="http://xmlsoft.org/XSLT/">libXSLT</ulink> support in
+    with <ulink url="&url.libxml2;">libxml2</ulink> and
+    <ulink url="&url.libxslt;">libXSLT</ulink> support in
     order for the config file facility to be enabled.
    </para>
+   <para>
+    See <xref linkend="yazproxy-schema"/> for an XML schema
+    for the configuration.
+   </para>
    <tip>
     <para>To check for a config file to be well-formed, the yazproxy may
      be invoked without specifying a listening port, i.e.
     <para>
      The proxy config file must have a root element called
      <literal>proxy</literal> and scoped within namespace
-     <literal> xmlns="http://indexdata.dk/yazproxy/schema/0.8/</literal>.
+     <literal> xmlns="http://indexdata.dk/yazproxy/schema/0.9/"</literal>.
      All information except an optional XML header must be stored
      within the <literal>proxy</literal> element.
     </para>
     <screen>
      &lt;?xml version="1.0"?>
-     &lt;proxy xmlns="http://indexdata.dk/yazproxy/schema/0.8/">
+     &lt;proxy xmlns="http://indexdata.dk/yazproxy/schema/0.9/">
       &lt;!-- content here .. -->
      &lt;/proxy>
     </screen>
      equivalent to command line option <literal>-t</literal>.
     </para>
     <para>
-     <screen>
-     &lt;?xml version="1.0"?>
-     &lt;proxy xmlns="http://indexdata.dk/yazproxy/schema/0.8/">
-      &lt;target name="server1" default="1">
-       &lt;!-- description of server1 .. -->
-      &lt;/target>
-      &lt;target name="server2">
-       &lt;!-- description of server2 .. -->
-      &lt;/target>
-     &lt;/proxy>
+      <screen><![CDATA[
+     <?xml version="1.0"?>
+     <proxy xmlns="http://indexdata.dk/yazproxy/schema/0.9/">
+      <target name="server1" default="1">
+       <!-- description of server1 .. -->
+      </target>
+      <target name="server2">
+       <!-- description of server2 .. -->
+      </target>
+     </proxy>
+      ]]>
      </screen>
     </para>
    </section>
     </para>
     <para>
      This can also be specified on the command line by using option
-     <literal>-T</literal>. Refer to OPTIONS.
+     <literal>-T</literal>. Refer to OPTIONS in <xref linkend="proxy-usage"/>.
     </para>
    </section>
 
      </para>
     <para>
      This can also be specified on the command line by using option
-     <literal>-i</literal>. Refer to OPTIONS.
+     <literal>-i</literal>.  Refer to OPTIONS in <xref linkend="proxy-usage"/>.
+    </para>
+   </section>
+
+   <section id="proxy-config-max-sockets">
+    <title>max-sockets</title>
+    <para>
+     The element <literal>max-sockets</literal> is the child of element
+     <literal>target</literal> and specifies the maximum number of sockets
+     to use for the target for all sessions using it. In other words: maximum
+     number of Z39.50 session to the target.
     </para>
    </section>
 
     </para>
     <para>
      The following sets maximum number of bytes transferred in a
-     target session to 1 MB and maxinum of requests to 400.
+     target session to 1 MB and maximum of requests to 400.
      <screen>
       &lt;keepalive>
        &lt;bandwidth>1048576&lt;/bandwidth>
-       &lt;retrieve>400&lt;/retrieve>
+       &lt;pdu>400&lt;/pdu>
       &lt;/keepalive>
      </screen>
     </para>
      The proxy records bandwidth/pdu requests during the last 60 seconds
      (1 minute). The <literal>limit</literal> may include the
      elements <literal>bandwidth</literal>, <literal>pdu</literal>,
-     and <literal>retrieve</literal>. The <literal>bandwidth</literal>
+     <literal>retrieve</literal> and <literal>search</literal>.
+     The <literal>bandwidth</literal>
      measures the number of bytes transferred within the last minute.
      The <literal>pdu</literal> is the number of requests in the last
      minute. The <literal>retrieve</literal> holds the maximum records to
-     be retrieved in one Present Request.
+     which may be retrieved in one Present Request.
+     The <literal>search</literal> is the maximum number of searches
+     within the last minute.
     </para>
     <para>
-     If a bandwidth/pdu limit is reached the proxy will postpone the
+     If a bandwidth/pdu/search limit is reached the proxy will postpone the
      requests to the target and wait one or more seconds. The idea of the
      limit is to ensure that clients that downloads hundreds or thousands of
      records do not hurt other users.
     </para>
     <para>
      The following sets maximum number of bytes transferred per minute to
-     500Kbytes and maximum number of requests to 40.
+     500Kbytes, maximum number of records retrievals to 40
+     and maximum number of searches to 20.
      <screen>
       &lt;limit>
        &lt;bandwidth>524288&lt;/bandwidth>
        &lt;retrieve>40&lt;/retrieve>
+       &lt;search>20&lt;/search>
       &lt;/limit>
      </screen>
     </para>
     <note>
      <para>
-      Typically the limits for keepalive are much higher than
-      those for session minute average.
+      Typically the values in the keepalive section are mugh higher
+      than their equivalent limit counterparts (bandwidth, pdu).
      </para>
     </note>
    </section>
      A target that supports use attributes 1,4, 1000 through 1003 and
      no other use attributes, could use the following rules:
      <screen>
-      &lt;attribute type="1" value="1,4,1000-1003">
+      &lt;attribute type="1" value="1,4,1000-1003"/>
       &lt;attribute type="1" value="*" error="114"/>
      </screen>
     </para>
     <title>syntax</title>
     <para>
      The <literal>syntax</literal> element specifies accept or reject
-     or a particular record syntax request from the client.
+     or a particular record syntax request from the client. It also
+     allows record conversion of XML records via XSLT.
     </para>
     <para>
      The <literal>syntax</literal> has one required attribute:
      If attribute <literal>marcxml</literal> is given, the proxy will
      perform MARC21 to MARCXML conversion. In this case the
      <literal>type</literal> should be XML. The proxy will use
-     preferred record syntax USMARC/MARC21 against the backend target.
+     preferred record syntax USMARC/MARC21 or <literal>backendtype</literal> 
+     (if given) against the backend target.
+     For the special case where <literal>backendtype</literal> is
+     <literal>opac</literal> the proxy will convert the OPAC
+     record to OPACXML.
+    </para>
+    <para>
+      When <literal>marcxml</literal> is used, yazproxy assumes
+      that records retrieved from the backend are encoded in the
+      <ulink url="&url.marc8;">MARC-8</ulink> character set.
+      This is correct for most MARC21 based systems, but not for 
+      other MARC variants or UTF-8 based MARC21 systems.
+      The <literal>backendcharset</literal> attribute specifies
+      the character set of the MARC records to be converted.
+    </para>
+    <para>
+     If attribute <literal>backendtype</literal> is given, that holds the
+     record syntax to be transmitted to backend.
+    </para>
+    <para>
+     If attribute <literal>backendelementset</literal> is given, that holds
+     elementset to be transmitted to backend. An empty value of
+     <literal>backendelementset</literal> has the effect of omitting
+     any Comp-Spec (and elementset) sent to backend.
+    </para>
+    <para>If <literal>backendelementset</literal> is omitted, the element
+     set from client is used, except if <literal>marcxml</literal> is used.
+     In that case (using <literal>marcxml</literal>), no Comp-Spec and no
+     elementset is sent to backend.
     </para>
     <para>
      If attribute <literal>stylesheet</literal> is given, the proxy
      will convert XML record from server via XSLT. It is important
      that the content from server is XML. If used in conjunction with
-     attribute <literal>marcxml</literal> the MARC to MARCXML conversion
-     takes place before the XSLT conversion takes place.
+     attribute <literal>marcxml</literal>, the MARC to MARCXML/OPACXML
+     conversion takes place before the XSLT conversion takes place.
     </para>
     <para>
      If attribute <literal>identifier</literal> is given that is the
-     SRW/SRU record schema identifier for the resulting output record (after
+     SRU record schema identifier for the resulting output record (after
      MARCXML and/or XSLT conversion). 
     </para>
     <para>
      If sub element <literal>title</literal> is given (as child element
-     of <literal>syntax</literal>, then that is the official SRW/SRU
+     of <literal>syntax</literal>, then that is the official SRU
      name of the resulting record schema.
     </para>
     <para>
        ..
        &lt;syntax type="usmarc"/>
        &lt;syntax type="xml" marcxml="1"
-        identifier="info:srw/schema/1/marcxml-v1.1"
-        &lt;title>MARCXML&lt;title>
-        &lt;name>marcxml&lt;name>
-       &lt;syntax>
+         identifier="info:srw/schema/1/marcxml-v1.1"
+         &lt;title>MARCXML&lt;title>
+         &lt;name>marcxml&lt;name>
+       &lt;/syntax>
        &lt;syntax type="xml" marcxml="1" stylesheet="MARC21slim2SRWDC.xsl"
-        identifier="info:srw/schema/1/dc-v1.1">
-        &lt;title>Dublin Core&lt;title>
-        &lt;name>dc&lt;name>
-       &lt;syntax>
+         identifier="info:srw/schema/1/dc-v1.1">
+         &lt;title>Dublin Core&lt;title>
+         &lt;name>dc&lt;name>
+       &lt;/syntax>
        &lt;syntax type="*" error="238"/>
        ..
        &lt;/target>
     <title>explain</title>
     <para>
      The <literal>explain</literal> element includes Explain information
-     for SRW/SRU about the server in the target section. This
+     for SRU about the server in the target section. This
      information must have a <literal>serverInfo</literal> element
      with a database that this target must be available as (URL path).
      For example,
       </explain>
       ]]>
      </screen>
-     In the above case, the SRW/SRU service is available as
+     In the above case, the SRU service is available as
      <literal>http://myhost.org:8000/mydatabase</literal>.
     </para>
     
    <section id="proxy-config-cql2rpn">
     <title>cql2rpn</title>
     <para>
-     The CDATA of <literal>cql2rpn</literal> refers to CQL to a RPN conversion
-     file - for the server in the target section. This element
-     is required for SRW/SRU searches to operate against a Z39.50
-     server that doesn't support CQL. Most Z39.50 servers only support
+     The content of the <literal>cql2rpn</literal> element specifies
+     the path from the working directory to a CQL-to-RPN conversion
+     file for the server in the target section. This element
+     is required for SRU searches to operate against Z39.50
+     servers that don't support CQL. Most Z39.50 servers only support
      Type-1/RPN so this is usually required.
+    </para>
+    <para>
      See YAZ documentation for more information about the
-     <ulink url="http://indexdata.dk/yaz/doc/tools.tkl#tools.cql.pqf">CQL
-      to PQF</ulink> conversion. See also the
+     <ulink url="&url.yaz.cql2pqf;">CQL to PQF</ulink> conversion.
+     See also the
      <filename>pqf.properties</filename> in the <filename>etc</filename> 
      (or <replaceable>prefix/share/yazproxy</replaceable>)
-     directory of the YAZ proxy.
+     directory of the YAZ proxy distribution.
     </para>
    </section>
    
     </para>
    </section>
 
+   <section id="proxy-config-target-authentication">
+    <title>target-authentication</title>
+    <para>
+     The element <literal>target-authentication</literal> specifies
+     fixed authentication information to be sent to the backend target.
+    </para>
+    <para>
+     This element takes a an attribute <literal>type</literal> which is
+     the authenticatin type to be used.. 
+    </para>
+    <variablelist>
+     <varlistentry><term><literal>none</literal></term>
+      <listitem>
+       <para>
+       No authentication. There is no CDATA associated with this.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry><term><literal>anonymous</literal></term>
+      <listitem>
+       <para>
+       Anonymous authentication. There is no CDATA associated with this.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry><term><literal>open</literal></term>
+      <listitem>
+       <para>
+       Open authentication. The CDATA consists of the
+       open authentication string.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry><term><literal>idPass</literal></term>
+      <listitem>
+       <para>
+       IdPass authentication. The CDATA consists of
+       three terms: user, group and password.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </section>
+
+   <section id="proxy-config-target-charset">
+    <title>target-charset</title>
+    <para>
+     The element <literal>target-charset</literal> specifies the
+     native character set that the target uses for queries.
+    </para>
+    <para>
+     If this is specified the proxy will act as a Z39.50 server
+     supporting character set negotiation. And in SRU mode
+     it will convert from UTF-8 (UNICODE) to this native character
+     set (if possible).
+    </para>
+   </section>
+
    <section id="proxy-config-max-clients">
     <title>max-clients</title>
     <para>
     </para>
     <tip>
      <para>
-      Using the <ulink url="http://www.gnu.org/software/bash/bash.html">
-       bash</ulink> shell, you can set the limit with
+      Using the <ulink url="&url.bash;">bash</ulink> shell, you can set
+      the limit with
       <literal>ulimit -n</literal><replaceable>no</replaceable>. 
        Use <literal>ulimit -a</literal> to display limits.
      </para>
          and the size of the APDU is logged.
         </entry>
        </row>
+       <row>
+        <entry><literal>client-ip</literal></entry>
+        <entry>
+         Log the client IP for each log entry. By default, the client IP
+         is only logged when a new session starts.
+        </entry>
+       </row>
        </tbody>
       </tgroup>
      </table>
      </screen>
     </para>
    </section>
-  </section>
-  
-  <section id="query-cache">
-   <title>Query Caching</title>
-   <para>
-    Simple stateless clients often send identical Z39.50 searches
-    in a relatively short period of time (e.g. in order to produce a
-    results-list page, the next page,
-    a single full-record, etc). And for many targets, it's
-    much more expensive to produce a new result set than to
-    reuse an existing one.
-   </para>
-   <para>
-    The proxy tries to solve that by remembering the last query for each
-    backend target, so that if an identical query is received next, it
-    is turned into Present Requests rather than new Search Requests.
-   </para>
-   <note>
+
+   <section id="proxy-max-connect">
+    <title>max-connect</title>
     <para>
-     In a future we release will will probably allows for
-     an arbitrary-sized cache for targets supporting named result sets.
+     The element <literal>max-connect</literal> is a child of element
+     <literal>proxy</literal> and specifies the maximum number
+     of connections to be initiated within the last minute (or
+     value of <link linkend="proxy-period-connect">period-connect</link>.
     </para>
-   </note>
-   <para>
-    You can enable/disable query caching using option -o.
-   </para>
-  </section>
-  
-  <section id="record-cache">
-   <title>Record Caching</title>
-   <para>
-    As an option, the proxy may also cache result set records for the
-    last search.
-    The proxy takes into account the Record Syntax and CompSpec.
-    The CompSpec includes simple element set names as well.
-    By default the cache is 200000 bytes per session.
-   </para>
-  </section>
-  
-  <section id="query-validation">
-   <title>Query Validation</title>
-   <para>
-    The Proxy may also be configured to trap particular attributes in
-    Type-1 queries and send Bib-1 diagnostics back to the client without
-    even consulting the backend target. This facility may be useful if
-    a target does not properly issue diagnostics when unsupported attributes
-    are send to it.
-   </para>
-  </section>
-  
-   <section id="record-validation">
-   <title>Record Syntax Validation</title>
-   <para>
-    The proxy may be configured to accept, reject or convert records.
-    When accepted, the target passes search/present requests to the
-    backend target under the assumption that the target can honor the
-    request (In fact it may not do that). When a record is rejected because
-    the record syntax is "unsupported" the proxy returns a diagnostic to the
-    client. Finally, the proxy may convert records.
-   </para>
-   <para>
-    The proxy can convert from MARC to MARCXML and thereby offer an
-    XML version of any MARC record as long as it is ISO2709 encoded.
-    If the proxy is compiled with libXSLT support it can also
-    perform XSLT on XML.
-   </para>
-  </section>
-  
-  <section id="other-optimizations">
-   <title>Other Optimizations</title>
-   <para>
-    We've had some plans to support global caching of result set records,
-    but this has not yet been implemented.
-   </para>
+    <para>
+     If the maximum number is reached the proxy will terminate the
+     just initiated session (connection terminated).
+    </para>
+   </section>
+
+   <section id="proxy-limit-connect">
+    <title>limit-connect</title>
+    <para>
+     The element <literal>max-connect</literal> is a child of element
+     <literal>proxy</literal> and specifies the limit of number
+     of connections to be initiated within the last minute (or
+     value of <link linkend="proxy-period-connect">period-connect</link>.
+    </para>
+    <para>
+     If the maximum number is reached the proxy delays the first operation
+     in the session by one second.
+    </para>
+   </section>
+
+   <section id="proxy-period-connect">
+    <title>period-connect</title>
+    <para>
+     The element <literal>period-connect</literal> is a child of element
+     <literal>proxy</literal> and specifies period - in the number of seconds
+     that <link linkend="proxy-limit-connect">limit-connect</link> and 
+     <link linkend="proxy-max-connect">max-connect</link>
+     should measure connections.
+    </para>
+    <para>
+     If <literal>period-connect</literal> is omitted, 60 seconds is used.
+    </para>
+   </section>
+
+   <section id="proxy-docpath">
+    <title>docpath</title>
+    <para>
+     The element <literal>docpath</literal> is a child of element
+     <literal>proxy</literal> and specifies an allowed HTTP path
+     for local file access. Using <literal>docpath</literal> the
+     proxy may return static file content.
+    </para>
+    <para>
+     The value of docpath both serves as a HTTP path prefix 
+     <emphasis>and</emphasis> as a local file prefix. 
+     If a value of <literal>etc</literal> is used only URLs with the
+     prefix <literal>/etc/</literal> results in a local file access to the
+     directory <literal>etc</literal> within the working directory
+     of yazproxy.
+    </para>
+    <note>
+    <para>
+      Care has been taken to ensure that hostile URLs are rejected - including
+      strings such as <literal>..</literal> and <literal>/</literal> (absolute
+      file system access).
+     </para>
+    </note>
+   </section>
+
   </section>
-   
   <section id="proxy-usage">
-   <title>Proxy Usage (man page)</title>
+   <title>Proxy Manual Pages</title>
    <refentry id="yazproxy-man">
     &yaz-proxy-ref;
    </refentry>
     The <literal>categoryTypeId</literal> is either
     OID 1.2.840.10003.10.1000.81.1, 1.2.840.10003.10.1000.81.2
     for proxy target and proxy cookie respectively. The
-    integer element <literal>category</literal> is set to 0.
+    <literal>categoryValue</literal> is set to 1.
     The value proxy and cookie is stored in element
     <literal>characterInfo</literal> of the <literal>information</literal>
      choice.
    </para>
-   </section>
+  </section>
+  <section id="yazproxy-schema">
+   <title>YAZ Proxy Configuration Schema</title>
+   <para>
+    Here an XML Schema for the YAZ proxy configuration file. 
+    The schema, <filename>yazproxy.xsd</filename> is located in sub
+    directory <filename>etc</filename> of the distribution.
+   </para>
+   <screen><![CDATA[
+<?xml version="1.0"?>
+<!-- XML Schema for YAZ proxy config file.
+-->
+<xs:schema
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:exp="http://explain.z3950.org/dtd/2.0/"
+  xmlns="http://indexdata.dk/yazproxy/schema/0.9/"
+  targetNamespace="http://indexdata.dk/yazproxy/schema/0.9/"
+  >
+ <xs:import namespace="http://explain.z3950.org/dtd/2.0/" 
+      schemaLocation="zeerex-2.0.xsd"/>
+ <xs:element name="proxy">
+  <xs:complexType>
+   <xs:sequence>
+    <xs:element ref="target" minOccurs="0" maxOccurs="unbounded"/>
+    <xs:element ref="max-clients" minOccurs="0"/>
+    <xs:element ref="log" minOccurs="0"/>
+    <xs:element ref="module" minOccurs="0"/>
+   </xs:sequence>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:element name="target">
+  <xs:complexType>
+   <xs:sequence>
+     <xs:element ref="url" minOccurs="0" maxOccurs="unbounded"/>
+     <xs:element ref="target-timeout" minOccurs="0"/>
+     <xs:element ref="client-timeout" minOccurs="0"/>
+     <xs:element ref="max-sockets" minOccurs="0"/>
+     <xs:element ref="keepalive" minOccurs="0"/>
+     <xs:element ref="limit" minOccurs="0"/>
+     <xs:element ref="attribute" minOccurs="0" maxOccurs="unbounded"/>
+     <xs:element ref="syntax" minOccurs="0" maxOccurs="unbounded"/>
+     <xs:element ref="preinit" minOccurs="0"/>
+     <xs:element ref="exp:explain" minOccurs="0"/>
+     <xs:element ref="cql2rpn" minOccurs="0"/>
+     <xs:element ref="target-authentication" minOccurs="0"/>
+     <xs:element ref="client-authentication" minOccurs="0"/>
+     <xs:element ref="negotiation-charset" minOccurs="0"/>
+     <xs:element ref="negotiation-lang" minOccurs="0"/>
+   </xs:sequence>
+   <xs:attribute name="default" type="xs:string" use="optional"/>
+   <xs:attribute name="name" type="xs:string"/>
+   <xs:attribute name="database" type="xs:string"/>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:element name="url" type="xs:string"/>
+ <xs:element name="target-timeout" type="xs:integer"/>
+ <xs:element name="client-timeout" type="xs:integer"/>
+ <xs:element name="max-sockets" type="xs:integer"/>
+ <xs:element name="bandwidth" type="xs:integer"/>
+ <xs:element name="pdu" type="xs:integer"/>
+ <xs:element name="retrieve" type="xs:integer"/>
+ <xs:element name="preinit" type="xs:integer"/>
+ <xs:element name="cql2rpn" type="xs:string"/>
+ <xs:element name="target-authentication">
+   <xs:complexType>
+    <xs:simpleContent>
+      <xs:extension base="xs:string">
+        <xs:attribute name="type" type="xs:string"/>
+      </xs:extension>
+    </xs:simpleContent>
+   </xs:complexType>
+ </xs:element>
+
+ <xs:element name="client-authentication">
+   <xs:complexType>
+    <xs:simpleContent>
+      <xs:extension base="xs:string">
+        <xs:attribute name="module" type="xs:string"/>
+        <xs:attribute name="args" type="xs:string"/>
+      </xs:extension>
+    </xs:simpleContent>
+   </xs:complexType>
+ </xs:element>
+
+ <xs:element name="negotiation-charset" type="xs:string"/>
+ <xs:element name="negotiation-lang" type="xs:string"/>
+
+ <xs:element name="keepalive">
+  <xs:complexType>
+   <xs:sequence>
+    <xs:element ref="bandwidth" minOccurs="0"/>
+    <xs:element ref="pdu" minOccurs="0"/>
+   </xs:sequence>
+  </xs:complexType>
+ </xs:element>
+ <xs:element name="limit">
+  <xs:complexType>
+   <xs:sequence>
+    <xs:element ref="bandwidth" minOccurs="0"/>
+    <xs:element ref="pdu" minOccurs="0"/>
+    <xs:element ref="retrieve" minOccurs="0"/>
+   </xs:sequence>
+  </xs:complexType>
+ </xs:element>
+ <xs:element name="attribute">
+  <xs:complexType>
+   <xs:attribute name="type" type="xs:string"/>
+   <xs:attribute name="value" type="xs:string"/>
+   <xs:attribute name="error" type="xs:integer"/>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:element name="syntax">
+  <xs:complexType>
+   <xs:sequence>
+    <xs:element ref="title" minOccurs="0"/>
+    <xs:element ref="name" minOccurs="0" maxOccurs="unbounded"/>
+   </xs:sequence>
+   <xs:attribute name="error" type="xs:string" />
+   <xs:attribute name="type" type="xs:string" />
+   <xs:attribute name="marcxml" type="xs:string" />
+   <xs:attribute name="identifier" type="xs:string" />
+   <xs:attribute name="stylesheet" type="xs:string" />
+   <xs:attribute name="backendtype" type="xs:string" />
+   <xs:attribute name="backendcharset" type="xs:string" />
+   <xs:attribute name="usemarconstage1" type="xs:string" />
+   <xs:attribute name="usemarconstage2" type="xs:string" />
+   <xs:attribute name="backendelementset" type="xs:string" />
+  </xs:complexType>
+ </xs:element>
+
+ <xs:element name="title" type="xs:string"/>
+ <xs:element name="name" type="xs:string"/>
+
+ <xs:element name="max-clients" type="xs:integer"/>
+ <xs:element name="log" type="xs:string"/>
+ <xs:element name="module" type="xs:string"/>
+
+</xs:schema>
+]]>
+   </screen>
+  </section>
  </chapter>
 
  <!-- Keep this comment at the end of the file