	 H i g h   P e r f o r m a n c e   S c r i p t   S e r v e r


     B r o w s e r   : W E B   S e r v e r :  A p p l i c a t i o n
                     :                     :    +-------------+
    +-------------+  :  +---------------+  :  +-------------+ |
    | WWW client  |==1==|  HTTP server  |  :  | FORTRAN     | |
    +-------------+  :  | client thread |  :  | application |-+
                     :  +- - -(2)- - - -+  :  +- - -(5)- - -+ |
                     :  | http_hpss_mst |==3==| hpss_share  | |
                     :  |service thread |==4==| shr. image  |-+
                     :  +- - - - - - - -+  :  +-------------+

Communication paths:

    1. HTTP connection (TCP/IP port 80) initiated by client for
       url /$hpss/hpss_srv_xxx/...

    2. Internal message-based communication path between thread
       servicing client connection and MST (Message-based Service Thread)
       thread.  The communication over this pathway uses the normal
       OSU server's script prototol (<DNETxxx> tags).

    3. Service request mailbox, written by MST and read by application.
       The user application creates this mailbox during its initialization
       and the MST assigns a channel to it the first time a web client
       references the HPSS application.  This is a directional mailbox, the 
       connection fails if no application is present with a channel assigned 
       to the mailbox.

       Each script invocation results in a single message being sent
       to the server request mailbox, the message contains:
	    Output mailbox unit number.
	    Input mailbox unit number (only if needed).
	    Invocation method (HTBIN, CONVERT, etc).
	    Request method (e.g. GET).
	    CGI variable symbol table.
	    Request content, (if room, if not input mailbox is supplied).

    4. Output mailbox, written by application and read by MST.
       This is a directional mailbox, allowing the application to
       detect if MST disconnects due to error or web client disconnect.
       Each MST thread creates a unique output mailbox that is only
       used for 1 script invocation.

    4a. Input mailbox. only created if needed to transfer MIME content
       included with the HTTP request.

    5. HPSS_SHARE API (application programmer interface), which hides the
       complexities of the I/O with the web server behind a simple
       set of HPSS_* functions (initialize, accept, read, write, disconnect,
       getenv, getform).

Programming model:

    The HPSS application runs continously in a dedicated process and
    has the following program structure:

        1. Initialize (call HPSS_INITIALIZE('mailbox_name',hndl) )

        2. Wait for next request (HPSS_ACCEPT(hndl,subfunc))

	3. Produce CGI (Common Gateway Interfae) response based on CGI 
	   variables, form input, or other request content. 
	   (HPSS_GETENV(hndl,name,value,vlen), HPSS_WRITE(hndl,buffer,carcon),
	   etc).

        4. Disconnect (HPSS_DISCONNECT) and return to step 2.

    Note that is model is not multi-threaded, the HPSS application only
    logically deals with one client request at a time.  Several aspects
    of the HPSS architecture should or can minimize the impact to
    the client:

       - The MST side (which is multi-threaded) reads any request content 
         prior to notifying the application, meaning the application never 
         has to wait on data from the client.

       - The output generated by the application (HPSS_WRITE) is
         written to the output mailbox asynchronously and buffered.
         The application can 'disconnect' and start processing the
         next request while the previous buffered output is still
         being drained back to the client.  The number of these output
         streams that may be active at one time is the lesser of the
         MST's threadpol limit or 1/2 the app. processes ASTLM quota.

       - The application can create several instances of itself running
         in separate processes.  The MST threads independantly write to
         the service request mailbox (and each has it's own output mailbox)
         so the multiple application instances will concurrently process the 
         requests.

Web server configuration:

   Since the web server side of HPSS is an MST, it is configured using the
   standard OSU configuration rules for MSTs, for example:

	service hpss pool=imap dynamic=(hpss,http_hpss_mst) info=hpss_srv_*
        exec /$hpss/* %hpss:
	suffix .hpss application/hpss
	presenation application/hpss %hpss:hpss_srv_preproc

Application configuration:

   The HPSS application designer is responsible for providing for the
   application process creation and other configuration.

Function descriptions:

   For all the functions, a STRING parameter is a character string
   passed by descriptor and an INTEGER parameter is a signed longword
   passed by reference.  All functions return a VMS-style status integer
   (low bit set for success).
         
   hpss_initialize ( STRING mbx_logical, INTEGER mbx_type, INTEGER context )

	This function initializes the hpss_share data structures and
	creates the service mailbox with the name specified by mbx_logical
        and in the table indicated by mbx_type.  The context variable is
        initialized with a handle to be used as an input argument to the
        other hpss_share library calls.

   hpss_accept (INTEGER context, INTEGER timeout, INTEGER pid, STRING subfunc)

	This function waits for up to timeout seconds for the next script 
	request to arrive from the web server or, if timeout is zero, wait 
        untimed for the next script request.  The pid argument receives
	the process ID of the requesting web server process (or one of its
        kernel threads).  The subfunc argument receives the internal script
	invocation code, indicating the method used to invoke the script:

	    HTBIN	Requested URL matched an exec rule (i.e. /$hpss/).
	    CONVERT	Requested URL's suffix (e.g. dave.hpss) mapped to a 
			presentation script.
	    SEARCH	The script was defined as the web servers search script.
	    POST	The script was named as the handler for an HTTP method
			(e.g. method put %hpss:hpss_srv_put).

	When a request arrives, hpss_accept initializes the CGI variable
	table and reads any accompanying request content into memory prior
	to returning.

    hpss_disconnect ( INTEGER context )

	This function indicates the application is done processing the
	script request from the last hpss_accept() call.  Any buffered output
	data is flushed the output stream is marked for rundown once the
	flush is complete.

    hpss_getenv ( INTEGER context, STRING name, STRING value, STRING length )

	This function looks up the CGI variable (e.g. PATH_INFO) specified by
	the name argument and if found copies its value into value argument,
	truncating it or padding with spaces.  The length argument receives 
	the number of bytes actually copied from the variable value.

	Note that name argument does not have a prefix (WWW_) and is
	case sensitive.  The special variable name %SYMBOL_LIST (note
	leading percent sign) will return a comma-separated list of the
	variables in the symbol table.

    hpss_getform (INTEGER context, STRING name, STRING value, STRING length)

	On the first call after an accept, this function builds a symbol
	table by parses the request content as form data.  It then looks up
	symbol specified by the name argument and if found copies its value
	into the value argument, truncating it or padding with spaces.
	The length argument receives the number of bytes actually copied
	from the symbol value.

	Unlike hpss_getform, the name argument is NOT case sensitive.  You
	cannot use this function and hpss_read on the same request.

    hpss_read ( INTEGER context, STRING buffer, INTEGER length )

	This function returns the next piece of the saved request content
	to the caller in the buffer supplied.  The length argument
	receives the number of data bytes copied.  The content data is
	stream-oriented and raw, the buffer will contain any embedded record
	delimiters or content encoding.  Caller should retrieve the
	value of the CONTENT_LENGTH variable to determine the total
	length needed to be read.

    hpss_write ( INTEGER context, STRING buffer, INTEGER flags )

	This function sends the data sepecified by the buffer argument
	to web server, the data stream produced is interpreted by the
	web server as a standard CGI response - header lines terminated
	by a null line followed by data.  The flags argument is a bit mask
	specifying arguments for the write:

	    Bit 0	If set, causes a CR LF sequence (i.e. record delimter)
			to be appended to the output following the buffer data.
			This flag makes it so you can send a header line
			as HPSS_WRITE ( ctx, 'Content-type: text/plain', 1 )
			without having to explicitly append the CR/LF.

	    Bit 1	If set, forces buffered data to be flushed immediately
			to the web server and hence to the web client.  You
			should only use this option if your application is
			doing server push type of operations.   Note that
			the flush will only queue the data to be written,
			it will not

Wrapper functions for 'C':

   Since string descriptors in C can be awkward to use, the hpss_share library
   also provides a set of wrapper functions to facilitate writing C-based
   HPSS applications.  In general, string descriptors (STRING arguments) are 
   replaced by null-terminated character strings if they are input parameters
   and a char pointer/in pair if they specify an output buffer.  Note that
   the context argument is always passed as an INTEGER (int *).  The prototypes
   for these functions are defined in hpss_share.h.

   The hpss_printf_c function is technically not a 'wrapper' since it
   provides functionality beyond passing it's arguments though to
   another function.

  int hpss_initialize_c ( 
	char *mbx_logical, 
	int mbx_type, 
	INTEGER context ); 		// returns handle

   int hpss_accept_c ( 
	INTEGER context, 
	int timeout, 
	INTEGER PID,			// returns process ID.
	char *function, 
	int func_size );

   int hpss_getenv_c ( 
	INTEGER context,
	char *name, 
	char *value, 
	int val_size,
	INTEGER ret_length );

    int hpss_getform_c ( 
	INTEGER context, 
	char *name, 
	char *value, 
	int val_size,
	INTEGER ret_length );

    int hpss_read_c ( 
	INTEGER context, 
	void *buffer, 
	int bufsize, 
	INTEGER ret_len);

    int hpss_write_c ( 
	INTEGER context, 
	void *buffer, 
	int bufsize, 
	int flags );

    int hpss_printf_c ( 
	INTEGER context, 
	const char *fmt, ... );
