
WebSite API 1.1 SDK
Server Function Descriptions
15-September-97
Index
Syntax
BOOL bind_wsapi(WORD major, WORD minor, BOOL strict);
- major
- The major version of your DLL, based on the header file which
was used to compile it.
- minor
- The minor version of your DLL, based on the header file which
was used to compile it.
- strict
- Version matching criteria. See the description section.
Returns TRUE or FALSE
to indicate that the versions are compatible.
Description
This routine performs run-time version locking between the extension
and the server. The header file used to compile extension contains
a #define that carries
the major and minor version numbers of the interface for which
the header file was written. The extension must call this function
at process-attach time, with its major and minor versions as arguments,
as shown above. If this function returns TRUE, the interface is
usable, else it returns FALSE. If the DLL gets a FALSE back from
this function, it must return FALSE from its DLLMain
function, refusing the load. The logic in the server will report
the load refusal to the logs and via a one-time MessageBox.
The ground rules are:
- strict = TRUE
- Major and minor versions must match
- strict = FALSE
- Fail if either the major versions do not match, or the minor
version of the extension is greater than that of the server.
Major version changes occur when the interface is changed so as
to be incompatible with previous versions (e.g., the TCTX structure
changes). Minor version changes occur when bugs are fixed and/or
new functionality is added in a way that is backward compatible.
The DLL cannot load if its minor version is greater than that
of the server because it may depend on such bug fixes or additional
functionality in the server for its proper operation.
Example
#include "wsapi.h"
...
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
return(bind_wsapi(MAJOR_VERSION, MINOR_VERSION, FALSE));
case DLL_PROCESS_DETACH: // No process-wise cleanup
case DLL_THREAD_ATTACH: // No thread-wise initialization
case DLL_THREAD_DETACH: // No thread-wise cleanup
return(TRUE);
}
}
Syntax
void close_form_decoder(FORM_CTX ctx, TCTX *tp);
- ctx
- The opaque decoding context handle returned by a previous call to
open_form_decoder()
.
- tp
- Transaction context pointer
Description
This function closes down the forms decoder instance created by a
previous call to
open_form_decoder()
.
Failing to call this for each successfull call to
open_forms_decoder()
will result in a memory leak.
Therefore, place the call to
close_form_decoder()
in the
__finally
block of a try/finally statement, with the
call to open_form_decoder()
in the
__try
portion.
Example
See the example in the description of
open_form_decoder()
and
the code in the formdump
sample provided with WebSite.
Syntax
void construct_url(char *dest, char
*src, TCTX *tp)
- dest
- buffer to receive the constructed "full" URL
- src
- buffer containing the URL path
- tp
- Transaction context pointer
Description
This function constructs a complete URL (including the scheme,
hostname, and port), given a URL path. The resultant URL has a
scheme of http:// or
https:// (if the connection
is using SSL). The hostname and port number depend on the identity
and port via which the current request arrived. If the port number
is 80 (or 443 for an SSL connection), the port component of the
URL is omitted.
Example
char dest[MED_STRING_LEN];
char *src = "/foo/bar.html";
...
construct_url(dest, src, tp);
The resulting complete URL might look like
http://www.me.com/foo/bar.html
Syntax
PFIELD decode_next_field(FORM_CTX ctx, TCTX *tp);
- ctx
- The opaque decoding context handle returned by a previous call to
open_form_decoder()
.
- tp
- Transaction context pointer
Returns a thread-safe pointer to a
FIELD structure:
typedef struct { // Field descriptor
char name[MED_STRING_LEN]; // Field name
BYTE *data; // -> field data
DWORD len; // Field data length
char ctype[MED_STRING_LEN]; // File content-type
char xftype[MED_STRING_LEN]; // File content-transfer-encoding
char fname[MED_STRING_LEN]; // Client's file name (file fields)
}FIELD, *PFIELD;
or NULL if there are no (more) fields to enumerate.
Description
Following a successful call to
open_form_decoder()
,
each call to this function retrieves the name, contents and optional
attributes of the "next" form field. This information is put into a
FIELD structure as shown above, and the function returns a
pointer to the structure. The structure is thread-safe; it remains
valid until the next call to decode_next_field() with the
given context handle.
Example
See the example in the description of
open_form_decoder()
and
the code in the formdump
sample provided with WebSite.
Syntax
void DbgDump (BYTE *buf, WORD len,
char *label)
- buf
- Buffer containing bytes to dump
- len
- Number of bytes to dump
- label
- Label for the dump listing
Description
Mainframe style buffer dump. Writes a hex/ascii dump of the buffer
to the server's log server.log.
Example
char buf[1024];
...
DbgDump(buf, 64, "Test dump
Dumps the first 64 bytes of buf.
The output to server.log
looks something like this:
10:10:46 Test dump [127.0.0.1] (64, 0x40)
-----|-------------------------------------|----------------
0000 48545450 2F312E30 20323030 204F4B0D HTTP/1.0 200 OK.
0010 0A446174 653A2054 75657364 61792C20 .Date: Tuesday,
0020 30352D53 65702D39 35203137 3A31303A 05-Sep-95 17:10:
0030 34362047 4D540D0A 53657276 65723A20 46 GMT..Server:
0040 57656253 69746553 65637572 652F312E WebSiteSecure/1.
Syntax
void die(int type, char *string,
TCTX *tp)
- type
- HTTP status code (see Description for legal values)
- string
- status-specific string (see Description for usage)
- tp
- transaction context pointer
Description
This function provides your extension with a "clean exit",
returning a properly formatted and worded HTTP status message
to the client. The function never returns; the thread is terminated
and cleaned up after returning the HTTP message. Use this only
in a generator, pre-processor or post-processor. Do not use
it in any other type of extension.
Die() can generate HTTP
responses for the most common HTTP/1.0 status codes, providing
the correctly worded reason phrases, and additional information
provided in the string
parameter. The status codes have corresponding symbolic definitions in
wsapi.h. You should use the symbolic code.
The following describes each of these status codes,
and the usage of the string
parameter. The symbolic status value is passed in the type
parameter. For details on the meaning of each of these responses,
see the
HTTP/1.0
Specification. If you need to return a response not supported by
die() you'll need to construct it yourself. Use
send_http_header() to start the
response.
- 204 (No Response)
- The body of the response will contain "<string>,
and there is nothing to return."
- 302 (Moved Temporarily)
- string is the target URL. The HTTP header will contain both
the (older) Location:
and the (preferred) URI:
forms of the redirection lines, each specifying the target URL.
The body of the message will contain "This
document has moved here", and the word here
will be a hyperlink to the target URL. Normally, the browser will
automatically fetch the target document, so the message body will
not be seen by the browser user. It is included for broken browsers.
- 304 (Not Modified)
- string is not used.
- 400 (Bad Request)
- The body of the message will contain "The
server could not handle your request. Reason: <string>".
- 401 (Unauthorized)
- This generates an HTTP/1.0 WWW-Authenticate:
header line, with string
as the data for that line. Normally string
should be something like Basic Realm="<whatever>".
This causes the browser to display the username/password dialog
with the realm as part of the prompt string.
- 403 (Forbidden)
- The body of the message will contain <string>
- 404 (Not Found)
- The body of the message will contain The
requested URL was not found on this server: <string>
- 500 (Server Error)
- The body of the message will contain The
server encountered an internal error or misconfiguration and was
unable to complete your request. Message: <string>...
(additional text follows this).
- 501 (Not Implemented)
- The body of the message will contain We
are sorry to be unable to perform the method <string> with
this URL... (additional text follows this).
Example
#include "wsapi.h"
die(REDIRECT, "http://other.web.site/foo.html", tp);
Syntax
void do_imagemap(int method, char
*map_name, char *coords, TCTX *tp)
- method
- The HTTP method to use (integer code, see wsapi.h)
- map_name
- The name of the imagemap (see description)
- coords
- coordinate string (see description)
- tp
- transaction context pointer
Description
Handle the current request as an imagemap. Handles traditional
imagemaps using GET and
an ISMAP image, as well
as alternative use of a form with <INPUT
TYPE=IMAGE>. Note: This supports only "nameless"
fields here. If there's a name on the IMAGE
field, it means in all likelihood it's part of a "real"
form that would have to be handled by an extension or CGI form
handler. Therefore, the form designer must not name imagemap
fields. With this in mind, the coordinates can be in two forms,
depending on the method in use:
GET (ISMAP): x,y
(on URL)
GET/POST (FORM): x=x&y=y
(on URL(GET), read from client(POST))
If the call specifies GET,
the coordinate string is assumed to be in the transaction context
block's args field. If
the call specifies post,
the function will read the coordinate string from the network
as "content".
The function will return only if the resulting target URL is local
(part of the local server's URL-space). If not, the function will
generate a redirect and complete the transaction without returning.
If the function does return, the server will have completed sending
the local document, so in general you can simply call the ABORT
macro to complete the transaction. This will log the request (including
calling the logger extension if any).
map_name can be either
a registry-resident imagemap or a file-based imagemap. The server
tells the difference by looking at map_name
and if there is no colon character present, it assumes that the
imagemap is registry-resident. Otherwise, it assumes that map_name
is a complete disk/directory/file pathname for the imagemap, which
must be an NCSA-format map file.
The easiest way to use do_imagemap
is shown in the example below.
Example
do_imagemap(M_GET, "d:\web-aux\maps\us.map",
"125,90", tp);
ABORT;
Syntax
void escape_url(char *buf)
- buf
- string that needs escaping according to the HTTP/1.0 rules.
Description
Escapes a string according to the conventions used in HTTP. The
escape operation is performed in place, therefore the result may
be longer than the original string. The buffer must be writeable.
Example
char buf[MED_STRING_LEN];
...
strcpy(buf, "/Name With Spaces/$$name.html");
escape_url(buf);
Returns with /Name%20with%20Spaces/%14%14name.html
in buf.
Syntax
void evaluate_access(char *url, TCTX
*tp)
- url
- string containing URL path of object
- tp
- Transaction context pointer
May not return (see description)
Description
Evaluate access control for the given URL. If access is allowed,
the tp->allow field
is set TRUE and the tp->allow_options
field is set with the access options bitmask. The bits in the
bitmask are defined in wsapi.h
and are:
OPTION SYMBOL DESCRIPTION
----------------------- ---------------------------------------------
SECOPT_SSL_ONLY Access permitted via SSL only
SECOPTS_OR_CLASS_USERS Access granted to user OR host address
SECOPTS_NO_BROWSE Disallow directory browsing
Normally, you won't be concerned about the options. They are used
by evaluate_access itself,
and internally by the server. They are provided for your information,
however.
If access fails for lack of user authentication this function
does not return. The server sends a 401
Not Authorized message to the browser, causing the
username/password dialog to appear. If the user enters a username
and password, the browser will reissue the same request again
with the new username and password.
If access fails because the client IP address or hostname is disallowed,
or access requires SSL and the connection is not SSL, or if the
URL specifies a directory and browsing is locked out, the function
returns with tp->allow
set to FALSE. In this
case, you are free to handle the issue any way you wish.
The function will fail via an exception if access control fails.
In general, you need to be concerned about this only if you have
allocated memory that needs to be freed or handles that need to
be closed. In this case, you should guard the call with a try/finally
or a try/except block as appropriate to your application. Do
not dismiss these exceptions under any circumstances. They
are used for proper completion of the transaction.
Example
evaluate_access("/docs/private/sales_3Q.html", tp);
Syntax
void exec_cgi(char *meth, char *file,
char *args, int intfc, TCTX *tp)
- meth
- Method (e.g., POST, PUT)
- file
- Full physical pathname of the executable or "associated"
document
- args
- URL arguments ("query string"), must not be NULL
- intfc
- CGI interface to use (e.g., SCRIPT_WIN,
see wsapi.h).
- tp
- transaction context pointer
May not return (see description)
Description
High level interface to the server's CGI handler. This function
will execute a CGI script or program using the selected method
and CGI interface, and send the results to the browser. The function
may not return, e.g., if the CGI program returns a Location:
or URI: header, or if
it fails access control. Errors will use the ABORT macro and will
not return either. If the function does return, the response
from the CGI program has been sent to the browser and the transaction
is finished.
WebSite has three CGI interfaces: Windows, DOS and Standard. This
function can be used to execute a CGI program using any one of
these interfaces. See wsapi.h
for the symbolic codes used to select the interface. The function
url_to_file() returns the document
type, which for a CGI type document, can be used to select the
CGI interface.
The function will fail via an exception if access control fails,
if the CGI returns Location:
or URI:, or (using the
ABORT macro) on a variety
of network I/O problems. In general, you need to be concerned
about these only if you have allocated memory that needs to be
freed or handles that need to be closed. In this case, you should
guard the call with a try/finally or a try/except block as appropriate
to your application. Do not dismiss these exceptions under
any circumstances. They are used for proper completion of
the transaction.
Example
exec_cgi ("GET",
"C:\\website\\cgi-win\\foo.exe",
"search=abcd&type=starts",
SCRIPT_WIN, tp);
Syntax
void exec_cgi_to_file(char *meth,
char *file, char *args, int intfc, TCTX *tp)
- meth
- Method (e.g., POST, PUT)
- file
- Full physical pathname of the executable or "associated"
document
- args
- URL arguments ("query string"), must not be NULL
- intfc
- CGI interface to use (e.g., SCRIPT_WIN,
see wsapi.h).
- tp
- transaction context pointer
May not return (see description)
Description
Identical to the exec_cgi() function,
except that the output of the CGI program is not sent to the client.
Rather, the function returns with the spooled output of the CGI
program open on a temporary file. The handle of the open file
is in tp->hOutFile.
It will include any HTTP headers generated by the CGI program
as well as any content. You must close this file when you are
finished with it, before you let the transaction complete.
Example
exec_cgi_to_file ("GET",
// Exec to a temp file
"C:\\website\\cgi-win\\foo.exe",
"search=abcd&type=starts",
SCRIPT_WIN, tp);
ReadFile(tp->hOutFile,
...); // Read CGI output
Syntax
void file_to_url(char *path, TCTX
*tp)
- path
- full file pathname (including drive spec)
- tp
- transaction context pointer
Description
File path to URL ("reverse") mapping. The opposite of
url_to_file(). Translates a physical
file pathname to a URL for the file. The conversion is done in
place, therefore the buffer containing the URL pathname must
be writeable. This translation depends on a unique relationship
between the physical pathname and the URL. Redundant mappings
can result in unpredictable results.
Example
char buf[MAX_STRING_LEN];
...
strcpy(buf, "c:\\website\\cgi-win\\test.exe");
file_to_url(buf);
The result will be something like /cgi-win/test.exe.
Syntax
char *get_content_type(char *file,
TCTX *tp)
- file
- filename of the file for which the content type is desired
- tp
- transaction context pointer
Returns HTTP/MIME content type in allocated string.
Description
Get the HTTP/MIME content type of the given file. This information
is taken from WebSte's registry-based content type mapping table,
which uses the file's "extension" as the key. If the
filename does not contain a period, the "default" content
type (usually application/octet-stream)
is returned. The function returns a pointer to the content type
string in allocated memory. Depending on how this is used,
you may need to free this space to avoid memory leaks.
Example
char *cp;
...
cp = get_content_type("abc.gif", tp);
Completes with allocated string containing (most likely) image/gif.
Syntax
BOOL get_server_variable(char *name, char *buf, DWORD size, TCB *tp)
- name
- the CGI-style name of the variable to get
- buf
- the buffer into which the value of the variable is placed
- size
- The length in bytes of buf. Overflow truncates the value string.
- tp
- transaction context pointer
Returns TRUE if the named variable exists (it still may be empty) and
FALSE if there is no such named variable.
Description
This function is provided for users who are upgrading from Microsoft
ISAPI or Standard CGI to WSAPI. It simply provides a way to access data
that is contained in the transaction context block
(TCTX) using CGI-style "environment variable" names. This is a
superset of the variables supported by ISAPI and most CGI interfaces.
Compatibility names have been provided as well.
get_server_variable() is less efficient than reading data
directly from the TCTX, so you should do the latter if at all practical.
Also note that the names used here are the "NCSA" style names, for maximum
compatility with ported applications. Name matching is caseless.
The following ISAPI/CGI-style named variables are supported by
get_server_variable():
Supported CGI-Style Variables
Variable Name |
Description |
Server Information |
DEBUG_MODE |
If WebSite's API/CGI tracing switch is on, this is "YES", otherwise it is "NO" |
DOCUMENT_ROOT |
The physical directory path corresponding to the URL "/" for the current request. May vary if multi-homing is in use. |
GATEWAY_INTERFACE |
The name and version of the gateway interface (e.g. "WSAPI/1.1") |
GMT_OFFSET |
Offset of local time from GMT, seconds, negative west of GMT (PST is -28800, 8 hours west) |
SERVER_ADMIN |
The email address of the server's administrator |
SERVER_NAME |
The server's current hostname (will vary if multi-homing is used) |
SERVER_PORT |
The TCP port on which the server received the current request (different ports are used for SSL and "normal"). |
SERVER_PROTOCOL |
The name and version of the server's protocol ("HTTP/1.0") |
SERVER_SOFTWARE |
The name and version of the server software (e.g. "WebSitePro/1.2") |
Client Info |
HTTP_ACCEPT |
List of media content types (and possibly Q-values) that the client will accept |
HTTP_ACCEPT_LANGUAGE |
List of languages that the client will accept |
HTTP_FROM |
Email address of the client user (not currently supported by browsers) |
HTTP_KEEP_ALIVE |
If the client supports keep-alive, this will be YES, otherwise it will be NO |
HTTP_USER_AGENT |
The name and version of the client (browser) software |
REMOTE_ADDR |
The IP address of the remote (client) host or proxy gateway. |
REMOTE_HOST |
The DNS hostname of the remote (client) host (only if DNS reverse lookup is enabled, else this is identical to REMOTE_ADDR) |
REMOTE_USER |
Identical to AUTH_USER. Provided for compatibility. |
Client Authentication |
(present only if client sends authentication data)
|
AUTH_NAME |
The realm from which user and group names are taken. WebSite supports multiple realms. |
AUTH_PASSWORD |
The password furnished with the authentication data |
AUTH_TYPE |
The authentication type. Currently always "BASIC" |
AUTH_USER |
The username furnished with the authentication data |
Request Info |
CONTENT_LENGTH |
Length in bytes of data sent with the request (e.g., form data) |
CONTENT_TYPE |
Media content type of data sent with the request (e.g. multipart/form-data) Includes parameters such as boundary strings. |
HTTP_REQUEST_RANGE |
Range spec(s) sent with request. See current HTTP byte-range spec for details. |
PATH_INFO |
"Extra" path information from the URL, also known as the "logical path" |
PATH_TRANSLATED |
The translation of PATH_INFO to a physical path, using the current mapping. May vary if multi-homing is in use. |
QUERY_STRING |
Data from the URL that follows the "?" in its raw original form |
QUERY_STRING_UNESCAPED |
Translation of QUERY_STRING from raw to final form (plus to space and URL unescaping) |
REQUEST_METHOD |
The HTTP method specified with the request (e.g., "GET", "POST") |
SCRIPT_NAME |
The URL path of the WSAPI extension, suitable for making self-referencing URLs |
HTTP Extra Headers |
Any header not assigned to one of the above variables may be accessed by it's header label, or as part of the ALL_HTTP list (provided for ISAPI compatibility) |
<extra-header-name> |
Returns the value of that header. For example "HTTP-Cookie" will get the cookie string sent with the request. Useful with SHTTP. |
ALL_HTTP |
All HTTP headers that are not assigned to one of the above variables. These variables are of the form HTTP_ for compatibility with ISAPI. The headers consist of a linefeed-separated list of <name>=<value> pairs. |
Example
char buf[MAX_STRING_LEN];
BOOL bExists;
...
bExists = get_server_variable("SERVER_SOFTWARE", buf, sizeof(buf)-1, tp);
Syntax
void get_temp_name(char *buf)
- buf
- buffer to receive the tempfile name (see below)
Description
Generate a unique name for temporary files. The form of the returned
string is xxxxxxws where
the xxxxxx is a hexadecimal
number, up to six digits, without leading zeroes. This name is
guaranteed to be unique among other such names generated by WebSite,
but not system-wide. Therefore, it is strongly suggested
that you create all temporary files in WebSite's CGI temporary
directory. The path to this directory is contained in tp->temp_name.
Example
char buf[16];
...
get_temp_name(buf);
Syntax
DWORD GetRegBin(char *name, HKEY
hKey)
- name
- name of 4-byte REG_BIN
or REG_DWORD value to
get
- hKey
- handle of key under which the value is located
Description
Get a 4-byte binary value from the registry. Works with either
4-byte REG_BIN or REG_DWORD
values. If the named value does not exist, or if it is not one
of these types, this function generates an exception via the ABORT
macro. You can trap these with a try/except block.
Example
DWORD foo;
HKEY hKey;
...
hKey = OpenRegKey("SOFTWARE\\Denny\\WebServer\\CurrentVersion");
foo = GetRegBin("LowTime", hKey);
RegCloseKey(hKey);
Syntax
Char *GetRegString(char *name, HKEY
hKey)
- name
- name of 4-byte REG_BIN
or REG_DWORD value to
get
- hKey
- handle of key under which the value is located
Returns a pointer to an allocated string
Description
Get a string value from the registry. If the named value does
not exist, or if it is not one of these types, this function generates
an exception via the ABORT
macro. You can trap these with a try/except block. The string
is created in allocated space. Depending on how the string
is going to be used, you may have to free this to avoid memory
leaks.
Example
char *foo;
HKEY hKey;
...
hKey = OpenRegKey("SOFTWARE\\Denny\\WebServer\\CurrentVersion");
foo = GetRegString("FilePath", hKey);
RegCloseKey(hKey);
...
free(foo); // Be careful!
Syntax
char *http_nt_timestr(LPSYSTEMTIME pst, char *buf, int len)
- pst
- Address of a SYSTEMTIME structure (GMT)
- buf
- Buffer into which the HTTP/1.0 date-time string is put
- len
- Length in bytes of buf
Returns buf
Description
Creates a date/time string, in the format required for HTTP headers,
from a Win32 SYSTEMTIME
structure. Do not use local time. This function assumes
that (as usual) the SYSTEMTIME
is in GMT. If the buffer is too small, the string is truncated.
Example
char buf[SML_STRING_LEN];
SYSTEMTIME st;
...
GetSystemTime(&st); // Not GetLocalTime()!!!
http_nt_timestr(&st, buf, sizeof(buf)); // Get HTTP-compliant
"now"
Syntax
#include <time.h>
...
char *http_timestr(time_t sec, char *buf, int len)
- sec
- C Runtime time value (e.g. from the time()
function)
- buf
- Buffer into which the HTTP/1.0 date-time string is put
- len
- Length in bytes of buf
Returns buf
Description
Creates a date/time string, in the format required for HTTP headers,
from Unix/C runtime time. If the buffer is too small, the string is truncated.
Example
#include <time.h>
char buf[SML_STRING_LEN];
...
http_timestr(time(NULL), buf, sizeof(buf)); // Get HTTP-compliant
"now"
O'Reilly Tech Support <support@ora.com>