Prepare examples. More info on syntax rules
[yazproxy-moved-to-github.git] / doc / reference.xml
1  <chapter id="proxy-reference">
2   <title>Proxy Reference</title>
3   <section id="proxy-operation">
4    <title>Operating Environment</title>
5    <para>
6     The YAZ proxy is a single program. After startup it spawns 
7     a child process (except on Windows or if option -X is given). 
8     The child process is the core of the proxy and it handles all
9     communication with clients and servers. The parent process
10     will restart the child process if it dies unexpectedly and report
11     the reason. For options for YAZ proxy,
12     see <xref linkend="proxy-usage"/>.
13    </para>
14    <para>
15     As an option the proxy may change user identity to a less priviledged
16     user.
17    </para>
18   </section>
19   <section id="proxy-target">
20    <title>Specifying the Backend Server</title>
21    <para>
22     When the proxy receives a Z39.50 Initialize Request from a Z39.50
23     client, it determines the backend server by the following rules:
24     <orderedlist>
25      <listitem>
26       <para>If the <literal>InitializeRequest</literal> PDU from the
27        client includes an 
28        <link linkend="otherinfo-encoding"><literal>otherInfo</literal></link>
29        element with OID
30        <literal>1.2.840.10003.10.1000.81.1</literal>, then the
31        contents of that element specify the server to be used, in the
32        usual YAZ address format (typically
33        <literal>tcp:<parameter>hostname</parameter>:<parameter>port</parameter></literal>)
34        as described in
35        <ulink url="http://www.indexdata.dk/yaz/doc/comstack.addresses.tkl"
36         >the Addresses section of the YAZ manual</ulink>.
37       </para>
38      </listitem>
39
40      <listitem>
41       <para>Otherwise, the Proxy uses the default server, if one was
42        specified in the proxy configuration file. See
43        <xref linkend="proxy-config-target"/>.
44       </para>
45      </listitem>
46
47      <listitem>
48       <para>Otherwise, the Proxy uses the default server, if one was
49        specified on the command-line with the <literal>-t</literal>
50        option.
51       </para>
52      </listitem>
53      <listitem>
54       <para>Otherwise, the proxy closes the connection with
55        the client.
56       </para>
57      </listitem>
58     </orderedlist>
59    </para>
60   </section>
61   <section id="proxy-keepalive">
62    <title>Keep-alive Facility</title>
63    <para>
64     The keep-alive is a facility where the proxy keeps the connection to the
65     backend server - even if the client closes the connection to the proxy.
66    </para>
67    <para>
68     If a new or another client connects to the proxy again and requests the
69     same backend it will be reassigned to this backend. In this case, the
70     proxy sends an initialize response directly to the client and an
71     initialize handshake with the backend is omitted.
72    </para>
73    <para>
74     When a client reconnects, query and record caching works better, if the
75     proxy assigns it to the same backend as before. And the result set
76     (if any) is re-used. To achieve this, Index Data defined a session
77     cookie which identifies the backend session.
78    </para>
79    <para>
80     The cookie is defined by the client and is sent as part of the
81     Initialize Request and passed in an
82     <link linkend="otherinfo-encoding"><literal>otherInfo</literal></link>
83     element with OID <literal>1.2.840.10003.10.1000.81.2</literal>.
84    </para>
85    <para>
86     Clients that do not send a cookie as part of the initialize request
87     may still better performance, since the init handshake is saved.
88    </para>
89    <para>
90     Refer to <xref linkend="proxy-config-keepalive"/> on how to setup
91     configuration parameters for keepalive.
92     </para>
93   </section>
94   
95   <section id="proxy-config-file">
96    <title>Proxy Configuration File</title>
97    <para>
98     The Proxy may read a configuration file using option
99     <literal>-c</literal> followed by the filename of a config file.
100    </para>
101    <para>
102     The config file is XML based. The YAZ proxy must be compiled 
103     with <ulink url="http://www.xmlsoft.org/">libxml2</ulink> and
104     <ulink url="http://xmlsoft.org/XSLT/">libXSLT</ulink> support in
105     order for the config file facility to be enabled.
106    </para>
107    <tip>
108     <para>To check for a config file to be well-formed, the yazproxy may
109      be invoked without specifying a listening port, i.e.
110      <screen>
111       yazproxy -c myconfig.xml
112      </screen>
113      If this does not produce errors, the file is well-formed.
114     </para>
115    </tip>
116    <section id="proxy-config-header">
117     <title>Proxy Configuration Header</title>
118     <para>
119      The proxy config file must have a root element called
120      <literal>proxy</literal> and scoped within namespace
121      <literal> xmlns="http://indexdata.dk/yazproxy/schema/0.8/</literal>.
122      All information except an optional XML header must be stored
123      within the <literal>proxy</literal> element.
124     </para>
125     <screen>
126      &lt;?xml version="1.0"?>
127      &lt;proxy xmlns="http://indexdata.dk/yazproxy/schema/0.8/">
128       &lt;!-- content here .. -->
129      &lt;/proxy>
130     </screen>
131    </section>
132    <section id="proxy-config-target">
133     <title>target</title>
134     <para>
135      The element <literal>target</literal> which may be repeated zero
136      or more times with parent element <literal>proxy</literal> contains
137      information about each backend target.
138      The <literal>target</literal> element have two attributes:
139      <literal>name</literal> which holds the logical name of the backend
140      target (required) and <literal>default</literal> (optional) which
141      (when given) specifies that the backend target is the default target -
142      equivalent to command line option <literal>-t</literal>.
143     </para>
144     <para>
145      <screen>
146      &lt;?xml version="1.0"?>
147      &lt;proxy xmlns="http://indexdata.dk/yazproxy/schema/0.8/">
148       &lt;target name="server1" default="1">
149        &lt;!-- description of server1 .. -->
150       &lt;/target>
151       &lt;target name="server2">
152        &lt;!-- description of server2 .. -->
153       &lt;/target>
154      &lt;/proxy>
155      </screen>
156     </para>
157    </section>
158    <section id="proxy-config-url">
159     <title>url</title>
160     <para>
161      The <literal>url</literal> which may be repeated one or more times
162      should be the child of the <literal>target</literal> element.
163      The CDATA of <literal>url</literal> is the Z-URL of the backend.
164     </para>
165     <para>
166      Multiple <literal>url</literal> element may be used. In that case, then
167      a client initiates a session, the proxy chooses the URL with the lowest
168      number of active sessions, thereby distributing the load. It is
169      assumed that each URL represents the same database (data).
170     </para>
171    </section>
172
173    <section id="proxy-config-target-timeout">
174     <title>target-timeout</title>
175     <para>
176      The element <literal>target-timeout</literal> is the child of element
177      <literal>target</literal> and specifies the amount in seconds before
178      a target session is shut down.
179     </para>
180     <para>
181      This can also be specified on the command line by using option
182      <literal>-T</literal>. Refer to OPTIONS.
183     </para>
184    </section>
185
186    <section id="proxy-config-client-timeout">
187     <title>client-timeout</title>
188     <para>
189      The element <literal>client-timeout</literal> is the child of element
190      <literal>target</literal> and specifies the amount in seconds before
191      a client session is shut down.
192      </para>
193     <para>
194      This can also be specified on the command line by using option
195      <literal>-i</literal>. Refer to OPTIONS.
196     </para>
197    </section>
198
199    <section id="proxy-config-keepalive">
200     <title>keepalive</title>
201     <para>The <literal>keepalive</literal> element holds information about
202      the keepalive Z39.50 sessions. Keepalive sessions are proxy-to-backend
203      sessions that is no longer associated with a client session.
204     </para>
205     <para>The <literal>keepalive</literal> element which is the child of
206      the <literal>target</literal>holds two elements:
207      <literal>bandwidth</literal> and <literal>pdu</literal>.
208      The <literal>bandwidth</literal> is the maximum total bytes
209      transferred to/from the target. If a target session exceeds this
210      limit, it is shut down (and no longer kept alive). 
211      The <literal>pdu</literal> is the maximum number of requests sent
212      to the target. If a target session exceeds this limit, it is
213      shut down. The idea of these two limits is that avoid very long
214      sessions that use resources in a backend (that leaks!).
215     </para>
216     <para>
217      The following sets maximum number of bytes transferred in a
218      target session to 1 MB and maxinum of requests to 400.
219      <screen>
220       &lt;keepalive>
221        &lt;bandwidth>1048576&lt;/bandwidth>
222        &lt;retrieve>400&lt;/retrieve>
223       &lt;/keepalive>
224      </screen>
225     </para>
226    </section>
227    <section id="proxy-config-limit">
228     <title>limit</title>
229     <para>
230      The <literal>limit</literal> section specifies bandwidth/pdu requests
231      limits for an active session.
232      The proxy records bandwidth/pdu requests during the last 60 seconds
233      (1 minute). The <literal>limit</literal> may include the
234      elements <literal>bandwidth</literal>, <literal>pdu</literal>,
235      and <literal>retrieve</literal>. The <literal>bandwidth</literal>
236      measures the number of bytes transferred within the last minute.
237      The <literal>pdu</literal> is the number of requests in the last
238      minute. The <literal>retrieve</literal> holds the maximum records to
239      be retrieved in one Present Request.
240     </para>
241     <para>
242      If a bandwidth/pdu limit is reached the proxy will postpone the
243      requests to the target and wait one or more seconds. The idea of the
244      limit is to ensure that clients that downloads hundreds or thousands of
245      records do not hurt other users.
246     </para>
247     <para>
248      The following sets maximum number of bytes transferred per minute to
249      500Kbytes and maximum number of requests to 40.
250      <screen>
251       &lt;limit>
252        &lt;bandwidth>524288&lt;/bandwidth>
253        &lt;retrieve>40&lt;/retrieve>
254       &lt;/limit>
255      </screen>
256     </para>
257     <note>
258      <para>
259       Typically the limits for keepalive are much higher than
260       those for session minute average.
261      </para>
262     </note>
263    </section>
264    
265    <section id="proxy-config-attribute">
266     <title>attribute</title>
267     <para>
268      The <literal>attribute</literal> element specifies accept or reject
269      or a particular attribute type, value pair.
270      Well-behaving targets will reject unsupported attributes on their
271      own. This feature is useful for targets that do not gracefully
272      handle unsupported attributes.
273     </para>
274     <para>
275      Attribute elements may be repeated. The proxy inspects the attribute
276      specifications in the order as specified in the configuration file.
277      When a given attribute specification matches a given attribute list
278      in a query, the proxy takes appropriate action (reject, accept).
279     </para>
280     <para>
281      If no attribute specifications matches the attribute list in a query,
282      it is accepted.
283     </para>
284     <para>
285      The <literal>attribute</literal> element has two required attributes:
286      <literal>type</literal> which is the Attribute Type-1 type, and
287      <literal>value</literal> which is the Attribute Type-1 value.
288      The special value/type <literal>*</literal> matches any attribute
289      type/value. A value may also be specified as a list with each
290      value separated by comma, a value may also be specified as a
291      list: low value - dash - high value.
292     </para>
293     <para>
294      If attribute <literal>error</literal> is given, that holds a 
295      Bib-1 diagnostic which is sent to the client if the particular
296      type, value is part of a query.
297     </para>
298     <para>
299      If attribute <literal>error</literal> is not given, the attribute
300      type, value is accepted and passed to the backend target.
301     </para>
302     <para>
303      A target that supports use attributes 1,4, 1000 through 1003 and
304      no other use attributes, could use the following rules:
305      <screen>
306       &lt;attribute type="1" value="1,4,1000-1003">
307       &lt;attribute type="1" value="*" error="114"/>
308      </screen>
309     </para>
310    </section>
311    <section id="proxy-config-syntax">
312     <title>syntax</title>
313     <para>
314      The <literal>syntax</literal> element specifies accept or reject
315      or a particular record syntax request from the client.
316     </para>
317     <para>
318      The <literal>syntax</literal> has one required attribute:
319      <literal>type</literal> which is the Preferred Record Syntax.
320     </para>
321     <para>
322      If attribute <literal>error</literal> is given, that holds a 
323      Bib-1 diagnostic which is sent to the client if the particular
324      record syntax is part of a present - or search request.
325     </para>
326     <para>
327      If attribute <literal>error</literal> is not given, the record syntax
328      is accepted and passed to the backend target.
329     </para>
330     <para>
331      If attribute <literal>marcxml</literal> is given, the proxy will
332      perform MARC21 to MARCXML conversion. In this case the
333      <literal>type</literal> should be XML. The proxy will use
334      preferred record syntax USMARC/MARC21 against the backend target.
335     </para>
336     <para>
337      If attribute <literal>stylesheet</literal> is given, the proxy
338      will convert XML record from server via XSLT. It is important
339      that the content from server is XML. If used in conjunction with
340      attribute <literal>marcxml</literal> the MARC to MARCXML conversion
341      takes place before the XSLT conversion takes place.
342     </para>
343     <para>
344      If attribute <literal>identifier</literal> is given that is the
345      SRW/SRU record schema identifier for the resulting output record (after
346      MARCXML and/or XSLT conversion). 
347     </para>
348     <para>
349      If sub element <literal>title</literal> is given (as child element
350      of <literal>syntax</literal>, then that is the official SRW/SRU
351      name of the resulting record schema.
352     </para>
353     <para>
354      If sub element <literal>name</literal> is given that is an alias
355      for the record schema identifier. Multiple <literal>name</literal>s
356      may be specified.
357     </para>
358     <example>
359      <title>MARCXML conversion</title>
360      <para>To accept USMARC and offer MARCXML XML plus Dublin Core (via
361       XSLT conversion) but the following configuration could be used:
362       <screen>
363        &lt;proxy>
364        &lt;target name="mytarget">
365        ..
366        &lt;syntax type="usmarc"/>
367        &lt;syntax type="xml" marcxml="1"
368         identifier="info:srw/schema/1/marcxml-v1.1"
369         &lt;title>MARCXML&lt;title>
370         &lt;name>marcxml&lt;name>
371        &lt;syntax>
372        &lt;syntax type="xml" marcxml="1" stylesheet="MARC21slim2SRWDC.xsl"
373         identifier="info:srw/schema/1/dc-v1.1">
374         &lt;title>Dublin Core&lt;title>
375         &lt;name>dc&lt;name>
376        &lt;syntax>
377        &lt;syntax type="*" error="238"/>
378        ..
379        &lt;/target>
380        &lt;/proxy>
381       </screen>
382     </para>
383     </example>
384
385    </section>
386
387    <section id="proxy-config-explain">
388     <title>explain</title>
389     <para>
390      The <literal>explain</literal> element includes Explain information
391      for SRW/SRU about the server in the target section. This
392      information must have a <literal>serverInfo</literal> element
393      with a database that this target must be available as (URL path).
394      For example,
395      <screen><![CDATA[
396       <explain xmlns="http://explain.z3950.org/dtd/2.0/">     
397         <serverInfo>
398           <host>myhost.org</host>
399           <port>8000</port>
400           <database>mydatabase</database>
401         </serverInfo>
402         <!-- remaining Explain stuff -->
403       </explain>
404       ]]>
405      </screen>
406      In the above case, the SRW/SRU service is available as
407      <literal>http://myhost.org:8000/mydatabase</literal>.
408     </para>
409     
410    </section>
411
412    <section id="proxy-config-cql2rpn">
413     <title>cql2rpn</title>
414     <para>
415      The CDATA of <literal>cql2rpn</literal> refers to CQL to a RPN conversion
416      file - for the server in the target section. This element
417      is required for SRW/SRU searches to operate against a Z39.50
418      server that doesn't support CQL. Most Z39.50 servers only support
419      Type-1/RPN so this is usually required.
420      See YAZ documentation for more information about the
421      <ulink url="http://indexdata.dk/yaz/doc/tools.tkl#tools.cql.pqf">CQL
422       to PQF</ulink> conversion. See also the
423      <filename>pqf.properties</filename> in the <filename>etc</filename> 
424      (or <replaceable>prefix/share/yazproxy</replaceable>)
425      directory of the YAZ proxy.
426     </para>
427    </section>
428    
429    <section id="proxy-config-preinit">
430     <title>preinit</title>
431     <para>
432      The element <literal>preinit</literal> is the child of element
433      <literal>target</literal> and specifies the number of spare
434      connection to a target. By default no spare connection are
435      created by the proxy. If the proxy uses a target exclusive or
436      a lot, the preinit session will ensure that target sessions
437      have been made before the client makes a connection and will therefore
438      reduce the connect-init handshake dramatically. Never set this to
439      more than 5.
440     </para>
441    </section>
442
443    <section id="proxy-config-max-clients">
444     <title>max-clients</title>
445     <para>
446      The element <literal>max-clients</literal> is the child of element
447      <literal>proxy</literal> and specifies the total number of
448      allowed connections to targets (all targets). If this limit
449      is reached the proxy will close the least recently used connection.
450     </para>
451     <para>
452      Note, that many Unix systems impose a system on the number of
453      open files allowed in a single process, typically in the 
454      range 256 (Solaris) to 1024 (Linux).
455      The proxy uses 2 sockets per session + a few files
456      for logging. As a rule of thumb, ensure that 2*max-clients + 5
457      can be opened by the proxy process.
458     </para>
459     <tip>
460      <para>
461       Using the <ulink url="http://www.gnu.org/software/bash/bash.html">
462        bash</ulink> shell, you can set the limit with
463       <literal>ulimit -n</literal><replaceable>no</replaceable>. 
464        Use <literal>ulimit -a</literal> to display limits.
465      </para>
466      </tip>
467    </section>
468
469    <section id="proxy-config-log">
470     <title>log</title>
471     <para>
472      The element <literal>log</literal> is the child of element
473      <literal>proxy</literal> and specifies what to be logged by the
474      proxy.
475      </para>
476     <para>
477      Specify the log file with command-line option <literal>-l</literal>.
478     </para>
479     <para>
480      The text of the <literal>log</literal> element is a sequence of
481      options separated by white space. See the table below:
482      <table frame="top"><title>Logging options</title>
483       <tgroup cols="2">
484        <colspec colwidth="1*"/>
485        <colspec colwidth="2*"/><thead>
486         <row>
487          <entry>Option</entry>
488          <entry>Description</entry>
489         </row>
490        </thead>
491        <tbody>
492         <row>
493          <entry><literal>client-apdu</literal></entry>
494          <entry>
495           Log APDUs as reported by YAZ for the
496           communication between the client and the proxy.
497           This facility is equivalent to the APDU logging that
498           happens when using option <literal>-a</literal>, however
499           this tells the proxy to log in the same file as given
500           by <literal>-l</literal>.
501          </entry>
502         </row>
503         <row>
504          <entry><literal>server-apdu</literal></entry>
505          <entry>
506           Log APDUs as reported by YAZ for the
507           communication between the proxy and the server (backend).
508          </entry>
509         </row>
510         <row>
511          <entry><literal>clients-requests</literal></entry>
512          <entry>
513           Log a brief description about requests transferred between
514           the client and the proxy. The name of the request and the size
515           of the APDU is logged.
516          </entry>
517         </row>
518         <row>
519          <entry><literal>server-requests</literal></entry>
520          <entry>
521           Log a brief description about requests transferred between
522           the proxy and the server (backend). The name of the request
523           and the size of the APDU is logged.
524          </entry>
525         </row>
526        </tbody>
527       </tgroup>
528      </table>
529     </para>
530     <para>
531      To log communication in details between the proxy and the backend, th
532      following configuration could be used:
533      <screen><![CDATA[
534       <target name="mytarget">
535        <log>server-apdu server-requests</log>
536       </target>
537       ]]>
538      </screen>
539     </para>
540    </section>
541   </section>
542   
543   <section id="query-cache">
544    <title>Query Caching</title>
545    <para>
546     Simple stateless clients often send identical Z39.50 searches
547     in a relatively short period of time (e.g. in order to produce a
548     results-list page, the next page,
549     a single full-record, etc). And for many targets, it's
550     much more expensive to produce a new result set than to
551     reuse an existing one.
552    </para>
553    <para>
554     The proxy tries to solve that by remembering the last query for each
555     backend target, so that if an identical query is received next, it
556     is turned into Present Requests rather than new Search Requests.
557    </para>
558    <note>
559     <para>
560      In a future we release will will probably allows for
561      an arbitrary-sized cache for targets supporting named result sets.
562     </para>
563    </note>
564    <para>
565     You can enable/disable query caching using option -o.
566    </para>
567   </section>
568   
569   <section id="record-cache">
570    <title>Record Caching</title>
571    <para>
572     As an option, the proxy may also cache result set records for the
573     last search.
574     The proxy takes into account the Record Syntax and CompSpec.
575     The CompSpec includes simple element set names as well.
576     By default the cache is 200000 bytes per session.
577    </para>
578   </section>
579   
580   <section id="query-validation">
581    <title>Query Validation</title>
582    <para>
583     The Proxy may also be configured to trap particular attributes in
584     Type-1 queries and send Bib-1 diagnostics back to the client without
585     even consulting the backend target. This facility may be useful if
586     a target does not properly issue diagnostics when unsupported attributes
587     are send to it.
588    </para>
589   </section>
590   
591    <section id="record-validation">
592    <title>Record Syntax Validation</title>
593    <para>
594     The proxy may be configured to accept, reject or convert records.
595     When accepted, the target passes search/present requests to the
596     backend target under the assumption that the target can honor the
597     request (In fact it may not do that). When a record is rejected because
598     the record syntax is "unsupported" the proxy returns a diagnostic to the
599     client. Finally, the proxy may convert records.
600    </para>
601    <para>
602     The proxy can convert from MARC to MARCXML and thereby offer an
603     XML version of any MARC record as long as it is ISO2709 encoded.
604     If the proxy is compiled with libXSLT support it can also
605     perform XSLT on XML.
606    </para>
607   </section>
608   
609   <section id="other-optimizations">
610    <title>Other Optimizations</title>
611    <para>
612     We've had some plans to support global caching of result set records,
613     but this has not yet been implemented.
614    </para>
615   </section>
616    
617   <section id="proxy-usage">
618    <title>Proxy Usage (man page)</title>
619    <refentry id="yazproxy-man">
620     &yaz-proxy-ref;
621    </refentry>
622   </section>
623   
624   <section id="otherinfo-encoding">
625    <title>OtherInformation Encoding</title>
626    <para>
627     The proxy uses the OtherInformation definition to carry
628     information about the target address and cookie.
629    </para>
630    <screen>
631   OtherInformation   ::= [201] IMPLICIT SEQUENCE OF SEQUENCE{
632     category           [1]   IMPLICIT InfoCategory OPTIONAL, 
633     information        CHOICE{
634       characterInfo            [2]  IMPLICIT InternationalString,
635       binaryInfo               [3]  IMPLICIT OCTET STRING,
636       externallyDefinedInfo    [4]  IMPLICIT EXTERNAL,
637       oid                      [5]  IMPLICIT OBJECT IDENTIFIER}}
638 --
639   InfoCategory ::= SEQUENCE{
640       categoryTypeId   [1]   IMPLICIT OBJECT IDENTIFIER OPTIONAL,
641       categoryValue    [2]   IMPLICIT INTEGER}
642   </screen>
643    <para>
644     The <literal>categoryTypeId</literal> is either
645     OID 1.2.840.10003.10.1000.81.1, 1.2.840.10003.10.1000.81.2
646     for proxy target and proxy cookie respectively. The
647     integer element <literal>category</literal> is set to 0.
648     The value proxy and cookie is stored in element
649     <literal>characterInfo</literal> of the <literal>information</literal>
650      choice.
651    </para>
652    </section>
653  </chapter>
654
655  <!-- Keep this comment at the end of the file
656  Local variables:
657  mode: sgml
658  sgml-omittag:t
659  sgml-shorttag:t
660  sgml-minimize-attributes:nil
661  sgml-always-quote-attributes:t
662  sgml-indent-step:1
663  sgml-indent-data:t
664  sgml-parent-document: "yazproxy.xml"
665  sgml-local-catalogs: nil
666  sgml-namecase-general:t
667  End:
668  -->
669