home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / srev13h.zip / negotiat.doc < prev    next >
Text File  |  2001-03-27  |  42KB  |  1,072 lines

  1. 14 September 1999
  2.  
  3.                SRE-http and Content Negotiation
  4.  
  5. Content negotiation refers to the choosing of a best representation
  6. of a web resource from several alternatives. SRE-http supports
  7. several http/1.1 compliant mechanisms for performing content negotiation.
  8.  
  9. Contents:
  10. I)        Introduction
  11. II)       Specifying a negotiable resource
  12. II.1)     Creating variants
  13. II.2)     Creating a Variant List
  14. II.3)     Identifying a negotiable resource.
  15. II.3.a)   Wildcarded form
  16. II.4)     Wildcarded variants
  17. III)      The content negotiation algorithim.
  18. III.a)    Using your own server-side content negotiation algorithims
  19. III.a.i)  The Custom Procedure
  20. III.a.ii) Special procnames
  21.  
  22. Appendix A) Sample Variants file.
  23. Appendix B) Specifying a Remote Variant Selection Algorithim
  24. Appendix C) Example of a TCN Request and Response
  25. Appendix D) The SREF_NEGOTIATE_ procedures.
  26.  
  27.  
  28.                          ---------------------
  29.  
  30. 1) Introduction
  31.  
  32. Content negotiation refers to the choosing of a best representation
  33. of a web resource from several alternatives.
  34.  
  35. In general, content negotiation is  used to choose between resources
  36. created with one of several languages, or one of several mimetypes. 
  37. Content negotiation can also be used to choose between resources
  38. using alternate character sets, and to choose shorter documents.  
  39. In the future, content negotiation may also be used to choose documents 
  40. using certain features (such as documents using different versions of html). 
  41.  
  42. There are basically two forms of content negotiation:
  43.  
  44.   1)Server-side. 
  45.      Server-side content negotiation (which is defined in http/1.0) 
  46.      is performed by the server -- the server uses ACCEPT request
  47.      headers (provided by the client) to automatically choose 
  48.      and return one of serveral variants.
  49.  
  50.   2)Client-side. 
  51.       Client-side content negotiation (which is new to http/1.1) 
  52.       is accomplished by the client automatically requesting one of 
  53.       several variants:
  54.          the choice is based on a "variants list" (that contains
  55.          URI's and descriptive information) contained in 
  56.          response headers returned by the server.
  57.  
  58. SRE-http supports both server-side  and client-side content negotiation.               
  59.  
  60.                          ---------------------
  61.   
  62. II) Specifying a negotiable resource
  63.  
  64. To specify a "negotiable" resource (a web resource with several possible
  65. variants) requires 3 steps:
  66.   
  67.   1) Create several "variants" of a resource
  68.   2) Create a file, in your web-space, containing a "variant list"
  69.   3) Create a special NEGOTIATE alias pointing to this file
  70.  
  71. These steps are described in the next three sections.
  72.  
  73. Notes:
  74.  
  75.   * SRE-http's implementation of content negotiation is loosely based on
  76.     Apache 1.3. You might want to examine 
  77.         http://www.apache.org/docs/content-negotiation.html
  78.     for a different description.
  79.  
  80.   * For a technical discussion of content-negotiation, see RFC 2295
  81.     "Transparent Content Negotiation in HTTP" at
  82.     http://gewis.win.tue.nl/~koen/conneg/
  83.  
  84.   * The rationale for client-side content negotiation is that the browser
  85.     is best equipped to choose a variant (given descriptive information
  86.     on the variants mimetype, language, etc.)  Furthermore, it is thought that
  87.     it is wasteful of bandwidth to provide the full range of Accept: headers 
  88.     on every request (since most resources will not be subject to content
  89.     negotiation). However, client-side content negotiation does require
  90.     two round trips (one to get an alternates list, and a second to
  91.     get the desired variant).
  92.  
  93.   * If all you are interested in is GZIPping a response (as a transfer or
  94.     content encoding), please see the description of CE_GZIP (in INITFILT.DOC).
  95.     
  96.  
  97.                      -------------------------
  98.  
  99. II.1) Creating variants
  100.  
  101. Basically, a variant is any server resource. This includes documents, images, 
  102. and even cgi-bin scripts and sre-http addons.  The notion is that variants 
  103. all represent variations of the same information.  For example,
  104. you may have several translations of the same document (say, an English, 
  105. Finnish and Korean version) which you'ld like to  automatically send
  106. to the appropropriate clients.
  107.  
  108. There are a few constraints:
  109.   1) variants must be on the same server as the "variant list" (discussed next).
  110.      In addition SRE-http enforces the "good practice" (from a security 
  111.      standpoint) of requiring that each variant to be in (or under) the 
  112.      same directory as the variant list. 
  113.   2) variants must be retrievable via GET requests.  That is, each
  114.      variant should be accessible with a standard URL; which also means that 
  115.      content negotiation will NOT work with POST requests.
  116.  
  117.                      -------------------------
  118.  
  119. II.2) Creating a Variant List
  120.  
  121. The variant list is at the heart of SRE-http's implementation of content
  122. negotiation.  The variant list is a simple (text) file containing
  123. several multi-line records. This file should be accessible from the web.
  124.    That is: the variant list must be in (or under) the GoServe data directory, 
  125.             or in an SRE-http virtual directory. 
  126.  
  127. Each record in the variant lists must specify a URI (a selector),
  128. and several pieces of identifying information.  This identifying 
  129. information is used to specify up to six "dimensions of negotiation": 
  130. such as the mimetype, charset, language, encoding, features, and length.
  131.  
  132. The syntax of these multi-line records is (note that a wildcarded form
  133. of these records can also be specified, as discussed in section II.4 below):
  134.  
  135. URI: a_selector
  136. Content-type: type/subtype ; charset=a_charset ; qs=m.mm
  137. Content-language: l1, l2 
  138. Content-encoding: enctype
  139. Content-length: nnnn
  140. Option: an option
  141.  
  142. Where:
  143.  
  144.   URI is required.
  145.  
  146.     URI should be a valid selector; that is, site information can not be 
  147.     included -- the resource must be on  the same site as the variant list.
  148.     Note that relative URI's are interepreted relative to the location 
  149.     of the  "variant list".  
  150.         ** Since variants (as identified by these URI entries) MUST
  151.            be in (or under) the directory containing the variant list
  152.            file, use of "relative" uri's is recommended.
  153.    
  154.   Content-type: Content-type is required. It contains 3 sub-fields.
  155.  
  156.      type/subtype: Only the type/subtype subfield is required.
  157.                    It identifies the mime-type of this variant.
  158.  
  159.      charset: Optional. Identifies the character set. If not specified,
  160.               a ISO-8859-1 (latin1) is assumed
  161.  
  162.      qs: Optional. The "selection quality". Must be between 0.0 and 1.0.
  163.          0.0 means "unacceptable", 1.0 means "perfect representation".
  164.          If not specified, a value of 1.0 is assumed.  All else equal,
  165.          variants with higher values are preferentially chosen. 
  166.  
  167.   Content-language: Optional.
  168.  
  169.      A comma delimited list of 2  character languages codes 
  170.      (i.e.; EN for  English, FR for French, DE for German). 
  171.      Note that the 2-2 letter codes, such as En-US, are
  172.      shortened (only the first two characters are used).
  173.  
  174.   Content-encoding: Optional.
  175.  
  176.      A comma delimited list of content encoding types (i.e.; identity,
  177.      gzip, and compress).
  178.  
  179.      Note: if a variant with GZIP content-encoding is chosen, then on-the-fly
  180.            GZIP content encoding (as controlled by the CE_GZIP parameter in 
  181.            INIT_STA.80) will be suppressed.
  182.  
  183.   Content-length: Optional.
  184.  
  185.      The length of the resource.  If not specified, a length of 0 is
  186.      assumed. Note that "longer" resources are less likely to be chosen
  187.      (all else equal).
  188.  
  189.   Description: Optional
  190.       An optional description of this variant.
  191.  
  192.   Features: Optional
  193.       Features allows you to note special "features" of the variant.
  194.       Although not widely supported, in the future browsers may use
  195.       such information to choose a variant (SRE-http does NOT use features
  196.       in its default variant selection algorithim).
  197.       For details on "feature", please see RFC2295.
  198.  
  199.   Option: Optional
  200.       You can specify "selector specific" advanced options to be
  201.       assign to this variant. These complement selector specfic
  202.       advanced options that are assigned to the original selector 
  203.       (that were assigned to the selector that points  to the variant list).
  204.       You can have multiple Option: lines in a given entry. 
  205.       Note that Option: entries are NOT used by SRE-http's default variant 
  206.       selection algorithim.
  207.  
  208. Notes:
  209.  
  210.   *  The "qs" quality specified in content-type applies to the
  211.      entire variant. You should NOT enter "quality" terms for the
  212.      other  content- factors.
  213.  
  214.   *  Appendix A contains an example of a variant list file.
  215.  
  216.   *  When a variant is selected, its Content-Type, Content-Language,
  217.      and Content-Encoding are returned as response headers. Thus,
  218.      in most cases the Content-Type specified in a variant list will 
  219.      override the "default" Content-Type (i.e.; the mimetype derived from 
  220.      the file's extension). The exception to this rule is when a
  221.      mime-type is specified as an advanced option, or when the variant
  222.      is a CGI script or an SRE-http addon (in which case the script/addon
  223.      should provide the content-type information).
  224.  
  225.   *  If the last variant in a variant only has a URI: field, then
  226.      it is treated as a "fall back" variant, and will (typically) be 
  227.      used only if there is no best match.
  228.  
  229.                      -------------------------
  230.  
  231. II.3) Identifying a negotiable resource.
  232.  
  233. SRE-http uses a special "alias" to identify variant lists. 
  234. Unless an alias is used to explicitily identify a variant list, a 
  235. request for a variant list will be treated in the normal fashion.
  236. That is, the variant list file would be returned verbatim (say, as a 
  237. text/plain response).
  238.  
  239. To identify a variant list, you can either:
  240.  
  241.  a) add an entry to to your ALIASES file, using:
  242.         sel   !NEGOTIATE target
  243.  b) define a realm in ATTRIBS.CFG using:
  244.        rule: sel
  245.        redirect: NEGOTIATE= target
  246.  
  247. where:
  248.      sel =  a selector that points to identified as a negotiable resource.
  249.             Alternatively, you can use a wildcarded selector.
  250.   target =  optional -- either a fully qualified file name or a
  251.             selector.
  252.     
  253. Typically, target is not specified; in which case SRE-http use its 
  254. normal rules to map sel to a file containing a variant list 
  255. (that is, sel is assumed to be under the GoServe data directory 
  256. or under a virtual directory).
  257.  
  258. If specified, target is used as the variant list.  If target
  259. is not a fully qualified file name, it should be relative
  260. to the GoServe data directory (or to a virtual directory).
  261.  
  262. In all cases, the variants must be "neighboring", which means they
  263. MUST be relative to the directory that contains the variant list.
  264.  
  265. **    If you use a wildcarded selector (containing *), you MUST specify
  266. **    a target -- see the section II.3.a for the details.
  267.  
  268. Some examples:
  269.  
  270.   ALIASES.IN example:
  271.      /VARTEST/VAR1.LST !NEGOTIATE
  272.  
  273.   ATTRIBS.CFG example:
  274.      realm: negot1
  275.      rule: /VARTEST/VAR1.LST
  276.      redirect: Negotiate=
  277.  
  278.   Assuming that your GoServe data directory is E:\WWW, this could mean:
  279.      /VARTEST/VAR1.LST is a negotiable resource, with a variant list defined
  280.      in E:\WWW\VARTEST\VAR1.LST.  
  281.  
  282. Notes:
  283.   * As noted,  "resources" pointed to by a variant list must be 
  284.     "neighboring"; they must be in or under the same directory as  
  285.     the variant list file.
  286.  
  287.  *  Unlike most SRE-http aliases, there is no explicit "replacement". 
  288.     Actually, you can think of the variant list itself as an extension 
  289.     of SRE-http's aliasing -- it contains instructions used to decide 
  290.     which (of several) replacements to use.
  291.  
  292.  
  293. II.3.a) Wildcarded form
  294.   
  295. When sel contains a wildcard (an *), you MUST use target to specify
  296. the file containing the variant list (you can use either a
  297. fully qualified file name, or another selector).
  298.    
  299. For example, using ALIASES.IN:
  300.      /MANUALS/*.HTM !NEGOTIATE /MANUALS/DOCS.LST
  301. or, using ATTRIB.CFG
  302.      Realm: negot2
  303.      Rule: /MANUALS/*.HTM
  304.      Redirect: Negotiate=/MANUALS/DOCS.LST
  305.      
  306. In this case, all request selectors that match MANUALS/*.HTM (note that the
  307. leading / is ignored) will use the variant list specified in 
  308. /MANUALS/DOCS.LST.  Please see the next section for details on how 
  309. variants are resolved when this wild_sel form is used.
  310.  
  311. Once you've accomplished these steps, all you need to do is put a URL
  312. pointing to sel (or that will wildcard-match sel); and hope that your 
  313. client's browser either provides useful ACCEPT headers, or knows how 
  314. to do client side content negotiation.
  315.  
  316.                      -------------------------
  317.  
  318.  
  319. II.4) Wildcarded variants
  320.  
  321. As outlined above, one creates a unique variant list (and a unique
  322. alias) for all negotiable resources. This may become quite tedious,
  323. especially when you have multiple sets of documents. For example, if you
  324. have a 10 chapter manual in 3 languages (hence, 30 files), it could be
  325. advantageous (that is, a lot less trouble) to use some wildcarded "variant 
  326. list" for all 10 chapters.
  327.  
  328. In recognition of this possibility, SRE-http supports a special form of 
  329. variant list that supports such "multiple sets of negotiable resources".  
  330. The specification of these sets requires two changes to the simple case. 
  331.  
  332. The first difference is discussed above -- the use of the "wildcarded form" 
  333. of sel.  The second involves modifications to the variant list file.
  334.  
  335. Recollect that the wildcarded form directs many possible "request selectors"
  336. to a single variant list.  Thus, the variant list should contain information 
  337. that allows the request selector to influence the value of the URI: field of 
  338. each record in the variant list.  To do this, two steps are required.
  339.  
  340.    a) A (case insensitive)
  341.        PATTERN: wild_sel 
  342.     entry should be put at the top of the variant list.
  343.     For example:
  344.         Pattern: /manuals/*.HTM  --    (note that a leading / is ignored)
  345.  
  346.       **  The value of "wild_sel" used in a PATTERN: entry should be the same 
  347.           as the "wild_sel" used as the "target" portion of the wildcarded 
  348.           alias (that is used to identify the variant list).
  349.  
  350.    b) The URI: fields may contain * characters. 
  351.       SRE-http will replace these * (in the URI:  entries) with 
  352.       corresponding portions of the request selector.
  353.  
  354.       For example:
  355.         i) the request selector is: manual/chap1.htm
  356.        ii) the alias is:  manual/*  !negotiate  manual/docs.lst
  357.       iii) manual/docs.lst contains
  358.  
  359.                pattern: manual/*
  360.                 
  361.                URI: de/*
  362.                Content-type: text/html
  363.                Content-Language: de
  364.  
  365.                Uri: en/*
  366.                Content-type: text/html
  367.                Content-language: en
  368.      then
  369.         a) If the request contain an accept-language: en request header, then
  370.               en/chap1.htm would be used
  371.          
  372.         b)  If the request contain an accept-language: de request header, then
  373.               de/chap1.htm would be used
  374.  
  375.           That is, the * in the Pattern: (in manual/*) "corresponds to" 
  376.           chap1.htm, which is then used as a substitute for the * in the  
  377.           various URI: entries.
  378.  
  379.                      -------------------------
  380.  
  381. III) The content negotiation algorithim.
  382.  
  383. The following sketches the default content negotiation algorithim 
  384. used by SRE-http. Note that this is used both for "server side 
  385. negotiation" (when the client does not include a Negotiate: request
  386. header), and as a "remove variant selection algorithim" (when the 
  387. client includes a Negotiate: * request header).
  388.  
  389.     Alternatively, you can specify your own "server side "content 
  390.     negotiation algorithim on a selector specific basis -- see section
  391.     III.a for the details!
  392.  
  393.  
  394. 1) First, SRE-http checks for a "Negotiate:" request header. If no 
  395.    such header exists, then server-side negotiation is always
  396.    attempted. If this header does exist, then server-side negotiation
  397.    may be attempted (see the notes for details).
  398.  
  399. 2) If server-side negotiation is to be attempted, by default
  400.    the following selection algorithim is used.  
  401.  
  402.       If the client allows  a "remote variant selection algorithim"
  403.       (by including a Negotiate: n.n request header), then a custom
  404.       procedure can be used instead (see Appendix B for the details).
  405.  
  406.    Note that this is a "leave as soon as a definitive answer is found"
  407.    method -- latter steps are only used if earlier steps yield ties.
  408.    Furthermore, variants eliminated in earlier steps are NOT 
  409.    available -- they are NOT considered in latter steps.
  410.    Lastly, if all variants are eliminated, a suitable "could not find
  411.    representation" response is immediately returned.
  412.  
  413.    a) Accept: headers are read. Accept: headers contains information
  414.       on acceptable mime-types.  This information can contain "selection
  415.       quality" (q) information.  
  416.       The variant with the best "combined" quality is used.  Combined quality
  417.       is deterimined by multiplying the variant-list qs (quality) by the
  418.       accept: header  "q: factors". 
  419.       If there are ties (i.e.; several mimetypes have a combined quality
  420.       of 1.0), then move to step b. If there is no accept: header (most 
  421.       browsers send some form of Accept: header) then skip this step.
  422.  
  423.    b) Accept-language: headers are read. These request headers can contain
  424.       "language specific q modifiers".  The variant (of those surviving
  425.       step a) with the highest language "q" factor is used. 
  426.       If there are ties, move to step c. If there is no accept-language
  427.       header, this step is skipped. Note that the content-language entries
  428.       in the variant list should NOT include "q" factors.
  429.  
  430.    c) Accept-Encoding: headers are read. These headers can also contain
  431.       "encoding specific q modifiers".  The variant (of those surviving
  432.       step b) with the highest encoding "q" factor is used. 
  433.       If there are ties, move to step d. If there is no accept-encoding
  434.       header, this step is skipped. Note that the content-encoding entries
  435.       in the variant list should NOT include "q" factors.
  436.  
  437.    d) Accept-charset: headers are read. Variants that do not match this
  438.       charset are dropped.
  439.       If there are ties then move to step e. If there is no accept-charset
  440.       header then skip this step.
  441.  
  442.    e) Use the variant with the smallest content-length (as pulled from the 
  443.       variant list).
  444.       If there are ties, move to step f.
  445.  
  446.    f) Use the first of the remaining variants.
  447.  
  448. Note:
  449.    If all variants are removed at any step in this process (say,
  450.    no variants have a content-language, and an explicit 
  451.    Accept-language was specified), then the algorithim exits.
  452.    In this case, if a default variant was specified, it will be used.
  453.    Otherwise,  either a 406 (for http/1.1 clients) or a 404 (for http/1.0 clients) 
  454.    response is returned.
  455.  
  456.  
  457.  
  458.  
  459. 3) If client-side negotiation is to be used, SRE-http returns a special
  460.    "300" return  code. The body of the response contains an <UL> list 
  461.    containing links to each  variant. Furthermore, the variant list 
  462.    (suitably formatted) is returned in an Alternates: response header.
  463.  
  464. Note:
  465.  
  466.    * SRE-http recognizes several values in the Negotiate: header (any
  467.      combination of them can appear in a comma delimited list)
  468.  
  469.         trans:  client supports client side content negotiation
  470.         vlist:  always send Alternates: response header (implies trans)
  471.             *:  server should attempt to choose best variant (implies trans).
  472.       guess-small: always send Alternates: response header (implies trans)
  473.                    This is minimal support -- with full support, sometimes
  474.                    a sufficiently small "best variant" guess is returned.
  475.         n.n     : A decimal number, such as 4.2.
  476.                  This specifies the major and minor versions of a customized
  477.                  "remote variant selection algorithim" (RVSA) -- a custom
  478.                  procedure to replace SRE-http's built in variant selection
  479.                  algorithim. See APPENDIX B for details on how to
  480.                  add a procedure to implement your favorite RVSA!
  481.  
  482.      In the following cases, server-side negotiation is not attempted:
  483.  
  484.         Negotiate: trans
  485.         Negotiate: vlist
  486.         Negotiate: vlist,trans   
  487.         Negotiate: guess-small
  488.  
  489.      In these cases,SRE-http returns a "300 Multiple Choices" response.
  490.  
  491.      A "300" response always includes an Alternates: header (containing a
  492.      suitably formatted version of the variant list). In addition, a <UL> list
  493.      of links to each variant is returned in the body of the response.
  494.          The assumption is that (in most cases) the user-agent 
  495.          (the browser) will use the variant list to choose  a best 
  496.          variant; but if it can't, the list will be displayed and the 
  497.          human can manually choose.
  498.  
  499.      When * is included, then server-side content negotiation will be
  500.      attempted. In particular:
  501.          Negotiate: *, vlist
  502.      means "attempt to find best match, but always return the variant list"
  503.      In contrast
  504.          Negotiate: *
  505.      means "return the best match, only return a variant list if no best
  506.      match found".
  507.  
  508.      When a "n.n" RVSA token is included, and the appropriate procedure
  509.      has been defined, then SRE-http will attempt to use the indicated
  510.      RVSA algorithim for server-side content negotation.
  511.      See Appendix B for the details.
  512.  
  513.      In either case (that is, whenever * or an n.n  appears in the 
  514.      Negotiate: header), failing to find a best match causes a  
  515.      "406 No acceptable representation"  response to be returned. 
  516.      This 406 response is similar to the 300 response described above -- 
  517.      it contains an Alternates: header and  a <UL> list of links.
  518.  
  519.  * To repeat: if no Negotiate: request header exists, then server-side
  520.    content negotiation is attempted. If no best-match can be found, then
  521.    a 404 response, containing a <UL> list of links to each variant,
  522.    is returned (but no Alternates: header).
  523.  
  524.  * Whenever server-side negotiation (either pure server side, or
  525.    due to a Negotiate:* header) is succesful, a Vary: header
  526.    will be included (Vary headers are used by proxy servers).
  527.  
  528.  * When a quality value is not specified (either as qs factor in the 
  529.    Content-type field in the variant list, or as a "q" factor in an Accept: 
  530.    or Accept-Language request header), a value of 1.0 is assumed. 
  531.    There are a few exceptions:
  532.        i)if a */* or xxx/* appear (in the Accept: header), and if no other
  533.          mimetypes have a q modifier, then */* is assigned a value of 0.01,
  534.          and xxx/* is given a value of 0.02.
  535.       ii)records in the variant list with no content-language field are given
  536.          a language quality factor of 0.01.
  537.    Both these exceptions are tricks that cause these "defaults" to be used
  538.    when no better match exists.
  539.  
  540.  * You can specify multiple languages in the Content-language entry
  541.    (in a variant list record). However, you can NOT specify a "q" modifier
  542.    for these languages.  Note that the accept-language header MAY contain
  543.    several languages, each of which may have a "q" modifier.
  544.  
  545.  * If no charset is specified (in a variant list record), then 
  546.    ISO-8859-1 (latin1) is assumed.
  547.  
  548.  * If no content-length is specified (in a variant list record), then 
  549.    a length of 0 is assumed. That is, content-length is really a final
  550.    "quality check", with lower values (and unspecified values) preferred.
  551.  
  552.  * Hint: the Options-General-Language tab of Netscape can be used to 
  553.    automatically generate Accept-language headers.
  554.  
  555.  * WARNING: the variant returned by server side negotiation should NEVER
  556.             be a negotiable resource. If this should happen, SRE-http
  557.             will return a 506 response (Variant Also Negotiates).
  558.  
  559.  
  560.  
  561.                      -------------------------
  562.  
  563. III.a) Using your own server-side content negotiation algorithims
  564.  
  565. Although client-side negotiation can be quite powerful, it does
  566. require fairly advanced http/1.1 clients. Until this is 
  567. commonplace, server-side negotiation is a good alternative.
  568.  
  569. Although the Apache-emulating content negotation algorithim 
  570. (described above) is fairly powerful, it is limited. For example,
  571. there is no way that cookies can influence the choice of variant.
  572. Therefore, SRE-http allows you to specify your own "server side"
  573. content negotiation algorithims, on a selector specific basis.
  574.  
  575. To do this, you must:
  576.  
  577.  a) Include a 
  578.       PROC: procname
  579.    element at the top of your variant list file.  
  580.  
  581.  b) Create a procedure with "procname" that can choose a variant.
  582.     This procedure should reside in a .CMD file in the
  583.     GoServe working directory, or in macrospace.
  584.  
  585. For example, your variant list could look like:
  586.  
  587.   URI: bar
  588.   Proc: SREF_NEGOTIATE_1
  589.  
  590.   Uri:bar.html
  591.   content-type: text/html ; q=1.0
  592.  
  593.   Uri:bar.txt
  594.   content-type: text/plain ; q=0.7
  595.  
  596. which would mean "use the SREF_NEGOTIATE_1 procedure to choose between
  597. these two variants".
  598.  
  599. III.a.i) The Custom Procedure
  600.  
  601. Your custom procedure will be passed four arguments:
  602.    i) the original request selector, 
  603.   ii) the variant list file (that the original selector maps to)
  604.  iii) number of entries in the variant list
  605.   iv) the variant list
  606.  
  607. For example, you can read these arguments using:
  608.  
  609.    parse arg  sel0,afile,nentries,varilist
  610.  
  611. Varilist (the variants list) will have the form:
  612.     n
  613.     spec_1
  614.      ...
  615.     spec_n
  616. where:
  617.    n = # of variants
  618.    spec_j = specifications for alternate j, with structure:
  619.            "a_sel" q  {field1 values1} {field2 values2} ....
  620.  
  621.   For example:
  622.      4
  623.      "tst.1" 1 {type text/plain } {language en } {charset cyrillic }
  624.      "tst.2" 0.3 {type text/plain } {language fr } {features tables def} 
  625.      "tst.3" 1 {type text/html } {language en } {length 20065 } {charset latin5 }
  626.      "/status?" 1 {type application/octet-stream } {language gr }
  627.  
  628.   Note that each entry appears on a single line (which may be quite long).
  629.  
  630.  
  631. The procedure should return:
  632.     statcode  header_list
  633. where
  634.  statcode:
  635.        '' -- a blank line means "could not find a best match,
  636.              use SRE-http's default algorithim instead"
  637.        0 -- 0 means "could not find best match, return a 406 response"
  638.        j -- A number between 1 and n, which points to the best variant.
  639.  
  640.  header_list (optional):
  641.  
  642.        only used if statcode=j (j=1..n). This should contain a space delimited
  643.        list of the request headers used to choose the variant. This list
  644.        is returned as a Vary: response header, and will then be used by
  645.        proxy servers to determine the cacachability of this variant.
  646.        If you don't specify header_list, a Vary: * header will be
  647.        added (which implies that this variant is not cachable).  
  648.  
  649. Example of a return:
  650.     return '3 Accept Accept-Language '
  651.      
  652.  
  653. Notes:
  654.   *  '' and 0 differ in that a return of 0 causes SRE-http to stop trying
  655.     to find a best variant (and return a 406 response); wheras as ''
  656.     means "now try the default algorithim" (which might yield a 
  657.     match).
  658.  
  659.   * Example of a header_list:  If you used the ACCEPT and ACCEPT-LANGUAGE
  660.     request headers to determine the best variant, header_list should
  661.     be "ACCEPT ACCEPT_LANGUAGE" (without the quotes). Or, if you also
  662.     used a cookie, then header_list should be 
  663.     "ACCEPT, ACCEPT_LANGUAGE, COOKIE".
  664.  
  665.   * The NEGOT.CMD file, that comes with SRE-http, provides a well-documented
  666.     example; it basically emulates the default "server side" content
  667.     negotiation algorithim.
  668.  
  669. III.a.ii) Special procnames
  670.  
  671. Since you can have several different procedures, for several different
  672. negotiable resources, you can use any "procname" you wish -- so long
  673. as it is a legal REXX procedure name, and so long as it can
  674. either be found in macrospace or in the GoServe working directory.
  675.  
  676. However, since this flexibility comes at some cost (SRE-http has to
  677. use the somewhat slow INTERPRET command), it is recommended that
  678. one of the following procnames be used:
  679.  
  680.   SREF_NEGOTIATE_1
  681.   SREF_NEGOTIATE_2
  682.   SREF_NEGOTIATE_3
  683.   NEGOT1
  684.   NEGOT2
  685.   NEGOT3
  686.  
  687. SRE-http is coded to recognize these names, thereby avoiding the 
  688. use of INTERPRET. In particular, the SREF_ names should
  689. refer to procedures that you load into macrospace (say, using the 
  690. CUSTOM_INITS facility of SRE-http), and the NEGOT names should
  691. refer to .CMD files in the GoServe working directory.
  692.  
  693. In any case, the procedure will be passed the arguments described above,
  694. and must return either a 0 (no best variant found), or an integer pointing
  695. to the best of the n variants provided.
  696.  
  697. III.a.iii) Useful procedures.
  698.  
  699. In order to ease the task of writing a custom procedure SRE-http provides 
  700. two procedures that you can use to search and extract information
  701. from the the variant list: SREF_NEGOTIATE_SEARCH and SREF_NEGOTIATE_EXTRACT.
  702. See Appendix D for the details.
  703.  
  704. In addition:
  705.  
  706.    * the GoServe reqfield(header_name) function can be used to 
  707.      lookup other specific request headers (see GOSERVE.DOC for the
  708.      details).
  709.    * The SRE-http SREF_GET_COOKIE(cookie_name) to read
  710.      the value of the cookie_name cookie (see SREFPRC.DOC for the details).
  711.  
  712. For an example of how to a custom "server side" content negotiation
  713. procedure, please see NEGOT.CMD.
  714.  
  715.    
  716.                      -------------------------
  717.    
  718.  
  719.  
  720.  
  721. Appendix A) Sample Variants file.
  722.  
  723.  
  724.         ---------------------- Start example -----------
  725. ; this is sample variant file
  726.  
  727. URI: foo
  728. PROXY-RVSA: 1.3
  729.  
  730. Uri:foo.fr.de.html
  731. content-type: text/html 
  732. content-language: sp,fr-ca,de
  733. content-length: 2005
  734.  
  735. Uri:foo.txt
  736. content-type: text/plain ; q=0.5
  737. content-length: 2005
  738. content-language: en 
  739. description: this is the english text version
  740.  
  741. Uri:foo.gz
  742. content-type: text/plain ; q=0.5
  743. content-length: 2005
  744. content-encoding: gzip
  745. content-language: en 
  746. option: header add x-advisory: needs Gzip
  747. option: header add set-cookie: foobar=this is foobar
  748.  
  749. uri: /status?
  750. content-type: application/octet-stream
  751.  
  752. uri: foo.en.html
  753. content-type: text/html ; charset=iso-8859-1 ; q=1
  754. content-language: en
  755. features: tables frames
  756.  
  757. uri:foo.def0
  758.  
  759.  
  760.         ---------------------- End of example -----------
  761.  
  762. Notes:
  763.   * Lines beginning with ; are comments, and are ignored
  764.  
  765.   * Each, typically multi-line record, contains a
  766.     URI: entry, and (optionally) a combination of content-type, 
  767.     content-language, and content-length entries.
  768.  
  769.   * Blank lines are treated as "record delimiters"
  770.  
  771.   * The first "one line record" URI: entry is optional -- it's skipped
  772.  
  773.   * An (optional) Proxy-RVSA: entry (at the top of the file, 
  774.     before the start of the first non-one line  record) is used to signal 
  775.     to proxies what  RVSAs they can use. 
  776.  
  777.   * Note that PROC:, if used, should also be placed before the 
  778.     start of the first record (i.e.; next to the first "one line record" URI).
  779.  
  780.   * Content-length is the estimated size of the file, 
  781.     it does NOT have to be the actual size of the file.
  782.     All else equal, smaller "lengths" are preferentially returned.  
  783.  
  784.   * Content-language is a comma delimited set of languages 
  785.  
  786.   * Content-encoding is an encoding type, with "identity" meaning
  787.     "no encoding". Only one encoding-type can be specified.
  788.  
  789.   * Content-type contains 3 fields. The type/subtype field is required,
  790.     the charset= field is optional (iso-8859-1 is the default), and qs
  791.     is the (optional) "quality" measure used to weight the variants.
  792.  
  793.   * Note the last entry is a "fall back" variant (the client's user-agent
  794.     can choose this if all else fails).
  795.  
  796.  
  797.                      -------------------------
  798.  
  799.  
  800. Appendix B: Specifying a Remote Variant Selection Algorithim
  801.  
  802. SRE-http provides a simple hook by which a custom remote variant
  803. selection algorithims (RVSA) can be implemented.  The process is:
  804.  
  805. a) obtain the RVSA. 
  806.  
  807. b) write a rexx procedure that calls this rvsa
  808.  
  809. c) save this procedure into macrospace using a name of
  810.    SREF_RVSA_n, where "n" is the major version number
  811.    of the rvsa.
  812.  
  813.    For example, if the request contains:
  814.        Negotiate: 2.3,vlist
  815.    then SREF_RVSA_2 is appropriate "macrospace" procedure name.
  816.  
  817. In the simplest case, the rvsa procedure will be a rexx procedure;
  818. in which step a and b are combined.
  819.  
  820. The rvsa procedure (say, SREF_RVSA_2) will be called with
  821. two arguments, the version number, and the list of alternates.
  822. For example, to read these arguments the procedure could use:
  823.   parse arg version,altlist
  824.  
  825. In the above example (Negotiate: 2.3,vlist) the version number would 
  826. be "2.3" (without the quotes). The list of alternates is simply a 
  827. copy of the Alternates: header (that would be returned to the client).
  828.  
  829. The rvsa procedure should use this information, along with request
  830. specific information (such as the various Accept headers, which 
  831. can be read using the GoServe reqfield function) to determine which
  832. variant is best.   The number of this best variant should be
  833. returned; or a 0 should be returned if there is no best match.
  834.  
  835. For example, if the second variant (in the list of alternates) is
  836. best, then SREF_RVSA_2 should return a "2" (without the quotes).
  837.  
  838. Notes:
  839.  
  840.   * You can use RXU, REXXLIB, or other DLLs to create macrospace
  841.     procedures
  842.  
  843.   * For details on the structure of the alternates list, see RFC2295.
  844.     (see Appendix 3 for an example).
  845.  
  846.                      -------------------------
  847.  
  848.  
  849. Appendix C: Example of a TCN Request and Response
  850.  
  851.  
  852. The following is a simple example of TCN request, and the response
  853. from SRE-http.
  854.  
  855. Assuming that:
  856.   TSTHTM/TSTHTM.NEG
  857. is a negotiable resource, and TSTHTM.NEG has the following structure:
  858.  
  859.    ;---- TSTHTM.NEG is a negotiable resources
  860.    uri:tsthtm
  861.  
  862.    uri:tst.1
  863.    content-type: text/plain; qs=0.8
  864.    content-language: en 
  865.  
  866.    uri: tst.2
  867.    content-type: text/plain ; qs=0.3
  868.    content-language: fr 
  869.    description: The French Version
  870.    features: tables [abc def] 
  871.  
  872.    uri: /gene_test?
  873.    content-type: application/octet-stream; charset=cyrillic
  874.    content-language: ru
  875.    ;---- End of TSTHTM.NEG
  876.  
  877.  
  878. Requesting a url of:
  879.   http://foo.bar.net/tsthtm/tsthtm.neg
  880.  
  881. causes a browser to issue the following request:
  882.  
  883.    GET /tsthtm/tsthtm.neg  HTTP/1.1
  884.    HOST:foo.bar.net
  885.    Negotiate: vlist,*
  886.    Accept: text/plain
  887.    Accept-language: fr
  888.  
  889. This would yield the response:
  890.  
  891.   HTTP/1.1 200 Ok
  892.   Date: Sat, 26 Jun 1999 13:49:10 GMT
  893.   Accept-Ranges: bytes
  894.   Connection: close
  895.   Last-Modified: Thu, 24 Jun 1999 05:52:38 GMT
  896.   ETag: "990624015238_18;7964E38D"
  897.   Server: GoServe for OS/2, version 2.52; SRE-http 130607.1
  898.   Content-Type: text/plain
  899.   Tcn: choice
  900.   Content-location: tsthtm/tst.1
  901.   Vary: negotiate,accept
  902.   Alternates: {"tst.1" 0.8 {type text/plain } {language en }},
  903.   {"tst.2" 0.3 {type text/plain } {language fr } {features tables [abc def] }
  904.   {description "The French Version"}},
  905.   {"/gene_test?" 1 {type application/octet-stream } {language ru } 
  906.   {charset cyrillic }}
  907.   Content-Language: en
  908.   Content-length: 18
  909.   Cache-control: public
  910.  
  911. Notes:
  912.   * Since * appears in the Negotiate: header, SRE-http will 
  913.     attempt the default server side negotiation.  The Accept: text/plain
  914.     is the only information used, and the explicit q=0.8 of the first
  915.     entry beats the explicit 0.3 of the second entry.  The implicit
  916.     q=1.0 of the third entry is irrelevant, since the third entry's
  917.     content-type is not text/plain
  918.   * the Alternates: header has been reformatted (it is actually on one 
  919.     long line).
  920.   * The contents of tsthtm/tst.1, which (in this example) has a size of 
  921.     18 characters, is sent as the body of the response. 
  922.  
  923.  
  924. Alternatively, if the client does not want the server to resolve the
  925. variant:
  926.  
  927.    GET /tsthtm/tsthtm.neg  HTTP/1.1
  928.    HOST:foo.bar.net
  929.    Negotiate: vlist
  930.    Accept: text/plain
  931.    Accept-language: fr
  932.  
  933. which yields:
  934.    HTTP/1.1 300 Multiple Choices
  935.    Date: Sat, 26 Jun 1999 14:01:20 GMT
  936.    Server: GoServe/2.52 ;130607.1
  937.    Tcn: list
  938.    Etag: 990626095912_324;7964E38D
  939.    Vary: *
  940.    Alternates: {"tst.1" 0.8 {type text/plain } {language en }},
  941.    {"tst.2" 0.3 {type text/plain } {language fr } {features tables [abc def] }
  942.    {description "The French Version"}},
  943.    {"/gene_test?" 1 {type application/octet-stream } {language ru } 
  944.    {charset cyrillic }}
  945.    Cache-Control: public
  946.  
  947. Note that the portion of the etag following the ; (the 7964E38D)
  948. is the same for both requests -- it's the "variant list validator".
  949. And since the Alternates: header is the same in both responses,
  950. this "variant list validator" is also the same.
  951.  
  952.  
  953.                      -------------------------
  954.  
  955.  
  956. Appendix D:  The SREF_NEGOTIATE procedures:
  957.  
  958. For both these procedures, afield can take the following values:
  959.  
  960.   SEL -- the variant's selector
  961.      Q --  the quality rating
  962.     TYPE -- content-type
  963.   LANGUAGE -- comma delimited list of languages
  964.     CHARSET -- the character set
  965.     ENCODING -- the content encoding
  966.     FEATURES -- Features.  Can be used for miscellaneous features
  967.   DESCRIPTION -- Description of variant
  968.  
  969.                         ----------
  970.  
  971.  
  972. SREF_NEGOTIATE_SEARCH:
  973.  
  974. Syntax:
  975.    matchlist=SREF_NEGOTIATE_SEARCH(avalue,afield,varilist,best,onlyin)
  976.  
  977. where:
  978.     avalue : a value, or a set of values, to examine
  979.     afield : the name of the "field" in the variant list, values
  980.              from this field will be compared against values in
  981.              avalue. 
  982.   varilist : the "variant list" (as provided by sre-http)
  983.     best   : optional. If 1 or 2, then do a "quality weighted" best
  984.              match, and return only the top scoring variant
  985.              (or variants, if a tie for top)
  986.    onlyin  : optional. A index of the entries in the variant
  987.              list to examine. 
  988.  
  989.    matchlist: a space delimited list of integers
  990.  
  991. Description:
  992.  
  993. Matchlist is an index to the variant list -- the indicated
  994. variants have a value in "afield" that is a match (or a best
  995. match) to a value in "avalue".
  996.  
  997. If no matches, returns a 0.
  998.  
  999. Basically, this procedure eases the comparison of Accept- headers
  1000. against the variant list; a typical use is to read an
  1001. accept- header, and use its value as "avalue".
  1002.  
  1003. Values in "avalue" can contain * wildcards. However, values in
  1004. "afield" should NOT contain * characters.
  1005.  
  1006. For both avalue and afield, values are seperated by commas.
  1007. Values in "avalue" may also be "modified" by ;q=n.nn -- these modifiers
  1008. are used as the "weighting factor" for that value. Thus,
  1009. different values within "avalue" can have different weights.
  1010.  
  1011. If an "afield" is missing from a variant, it is skipped.
  1012. Note that the "language" and "features" fields may contain
  1013. more then one value; all other fields contain 1 value (or
  1014. 0 values, if they are not defined).
  1015.  
  1016. If best=1, then instead of returning all variants that "match", only
  1017. return the variants with the highest match (if a tie for highest, return
  1018. all the top matches).  
  1019.  
  1020. The "highest match" is determined by using the "q" weighting factors that 
  1021. may appear in "avalue".  Note if a value in avalue does not have an
  1022. explicit q factor:
  1023.    a) if it does not contain a *, q=1 is used.
  1024.    b) if it has one * (say, text/*), q=0.02
  1025.    c) if it has two * (say, */*), q=0.01
  1026.  
  1027. If best=2, then modify this by multiplying the q weighting factor of the
  1028. value from "avalue"  by the "Q" field of the variant.
  1029.  
  1030. If onlyin is specified, then only the records indexed by onlyin 
  1031. are searched (records not indexed by onlyin can NEVER appear
  1032. in matchlist).
  1033.  
  1034. Examples:
  1035.    
  1036.    kth=sref_negotiate_search('fr;q=0.5, sp','language',varilist,1)
  1037.    mth=sref_negotiate_search('text/plain','type',varilist,2,'1 3 6 7')
  1038.    mth=sref_negotiate_search('text/plain, text/* , */* ','type',varilist)
  1039.  
  1040.                         ----------
  1041.  
  1042. SREF_NEGOTIATE_EXTRACT:
  1043.  
  1044. Syntax:
  1045.   avalue=SREF_NEGOTIATE_EXTRACT(afield,j,varilist)
  1046.  
  1047. where:
  1048.    afield = a "field name"
  1049.    j      = an index into the variant list
  1050.   varilist = the variant list
  1051.  
  1052. Description:
  1053.  
  1054.   Extract the value of the "afield" field from the j'th entry in the
  1055.   variant list. If no such field, or if j is invalid (less then 1 or 
  1056.   greater then the number of variants, then return '')
  1057.  
  1058.   Alternatively, j can be a space delimited list of entry numbers,
  1059.   in which case avalue will be a CRLF ('0d0a'x) delimited
  1060.   list of the values of afield from these entries.
  1061.  
  1062.   Lastly, if j='*', the values of afield for all entries will be returned
  1063.   in a CRLF delimited list.
  1064.  
  1065. Examples:
  1066.   
  1067.    alang=sref_negotiate_extract('language',2,varilist)
  1068.    atype=sref_negotiate_extract('type',3,varilist)
  1069.    sels=sref_negotiate_extract('sel','1 4',varilist)
  1070.  
  1071.  
  1072.