The following lists the functions contain in the SRE2002 procedure library. Note that filters (such as SRELite2 or SREhttp/2) may have their own set of functions -- in many cases these provide additional capabilities that addon/script creators may find useful.
Some of the more important functions are: | SRE_AUDIT, SRE_AUTH_RESPONSE, SRE_COMMAND, SRE_DATADIR, SRE_ERROR_RESPONSE, SRE_REQFIELD, SRE_SERVER, SRE_SERVERNAME, SRE_WRITE_ERROR, and SRE_WRITE_MESSAGE. |
ADD_TH | add "st", "nd", "rd", or "th" to a number |
SRE_ADDCOMMA | Add commas to a number |
SRE_APPEND_FILE | append a string to the end of a file |
SRE_AUDIT | write lines to the AUDIT.LOG file |
SRE_AUTH_RESPONSE | return an authorization required response |
SRE_CACHE | manipulate "caches" |
SRE_CACHED | return whether the current request was satisfied from the cache |
SRE_CHECK_USERNAME | check username & password against authorization |
SRE_CHUNK | chunk encode a string |
SRE_COMPLETED | return whether current request has been completed |
SRE_CLIENTNAME | do a DNS lookup of an IP name |
SRE_CLIENTS | do a DNS lookup of an IP name |
SRE_COMMAND | recieve and send information to the client, etc. |
SRE_COUNTVARS | manipulate counter variables |
SRE_DATADIR | return the default (or host specific) data directory |
SRE_DATESTAMP | compute a time & date string |
SRE_ETAG | automatically generate an Etag |
SRE_EVENTVARS | manipulate event variables |
SRE_ERROR_RESPONSE | return a server error response |
SRE_EXTRACT | returns settings of several SRE2002 variables. |
SRE_EXTRACT_USERNAME | extract username from authorization header |
SRE_FIX_URL | construct a fully qualified URL |
SRE_GET_URL | get contents of URL |
SRE_GMT | compute a GMT time, incorporating an additional offset |
SRE_HOSTINFO | read & set host information |
SRE_LIST | manipulate "lists" |
SRE_LIST_STATS | compute statistics on values stored in a list |
SRE_MD5 | compute and MD5 of a file or string |
SRE_MOVE_RESPONSE | return a resource moved response |
SRE_PACK64 | unpack a "pack64" encoded string |
SRE_PACK64_MAKE | create a "pack64" encoded string |
SRE_PACKUR | unpack a URL-encoded string |
SRE_PAUSE | check & set PAUSE status of SRE2002 |
SRE_PMPRINTF | write a message to the PMPRINTF window |
SRE_REPLACESTRG | replaces occurences of a substring |
SRE_READ_FILE | read the contents of a file |
SRE_REPLACEWILD | compare strings & replace portions |
SRE_REQFIELD | returns the value of a request header |
SRE_REQUEST_INFO | read "id" info for a request. |
SRE_SAY | write a message to the bottom of the status screen |
SRE_SERVER | return descriptive name of the server software |
SRE_SERVERNAME | return the domain name of the server |
SRE_SHUTDOWN | shutdown SRE2002 |
SRE_TEMPFILE | return a filename for use as a temporary file |
SRE_TRACKIT | set and get client specific tracking info |
SRE_UNCHUNK | unchunk a chunk-encoded string |
SRE_VALUE | read & set SRE2002 variables |
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_WILD_MATCH | multiple wild card string comparisons |
Advanced Users Notes SREAPI.TXT contains further details on working with SRE2002. SRE_DMN.TXT discusses how you to user SRE's functions that create and manipulate daemons, flags, and queues.
Syntax:
asuffix=add_th(numeric_value)
Examples:
say 'This is the 21 '||add_th(21)||' birthday' app1=add_th(user_ct) ; say 'You are the 'user_ct||app1' visitor'
Examples:
newval=add_comma(1512563) which yields:newval = 1,512,563
Syntax:
astat=sre_append_file(filename,astring,ntries,addcrlf)
where:
filename | the file to append to |
astring | the arbitrarily long string to append |
ntries | Optional.
How many times to try and open the file (with a 1 second
delay between attempts). The default is 1 (just try once) |
addcrlf | Optional.
If 1, then astring will always be preceded by a crlf (a '0d0a'x):
|
astat will be:
|
|
Syntax:
astat=sre_audit(mess_hdr,message,whereto,brief)
where:
mess_name | a short string used to form a message header.
The message header helps identify the time and origin of the message. |
message | the message |
whereto | where to write the message to |
brief | Optional. If 1, then only use the mess_name
in the message header (suppress the time and process identifers). |
astat | SRE_AUDIT always returns a 1 |
whereto should be a 3 character long string of 0's and 1's
Special values of whereto:
Notes:
Examples:
foo=sre_audit('This is a simple message to the audit file') foo=sre_audit('PROC1','Starting loop in proc 1 ',0) foo=sre_audit('HELP',' generating new help files ','011',1)
Syntax: rcode=sre_auth_response(realm_name,servername,dodigest,message,id_info,sht_mess)where:
realm_name: | the realm name. This is displayed in the username/password request box displayed by the client's browser. |
servername: | optional. Used in the text of the response (not typically displayed) If not included, it will be looked up |
dodigest: | Possible values: |
message: | Optional. If specified, this should be a full html response (including
< / html > ... </html >) Otherwise the body of a response will be created. Note that this "body" is only displayed if the client cancels out of filling in the authorization box. |
id_info: | Optional the "id_info" |
sht_mess: | Optional If specified, and if message is NOT specified, then this should be a short description (it will be placed in a <blockquote>). |
Note that if the client is http/1.0, then digest authentication info is not sent (regardless of the value of dodigest).
For example, SRE_CACHE is used to implement the MD5, Request, and IPNAME caches of SRE2002. Note that "lists" and "queues" are also implemented in SRE2002 -- caches differ from lists and 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)
where
cache_name | The name of a cache. Examples of cache_names: MD5 IPNAME REQUEST |
action | 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) |
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 success |
RESET | clear all items in acache.
If varname is specified, reset the size of the cache to varname. Returns: 1 on success |
WRITE | create, or change value of, varname; using avalue Returns either 'OK 'value or 'ERROR 'error_message |
WRITE_CT
Same as WRITE, but also write (to an SRE environment variable)
the current number of variables currently defined in the
cache (after "writing" this variable). The SRE environment variable
name will be cache_name_CT.
For example: If you WRITE_CT a variable to the FOOBAR cache, you can
read the total number of variables in the FOOBAR cache using | |
ADD | 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 value |
PRUNE | remove 30% of the cache, using a LRU algorithim Returns 'Ok 'Num_left_in_cache |
REMOVE | 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' |
REMOVE_CT
Same as REMOVE, but also write (to an SRE environment variable)
the current number of variables currently defined in the
cache (after "removing" this variable). The SRE environment variable
name will be cache_name_CT.
For example: If you REMOVE_CT a variable to the FOOBAR cache, you can
read the total number of variables in the FOOBAR cache using | |
STATUS | returns 1 line of status info: 'Active_entries='nactive', Max_entries='cache_size', Last_reset='last_reset |
LIST 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='VAR' #entries_in_cache (crlf) varname (crlf) ... IF xxx='BOTH' #entries_in_cache (crlf) varname','value (crlf) ... IF xxx='THREE' #entries_in_cache (crlf) 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. |
Syntax: iscached=SRE_cached()
Syntax:
okay=sre_check_username(username,password,auth_header)
where:
username: | the username to check |
password: | the password of this username |
auth_header: | the value of the Authorization: request header. This can be obtained either by using the SRE_REQFIELD function, or by using the AUTHH argument sent to the filter. |
okay: | okay=1 if the username and password match what the client provided, Otherwise, okay=0 |
This function is particularly useful when the DIGEST method of authorization is used.
Example:
aa=SRE_reqfield('Authorization') username=sre_extract_username(aa) /* insert code lookup "username's" password in a database */ okay=sre_check_username(username,password,aa)Note that a password must be supplied (if it's not, a password of ' ' is used).
Syntax:
cstuff=sre_chunk(stuff,final,trailer)
where:
stuff: | the string (text or otherwise) to be chunked |
final: | if final=1, this is the last chunk (end with a terminator) |
trailer: | if final=1, the contents of trailer will be added as "trailers" to the chunked message |
Example:
aa=sre_chunk(a_string)
iscompleted=sre_completed() iscompleted=sre_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.
Syntax: cname=SRE_clientname() cname=SRE_clientname('151.22.51.76')SRE2002 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.
cname=SRE_clients()
Total number of active clients
| cname=SRE_clients('!CT_T')
| Total number of active clients. This uses an SRE environment
variable.
| cname=SRE_clients('!CT_R')
| Total number of active requests.
This uses an SRE environment variable.
| cname=SRE_clients('!LIST_TRAN')
| Returns a list of currently active transactions
|
| Notes: |
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',amessage,id_info)
where:
The following describes the ACOMMAND modes of SRE_COMMAND in greater detail.
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: Returns:
Notes:
| ||||||||||||||||||||||||||||||||
AUDIT |
Write information to the audit log file.
Syntax: Will write the message to the SRE2002 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: The possible options are:
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 SAY | ||||||||||||||||||||||||||||||||
FILE |
Send a file to the client.
This is similar to the GoServe FILE command, with several new options (such as CHUNK and ETAG) and without the BINARY option.
Syntax:
The remaining options (none of which are required) may be specified in any order. They have the following effects:
| ||||||||||||||||||||||||||||||||
HEADER |
Add or remove a response header.
Syntax:
| ||||||||||||||||||||||||||||||||
IMINFO |
Specify some information to be sent to an IM module. See IM_USE.HTM
for details on how IM modules can use this information.
Syntax: vv=sre_command('IMINFO [CLEAR| [PLACE] [READ] ',im_message) where one (or none) of the options may be used: Examples:foo=sre_command('IMINFO ','Strings=Section+1 - Section+2') bybbye=sre_command('IMINFO CLEAR') NODATA
|
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:
READ
|
Read the request headers or the request body.
|
Syntax: where:
Example: hdrs=sre_command('READ HEADER') Notes:
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:
Example: Notes:
SET
|
SET is used to set "connection specific" values of several variables.
|
Syntax:
Examples: Notes:
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 response. For example: The NOWAIT option can be used in either the first or final SEND. If used in the first SEND, then a Connection: Close response header is added, and the connection is closed (after a SEND COMPLETE). If NOWAIT is only used on the final send (i.e.; SEND NOWAIT COMPLETE) then the connection will be closed, but a Connection: Close response header will not be sent.
The EXPIRES option can be used to create an Expire: response header.
offset is when this file expires, as measured from
the current time. Notes:
STRING
|
STRING is used to send a short string to the client.
|
Syntax:
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: Notes:
VAR command
|
Return the contents of a "variable" to the client.
|
Syntax: 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:
/* This is Rexx code */ mydoc=' Hello world! ' /* may be large */ stat=sre_command('var type text/html ', mydoc) returnNotes:
|
There is an advanced form of sre_command that can be used with completion codes (such as VAR, FILE and STRING). | |||||||||||
Syntax:
|
Syntax:
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. |
sname=SRE_datadir() sname=SRE_datadir('host') sname=SRE_datadir('default')If 'host' is specified, then the default host-specifc data directory (as set in SRE2002.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 SRE2002.CFG).
If no argument is given, then either:
Notes:
Syntax:
adate=sre_datestamp(filedate,gmtoff)
where:
filedate: | a date in one of two formats: If not specified, use the current date and time |
gmtoff: | Optional, the offset from GMT time, in seconds. If not specified, SRE_DATESTAMP will lookit up (using the GMTOFFSET computed by SRE2002). |
Examples:
t1=sre_datestamp() edtoffset=14400 t2=sre_datestamp(,edtoffset) a=sysfiletree('C:\CONFIG.SYS','aa.') parse var aa.1 adate . t3=sre_datestamp(adate,edtoffset) which could yield: t1: Fri, 20 Jul 2001 12:30:10 GMT t2: Fri, 20 Jul 2001 16:30:10 GMT adate: 01/06/29/16/15 t3: Fri, 29 Jun 2001 20:15:00 GMTNote: See SRE_GMT for a more complicated version of SRE_DATESTAMP
Syntax: rcode=sre_error_response(type,amessage,servername,log_message,id_info)where all the variables are optional:
type | The type of the error. The currently supported types are: |
amessage | Optional. If specified, this should be a full html response (including <html> ... </html>) A response message will be automatically generated (depending on the Type and the Log_message). |
servername | optional. The DNS (or ip address) of this server. Looked up if not provided. |
log_message | Optional. If provided, and if amessage is not provided, then log_message will be added to the automatically generated message. Also, if type=500, then log_message is written to the SRE2002 error log file. |
id_info | Optional, the "id_info" |
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 LASTADDRESS
Syntax:
foo=sre_eventvars(varname,avalue,ownid)
where:
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. |
in_type | What type of input. |
||||||||||||
filename_or_var | The contents to compute an etag for. |
||||||||||||
use_crc | use_contents controls whether to use the actual contents, of
the file or message, when creating an etag.
|
||||||||||||
more_stuff | An arbitrary string. This is typically the values of a set of the entity-headers (since etags are formally defined as covering both entity body and entity headers). |
an_etag will be the value of the etag.
Notes:
Syntax:
avalue=SRE_EXTRACT(varname,id_info)
where:
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 SRE2002.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 SRE2002 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 SRE2002.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 SRE2002 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 SRE2002.CFG).
| LIMITHEADER | Maximum size of headers (including the request
line), in kB
| LIMITTIMEINACTIVE | Connection specific maximum time, in seconds, for which
SRE2002 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 SRE2002 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 SRE2002 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 SRE2002 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_NUMERIC the 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 REQUESTS | the number of HTTP requests read since SRE2002 was
started.
| REQUEST_ERROR | most recent connection error (for this connection)
or '', if no connection.
| REQUEST_LINE | the request line (for this request). | For example:GET /INDEX.HTM HTTP/1.0 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
"SRE2002 ver 1.10"). This is the same as returned by the function calls
SRE_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.
| |
Syntax:
username=sre_extract_username(auth_header)
where:
auth_header |
auth_header is the value of the Authorization: request header. This can be obtained either by using the SRE_REQFIELD function, or by using the AUTHH argument sent to the filter. |
SRE_EXTRACT_USERNAME will extract the "username" from either a BASIC of a DIGEST Authorization: request header. If the auth_header is empty, malformed, or otherwise does not contain username information, then a ' ' is returned.
Example:
aa=SRE_reqfield('Authorization') username=sre_extract_username(aa)
Syntax:
theurl=sre_fix_url(aurl,servername,serverport)
where:
aurl: | a relative or absolute url. |
servername: | optional. The ip name (domain name) or numeric ip address of the server. If not specified, use the local domain name. |
serverport: | optional. The serverport. If not specified, use the local port (if servername not specified), or use port 80. |
theurl will be a fully qualified url.
Examples (assuming SRE2002 is running on server with a domain name of foo.bar.net):
aa=sre_fix_url('/files/index.htm') aa ==> http://foo.bar.net/files/index.htm bb=sre_fix_url('/animals/images/tiger.jpg','www.funplaces.org') bb ==> http://www.funplaces.org/animals/images/tiger.jpg
Syntax:
stuff=sre_get_url(aurl,maxchars,verbose,headers)
where:
aurl: | a relative or absolute url. If it's a relative URL (no domain name), then use the local host and local port. |
maxchars: | Optional. Maximum # of characters to read. If not specified, then get up to 10 million |
verbose: | Optional. If 1, then pmprintf some status messages |
headers: | Optional. A CRLF delimited list of request headers to add to the request. |
Examples:
stuff=sre_get_url('family/doglife.html') stuff=sre_get_url('foo.bar.net/pictures/maple_tree.jpg') stuff=sre_get_url('http://foo.bar.net/pictures/apple_tree.jpg') stuff=sre_get_url('www.goo.org:8080/class8/lessons.shtml') stuff=sre_get_url('www.goo.org:8080/class8/lessons.shtml') stuff=sre_get_url('www.junkstuff.com/biglist.txt',,10000,'X-limit:10 pages')
Syntax:
newtime=sre_gmt(offset,basetime,outtype,gmtoffset)
where:
offset: | offest in days, hours, seconds, or minutes |
basetime: | in several formats |
outtype: | format of output |
gmtoffset: | Optional, the size of gmt offset (in seconds). If not provided, it will be looked up. |
Offset |
Add an offset to the "current time". Format can be:
If not specified (or '' is specified) then compute current GMT time (for supplied basetime) | ||||||||||
basetime: |
The time to add the offset to. The input format can be any of the following (SRE_GMT
will recognize the format)
| ||||||||||
Outtype |
The output format
| ||||||||||
GMT_OFFSET |
|
Examples:
say sre_gmt(,728882.88773) say sre_gmt(.12,'Sat, 12 Aug 1996 21:18:20 GMT','J') say sre_gmt('18000s','Saturday, 12-Aug-96 21:18:20 GMT') say sre_gmt('300m','Sat Aug 12 21:18:20 1996 ') say sre_gmt('5h','96/08/12/21/18','C',0) say sre_gmt('5h','03/08/12/21/18','C',0) say sre_gmt(,,'F',0) yields .... Tue, 13 Aug 1996 02:18:19 GMT 728883.216064 Tue, 13 Aug 1996 07:18:19 GMT Tue, 13 Aug 1996 07:18:19 GMT Tue, 13-Aug-1996 02:17:59 Wed, 13-Aug-2003 02:17:59 01/11/25/16/54Note: SRE_DATESTAMP is a simpler version of this procedure.
To support multi-hosting (one server supporting multiple domains), SRE2002 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 SRE2002 supplies the filter with this information (see section 5a of the main documentation), you can also use SRE_HOSTINFO to look it up. Furthermore, although you can use the INITHOST.RXX initialization procedure 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.
Syntax:
val=sre_list(list_name,action,avalue,ownid)
where:
list_name | The name of a list. Examples of list_name: BYTES TOTAL_TIME START_TRANSMIT_TIME |
action | Possible actions: CREATE RESET PUSH QUEUE POP PEEK READ STATUS LIST |
avalue | A value to store. If you intend to use SRE_LIST_STATS on this list, 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) |
CREATE | create a list aval is the length of the list. If aval is not specified, a default of 600 is used. Returns: 1 on success | ||||||||
RESET | clear all items in alist If avalue is specified, reset the size of the list to avalue. Returns: 1 on success | ||||||||
PUSH | add aval to top of list (will be first out on a pop) Returns either 'OK 'value or 'ERROR 'error_message | ||||||||
QUEUE | add aval to bottom of list (will be last out on pops) Returns either 'OK 'value or 'ERROR 'error_message | ||||||||
POP
pop top value from list (remove the value).
If list is empty, return '' or the value of aval. |
PEEK
| look at top value from list (do not remove)
If list is empty, return '' or the value of aval. |
READ nnn |
look at the nnn'th value from list; where 1 is the
bottom value (the last value before list is emptied) |
STATUS |
returns 1 line of status info: |
'#_entries='nentries', Max_entries='list_size LIST |
returns list of lists, using | #entries_in_list (crlf) value (crlf) ... |
Syntax:
val=sre_list_stats(list_name,action,nentries,ownid)
where:
list_name | name of list. Examples include: BYTES TOTAL_TIME START_TRANSMIT_TIME If the list_name doesn't exists, error |
action | stat to compute. Currently supported: NUM MEAN MAX MIN SD SUM. If nentries specified, NUM is <= NENTRIES |
nentries | Number of entries to use. If not specified, then use all entries available in the list. |
ownid | optional. |
Syntax:
md5val=sre_md5(var_or_file,file_flag,nocache)
where:
var_or_file: | either a variable containing the string you want the hash of, or a fully qualified file name |
file_flag: | If 1, then var_or_file is a file name. Otherwise, var_or_File is a variable. |
nocache: | if 1, then do NOT look in the SRE2002 "MD5 of files" cache. This can be used to force recomputation of the MD5 of a file. |
Examples:
amd5=sre_md5('hello world ') bmd5=sre_md5('D:\CONFIG.SYS',1)
This helps system stability: the MD5 procedures in SRXFUNC.DLL can sometimes CRASH THE PROCESS (i.e.; kill SRE2002), a phenomemnon that seems to happen when its functions are called simultaneously.Thus, use of SRE_MD5 (rather then the SRXFUNC functions directly), in conjunction with MD5 cache, will bolster system stability (as well as possibly improve speed).
Syntax: rcode =sre_move_response(movetype,selector,servername,port,age,sel0)where
movetype | Type of move. Can be 301 302 303 200 or 307 or, equivalently, MOVE TEMP REDIRECT NOTIFY or REPOST. |
selector | the selector (or fully qualified uri) to "move" to |
servername | (optional) If no ip address listed in the selector argument, "servername" is used |
port | (optional) If specified, redirect to this port (otherwise, redirect to the standard http port) |
age | (optional) Length of time proxy caches should store this response (in seconds) |
sel0 | (optional) The "original selector". It is used only with NOTIFY ( (it is written in the body of the response). |
and | |
rcode | the return code from SRE_COMMAND('VAR ..) |
Syntax: rcode=sre_notfound_response(type,message,servername,sel,id_info)where:
type | Either 403,404 or 410. Or, FORBIDDEN, NOTFOUND, or GONE 403 or FORBIDDEN = the server is refusing to honor this request (authorization will not help) 404 or NOTFOUND= The default. Resource can not be found 410 or GONE = The resource has been permanently removed. |
message | Optional. If specified, this should be a full html response (including
< / html > ... </html >) Otherwise the body of a response will be created (depending on type). |
servername | optional. Looked up if not provided |
sel | Optional. The requested resource (if not provided, it will be looked up) |
id_info | Optional. The "id_info" |
Syntax:
text_val=SRE_pack64(encoded_string)
Syntax:
encoded_string=sre_pack64(some_text)
Syntax:
uval=packur(pval)
Example:
pval='DOG+%26+CAT+%3D%3D+FUN%21+%0D%0A%24+%2F+TIME+%3D+%25+%3F+' uval=sre_packur(pval) and then uval will equal DOG+&+CAT+==+FUN!+$+/+TIME+=+%+?+ Note that + are NOT converted to spaces! You can use uval=sre_packur(translate(pval,' ','+')) to convert + to spaces (do + conversion first, otherwise you might transform true "+" characters into spaces).
Syntax:
pstate=sre_pause() -- pstate=1 if curently paused, 0 otherwise call sre_pause(0) -- unpause SRE2002 call sre_pause(1) -- pause SRE2002
SRE_PMPRINTF basically uses the PMPRINTF function, but it first checks for some possible bugs; for example, it won't try to write overly long lines.
Note: to view the PMPRINTF window, you can use the PMPRINTF program
Syntax:
call sre_pmprintf(message) or foo=sre_pmprintf(message,all)
message: | is the text message to write to the pmprintf window |
all: | optional. If message is > 110 characters, write on several 80 character lines |
Examples:
call sre_pmprintf('a message here') foo=sre_pmprintf(' this is a long message .... ',1)
Syntax:
stuff=sre_read_file(filename,wait_sec,stype)
where:
filename | file to read |
n_tries | Optional # of times to try to open file (if temporarily locked). If not specified, only 1 attempt is made to open the file. |
stype | Optional Effects what is returned. |
stuff | status code and contents of file, or an error response |
The structure of stuff is:
If file was successfully read |
file_contents Notes: Exceptions:
|
file could not be read | error_code error_message
The error_codes are always negative valued integers: |
Notes:
Examples:
parse value sre_read_file('fname.1',4) with ilen fdate fname2 '0d0a'x content if ilen<0 then signal error_read content=sre_read_file('fname.1',4,2) if content='' then signal error_read
Syntax:
avalue=SRE_reqfield(header_name,ith,id_info)
where:
header_name | the name of a request header. For example: "User-Agent", "Authorization", "If-Modified-Since", or "X-Option1" Header_name is case insensitive |
ith | 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. |
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:
Syntax:
aval=sre_request_info(avar,tid,id_info)
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. |
id_infod | optional. The "id_info" (that is provided to the filter). This can speed processing a bit. |
Supported variables include:
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:
Syntax:
newstring=sre_replacestring(astring,target,putme,type,exact)
where:
astring: | the string to change |
target: | the substring to replace |
putme: | the substring to use as a replacement |
type: |
Example:
newstring=sre_replacestrg('This is too big ','too','very') yields: 'This is very big ' newstring=sre_replacestrg('This is also small, also ','also') yields: 'This is small, also ' newstring=sre_replacestrg('This is also small, also ','also','ALL') yields: 'This is small, ' newstring=sre_replacestrg('Is Also small, also ','also','ALL',1) yields: 'Is Also small, '
This permits quite extensive transformations of the needle.
Syntax:
new_string=SRE_REPLACEWILD(needle,template,replacement)
where:
needle: | the string to search for. It should not contain any * (wildcard) characters |
template: | compare needle to this string. This string usually contains one or more * (wildcard) characters |
replacement: |
substitute apporpriate wildcarded
portions of needle into the corresponding wildcarded
portions of replacement If replacement is not specified, set replacement=template |
Examples:
needle = /proj1/mine/joe.htm template = /proj1/* replacement = /work2/project8/ver1/* would yield: /work2/project8/ver1/mine/joe.htm needle= /proj1/eek/mine/joe.htm template= /proj1/*/joe.htm replacement= /work2/project/*/joe.htm would yield: /work2/project/eek/mine/joe.htm
where which is optional, and should be one of:
In general, we recommend using SRE_WRITE_MESSAGE instead of SRE_SAY.
Example:
call sre_say("this is my message to you, rudy. ")
If 'default' is specified, then the "canonical" (default) servername for this computer is returned: either as determined from TCP/IP calls, or as set in the SERVERNAME_USE configuration parameter.
For what TCP/IP reports as the servername, check (using SRE_VALUE) the SRESYS variable SERVERNAME_CANONICAL
Syntax:
call sre_shutdown(1) -- tell SRE2002 to shutdown isdown=sre_shutdown() - returns 1 if "shutdown" has been signalled, 0 otherwiseOn SHUTDOWN, SRE2002 will stop accepting new connections, and will give current connections up to 90 seconds to finish.
Syntax:
tempfile_name=sre_tempfile(pid,tid,tempdir,del_opt)
where (all of the arguments are optional):
pid: | process id. If not specified, it will be looked up.
Actually, this can be any string that is unique to this process. |
tid: | thread id. If not specified, it will be looked up |
tempdir: | directory where temporary file will reside. If not specified, use the SRE2002 TEMP directory. |
delopt: |
Example:
tname=sre_tempfile() tname=sre_tempfile("PX"||dospid(),dostid())
Syntax:
aval=sre_trackit(varname,avalue,record_id,record_name,ownid)
where
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) |
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. |
Syntax:
stuff=sre_unchunk(cstuff,inct)
where:
cstuff: | a chunked message |
inct | if 1, add trailers (if any are found at the end of the message) at beginning of returned value (trailers blank_line entity). |
Syntax:
avalue=sre_value(varname,value,enviro,ownid,transaction_id)
where:
varname: | variable name to get or set | ||||||||||
value: | value to set. If empty, then lookup value | ||||||||||
enviro: | where to get value from. There are six environments: OS2, SRESYS, SRE, GLOBALS, SRELARGE, and REQ
| ||||||||||
ownid | Optional. The "own id", used for daemon communication. This is optional; if not provided, an "own id" will be created | ||||||||||
transaction_id: | only use if enviro=REQ.
If specified, then this is the daemon id of the transaction for which you want request specific info (note that transaction daemons launch request daemons in a sequential fashion; a transaction is responsible for one request at a time, but it may be responsible for several sequential requests over the same connection) If not specified, then use the transaction associated with the current request -- this REQUIRES that sre_value be called from a procedure running under a request daemon (that is, be called by the filter or a script launched by a filter, but not by a "support" daemon). |
Examples:
vv=sre_value('DPATH',,'OS2') vv2=sre_value('TEMP_DIR',,'SRESYS') vv3=sre_value('SMALL_VAR_1','this is a small var ','SRE') vv4=sre_value('FILE_X',charin('C:\CONFIG.SYS',1,1000),'SRELARGE') vv5=sre_value('REQ_Z','request is running ','REQ') vv4=sre_value('ADDON_2_V10',,'GLOBALS')
Note: OWNID and TRANSACTION_ID are ignored when reading or writing to the OS2, SRE, and SRESYS "environments".
Examples:
call sre_write_error('Foo1: got a BAR error')
call sre_write_error('This silly error message will also be pmprintfed',,1)
Syntax: foo=sre_write_message(messge_string,toaudit)
Where:
Examples:
call sre_write_message(' Hello cruel world? ')
call sre_write_message(' Not ready to quit ',1)
Syntax:
resu=SRE_WILD_MATCH(needle,haystack,oldresult,suppress_noslash)
where:
needle: | what to look for |
haystack: | what to compare it to. Haystack may contain numerous * wildcard characters |
oldresult: | prior return from sre_wild_match; or ' ' (if no prior match was made) |
suppress_noslash: | if 1, suppress the "no slash" special feature (see below) |
Basically, -1 means "exact match", 0 means "no match" or "not better match" (if oldresu not specified, 0 always means "no match"), and everything else means "better wild card match". bgcolor="%99ffee">
Example:
a.1='This is *' a.2='This is a *' a.3='This is a funny * story' a.4='* is * ' a.5='Th* fun*' a.6='This is funny *' say "Enter string : " parse pull ans oldresu=''; isit=0 do mm=1 to 6 resu=sre_wild_match(ans,a.mm,oldresu) if resu=-1 then do isit=mm leave end if resu=0 then iterate isit=mm oldresu=resu end if isit=0 then say " no match " else say " match= "a.isit
For example, using a needle of: animal/cats/food.1
The follwing haystacks yield:
animal/*candy -- no match anim*/*.1 -- match animal/*.1| -- no match (* covers cats/food, which contains a /) anim*/food*| -- match (final * covers ".1") */cats*| -- no match (final * covers "/food.1")