SREhttp/2 Manual|| SREhttp/2 and CGI-BIN

## Creating Addons for SREhttp/2

### Contents

- Introduction
- Invoking an SREhttp/2 addon
- How SREhttp/2 finds an addon program
- Arguments supplied by SREhttp/2
- Returning a response from an SREhttp/2 addon
- Miscellaneous hints and notions
- Forcing SREhttp/2 to lookup client privileges
- A note on decoding request strings
- Encryption
- Multiple part documents
- SRE2003 facilities
- Addons bundled with SREhttp/2
- Addons not bundled with SREhttp/2

### Introduction

The combination of SRE2003's built-in commands and the SRE2003 procedure library, in addition to the SREhttp/2 procedure library, creates an environment that is conducive to the creation of web aware applications. In this document we discuss how to create these web aware applications, which we call SREhttp/addons.

First, SREhttp/2 is fully compatabile with CGI-BIN; and can even use PERL scripts. While CGI-BIN has the huge advantage of portability, it is a clunky and sort-of-slow interface. Hence, SRE-http also offers its own method of allowing for "server side processing of client requests" -- through the use of SREhttp/2 addons. For example, we've created a number of publically available addons, including a bulletin board system, a search engine, and a text-to-gif utiliity.

Creation of these addons requires writing an external REXX procedure that is then called by SREhttp/2. This procedure can handle the request, or it can subsequently call any other program (such as a database manager).

We hope the following hints will aid, and entice, you in creation of your own addons! We do presume that you understand some of the somewhat-arcane SRE2003 terminology; such as selector and action .

### Invoking an SREhttp/2 addon

Addon's are invoked when:

1. When a POST method request is recieved, or
   a GET method request is recived that includes a ?,

   and ...

2. The action portion of the selector does not contain a CGI-BIN substring

In either case, the `action` portion of the selector (the part before the `?`) is assumed to point to a file containing a REXX procedure (if no extension is give, a .CMD extension is assumed). The file should be in (or under, since action can contain subdirectory information) the possibly host-specific (or possibly request specific) ADDON directory. Or you can expedite execution by loading addons into macrospace, and using a shorthand to invoke them.

Example: | SREhttp/2's `STATUS.CMD` (it's installed in the SREHTTP2\ADDON directory) is a simple addon that displays arguments passed to addons. It can be called using: /status?hello (the hello is optional).

#### How SREhttp/2 finds an addon program

SREhttp/2 will match the requested addon to a program (typically a REXX program). There are several places this program can be stored.

1. First, see if the addon has been pre-loaded into macrospace
2. If not, is there a selector-specific virtual directory defined for this request? If so, use it as the base directory (if the includes subdirectory information, the file will be in a subdirectory relative to this base directory).
3. Otherwise, use the host-specific addon directory as the base directory.
4. If (as is often the case), a host-specific addon directory was not defined for this host, use the default addon directory as the base directory.

### Arguments supplied by SREhttp/2

When calling an addon, SREhttp/2 will provide a set of arguments. You can retrieve them using:

    parse arg list,servername,verb,tempfile,,
              prog_file,reqnum,verbose,user,privset,,
              uri,host_nickname,id_info,aiter,attribs,seluse2

where ...

list | The list of arguments passed to the addon. If a `GET` request: this is the portion of the request following the `?`. If a `POST` request: this is the body of the request. If it's a GET request, URL-decoding will have been done on `list`. If, for some reason, you need the raw contents, you can use the `URI` argument.
servername | the domain name (or IP address) to whom this request was addressed.
verb | The request method. Either GET, POST, or HEAD.
tempfile | A name of a temporary file that the addon can use to build a response. The addon is not required to use this file, but it is a file name that is reserved for this request.
prog_file | The name of the file containing the addon. Actually, prog_file should be parsed using: `parse var prog_file prog_file ',' mproc` If the addon was pre-loaded into macrospace, then the `mproc` contains the name of this macrospace procedure. Otherwise, `mproc` will be blank.
reqnum | The request number. This has the form `nnCC`, where: `nn`: The transaction number `CC` : the request number within this transaction, indicated using letters: `A,B,..,I,AX,AA,..,AI,BX,..`. Note that browsers that can `maintain-connections` will often make multiple `request`s within a `transaction` -- hence the use of this request numbering scheme.
verbose | The value of the SREhttp2 VERBOSE variable.
client_ip | the client's IP address. Note: you can use SRE_CLIENTNAME to retrieve the client's IP name.
privset | the client privileges granted to this client. The `privset` should be parsed using: `parse var privset normal_privs ',' secret_privs` If the client matched an inhouseips, the `INHOUSE` privilege is added to privset. If the client has a username (and password) defined for this site, the `USER` privilege is added to privset. You might have to force a privileges lookup for these `inhouseips` and `username` check to occur.
uri | the request-string, without any url-decoding; and without any removal of `!SPECIAL` commands.
host_nickname | the HOST_NICKNAME (corresponding to the `servername`).
id_info | Special identifier information that can be used by several SRE2003 and SREHTTP2 procedures.
aiter | Usually blank. However, if `1`, then this is the second (or more) time this addon has been called during this request. Multiple calls can only occur if the addon had previously returned a PRIVS to SREhttp/2.
attribs | The selector-specific attributes. This can be parsed using:
      parse var attribs ,
        realm   '01'x   ,
        rule    '01'x   ,
        redirect '01'x  ,
        options '01'x    ,
        failure_file '01'x ,
        permissions  '01'x ,
        requires
seluse2 | The selector, after internal redirection.

### Returning a response from an SREhttp/2 addon

After using client-specific, etc. information to construct a response (such as an image file, or an HTML document) SREhttp/2 addons need to send this to the requesting client. This can be done either directly, or by telling SREhttp/2 to do it.

- Directly. SREhttp/2 can use the SRE2003 SRE_COMMAND procedure to directly return responses to the client. If you use SRE_COMMAND, you should then save the value returned by SRE_COMMAND, and return it to SREhttp/2 -- it contains useful response code and response length information.

  Example: |
      code that uses lineout to write HTML to TEMPFILE...
       rcode=sre_command('FILE  ERASE type text/html name 'tempfile)
       return rcode

- Let SREhttp/2 do it. You can either return a file containing the response, or you can a `string` containing the response, to SREhttp/2. SREhttp/2 will then send this response (either as a file, or as a string) to the client.

  This technique is often recommended -- since SREhttp/2 will then be able to apply its pre-reply procedures to the addon output.

  Syntax: | Returning a file: `return 'FILE [ERASE] [TYPE type/subtype] NAME filename'` where... `ERASE` is optional. If included, `filename` will be erased after the response has been sent. `TYPE type/subtype` is optional. If included, then `type/subtype` is the mimetype, and it will be used in the `Content-Type` response header. If not included, SREhttp/2 will use its normal rules for determining the mimetype of the file. `filename` must be a fully qualified filename. Returning a string: `return 'VAR [TYPE type/subtype] '||'0d0a'x||a_string` where... `TYPE type/subtype` is as defined above. If not included, then a mimetype of `application/octet-stream` is assumed. `a_string` is the contents to return. Note that it is immediately preceded by a CRLF (a `'0d0a'x`). `A_string` can be anything -- text, HTML text, an image, a word processing file, a database, whatever.

### Miscellaneous hints and notions

Forcing SREhttp/2 to lookup client privileges

  If there are no access controls on a resource, then unless explicitily instructed, SREhttp/2 will not bother looking up client privileges. However, addons may want to use client privileges (as provided by the `privset` parameter) to customize responses, or to provide a secondary level of access control.

  To induce SREhttp/2 to lookup client privileges, you can use one of these returns:

  - `PRIVS_CHECK priv_list , auth_message` (`auth_message` is optional)
    Check the client privileges contained in the (spaced delimited) `priv_list` -- look for INHOUSEIPS matches and (if necessary) username matches.
    - If the client did not provide a `Authorization:` request header, then send an authorization request.
    - If an invalid username is given, send an authorization request.
    - If a valid username is given, but her privileges do not match those in the `priv_list`, send an authorization request
  - `PRIVS auth_message` (`auth_message` is optional)
    Similar to `PRIVS_LOOK` -- SREhttp/2 will lookup privileges. However, if there is no `Authorization:` request header, SREhttp/2 will first send an authorization (401) response to the client, using the `auth_message` (if it was specified) in the body of this response.
  - `PRIVS_LOOK`
    Check client privileges-- look for INHOUSEIPS matches and (if possible) username matches. If the client did not provide a `Authorization:` request header, then username matches will not be attempted.
  - `AUTH auth_message` (`auth_message` is optional)
    This forces SREhttp/2 to immediately send an authorization response, even if the client already provided a `Authorization:` request header.

  Note: | In both the `AUTH` and `PRIVS` cases, if the client has no username/password defined, she can leave the username and password fields blank, and re-submit the request -- SREhttp/2 will not find any client privileges, and will set the `privset` to be empty.

  After determining the (possibly blank) client privileges, SREhttp/2 will then recall the addon. Note that other then the `privset` parameter (and the `aiter` parameter), all of the other parameters will be the same.

  The `aiter` parameter is also set on a re-call after a `PRIVS, PRIVS_CHECK,` or `PRIVS_LOOK` return. Specifically, when an addon is first called, `aiter` is blank. On subsequent calls (after one of these returns), `aiter` is set to `1` .

  > Addons should examine the value of `aiter` before issuing a `PRIVS, PRIVS_CHECK,` or `PRIVS_LOOK`. Failure to do so could cause an infinite loop!

  Note that if, after using `PRIVS`, a client does not have sufficient privileges, addons can:
  - use an `AUTH` return, or
  - use the SRE_AUTH_RESPONSE procedure to directly send an authorization response to the client; possibly one that tells them to try a new & different username & password.

  Hint: | Some sample code using `PRIVS` and `AUTH`:
        if wordpos('SUPERUSER',privset)=0 then do
          if aiter='' then return 'PRIVS This addon requires superuser privileges '
          return 'AUTH  This addon requires that you have superuser privileges ' /*force auth response */
        end

A note on decoding request strings
  SREhttp/2 provides the arguments to the addon in the `list` parameter. This is either the body of a POST request, or the stuff following a `?` of a GET request. In the former case (POST), the information is as is, with no conversions. In the latter case (GET), the information has been URL-decoded; with URL encoding (of & and other special characters) reversed.

  While this decoding does save a step, in many cases it can be a hindrance.

  In particular, if the request may contain special characters, such as +, = and &, it can be difficult to determine whether these characters were seperators added by the browser or important characters that are part of the response.

  If this is likely to occur; we recommend use of the `URI` argument.

  For example, the following can be used to parse the request information into a VARLIST stem variable:

         /* if GET, use original request string*/
         if VERB="GET" then  parse var uri . '?' list
         do until list=""
             parse var list a1 '&' list
             parse var a1 avar '=' aval
             avar='!'||translate(avar)
             aval=sre_packur(translate(aval,' ','+'))
             varlist.avar=aval
         end

  Note: | The URL-decoding performed by SREhttp/2 will not convert + characters to spaces -- you'll always have to do that yourself. This can be done with: `newlist=translate(list,' ','+')`. Caution: do this before you call SRE_PACKUR; else you'll end up converting legitimate + characters to spaces!

Encryption
  SREhttp/2 comes with several encryption facilities:
  - In addition to SREhttp/2's access control capabilities, you can require a "dynamic-password" based on shared-secret -- see DYNPWD.TXT for the details.
  - You can encrypt responses using a moderately strong (a 40bit) non-SSL encryption algorithim -- see ENCRYPT.HTM for the details
  - You can also use javascript to encrypt responses from a client

Multiple part documents
  Multiple part documents are used when performing server-push. Since this requires a fairly precise syntax, SREhttp/2 provides SREH2_MULTI_SEND, a procedure that facilitates the creation of these documents by taking care of these grubby details.

SRE2003 facilities
  In addition to the SREhttp/2 procedure library, SRE2003 comes with a number of useful tools, tools that can help you build your addons. You can find more info at ...
  - SRE2PRC.HTM contains detailed descriptions of SRE2003 functions.
  - SREH2CFG.HTM describes the SREhttp/2 configuration variables -- it also notes a few special system variables
  - SREAPI.TXT contains further details on working with SRE2003
  - SRE_DMN.TXT discusses how you to user SRE's functions that create and manipulate `daemons, flags, and queues`.
  - SRE_TASK.HTM discusses SRE2003's built in task manager.
  - SRE_DCSH.TXT discusses SRE2003's built in database facility.

### Addons bundled with SREhttp/2

In addition to the various configuration and status utilities; SREhttp/2 comes bundled with a small set of utilities. These include:

- _COMMAND Issue an OS/2 command to the server (with fairly tight access controls).
- _DIR a full-featured directory lister (with BBS-like features)
- GET_URL -- get a remote resource, using a URL, and copy contents to a local file
- MANAGER Remotely manage (copy/edit/delete) files on your server (with fairly tight access controls).
- MESSAGES -- support for discussion groups & forums using MESSAGE boxes
- PUT_FILE -- upload a file using HTML
- SENDFILE -- sends one or many files, and keeps track of successful completions
- TXT_FIND -- search text files for a matching string

These utilities are contained in several files in the SREHTTP2\ADDON directory (README.ADD contains a full list). Note that several of these of these utilties use parameters set in the SRE_UTILS.CFG (and other) configuration files located in the SREHTTP2\CFG directory. You can modify SRE_UTILS.CFG with the SREhttp/2 configurator.

### Addons not bundled with SREhttp/2

A number of additional addons are available for SREhttp/2 -- you can find several at srehttp2.srehttp.org.

These addons might have installation procedures that register the addon with SREhttp/2.

Would you like to list the addons currently registered with SREhttp/2

Last updated 26 Dec 2002.