Abstract | SRE2001 is an Internet server for OS/2. More precisely, SRE2001 provides a set of functions and capabilties that allow you to implement a web server through a "filter" program that is written in REXX. In addition to a fairly simple filter include with SRE20001, several filter programs are publically available, such as SREhttp/2 - or you can write your own. |
---|
SRE2001 is designed for small to intermediate sized sites. It's primary strengths are flexibiity and ease of customization. Speed, resource use, security, and scalability are not the primary goals. That said, these are operational concerns; and quite a bit can be done to enhance performance along any of these dimensions.
In many ways, SRE2001 is an outgrowth of GoServe, which was designed and created by Mike Cowlishaw In fact, it is the end of support for GoServe that motivated the creation of SRE2001. |
In comparison with GoServe, the primary advantage of SRE2001 is increased support for http/1.1 functions, including a greatly improved cache. Just as important, SRE2001 can be readily modified (it's written in REXX) -- we are always interested in suggestions and ideas! |
Are you are upgrading from GoServe/SRE-http? Then you'll find a number of hints and suggestions in UPGRADER.TXT! |
Of course, there is a disclaimer ..
Before choosing & using SRE2001, you must read the disclaimer (in appendix 1). Basically, SRE2001 is gnu style freeware; and is to be used at your own risk. We do try to create a fairly secure product, and we try to quickly fix any problems (or potential problems). However, we can NOT guarantee that SRE2001 has no security holes or is free from other potentials for failure.
To use a different port,all you need to change is the PORT parameter in SRE2001.CFG.
However, using seperate subdirectories avoids some resource clashes. Note that at this writing, there are some glitches that arise when multiple ports are supported on the same machine. Hence, it's safest to run only one instance of SRE2001 on a single machine (until we get some of these bugs ironed out).
Esc | Shutdown SRE2001 After hitting Esc, it may take a few seconds to shutdown. In some cases, hitting Ctrl-C may be faster. However, it's cleaner to shut down using ESC (various resources will be properly freed up). |
Alt-R | Refresh the screen. This is useful if error messages, or other unusual conditions (such as your filter using SAY) causes information to be written to the screen in an uncontrolled fashion. |
Alt-M | Modify parameters. This will let you modify the dynamically-modifiable parameters. You can suppress this option by setting the NO_MODIFY_ONTHEFLY option. |
Alt-S | Snipe (kill) connections. Use this to list, and selectively close, currently active connections. When in snipe mode, no more connections will be accepted (though currently open connections will continue to be active). |
SREWATCH will start SRE2001, and will the monitor its status. If SRE Watch detects that SRE2001 has crashed (or is otherwise hopelessly hung), it will attempt to kill, and then restart, SRE2001. In fact, you can even tell SRE Watch to reboot the machine when things get bad enough.
Since there are transient conditions that can crash SRE2001 (for example, there is a very rare bug in the MD5 procedure that will crash SRE2001), the use of SREWATCH is highly recommended for those running unattended servers.
For example: run SREWATCH.CMD from your STARTUP.CMD file, and enable the SRE Watch "reboot if necessary" option,To run SRE Watch, run the SREWATCH.CMD program (located in the SRE2001 working directory) instead of SRE2001.CMD. You might need to set a few parameters (in SREWATCH.CMD) before the first time you run it, but most people can use it as delivered.
SRE2001.CFG is located in the CFG subdirectory.
AUDITFILE | File containing audit and status information |
AUDIT_ITEMS | Specifies what is written to the AUDITFILE |
AUDIT_DELAY | Time span (in minutes) to wait before writing to audit file |
DAEMON_MANAGER | Name of a "daemon manager" program, or 0. |
DATADIR | The default "data" directory (your site's root directory) |
DEFAULT_SOCKET_TIMEOUT | Time to wait on a socket, in seconds |
ERRORFILE | Name of the error log file. |
FILTER | Name of the filter program |
FAST_FILTER | Name of "fast-filter" program |
INIT_PROC | File containing an initialization procedure, or 0 |
LIMITBODY | Maximum size of request body (in Kbytes) |
LIMITCLIENTS | Maximum simultaneous connections |
LIMITHEADER | Maximum size of request headers (in Kbytes) |
LIMITTIMETOTAL | Maximum time allowed per request (in seconds) |
LIMITTIMEWAIT | Maximum time to wait on a maintained connection |
LIMITTIMEINACTIVE | Maximum intra-request idle time (in seconds) |
MAXCOUNTERS | Maximum number of "counter" variables |
MAXCLIENTNAMES | Size (number of entries) in "client name" cache |
MAXSTATVALS | Size (number of entries) to use to compute statistics |
MAXMD5S | Size (number of entries) in MD5 cache |
NO_MODIFY_ONTHEFLY | Suppress on-the-fly modification of parameters |
PORT | Port the server is running on |
REQ_CACHE_CALL_ANYWAYS | Call the filter even if request cache is used |
REQ_CACHE_ENABLE | Enable the request cache |
REQ_CACHE_HITFILE | File containing record of cache hits |
REQ_CACHE_RECORD | Record cache hits to the cache_hitfile |
REQ_CACHE_SIZE | Size of "request cache" |
REQ_CACHE_VERIFY | Enable http/1.1 style verification prior to use of cache |
SERVER_SOFTWARE | Reported name of this server software |
SERVER_SOFTWARE_SHORT | Short reported name of this server software |
STATUS_ITEMS | Specify what to display on status screen |
STATUS_MESSAGE | Short message (displayed on side of status screen) |
TRACKING_ON | Enable SRE2001's "client tracking" facility |
UNALLOWED_FILE | File containing a list of "UnAllowed" IP addresses. |
USER_STATS | List of variables to set up as "statistics" variables |
AUDIT_ITEMS | DAEMON_MANAGER | DATADIR |
FILTER | LIMITCLIENTS | PORT |
REQ_CACHE_ENABLE | REQ_CACHE_RECORD | STATUS_ITEMS. |
DATADIR | LIMITBODY | LIMITCLIENTS |
LIMITHEADER | LIMITTIMETOTAL | LIMITTIMEWAIT |
LIMITTIMEINACTIVE | SERVER_SOFTWARE | SERVER_SOFTWARE_SHORT |
You can use fractional values. For example:
AUDIT_DELAY=0.25
means "write to audit file every 15 seconds"
Notes:
These options yields the following information.
C : 1A 00:25:07: 131.10.51.21 80 1 15.12.112.3 1104 where: C : -- this is the "client audit item" 1A -- transaction and request number 00:25:07 -- time of connection 31.10.51.21 -- ip address of server 80 -- port of server 15.12.112.3 -- ip address of client 1104 -- port of the client
D : 3A 00:33:50: REQFIELD = If-match If-Unmodified-Since If-None-Match D : 3A 00:33:50: FILE = CHUNK NOWAIT ERASE type text/plain NOCACHE Name G:\SRENEW\TEMP\_17111__.TGZ
D : 3A 00:33:50: Header = HEADER NOAUTO D : 3A 00:33:50: Header = Header Add Date: Sat, 25 Mar 2000 05:33:49 GMT D : 1A 00:25:06: ReqHdr = Referer:do_get@localhost D : 1A 00:25:06: ReqHdr = If-none-match: "dir.d","dir.doc"
For example, the SREhttp/2 filter uses daemons to provide user authorization information, selector specific attributes, auditing, and several other functions. These daemons are launched by the DMN2000 "daemon manager" program.
Examples:
DAEMON_MANAGER="DMN2000.RXX"
DAEMON_MANAGER=0 (no daemon manager)
Notes:
flag_go | a flag to use to signal "ready to continue" |
---|---|
flag_shutdown | a flag to use to signal "shutdown" |
pid | process id (of the SRE2001 process) |
maindir | the SRE2001 main ("working") directory |
port | the http port |
servername | the canonical name of this site |
Note that the filter does NOT have to use this directory!
Notes:
Notes:
Examples:
INIT_PROC= PSTART1.RXX
INIT_PROC=0 -- no initialization procedure
Notes:
Note that there are no size restrictions on a single request header -- so long as all request headers (including the request line) are less then LIMITHEADER kbytes.
Example: LIMITHEADER=10
Example: LIMITBODY=150
Notes:
Example: LIMITCLIENTS=15
Example: LIMITTIMETOTAL=160
Notes:
Example: LIMITTIMEWAIT=10
Notes:
Example: LIMITTIMEINACTIVE=20
Notes:
Thus, MAXCOUNTERS should be at least 10.
Examples: MAXCOUNTERS=30
Notes:
Example: MAXCLIENTNAMES=250
Notes:
Currently, SRE2001 maintains statistics on the following measures:
TOTAL_TIME,START_TRANSMIT_TIME, BYTES.
SRE2001 also retains the most recent values of CLIENTADDR (dotted numeric
address) and REQUEST (the request line).
In other words, MAXSTATVALS sets the number of "measures of the most recent responses" to retain.
Example: MAXSTATVALS=100
Notes:
Since computation of an MD5 is mildly CPU intensive (especially for long files), SRE2001 maintains an "MD5" cache. The MD5 cache is used for "permanent" files -- when SRE2001 is asked to compute an MD5 for such a file, SRE2001 can first check it's cache to see if such a value has already been computed.
Examples:
MAXMD5S= 200
MAXMD5S=0 -- do NOT maintain an MD5 cache.
Notes:
Examples:
NO_MODIFY_ONTHEFLY=1 suppress on the fly modification
NO_MODIFY_ONTHEFLY=0 allow on the fly modification
Notes:
Example: PORT=80
REQ_CACHE_ENABLE=nn | enable, with nn the time-to-live of each entry, in days. Thus, REQ_CACHE_ENABLE=1 means "enable the cache, each item has 24 hour lifespan" |
REQ_CACHE_ENABLE=0 | do NOT attempt to resolve requests from the request cache |
REQ_CACHECALL_ANYWAYS can take the following values:
REQ_CACHECALL_ANYWAYS 0 | Do not call the filter after use of the request cache |
REQ_CACHECALL_ANYWAYS * | Always call the filter |
REQ_CACHECALL_ANYWAYS 1 | Always call the filter (same as *) |
REQ_CACHECALL_ANYWAYS A_LIST | Call the filter if any of the "abbreviations" in the spaced delimited A_list matches the selector |
Notes:
Example: REQ_CACHE_HITFILE=LOG\CACHEHIT.LOG
As an alternative to "calling the filter anyways", SRE2001 can maintain a simple log of all requests for which a "request cache" response was used. This log file (specified in REQ_CACHE_HITFILE) contains a running sum, by selector, of the 200 and 30x (unmodified) responses).
REQ_CACHE_RECORD can take the following values:
0 | Do NOT use the cache-hit file |
mmm | Use the cache hit file, and save results very mmm minutes |
Notes:
Example: REQ_CACHE_SIZE=200
REQ_CACHE_VERIFY can take the following values:
0 | never verify (always use cache entry if it exists) |
1 | verify, check Pragma, Cache-Control, If-None-Match, and If-modified request headers. If these are active (i.e.; if Cache-control: no-cache is specified), then do NOT use the request cache. |
2 | verify, but ignore Pragma and Cache-Control:no-cache request headers (that is, just check etag and date) |
Example: SERVER_SOFTWARE = SRE2001 for OS/2, ver 1.04
Notes:
Example: SERVER_SOFTWARE_SHORT= SRE2001
Notes:
STATUS_ITEMS should be a space delimited list containing one or more of the following tokens:
ERRORS, CONNECTION, CLIENTS, CLOCK, LASTACCEPT, LIMITS, PEAK,
STATS, VERBOSE
where:
CLIENTS | report number of currently active connections |
CONNECTION | report each connection |
CLOCK | display current time |
ERRORS | report cumulative number of errors. |
LASTACCEPT | display time of most recent connection |
LIMITS | report cumulative number of timeouts |
PEAK | report peak number of connections |
STATS | report summary statistics |
VERBOSE | report various other items |
The tracking facility instructs SRE2001 to store "status" and other "tracking" information. You can the retrieve this tracking information, on a client specific basis, by using SRE_TRACKIT.
For more details on tracking, see Appendix 5.
If you do NOT need this capability, set UNALLOWED_FILE=0
Examples:
UNALLOWED_FILE=BadIPS.IN
UNALLOWED_FILE=0
The UNALLOWED_FILE should contain one IP address per line. Lines that start with a semi-colon are comments (and are ignored), as are blank lines.
IP addresses should be the dotted numeric address. Alternatively,
you can use * as a wildcard for an octet. That is,
125.22.*.1 matches 125.22.0.1 to 125.22.255.1
Examples of UNALLOWED_FILE entries
98.13.61.22 98.13.61.23 ;clients from 98.14.* are not granted access 98.14.*Note that you can add and remove entries from the UNALLOWED_FILE at any time -- SRE2001 will check the UNALLOWED_FILE about once a minute.
Before proceeding, consider this short introduction to how SRE2001 works. Abstracting from configuration and startup issues, and ignoring some fancy tricks one can use, the sequence of events leading to resolution of a request is:
In some sense, one can think of SRE2001 as providing an API, an API that a REXX "filter" uses to recieve http requests and send http responses.
Note: | "daemons" are independent threads. Actually, in order to avoid operating system overhead, daemons are "recycled", so that rather then ending, they go into a dormant state and await re-invocation. |
source | where, and to whom, the request is sent |
---|---|
request | the request line |
selector | the "selector" portion of the request line |
hostinfo | the host (and host-nickname) to whom the request is sent |
id_info | used to expedite processing of some SRE2001 functions |
request_number | the request number |
authorization_header | the value of a Authorization: request header |
is_alive | flag indicating whether the request is still alive |
In greater detail ...
servaddr | ip address of destination server (may vary if your server
is handling multiple ip addresses)
| port | port that recieved the request
| transaction | the transaction number
| who | numeric IP address of the client
| whoport | port used by the client
| |
From the above example, the selector is samples/foo.bar
host | either the ip name of your site, or the value of a HOST: request header. |
host_nickname | the "host-nickname" assigned to this host, or ' ' (if a host-nickname was not defined for this host) |
datadir | the "default data directory". If no host_nickname is available, this will be the value specified by the DATADIR parameter (in SRE2001.CFG). Otherwise, it's a host-specific data directory (which may be the same as the "default" data directory). |
The first example could be to a site for which no hosts have been defined.
Notes:
Note that the sequence of request numbers is: A,B,..,J,AA,AB,..,AJ,BA,...
Example: 4A
Example: Basic ZGFuOmRhbg==
If IS_ALIVE=1, the request has NOT been satisfied.
Otherwise, it has.
parse arg source,request,sel,MOREINFO,idInfo,reqnum,authh,isalive
The following lists the SRE2001 functions. Note that filters (such as SREhttp/2) may have their own set of functions -- in many cases these provide additional capabilities that addon/script creators may find useful.
CACHED | return whether the current request was satisfied from the cache |
COMPLETED | return whether current request has been completed |
DATADIR | return the default (or host specific) data directory |
CLIENTNAME | do a DNS lookup of an IP name |
EXTRACT | returns settings of several SRE2001 variables. |
REQFIELD | returns the value of a request header |
SRE_AUDIT | write lines to the AUDIT.LOG file |
SRE_COMMAND | recieve and send information to the client, etc. |
SRE_REQUEST_INFO | read "id" info for a request. |
SRE_TRACKIT | set and get client specific tracking info |
SRE_CACHE | manipulate "caches" |
SRE_QUEUE | manipulate "queues" |
SRE_QUEUE_STATS | compute statistics on values stored in a queue |
SRE_COUNTVARS | manipulate counter variables |
SRE_EVENTVARS | manipulate event variables |
SRE_HOSTINFO | read & set host information |
SRE_WRITE_ERROR | write a message to the error log and to the status screen |
SRE_WRITE_MESSAGE | write a message to the status screen |
SRE_SAY | write a message to the status screen |
SERVERNAME | return the servername |
Advanced Users Note The SREAPI.TXT file (in the DOC subdirectory) contains further details on working with SRE2001.
5c) The SRE2001 functions: full descriptions
- CACHED: return whether current request was resolved from the request cache
- CACHED will return a 1 if the current request was resolved using information from the request cache.
Otherwise, it returns a 0.Syntax: iscached=cached()- COMPLETED: return whether current request has been completed
- COMPLETED will return a 0 if the current request is still open.
Otherwise, it returns a 1.
Syntax:iscompleted=completed() iscompleted=completed(transaction_id)transaction_id is optional-- it is used if you want to lookup the completion status of the request running under a given transaction. If not specified, then the "current request" is checked.
- CLIENTNAME [ipaddress]) : Do a DNS lookup of an IP name
- Returns the ip name of the current client, or of the numeric ipaddress (if ipaddress is specified).
Syntax: cname=clientname() cname=clientname('151.22.51.76')SRE2001 uses a "IPname" cache to avoid unnecessary calls to a DNS -- the most recent several hundred IP name lookups (are retained) -- see the description of MAXCLIENTNAMES.
- DATADIR: return the default data directory
- DATADIR will return the default data directory. This may be a host specific directory. In fact, it may be dynamic to the request.
Syntax:sname=datadir() sname=datadir('host') sname=datadir('default')If 'host' is specified, then the default host-specifc data directory (as set in SRE2001.CFG, or as specified by a calls to SRE_HOSTINFO) is returned.If 'default' is specified, the default data directory is returned (as specified in SRE2001.CFG).
If no argument is given, then either:
- a request specific datadir (as may be set by a SRE_COMMAND)
- a host specific data directory
- the default data directory (with the request specific datadir returned if available, otherwise the host specific, otherwise the default)
Notes:
- SRE_COMMAND('SET DATADIR ',adir) can be used to set the "request- specific" value returned by datadir().
- EXTRACT: returns settings of several SRE2001 variables.
- EXTRACT is used to obtain values of the SRE2001 variables, several of which are request (or connection) specific. The syntax of EXTRACT closely follows the GoServe EXTRACT function, with several additional fields supported (and a few not supported).
Syntax:
avalue=EXTRACT(varname,id_info)
where:
Notes:
id_info optional -- the "id info" of the transaction/request you want information from. If not specified, use the current transaction/request. varname is one of the following variables. BYTESREAD the number of bytes received from the network, so far during the current transaction. BYTESREADTOTAL the total number of bytes received from the network. You may need to increase the Rexx NUMERIC DIGITS setting if you wish to do arithmetic on this count. 16 digits should be sufficient. BYTESSENT the number of bytes sent to the network, so far during the current transaction. BYTESSENTTOTAL the total number of bytes sent to the network. You may need to increase the Rexx NUMERIC DIGITS setting if you wish to do arithmetic on this count. 16 digits should be sufficient. CLIENTADDR the client's address used for the connection, in numeric form (for example, 12.34.56.78). For a symbolic name for the address, see the CLIENTNAME function. CLIENTMETHOD the method (verb) being invoked by the client. For example, "GET" or "POST". CLIENTPORT the client's port number used for the connection. CLIENTPROTOCOL the protocol being used by the client. For example, "HTTP/1.0". CLIENTS the number of clients currently connected. DATADIR The connection specific default data directory. You can also use the datadir() function to return this value. In addition, the filter will called with datadir as one of the entries in the hostinfo argument. DATADIR_DEFAULT The default value of datadir (as set in SRE2001.CFG). ELAPSED the elapsed time, in seconds, since the current transaction started (that is, when the network connection was accepted). ERRORS the count of errors detected. BROKEN the count of broken connections (connections closed by the client) FILTER the name of the Rexx filter. HOST_NICKNAME the "host nickname" assigned to this "host" If no host nicknames are assigned, returns a '' GMTOFFSET the GMT offset (in seconds). LASTADDRESS IP address (numeric) of the most recent client
LASTACCEPT timestamp of the last accepted connection [format: yyyy.mm.dd hh:mm:ss]. LASTIDLE timestamp of when SRE2001 last entered an idle state, with no connections [format: yyyy.mm.dd hh:mm:ss]. Note that this is only as accurate as the "update rate" (set in SRE2001.CMD). LASTSECOND time now, in the same format [yyyy.mm.dd hh:mm:ss] as the other LASTxxxx items. LASTSTART timestamp of when this instance of SRE2001 was started [format: yyyy.mm.dd hh:mm:ss]. LASTRESET timestamp of last RESET ALL "CONTROL" command [format: yyyy.mm.dd hh:mm:ss]. LIMITS the count of limits exceeded (that is, the count of transactions that were ended due to a limit being exceeded). The limits counted are the total connection timeout (LIMITTIMETOTAL), the incoming data measures (LIMITBODY and LIMITHEADER), and maximum clients exceeded (LIMITCLIENTS). The latter is only counted once for each non-idle burst of connections. LIMITBODY Connection specific maximum size of request body (as sent by a POST or PUT request), in kB LIMITBODY_DEFAULT Default value of LIMITBODY LIMITCLIENTS maximum number of client connections allowed concurrently [1 through 200 -- to increase max size, set the MAXCLIENTS value in SRE2001.CFG). LIMITHEADER Maximum size of headers (including the request line), in kB LIMITTIMEINACTIVE Connection specific maximum time, in seconds, for which SRE2001 will allow a client to remain connected but inactive (that is, without sending or reading data) [0 through LIMITTIMETOTAL]. LIMITTIMEINACTIVE_DEFAULT The default value of the above. LIMITTIMETOTAL Connection specific maximum time, in seconds, for which SRE2001 will allow a client to remain connected, even if active [LIMITTIMEINACTIVE through 1E+9]. LIMITTIMETOTAL_DEFAULT default value of the above LIMITTIMEWAIT Connection specific maximum time, in seconds, for which SRE2001 will keep a client connection open waiting for a new request. This applies for all http/1.1 requests, and for all http/1.0 requests that contain a 'Connection: keep-alive' header with the previous request [0 through 1E+9]. LIMITTIMEWAIT_DEFAULT default value of the above LISTEN_SOCKET the socket bound to the http port. This is the socket that SRE2001 SOCKLISTEN's to NUMSENDS number of VAR, FILE, CONTROL, STRING, and NODATA commands issued after a SEND command (0 if no SEND command was ever issued). Note that the initial SEND will set NUMSENDS=1. PEAKCLIENTS the maximum number of clients that were connected simultaneously. READWAITTIME average read wait time (seconds). READBODY_STATUS The status of a read of the request body. If not POST or PUT, then returns 'none'. Otherwise, returns 'pending','completed', or 'error'. REQUEST and
REQUEST_NUMERICthe unique number for this HTTP request. This is incremented as each HTTP request is read. This can differ from the TRANSACTION (connection) number if a connection fails to send a request, or if there is more than one request in a transaction. REQUEST is structured as TRANSACTION_NUMBER || REQUEST_AS_LETTER
REQUEST_NUMERIC is structured as TRANSACTION_NUMBER || REQUEST_AS_DIGITS
Thus, for transaction # 115, request 1 would yield:
REQUEST: 115A
REQUEST_NUMERIC: 1151
For transaction # 4312, request 3 would yield:
REQUEST: 4312C
REQUEST_NUMERIC: 43123REQUESTS the number of HTTP requests read since SRE2001 was started. REQUEST_ERROR most recent connection error (for this connection) or '', if no connection. RESPONSE_CODE the response code (i.e.; 200, 404, 301). If response not yet send, returns '000'. RESPONSETIME average response time (seconds). RESPONSEOVER number of connections over which RESPONSETIME and READWAITTIME have been averaged. SELECTOR the selector string: the Universal Resource Indicator, as recieved from the client (that is, the leading / is retained, and without url unpacking) SERVERADDR the server's address used for the connection, in numeric form (for example, 11.22.33.44). For a symbolic name for the address, see the SERVERNAME function. SERVERPORT the server's port number used for the connection (for example, 80 for default HTTP). SERVERPROTOCOL always returns "http/1.1" SERVERSOFTWARE the level of the server software (for example "SRE2001 ver 1.04"). This is the same as returned by the function calls SERVER() . TRANSACTION the unique number for this transaction (connection). This is incremented as each client connects to the server. Note that each transaction may yield several requests (though not concurrently). TRANSACTIONS the number of transactions since SRE-http was started.
- The following "GoServe EXTRACTABLE" variables are not supported.
- GMTSET -- GMT MUST be available
- FASTFILE -- Instead, see the REQ_CACHE* parameters in SRE2001.CFG
- FASTFILTER -- Instead, see the REQ_CACHE* parameters in SRE2001.CFG
- NETBUFFER -- May be supported later
- TRACE -- Instead, see the AUDIT_ITEMS parameter in SRE2001.CFG.
- There are a number of other variables (such as the various AUDIT and DIAG variables) for which no support is currently planned. However, the AUDIT_ITEMS parameter (in SRE2001.CFG) can be used to obtain much of this information.
- Also note that the GOSERVE QUERY command is NOT supported by SRE2001.
- REQFIELD: Read request headers
- Reads one (or several) request header(s).
Syntax:
avalue=reqfield(header_name,ith,id_info)where:
Actually, header_name can be a space delimited list of names.
header_name the name of a request header.
For example: "User-Agent", "Authorization", "If-Modified-Since", or "X-Option1"
Header_name is case insensitiveith Optional. Ith instance of this header_name. If not speciifed, all instances of header_name will be concatenated and returned. id_info Optional. Including the "id_info" (say, as supplied to the filter) will speed things up a bit.
For example:
oo=reqfield('TE ACCEPT-ENCODING')
Note that you can NOT combine "list of headernames" with "ith instance"When asking for several headers, each header will be seperated by a '01'x character. Thus, in the above example you could use:
parse var oo is_te '01'x accept_enc
to obtain the "TE" and the "ACCEPT-ENCODING" request headers.Note:
- If header_name='!ALL', then a list of all the request headers is returned
- SRE_AUDIT: Write "audit messages"
- Write a message to the audit file (or to the screen or pmprintf window)
Syntax:
foo=sre_audit(source_name,message,whereto,brief)
where:
source_name a short string identifying from where this message came message the message whereto where to write the message to brief Optional. If 1, then write a "briefer" message (don't write time and process identifiers). whereto should be a 3 character long string of 0's and 1's
For example: 101 means write to audit_file and to screen
- character 1: audit file
- character 2: pmprintf window
- character 3: status screen
Special values of whereto:
- ' ' = write to audit_file and to pmprintf (the default)
- '0' = write to audit_file only
- '1' = write to audit_file and to screen
- SRE_COMMAND: Recieve and send information to the client, etc.
- SRE_COMMAND is used to recieve and send information to the client and to set certain server variables.
SRE_COMMAND follows the syntax used in several of GoServe's "completion codes" -- many of the GoServe "completion codes" are implemented via calls to SRE_COMMAND (upgraders may want to refer to GOSERVE.DOC for alternative descriptions).
Syntax:
status=SRE_COMMAND('ACOMMAND option')where:
The following describes the ACOMMAND modes of SRE_COMMAND in greater detail.
- ACOMMAND can be one of:
- ALIVE AUDIT CONTROL FILE HEADER NODATA READ REPSONSE SEND SET VAR
- option is an option list that depends on ACOMMAND.
Note that several of these modes (FILE, VAR, CONTROl, NODATA, and STRING) are "completion commands" -- by default, performing the action entails finishing the request (and possibly closing the connection). This default may be modified if you've enabled "SEND" mode.
ALIVE Checks to see whether the socket (for this connection) is still alive. Syntax:
sre_command('ALIVE')Returns:
Note that if a client dies, or otherwise uncleanly breaks a connection, then a 0 may be returned. Thus, 0 indicates, but does not guarantee, that the client is waiting.
- -3 = SockSelect error
- -2 = Could not determine current connections socket
- -1 = Socket has been closed
- 0 = Socket is inactive
- > 0 = Bytes pending on socket
Notes:
- The STILL_ALIVE function can also be used to check connection status.
AUDIT Write information to the audit log file. Syntax:
vv=sre_command('AUDIT message')Will write the message to the SRE2001 audit log file. Example: foo=sre_command('AUDIT FOOBAR used on '||date('n')) Notes: * The SRE_AUDIT function can also be used to write to the audit log file.
CONTROL Compute statistics, and reset counters. Syntax:
vv=sre_command('CONTROL [NOWAIT] [VAR] option') The possible options are:
- RESET [BYTES] [REQUESTS] [RESPONSE] [TRANSACTIONS] [LIMITS] [ERRORS] [BROKEN] [ALL]
The specified SRE2001 counters and statistics are reset (after auditing, if appropriate). Any or all of the keywords may be given, in any order. RESPONSE refers to the response time record. If ALL is used, all of the items are reset, and the current time is noted as the "time of last reset" -- the last reset time is shown on the display window and in any statistics requests.
- STATISTICS
Current statistics and settings are returned. These include:
- Transaction, error, limits, byte, and client counts, with response time averages
- Certain settings and options (not including audit selections)
- The local time of certain events (if an event has not occurred, it is shown as the SRE2001 start time). Examples:
status=sre_command('CONTROL STATISTICS ')
val1=sre_command('CONTROL RESET LIMITS VAR') The result of a CONTROL command is a single string, which may include multiple lines, separated by Carriage Return-Line Feed (CR-LF, ASCII '0d0a'x) sequences. The result string is either placed in a variable or returned to the client:
The NOWAIT keyword may be used to force the current connection to be closed after any response is sent, even if a persistent connection had been requested.Upgraders note:
The following GoServe CONTROL options are not supported: MOVEAUDIT RESET PEAK SAYFILE Send a file to the client. This is similar to the GoServe FILE command, with a few new options (CHUNK, ETAG, QUICKPOST) and without the BINARY and TEXT options.
Syntax:
vv=sre_command('FILE [ERASE] [NOWAIT] [TYPE content-type] [CHUNK] [QUICKPOST] [ETAG etag] [NOCACHE] NAME filespec')The file named by filespec will be sent to the client. filespec should normally be a fully qualified name (if it is not, SRE2001 will look for it in the SRE2001 working directory).
The optional keywords may be specified, in any order, and have the following effects:
Examples:
- CHUNK -- send the file using a chunked format
- ERASE -- the file is a temporary file, and should be erased after being sent.
- ETAG eee -- eee is the etag associated with this response.
If used, an Etag: eee response header will be added.
For example:
Etag gxyq1
will cause a
Etag: "gxyq1"
response header to be added.- NOWAIT -- forces the current connection to be closed after any response is sent, even if a persistent connection had been requested.
- QUICKPOST --immediately return "anticipated status" information prior to responding to the client. This can speed up throughput, since the filter can exit (releasing memory) prior to completion of response. Though potentially wrong (say, if a client kills a connection) this "anticipated" information is often sufficient for logging purposes.
- TYPE xxx -- xxx is the "mimetype" of this resource. SRE2001 will include a Content-type response header that uses xxx.
For example:
type text/plain
will cause SRE2001 to add a
Content-type: text/plain
response header.- NOCACHE -- prevents this FILE URI from being added to the request cache. See Appendix 2 for more details.
Notes:
- stat=sre_command('file type text/html etag fae94 name d:\sre\index.htm')
- stat=sre_command('file erase type image/gif name d:\sre\temp\$7681.80')
- stat=sre_command('file chunk type application/octet-stream e:\arc\fo.zip')
- The FILE mode of SRE_COMMAND will always return two numbers, seperated by a space -- a status code and the bytes sent.
For example: 200 15161- The filespec may not include an 'upwards reference' sequence ("..\") as such a sequence could possibly allow clients access to any file on the server machine.
- SRE2001 will generate a header automatically if the TYPE option is specified. You can also use the HEADER option to specify a content-type.
- When using CHUNK, you should NOT include a content-length header, and you SHOULD specify a "transfer-encoding: chunked" header.
- CHUNK can also be used with SRE_COMMAND('VAR ...
- FILE is a "completion code"
HEADER Add or remove a response header. Syntax:
aa=sre_command('HEADER [ADD|DROP] [NOAUTO] [NOTIME] aheader')
where:Examples:
ADD
DROPEither ADD or DROP.
If ADD, then the header specified in aheader is added
If DROP, then the header specified in aheader is dropped (assuming it was specified by an earlier ADD).NOAUTO Optional. If specified, then the automatically generated headers (time, servername, etc.) will NOT be added. NOTIME Optional. If specified, then Last-Modified and/or Expires: headers will not be included aheader A response header, of the form:
header_name: header message
For example:
x-new-header: This is my new headerNotes:
- foo=sre_command('Header add X1: This is x1 ')
- foo=sre_command('Header add X2: This is X2 ')
- ...
- foo=sre_command('Header drop x2:')
- foo=sre_command('Header NoAuto Add Simple: this is the only header')
- NoAuto and NoTime can be included with ADD or DROP. But you should only use it once per response.
- HEADER DROP only examines the portion of aheader that precedes the first ":".
- You can specify multiple "aheaders" by concatenating several of them, with each aheader seperated by a '0d0a'x.
For example:
rh='Header Add H1: my name is Gus '
rh=rh||'0d0a'x||'Header Add S1: Her name is Sally'
- If you use two Header Adds with the same header_name, the second will be concatenated onto the first. To replace a header, first use Drop and then use Add.
- sre_command('Header ...') always returns a '1'.
NODATA command Send a null response.
Syntax:
vv=sre_command('NODATA [NOWAIT] [NORESPONSE]')No data are to be sent; the response is complete. This command is intended to be used when only a header, or nothing at all, is to be returned to the client.
If NORESPONSE is specified, then no response line and header will be sent either, even for an HTTP/1.0 or later request; the connection will be closed (unless persistent). This option could be used for testing, or if (say) a faulty client was sending repeat messages.
The NOWAIT keyword may be used to force the current connection to be closed after any response is sent, even if a persistent connection had been requested.
Notes:
- NODATA is a completion command
READ Read the request headers or the request body. Syntax:
status=sre_command('READ HEAD|BODY [ENABLE_CE_GZIP] [SUPPRESS_TE_GZIP]')where:
By default, ungzip is done for "GZIP as a transfer encoding", but not for GZIP as a content encoding.
READ is used to read the request headers, or the request body. The two options are only used with BODY: ENABLE_CE_GZIP enables UnGZIP of a request body that is gzipped, and that contains a Content-Encoding: GZIP header. SUPPRESS_TE_GZIP disables UnGZIP of a request body that is gzipped, and that contain a Transfer-Encoding: GZIP header.
Examples:
hdrs=sre_command('READ HEADER')
abody=sre_command('READ BODY ENABLE_CE_GZIP')
Notes:
In addition, A REQUEST_ERROR variable contains the "error status" of this connection. It can be checked with Extract('REQUEST_ERROR').
- when SUPPRESS_TE_GZIP is not specified, and an unknown transfer-encoding is encounted, a 501 Unimplemented response is automatically generated.
- when ENABLE_CE_GZIP is specified, and an unknown content-encoding is encountered, a 415 Unsupported Media Type response is automatically generated.
- when an error occurs, a '' is returned. You can check to see if this is a real error by using
EXTRACT('READBODY_STATUS')
which will return one of the following words ) words:
none if the request is not POST or PUT pending request body has not yet been read completed request body was successfully read error an error occurred when reading the body, and the connection was closed
REQUEST_ERROR will have a number of possible values, with a value of ' ' meaning "no error".RESPONSE RESPONSE is used to change the response line. Syntax:
aa=sre_command('RESPONSE response line ')
where
response_line is your desired response line.Example:
aa=sre_command('RESPONSE http/1.1 206 Partial Content') Notes:
- By default, SRE2001 sends a response line of: http/1.1 200 Ok
- sre_command('RESPONSE ...) always returns a '1'
SET SET is used to set "connection specific" values of several variables. Syntax:
status=sre_command('SET option',avalue)
where option is one of:
LIMITTIMEINACTIVE
LIMITTIMEWAIT
LIMITTIMETOTAL
LIMITBODY
DATADIR
and
avalue is the new "connection specific" valueExamples:
status=sre_command('SET DATADIR','e:\special\doc')
status=sre_command('SET LIMITTIMETOTAL ',1000)Notes:
- these do NOT effect the default values -- they only effect the current (possibly multiple request) transaction.
- EXTRACT can be used to read these "modified" values
- to permanently change these variables, you must change SRE2001.CFG (say, by running SRE2001 -m from an OS/2 prompt).
SEND SEND is used to build multipart messages, or to send pieces of a response as it is being built. Syntax:
The basic idea is that all "completion codes" (STRING, VAR, FILE, CONTROL, and NODATA) between a 'SEND ' and a 'SEND COMPLETE' will NOT mean "end of response".
Instead, the start of a response (the response line and response headers) is sent to the client when the first SEND is issued, and the response is completed when a 'SEND COMPLETE' is recieved.
Typically, the response headers (and perhaps the response line) are specified before the first call to SEND. However, you can specify the type/subtype (and perhaps a boundary string) in the SEND command by including a TYPE modifier.
Examples: SEND COMPLETE ends the request -- you can force the connection to be closed by including a NOWAIT option.
For example: * Note that within the boundaries of a SEND and a SEND COMPLETE:
- All header specifications are ignored (including TYPE), and NOWAIT is ignored. If you want to specify different types for each part of a multipart response, you can use VAR (you can also use VAR to include boundary lines).
- The status returned is either the number of bytes sent, or a negative error code.
- The ERASE modifier of a FILE command is ignored (temporary files will not be deleted).
Reminder SEND is not used to return responses to multiple requests on a single "maintained" connection. Instead, SEND can be used to return multiple "parts" within a single "multi-part aware" request. STRING STRING is used to send a short string to the client. Syntax:
vv=sre_command('STRING string',header)
The STRING command can be used to return a simple message to the client. Multiple lines can be sent, if necessary, by embedding a CR-LF sequence ('0d0a'x) to separate lines.
Example:
stat=sre_command('STRING Hello World!')Notes:
- STRING is a completion command
- The STRING mode of SRE_COMMAND will always return two numbers, seperated by a space -- a status code and the bytes sent.
For example: 200 15161VAR command Return the contents of a "variable" to the client. Syntax:
ff=sre_command(' VAR [NOWAIT][CHUNK][QUICKPOST] [TYPE content-type ', varname]
The contents of the Rexx variable named by varname will be sent to the client. varname is a standard REXX variable, as it would be written in the filter.
The optional keywords may be specified, in any order, and have the following effects:
Example (returning an HTML document to a Web client) :
- NOWAIT -- forces the current connection to be closed after any response is sent, even if a persistent connection had been requested.
- QUICKPOST --immediately return "anticipated status" information prior to responding to the client. This can speed up throughput, since the filter can exit (releasing memory) prior to completion of response. Though potentially wrong (say, if a client kills a connection) this "anticipated" information is often sufficient for logging purposes.
- CHUNK -- send the contents of the variable using a chunked format
- TYPE xxx -- xxx is the "mimetype" of this resource. SRE2001 will include a Content-type response header that uses xxx.
For example:
type text/plain
will cause SRE2001 to add a
Content-type: text/plain
response header./* This is Rexx code */ mydoc=' Hello world! ' /* may be large */ stat=sre_command('var type text/html ', mydoc) returnNotes:
- The VAR mode of SRE_COMMAND will always return two numbers, seperated by a space -- a status code and the bytes sent.
For example: 200 6236- SRE2001 will generate a header automatically if the TYPE option is specified. You can also use the HEADER option of SRE_COMMAND to specify a content-type.
- When using CHUNK, you should NOT include a content-length header, and you SHOULD specify a "transfer-encoding: chunked" header.
- VAR is a "completion code"
- SERVERNAME: return the servername
- SERVERNAME will return the servername. This may be a host specific servername.
Syntax:
sname=servername()
sname=servername('default')If 'default' is specified, then the "canonical" (default) servername for this computer is returned.
- SRE_CACHE: Write/read entries in a cache
- Caches are used to store semi-permanent variables. Each cache is allocated a fixed number of slots (one slot per variable), As you add variables, eventually all the slots will be taken. At that point, a LRU (least recently used algorithim) is used to remove the oldest variables, thereby freeing up slots for new variables (about 30% of the oldest variables are removed during this "pruning").
For example, SRE_CACHE is used to implement the MD5, Request, and IPNAME caches of SRE2001. Note that "queues" are also implemented in SRE2001 -- caches differ from queues in several ways: you can lookup specific entries, and an LRU algorithim is used to discard old values.
Syntax:
val=sre_cache(cache_name,action,varname,avalue,time_to_live,ownid)
whereThe supported "actions" are:
cache_name The name of a cache.
Examples of cache_names: MD5 IPNAME REQUESTaction What to do. Possible actions include: CREATE RESET WRITE ADD READ PRUNE REMOVE STATUS LIST varname variable name to store in the cache.
Case insensitive, and must NOT contain spaces.avalue value of this variable Time-to-live In fractions of a day, is the desired lifespan of the cache entry.
This can be used to remove cache entries, even if they are not necessarily the "least recently used". It can NOT be used to protect a "least recently used" entry.Ownid Optional, it's the "id" of the caller. Or, set to 0 to mean "don't bother responding" (typically used with action of WRITE or ADD) Examples:
CREATE create a cache
varname should be the length of the cache.
If varname is not specified, a default size of 500 is used. Returns: 1 on successRESET clear all items in acache.
If varname is specified, reset the size of the queue to varname.
Returns: 1 on successWRITE create, or change value of, varname; using avalue
Returns either 'OK 'value or 'ERROR 'error_messageADD create a numeric variable, or add avalue to existing numeric variable
Returns either 'OK 'value or 'ERROR 'error_message
Note that if you try to ADD to a non-numeric value, an error occurs.READ return the value of avar. If avar is not defined, return avalue (if avalue is not specified, return ' ').
Returns the valuePRUNE remove 30% of the cache, using a LRU algorithim
Returns 'Ok 'Num_left_in_cacheREMOVE remove the entry for varname. REMOVED entries are deleted when a PRUNE is issued (till then, they just occupy space, but are not read)
Return 'Ok removed' or 'Error no entry'STATUS returns 1 line of status info:
'Active_entries='nactive', Max_entries='cache_size', Last_reset='last_resetLIST xxx returns list of items in a cache. Syntax depends on the value of xxx: If xxx=' ' #entries_in_cache (crlf) varname','last_read_timestamp','expiration_time','#reads','value (crlf) ... IF xxx='VAL' #entries_in_cache (crlf) value (crlf) ... IF xxx='VAL' #entries_in_cache (crlf) varname (crlf) ... IF xxx='BOTH' varname','value (crlf) ... IF xxx='THREE' varname','#reads','value (crlf) ...Note: if you specify a varname, it will be used as a seperator. For example, using '09'x will use a TAB as a seperator (this is useful if you have multiple line values stored in the cache). There is one proviso: you can not use '01'x as a seperator.
- goo=sre_cache('REQUEST','WRITE','REQ1','foo/bar/hello',0.1,0)
- aval=SRE_CACHE('REQUEST','READ','VAR1',,,own_id)
- SRE_QUEUE: Write/read entries in a queue
- Queues are used to store semi-permanent variables. Each queue is allocated a fixed number of slots (one slot per variable), As you add variables, eventually all the slots will be taken. At that point, a LIFO (last in first out) algorithim is used to free up space -- with one value removed. Items on a queue are NOT referenced by variable name, though they can be read by position number (however, this position number will change as items are added to the queue).
For example, SRE_QUEUE is used to implement the various statistics reported on SRE2001's status screen.
Note that "caches" are also implemented in SRE2001 -- see SRE_CACHE for the details.
Syntax:
val=sre_queue(queue_name,action,avalue,ownid)
where:The supported actions are:
queue_name The name of a queue.
Examples of queue_name: BYTES TOTAL_TIME START_TRANSMIT_TIMEaction Possible actions: CREATE RESET PUSH QUEUE POP PEEK READ STATUS LIST avalue A value to store. If you intend to use SRE_QUEUE_STATS on this queue, these values must be numeric. ownid optional, it's the "id" of the caller. Or, set to 0 to mean "don't bother responding" (typically used with action of PUSH or QUEUE) Examples:
CREATE create a queue aval is the length of the queue. If aval is not specified, a default of 600 is used. Returns: 1 on success RESET clear all items in aqueue If avalue is specified, reset the size of the queue to avalue. Returns: 1 on success PUSH add aval to top of queue (will be first out on a pop) Returns either 'OK 'value or 'ERROR 'error_message QUEUE add aval to bottom of queue (will be last out on pops) Returns either 'OK 'value or 'ERROR 'error_message POP pop top value from queue (remove the value). If queue is empty, return '' or the value of aval. PEEK look at top value from queue (do not remove) If queue is empty, return '' or the value of aval. READ nnn look at the nnn'th value from queue; where 1 is the bottom value (the last value before queue is emptied) STATUS returns 1 line of status info:
'#_entries='nentries', Max_entries='queue_sizeLIST returns list of queues, using
#entries_in_queue (crlf)
value (crlf)
...
foo=sre_queue('REQUEST','QUEUE',request_line,0)
nextval=sre_queue('DELETEME','POP')
- SRE_QUEUE_STATS: Compute statistics on values stored in a queue
- SRE_QUEUE_STATS is used to compute simple statistics on values stored in a queue. Of course, this should only be used with queues that are known to contain ONLY numeric values!
Syntax:
val=sre_queue_stats(queue_name,action,nentries,ownid)
where:Examples:
queue_name name of queue. Examples include: BYTES TOTAL_TIME START_TRANSMIT_TIME If the queue_name doesn't exists, error action stat to compute. Currently supported: NUM MEAN MAX MIN SD SUM.
If nentries specified, NUM is <= NENTRIESnentries Number of entries to use. If not specified, then use all entries available in the queue. ownid optional.
foo=sre_queue_stats('TOTAL_TIME','MEAN',100,own_id)
- SRE_REQUEST_INFO
- Read "id" info for a request.
Syntax:
aval=sre_request_info(avar,tid,ownid)
where:
avar variable to lookup tid optional. The request identifier. If not specified, lookup info for the current request. Or, the tid can be the "id_info" (provided as the 5th argument to the filter) -- using this can speed up processing a bit. ownid optional. The caller's "own id". This can speed up some lookups a little bit. Supported variables include:
Note that these are "abbreviation matches". For example, CLIENTADDR is the same as CLIENT
CLIENT return client ip address of this request OWN return "own id" of this request TRAN return transaction id of this request NTH the transaction number (which will be the same for maintained-connection requests) SOCK socket of this request HOST host name SEL selector START starttime (date & second) PARENTID the thread id of this requests "parent" (a transaction daemon) Example:
Notes:
- If tid is not specified, look up info from the current request. This assumes that sre_request_info is called as part of "request processing", and NOT as part of a non-request related daemon.
Otherwise, it must be the thread-id of a currently-active request daemon (NOT the thread id of a transaction daemon).- You can specify multiple variables names (in a space delimited list) -- a comma (",") delimited list of values will be returned (in the order specified).
- SRE_SAY Write to lines 18 to 23 of the status scrren.
- Example:
call sre_say("this is my message to you, rudy. ")
- SRE_COUNTVARS: set and get "counter" variables
- This is used to set global counters variables (such as a running count of bytes sent). Several special counter variables are stored in the OS/2 environment for quick (though not totally up-to-date retrieval).
These "quicklist" variables are: BYTESREADTOTAL BYTESSENTTOTAL TRANSACTIONS REQUESTS LIMITS ERRORS CACHEHITSSyntax:
foo=sre_countvars(varname,avalue,ownid)where:
varname the counter variable. If you begin varname with a "=" (without the ") then "force" a read from the cache (rather then from the enviroment) -- this only applies to the quicklist variables. avalue the value to add If avalue is not specified, then return current value of varname
If avalue = RESET, then reset the counter to 0.ownid optional, the clients "own_id". This is used ONLY if you are reading the value of a non "quick list" counter. If not specified, an own_id will be generated automatically.
- SRE_HOSTINFO: read & set host information
- SRE_HOSTINFO is used to read the host-nickname and default data directory for a host name. Host names are typically domain names (such as foo.bar.net), but they can also be dotted IP addresses (such as 125.221.51.2), or "intranet" addresses (such mymachine).
To support multi-hosting (one server supporting multiple domains), SRE2001 uses the idea of a "host nickname". Every request is compared against the list of defined hosts. If a match is found, the host-nickname and the default data diretory are returned. The filter can then use this information to determine where to get a file from, where to store logging information, etc etc etc.
Although SRE2001 supplies the filter with this information (see section 5a), you can also use SRE_HOSTINFO to look it up. Furthermore, although you can use the INITHOST.RXX INIT_PROC (see INITHOST.RXX in the BIN subdirectory) to define Host entries, you can also use SRE_HOSTINFO.
SRE_HOSTINFO has two modes: read and set.
You can also get the list of currently defined host using hinfo_list=sre_hostinfo('!LIST') -- a space delimited list of hosts are returned (you can then lookup each host using calls to SRE_HOSTINFO)
- READ: To search for a matching, use
match=sre_hostinfo(a_host)
If a match is found, the following is returned:
a_host,host_nickname,default_datadir
- SET: To add a host entry to the list of hosts, use
astat=sre_hostinfo(a_host,host_nickname,default_datadir)
For example:
astat=sre_hostinfo("MYSITE.FOO.ORG","MYSITE_X",'E:\WEBS\ME")
ASTAT will be 1 if success, 0 if falure.
- SRE_EVENTVARS: set and get "event" variables
- This is used to store event variables.
Event variables are variables whose value changes frequently (such as the time the most recent connection was accepted). These are NOT necessarily numeric values (i.e.; it could be a timestamp, or a client a IP address).
As with Counter variables, a "quicklist" is maintained of events that are also stored in the environment.
These are: LASTACCEPT LASTIDLE LASTRESET LASTADDRESSSyntax:
foo=sre_eventvars(varname,avalue,ownid)
where:Notes:
varname the event variable. If you begin varname with a "=" (without the ") then "force" a read from the cache (rather then from the enviroment) -- this only applies to the quicklist variables. avalue the value to store If avalue is not specified, then return current value of varname ownid optional, the clients "own_id". This is used ONLY if you are reading the value of a non "quick list" event. If not specified, an own_id will be generated automatically.
- One could also use SRE_VALUE for event-like variables
- SRE_TRACKIT: set and get "tracking" variables
- Syntax:
aval=sre_trackit(varname,avalue,record_id,record_name,ownid)
whereNotes:
varname the "tracking" variable to set/get value the value. If '', then "get" value; otherwise set the value record_id the id of the record to read variables from. If not specified, use the current thread id. record_name optional. Record_name if included, will be compared to the "assigned name" for this "record" -- an error is returned if there is no match. ownid optional. You can include this "ownid" if READING tracking info from a request thread (i.e.; from a filter) Or, set to 0 to suppress reply (i.e.; on !CLEAR or a variable set) Examples:
- To set "record_name", use either:
- foo=sre_trackit('!NAME',assigned_id,record_name)
- foo=sre_trackit('!INIT',assigned_id,record_name)
- Special Varnames include:
- !INIT = initialize a record (possibly with a record_name)
- !CLEAR = clear all variables assigned to record
- * = list variables
- ** = list variables and their values (crlf delimited list)
- !NAME = set the "record_name" of this record
- Multiple variable names. You can set, or read multiple variables on a single call. To do this, use a space delimited list of varnames.
Thus, if you want to set multiple word (or multiple line) values, you can must do it one variable at a time. Similarly, you must read multiple line values one variable at a time.
Setting : if setting multiple variables, use a space delimited list of values. Thus, setting multiple variables can only be used with "1 word values" Reading when reading multiple variables, each value will be seperated by a crlf ('0d0a'x). Thus, you read have multiple word values, but not multiple line values. - Special record_id
- * = list all active record_ids (space delimited list)
- ** = list all record ids, and currently defined variables Each record & varnames-for-record are on a seperate (CRLF delimited) line. List of varnames are space delimited.
- *** = list all record ids, and currently defined variable and their values. Each record's variables/value pairs are in a block of lines, with each block seperated by a blank line.
Thus, the structure is
record_id
var1 = val1
var2 = val2
..
varn = valn
record_id
etc.
- foo=sre_trackit('READHEAD','END' ,mytid,mytid,0)
- foo=sre_trackit('VAR1 VAR2 ','125 MARS',25)
- aval=sre_trackit('VAR10',,,,ownid)
- SRE_WRITE_MESSAGE
- Write a message string (up to 2 lines, 70 characters per line) to the SRE2001 status screen message area).
Example:
call sre_write_message(' Hello cruel world? ')
- SRE_WRITE_ERROR
- Write an error message (up to 2 lines, 70 characters per line). This will be written to
Example:
- the SRE2001 status screen "error messages" area
- the PMPRINTF window
- the ERRORS.LOG file
call sre_write_error('Foo1: got a BAR error')
Appendix 1: Basic copyright and it's never our fault disclaimer
Copyright 2000,2001 by Daniel Hellerstein. Permission to use this program for any purpose is hereby granted without fee, provided that the author's name not be used in advertising or publicity pertaining to distribution of the software without specific written prior permision. Use of this product, or portions of this product, is subject to the following: 1) Portions of the code are adapted from other authors' work (these are noted where appropriate); you'll need to contact these other authors for appropriate permissions. 2) SRE-http uses several 3rd party dynamic libraries and executables: i) Quercus System's REXXLIB procedure library. The license for REXXLIB gives the author the right to distribute REXXLIB without charge. This right may NOT extend to redistributors (though as of April 2000 it appears that REXXLIB has been released to the public domain). Please contact Quercus Systems for details. 3) We, the authors of SRE2001 and any potentially affiliated institutions, disclaim any and all liability for damages due to the use, misuse, or failure of the product or subsets of the product. * In particular, SRE2001 and related product are NOT * * guaranteed to be secure. * We do design and code our product with careful attention to potential security holes, and and we try to quickly fix any problems (or potential problems) that may be discovered. However, SRE-http's fundamental design precept is "open-source", with security an important secondary consideration. If you REQUIRE a highly secure web-server, you should carefully review and test SRE2001. In other words, you may need to choose a different server. Furthermore you may also charge a reasonable re-distribution fee for SRE2001; with the understanding that this does not remove the work from the public domain and that the above provisos remain in effect. THIS SOFTWARE PACKAGE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE PACKAGE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR (Daniel Hellerstein) OR ANY PERSON OR INSTITUTION ASSOCIATED WITH THIS PRODUCT BE LIABLE FOR ANY SPECIAL,INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE PACKAGE. Lastly, if you would like to modify SRE2001, please contact the authors for the source code (Daniel Hellerstein, danielh@crosslink.net).
Appendix 2: The SRE2001 request cache
The SRE2001 "request cache" is used as a "proxy like" mechanism for quickly returning a response. It is used for static resources that are associated with non-temporary files on your hard drive. Basically, the request cache matches a URI to a file. If such a match exists (if a cache hit occurs), the SRE2001 will return the file to the client, without "calling the filter". By not calling the filter, hence avoiding request resolution overhead, responses can be sent substantially quicker -- 50% time savings are not uncommon. Entries are automatically created in the request cache when: 1. SRE2001 used a 'FILE' mode to respond to a prior request for this URI, 2. caching is not explicitily suppressed (on a selector specific basis), 3. the file is not temporary 4. and, of course, request caching is enabled. For more details on 'FILE' mode, see the description of the FILE option in SRE_COMMAND. Use of the request cache does have a few drawbacks : * The request cache requires memory resources * The request cache should not be used with dynamic resources * Auditing of responses resolved "from the request cache" may be incomplete. These concerns are addressed via the use of the several REQ_CACHE* variables. With these REQ_CACHE* parameters, you can .. * set the maximum size of the cache (a Least Recently Used algoritihim is used to remove old entries) * set the level of auditing -- either by calling the filter anyways, or by using a "cache hit log" * enable checking of request headers to determine whether or not the cache should be checked. Please see the description of these REQ_CACHE* parameters (in section 4) for the details.
Appendix 3: Running SRE2001 in loopback mode
The following description is taken from the GoServe documentation, with a few minor changes. SRE2001 and your favorite browser can be run on a stand-alone machine that is not connected to a network, provided that TCP/IP is installed and the loopback driver is started. This is especially useful for developing Web pages offline, or for demonstrations. To do this, two additions are needed to a standard TCP/IP installation. 1. To the file called 'HOSTS' (no extension) in your \TCPIP\ETC, or in \MPTN\ETC, directory add the line: 127.0.0.1 loopy where 'loopy' is the name by which you want your machine to be known when using the loopback connection. This name can be a single word (e.g., 'loopy'), or an internet-style name (e.g., 'loopy.my.org'). It's a good idea to have both formats, on two lines: 127.0.0.1 loopy.my.org 127.0.0.1 loopy Note: In general, check the value of the ETC environment variable to find out where the HOST file should be placed. If there is no \xxx\ETC\HOSTS file, create one. 2. Before running SRE2001, execute the command: ifconfig lo 127.0.0.1 This only needs to be run once, so can be run from STARTUP.CMD or from any command referenced in your Startup folder. Note that the second word is the lowercase of the two letters 'L' and 'O'. Once set up, you can then connect to SRE2001 on your own machine using (for example) the URL: http://loopy You can also carry out step 2 above by using the TCP/IP configuration notebook (say, by running TCPCFG or TCPCFG2 from a command prompt). On the 'Network' page, click on 'loopback interface', then check 'Enable interface' and 'Manually, using', then enter '127.0.0.1' as the 'IP address'. The loopback address will be active even when connected to a network, so you can always connect to SRE2001 running on the same machine using the loopback name that you chose, provided that your browser does not have a proxy or SOCKS server enabled (the proxy won't be able to find your local loopback address). Even if you are not connected to a network, your browser should not have a proxy or SOCKS server enabled (or it will try and use the network to find it before checking the HOSTS file).
Appendix 4: Using a fast filter
In many cases, one can divide a site's resources into "simple resources" (such as static images), and more complicated resources (such as dynamic documents, and access controlled documents). In general, simple resources can be handled by short (hence, faster) filter. Thus, throughput could be greatly improved if one could use a "simple and fast" filter for requests for these "simple" resources, and use a longer (and slower) filter for more complicated requests. The FAST_FILTER option allows you to do this. If you specify FAST_FILTER, then SRE2001 will: 1. first call the FAST_FILTER. 2. if the fast filter is able to handle the request, SRE2001 exits (or waits for the next request on a maintained connection) 3. otherwise, SRE2001 calls the "normal" filter This does involve a tradeoff -- slower response time for "complicated" requests (since the fast-filter has to be called first), but quicker response time for "simple" requests. Fast-filters are essentially the same as normal filters, they are sent the same arguments, and can access the same parameters and functions. There is one difference -- the fast-filter needs to inform SRE2001 as to whether it was successful or not. To do this, the fast filter should return either: 0 not successful -- the normal filter should be called 1 success. SRE2001 can close the connection, or wait for next request on a maintained connection An example of a fast-filter, FASTFILT.RXX, is included with SRE2001.
Appendix 5: Tracking client status
When enabled (with the TRACKING_ON parameter), SRE2001 will maintain information on the current status of each client. This information is can be read (or modified) by using the SRE_TRACKIT procedure. Note that a shared daemon is used to store this information. Therefore, it may not be completely up to date -- when reading parameters, the actual parameters are not read; rather, their values as of their most recent update is used. Many of the variables that are "tracked" are also available via SRE2001 "EXTRACT" procedure. However, EXTRACT is designed to be used to obtain values of a client (where a client is synonymous with a connection) "own" variables. Basically, SRE_TRACKIT makes it easy to find status information for other clients. Currently, the following client-specific parameters are set by SRE2001. BYTESSENT_REQ bytes sent for this request (possibly reset if multiple requests per connection) BYTESREAD_REQ bytes read for this request (possibly reset if multiple requests per connection) CLIENTADDR dotted numeric IP address of the client RECIEVE RECIEVE can take the following values 0 - not currently sending >0 - amount to be received READHEAD Read header data. READHEAD can take the following values: PENDING Waiting to read ACTIVE Currently reading header END Header has been read READBODY Read body data. READBODY can take the following values: 0 Not yet read START Currently reading body END Body has been read REQUEST the request (within a transaction, starting with 1) SELECTOR the full request selector (as recieved from the client) SEND Currently "sending" information to client. SEND can take the following values: 0 not currently sending >0 sending this many bytes timeout timeout occurred on most recent send broken client broke the connection error error when sending ok piece succesfully sent SENDPIECES # of pieces sent 0 -- send mode not activated START -- send mode activated END -- send mode completed number -- number of pieces sent STATUS Current action being undertaken. STATUS may take the following values: START ERROR_CONN_CLOSE ERROR_LIMIT WAITING ERROR_417 (expectation failed) ERROR_TIMEOUT ERROR_NO_HOST (Host: missing from http/1.1 query) REQ_CACHE_USED (request-cache used) PROCESS_xxx (xxx is one of the SRE_COMMAND options) SNIPE (ALT-s "sniping" is currently active) TRANSACTION the transaction In addition, you can set your own "connection specific" values by using SRE_TRACKIT.