QWEBS (A.01.10 - 01/18/1999)

Information on QWEBS, installation, and configuration can be accessed by selecting from the list of topics below.

Welcome to QWEBS

Welcome to the world of QWEBS! In order to help you setup and enjoy QWEBS we have prepared this html document. Please use it to as a reference guide for the use and setup of QWEBS.

QWEBS is being distributed through mail (dat tape) and web file-transfer. You will find information in this document referring to both installation methods. Please consult the installation notes that pertain to your copy of QWEBS.

QWEBS is an acronymn for the QSS Web Server, which is a web server for the HP 3000 MPE/iX operating system. QWEBS is unique in that it was written from scratch for the HP 3000 in COBOL and PASCAL. It is not a port from an existing 'c' based server and does not require the POSIX extensions of MPE/iX. It was written to be used as a web server for intranets where the HP 3000 is the host server system.

Copies of QWEBS downloaded from QSS have a built-in expiration date. You can determine the expiration date of your copy of QWEBS by this simple. procedure:

:HELLO MGR.QWEBS
:FILE QSDKOBJ=QWEBL.PROGRAM
:RUN QSDKLV.PROGRAM
The version and expiration date will be displayed on your terminal.

Copyright/Disclaimers

This document and QWEBS are Copyright © 1996-1999 Quintessential School Systems

We have attempted to do the best possible job in producing QWEBS. However, problems may arise with its use. We want you to know up front we assume no responsibility for any problems that arise from the use of QWEBS. Our responsibility is limited to making a best faith effort to fix reported problems with QWEBS.

Don't you hate statements like that? We sure do, but our lawyers really like them. These are the kind of disclaimers we like:

It is really cool you have decided to use QWEBS for your web server needs. You should know up front that we wrote QWEBS without really knowing much about HTML/HTTP and the standards they are based upon. We acquired some RFC documents, sampled various HTML/HTTP requests and finally came up with a web server that works (at least to us it seems to work!). You may know more about this than we do! If so, and you discover anything we should be doing differently (with respect to QWEBS...) please feel free to let us know. We are always open to suggestions and direction, especially from those with more knowledge than us.

Why QWEBS?

Since we unleashed QWEBS we have had the opportunity to mention to friends and colleagues that "we wrote a web server for the HP 3000". The number one response has been: why?. Before answering we quickly mention: and its written in COBOL. You cannot believe the number of weird/strange looks we get! In case you are tempted to call us and ask why, here are the reasons we wrote QWEBS:

QWEBS Support

QWEBS is brought to you by Quintessential School Systems (QSS). We can be found on the WWW at this URL: http://www.qss.com/. The server at this site is running on NT, but there are links to QWEBS. Use this URL: http://qwebs.qss.com/ to access a server running QWEBS so you can see how it operates. Our system is a HP 3000 937/LX (MPE 5.5) connected to the Internet using a 416K DSL connection.

There is a built-in debug mode which is activated whenever you use a URL that has /debug as the root directory. For example, the following URL will activate debug mode: http://www.qss.com/debug/testcmd.html

The /debug text is removed from the request before it is parsed.

Debug mode will display various variables and the status of QWEBS as it is processing the request. When using debug mode it is suggested you run QWEBS from a session instead of a batch job so you can see the results immediately. You may be asked to do this when we are attempting to diagnose a problem.

When sending bug reports please include your HP/desktop configuration and the specific problem you are having. Faxing us screen prints of relevant information is highly recommended. Also, don't forget to include your phone# (and the best time to call) in case we need to talk to you directly.

Please direct all inquiries for QWEBS support to:

Duane Percox
phone: (650)372-0200x608
e-mail: duane@qss.com
fax: (650)372-3386

Getting Started

It seems, based on the volume of books published, that setting up your own web site must be a huge undertaking! Well, to be honest its not as simple as installing some software and turning on the switch. Before attempting to setup QWEBS you should have some understanding of HTML and the web in general. Just cruising around the internet for awhile will give you the basic understanding you need. However, just to make sure, here is a list of the basics you should be familiar with before attempting to get QWEBS operational (this document isn't meant to describe these topics so you are on your own).

Also, you should be familiar with these HP 3000 related topics.

If you are new to the world of web serving then I would suggest you read this complete document. Otherwise you can pick and choose your topics based on your background and level of expertise.

QWEBS includes HTML documents, images (gif) and sample cgi forms for you to exercise and check out QWEBS without having to create any of your own content. Feel free to use the sample HTML as starting points for your own documents. Besides, we probably borrowed it from someone else on the web anyway!

Once you have installed QWEBS you can check out the samples by accessing QWEBS with this URL: http://www.company.com/home.html If you are having problems getting your environment to recognize your domain name you can try to use your HP 3000 IP address.

Create some of your own documents and voila! You are in the web serving business.

Running QWEBS

QWEBS is designed to run in a batch job, but it can be run from a session just as well. In fact, we usually run QWEBS from a session during testing and debug times. Use the job stream called QWEBS.JOB.QWEBS to run QWEBS in batch. To run QWEBS in a session, follow these simple steps.

:HELLO MGR.QWEBS
:FILE WEBCTL=WEBCTL.DATA;SHR;LOCK;NOMULTI
:RUN QWEBL.PROGRAM

QWEBS Feature Set

QWEBS is designed to be a full-response web server conforming to the HTTP/1.0 specifications. Here is a summary list of the features that are supported by QWEBS version A.01.10 which address the HTTP/1.0 specs.

QWEBS includes the following features which were added to provide additional functionality and better operation with MPE.

In addition, the system administrator is able to configure many of the operating charactistics of QWEBS. Items in italics can be configured but are not fully implemented in this version of QWEBS.

Designed (architected in QWEBS), but not released in this version are the following features which will be added in the near future.

HP 3000 System Requirements

Your HP 3000 must be a series 900 system, have a network interface card and the software required to access this card using the standard TCP/IP protocol. All newer HP 3000 systems come pre-configured with network cards and since 5.0 of MPE/iX the networking software has been bundled with FOS. If you can connect to your HP 3000 using VT services then you have the necessary hardware/software on your HP 3000 system.

In addition to the networking capability, you must have a version of MPE that supports Native Mode KSAM (KSAM/XL) files.

Client Requirements

You must have a HTML compatible client browser (Netscape, Mosaic for example) for viewing documents. To access the HP 3000 you must have a tcp/ip stack on your desktop system. If you are running Microsoft Windows you must have a winsock compatible tcp/ip stack.

QWEBS Store Tape

The QWEBS tape is written in NM Store format. It contains three files in PUB.SYS and the complete QWEBS account. The files from PUB.SYS are:

QWEBS Installation LZW File

The QWEBS LZW file is located on our web server and can be downloaded by pointing your browser to: http://www.qss.com/download.qwebs.html and choose the file option your prefer.

The QWEBS MPE Account

QWEBS comes pre-assigned to the account called QWEBS. However, there is no hardcoding in QWEBS which would preclude it from being run from another account. This is a listing of the files you will find in the QWEBS account once it has been successfully created.

QWEBS Technical Issues

QWEBS comes pre-packaged, ready to run. However, should you be curious, or need to relocate some or all of the QWEBS files this information should assist you. Also, it is possible to run multiple copies of QWEBS simultaneously (on different tcp ports of course) and this information will help you understand how that can be accomplished.

QWEBS Architecture

QWEBS operates as two programs. The first, a listener (QWEBL), is the program that listens for connection requests from the client browser. When a connection is made the listener passes the connection to a new instance of the second program which is the web server (QWEBS). There is a separate and unique process for each client browser connection. The server process terminates immediately after providing a full-response to the client browser. This is a block diagram of what this looks like:

     -----------
    | Listener  |-----------------------------
    |  (QWEBL)  |                            |
     -----------                             |
          |        ----------------          |
          |-------| Server (QWEBS) |-----\   |
          |        ----------------      |   |    ----------------------
          |        ----------------      |   --> | WEBCTL   (ksam/xl)   |
          |-------| Server (QWEBS) |-----|-----> |                      |
          |        ----------------      |       | read access          |
          |        ----------------      |        ----------------------
          |-------| Server (QWEBS) |-----/
                   ----------------

Web servers are state-less servers, which are created for the transaction and then shutdown after the transaction is complete. This diagram is an example of three (3) transactions active at the same time.

In the QWEBL/QWEBS implementation the server processes are created (but not activated) prior to any client connection. When a client connection is received the son process is activated and a new son process is created (not activated) for the next connection.

The ksam/xl file (WEBCTL) contains configuration parameters and all the mapping from HTML style URI strings to MPE file names.

The following is a brief narrative which describes how QWEBL/QWEBS handles the different type of document/script requests. This narrative assumes default behavior and configuration for QWEBS.

Assuming that there are no other users active, the state of the server is the listen process (QWEBL) waiting (listening) for a connection on port 80 and one server process (QWEBS) created (but not activated).

Installing QWEBS from the Store Tape

You should have a document called QWEBSRME.PUB.SYS which describes how to setup the QWEBS account from the store tape. You should locate that document and follow the instructions. If the printed copy cannot be located, you should check for it on your HP 3000 system. If you do not have it on your HP 3000 you can follow these simple instructions to restore the QWEBS files from your store tape.

Restore QWEBS files from tape for PUB.SYS

   :hello manager.sys
   :file t;dev=tape
   :file syslist=$stdlist
   :restore *t;@.pub.sys;show

You should get three files restored. Click here to read about the files that are restored. Print out QWEBSRME.PUB.SYS which contains the QWEBS account installation notes.

Installing QWEBS from the lzw file

The lzw file is named qwebskit.qwebs.zip on our web server. You should download it to your PC, unzip it and then upload it to your HP 3000 using WRQ labels as QWEBSLZW.PUB.SYS. Use LZW to extract the file QWEBSINS.PUB.SYS which contains instructions on installing QWEBS from the lzw package.

Setting Up QWEBS

You must update WEBCTL with configuration options prior to starting QWEBS for the first time. Follow these steps to make sure QWEBS is setup properly prior to using it for the first time. All maintenance of WEBCTL is performed using the program called QWCMNT.PROGRAM.QWEBS.

A job stream named UPWEBCTL.JOB.QWEBS has been provided which contains the jcl to add each of the files referenced above to WEBCTL.DATA.QWEBS. Edit this job stream to add the file(s) you wish to add and then stream the job.

Using QWCMNT to Configure QWEBS

QWEBS uses the file WEBCTL to contain all the configuration parameters. The program QWCMNT is used to maintain WEBCTL. The standard QWEBS installation creates WEBCTL.DATA.QWEBS and QWCMNT.PROGRAM.QWEBS. These notes assume a default installation of QWEBS.

To maintain WEBCTL, you should login to the QWEBS account using the MGR user and issue this file equation: FILE WEBCTL=WEBCTL.DATA;SHR;LOCK;NOMULTI. Run QWCMNT like this: RUN QWCMNT.PROGRAM. QWCMNT will prompt you with a '$'. You may enter a valid command or an MPE command prefixed by the ':' character. Valid commands are:

add     - add a new entry
change  - change an existing entry
delete  - delete an existing entry
inspect - inspect an existing entry
mode    - change modes
show    - show the current mode
exit    - exit the program

Any command can be abbreviated to the first 3 characters. The commands are not case sensitive. No command has any parameters except 'mode' which can take an optional mode name in this format: mode mode-name. For example: mode list

WEBCTL is a ksam/xl file which contains many different types of records, all designed to define the operating environment for QWEBS. QWCMNT is a simplistic program designed more for the programmer than for the user (sorry about that folks!). There are 15 different record types that can be maintained. Each record has been assigned a unique 2 digit id (record type) and has been equated to a mode. You maintain a particular record type by setting the mode within QWCMNT. The modes, and therefore the record types, are:

Mode     Type    Description
------   ----    -----------
ctl      00      Basic control settings for QWEBS
root     01      HFS document root directory
name     02      WWW server formal name
list     03      Control settings for QWEBL
ver      04      Server id and gateway version
ref      10      Reference maps for URI-->MPE names
mime     20      Mime content-type extension maps
sec      30      IP security (connection and URI)
dir      31      Directory security settings
user     40      User definition
realm    41      Realm definition
udn      42     *User data name table
udp      43     *User data parse rules
err      50      HTTP err document location
icon     60     *Directory icon location
icont    61     *Directory icon text descriptions

* This information can be maintained but is not used by QWEBS in version A.01.10.

There is little or no logical consistency checking and editing is limited to the data field being entered at the time. Some record types have keys which are 'hardcoded' because there can only be one record on file. These record types will not prompt you for the key value. When you add/change/delete/inspect you operate on the record immediately. This can be deceiving and cause an accidental delete of the entry since there is no delete confirmation.

When you are using 'add' or 'change' and need to abort the process you can use 'cr' and the command will be cancelled. When you are using 'change' you can keep the previous value of a field by entering '\' as the value if the value is not numeric.

All values you enter must be followed by a 'cr' and the maximum size of text fields is displayed in the prompt in parenthesis.

What follows are the fields you can enter for all the modes (record types) which are currently used by QWEBS. A brief synopsis of the use of the record type is included for your reference.

Fields or field values flagged with a '*' are not implemented by QWEBS version A.01.00



  Mode: ctl (00)

   Use: This record contains settings that control the basic operation of
        QWEBS. This record is required for QWEBS to operate.

   Key: none (hardcoded to: 'parameters')


Fields
------
*Server mode (a, n)

     This is used to control how QWEBS will setup for processing. Choose
     from one of these options:

     a    - Advanced mode. QWEBS servers are pre-created/activated and
            use MPE message files to manage client connections between
            the QWEBL and QWEBS. This mode allows cacheing of documents
            and images to significantly improve performance.

     n    - Normal mode. QWEBS servers are pre-created and activated
            on demand when a new client browser connection is made.

File (uri) option (m, ma, mx, h, ha)

     This is used to control how QWEBS processes URI strings. Choose one of
     these options:

     m    - Map uri strings to mpe file names. All uri strings must be
            mapped and no HFS access is allowed.

     ma   - Same as 'm', but if not in map file then QWEBS will attempt
            to open the file as the name in the account where QWEBS is
            running. This means that all preceding directory info is
            ignored. For example, if QWEBS received this URI:
            /webroot/mydir/myfile.html
            and it was not mapped, it would attempt to open the file
            myfile.html (if ma is enabled of course). This allows
            you to put up pages for testing if you have created the groups
            that equate to the common extensions found in HTML (html, gif,
            jgep) without entering any maps. This option forces the file
            to be opened in the account QWEBS is being run from. Use the
            'mx' option to allow files in other accounts to be accessed.

            The following description applies when an entry is not mapped
            and the actual file name is being processed:

                  QWEBS parses each URI and allows up to 2 extensions to
                  be checked starting from the end of the string. The
                  extension is checked before the account name is removed
                  so you can use this to your advantage in developing
                  a document scheme. The URI: /test.payroll.html will
                  be interpreted as an html file, but the actual file
                  accessed will be test.payroll

     mx     Same as 'ma', but allows files to be accessed in other
            accounts. Be careful with this option as it can cause you
            security problems!

     h    - Use HFS exclusively. No 'ref' records are being used to define
            resource information. If the HFS root directory is not
            defined then '.' will be used, which will equate to the
            current working directory of QWEBS.

     ha   - Same as 'h', but attempt to get 'ref' record for additional
            control information that might exist for the resource.

Default document (20)

     This is used when a request is made for a document without a file name.
     This name will be appended to the request. Typically this is home.html
     or index.html depending on your preference.

*Count hits  (y,n)

     Set this to 'y' to update the hit counter for each document/script that
     is accessed. The count is updated after the page has been delivered.

Allow /cgi-bin/  (y,n)

     Set this to 'y' to allow out-of-process scripts to be identified by
     their location within the /cgi-bin/ directory. Setting this to 'n'
     disables out-of-process scripts.

Allow /cgi-lib/  (y,n)

     Set this to 'y' to allow in-process scripts (virtual) to be identified
     by their location with the /cgi-lib/ directory.  Setting this to 'n'
     disables in-process scripts using the built-in CGILIB procedure.

Allow /cgi-ulb/  (y,n)

    Set this to 'y' to allow in-process scripts (user written) to be
    identified by their location within the /cgi-ulb/ directory. Setting
    this to 'n' disables in-process scripts (user written).

/cgi-bin/ uses $stdin (y,n)

    Set this to 'y' to create a redirected $stdin file that contains the
    information for the request that is also stored in variables. This
    allows scripts to be written which can use a simple read from $stdin
    instead of having to get the vars using MPE commands or instrinsics.

Use MPE file specs  (y,n)

    Setting this to 'y' lets QWEBS know that it can depend on the
    ascii/binary record definition of the file for determining whether to
    append cr/lf to the end of each record. Setting this to 'n' causes
    QWEBS to use the mime type settings for this definition.

Directory option  (d,s,f)

    This controls how QWEBS processes URI strings that point to directories
    and you have no default document defined or available. The values are:

    d   - Disable the sending of directory information. Return document not
          found error instead.

   *s   - Simple directory format.

   *f   - Fancy directory format. You must define the icons to use for the
          fancy directory format (or you won't get a very fancy output!).

 Check directory security  (y,n)

    Setting this to 'y' will instruct QWEBS to check the URI directory for
    IP security provisions. This can be used if you don't wish to add IP
    security to each resource individually. This will add a small amount
    of overhead. If you have configured QWEBS to use 'ma' or 'mx' file
    options then QWEBS will check for MPE Group and/or Account security
    in lieu of a HFS style directory.

Decode query  (y,n)

    Setting this to 'y' will cause QWEBS to parse the query/form entity data
    for variable names and values and make this parsed data available to
    your scripts (out-of-process only).  This will add a small amount of
    overhead to script processing, but makes writing scripts much easier.

Send server ident  (y,n)

    Setting this to 'y' allows the server id/version to be sent in the
    response headers back to the client.

Log-id ('<none>' disables)

    This defines how logging should be performed. Your choices
    are:

    <none>     - disable logging
    $stdlist  - log to $stdlist
    $console  - log to the system console
    group     - MPE group where log files are created/updated

 Echo log to console (y,n)

    Setting this to 'y' causes the logging information to be sent to
    the system console in addition to the other defined location. If
    logging is disabled then this option is ignored.

 Log referer (y,n)

    Setting this to 'y' causes the 'referer' header data to be logged.

 Log 'from' (y,n)

    Setting this to 'y' causes the 'from' header data to be logged.

Net-buf size (a) (0-28000)

    This is the buffer size to use when sending ascii (usually html)
    data back to the client. The default size is 512. Setting this to 0
    or any invalid value will cause QWEBS to use the default size.

Net-buf size (b) (0-28000)

    This is the buffer size to use when sending binary (usually
    images/audio/video) data back to the client. The default size is
    512. Setting this to 0 or any invalid value will cause QWEBS to
    use the default size.



  Mode: root (01)

   Use: This record contains the HFS root directory when you are using
        the HFS option for file location.

        This record is optional.

   Key: none (hardcoded to: 'parameters')

Fields
------
HFS Root Directory (72)

    The HFS directory to append to the front of any request received
    by QWEBS. This should start with a '/' or '.' and should NOT end
    with a '/'. The current working directory of QWEBS is assumed if
    you do not define the root directory.


  Mode: name  (02)

   Use: This record contains the formal name of your web server in
        a format similar to this: www.qss.com

        This record is optional.

   Key: none (hardcoded to: 'parameters')

Fields
------
Web Server name (72)

    The formal name of the web server as in: www.yourcompany.com


  Mode: list  (03)

   Use: This record contains settings that control the basic operation of
        QWEBL. This record is required for QWEBL to operate. And since
        QWEBL creates QWEBS this means you definitely need this record!

   Key: none (hardcoded to: 'parameters')

Fields
------
Server program name (30)

    This is the name of the web server program file. It should be
    entered as qwebs.grp.act  where 'grp' is the group and 'act' is
    the account where the QWEBS program resides on your system.
    The default location of QWEBS is QWEBS.PROGRAM.

 Logging program name (30)

    This is the name of the program which is used to do logging for
    QWEBL/QWEBS. The program is usually called QWEBSLOG.PROGRAM.

TCP port (1-32767)

    This is the tcp port that QWEBL should use to listen for connections.
    This is usually 80, but could be any other port not already in use.

*Administrator TCP port (1-32767)

    This is the tcp port that QWEBL will monitor for control purposes.

*Logging TCP port (1-32767)

    This is the tcp port that the logging process will monitor for log
    control purposes.

Maximum waiting connects (1-999)

    This is the number of connection requests that you want MPE to queue
    up to wait for QWEBL to process.

 Server pool size (1-999)

    The number of pre-created servers to initialize.  Setting this to a
    large number will reduce delays for serving up documents that have
    complex graphics or multiple in-line references.


  Mode: ver  (04)

   Use: This record contains the server id and version of
        CGI that the server supports.

        This record is optional, but recommended.

   Key: none (hardcoded to: 'parameters')

Fields
------
Server identifier (30)

    The id sent to the client browser which identifiers the server.
    You can use anything you want, but we recommend this text:
    'QWEBS/0.0 (HP3000)'.

Gateway version (12)

    The version of CGI the server supports. This should be set
    to 'CGI/1.1'.



  Mode: ref  (10)

   Use: This record contains the URI-->MPE filename mappings.
        This record is required for QWEBS to find your documents if
        you are not using HFS exclusively.

   Key: URI name (as it is used in HTML)

Fields
------
URI reference (72)

    This is the MPE file name associated with the URI name in the key.
    If this resource has been re-directed this should be the re-directed
    URL.

URI object flag

    A flag to indicate special disposition of this object. The values are:

    '* '  - No special disposition (the default). You enter '*', but the
            field will be set to '  ' in the file.

    ld    - This resource has been logically deleted. Send the not found
            HTTP error code.

    rp    - This resource has been permanently re-directed. The re-directed
            URL is in the URI reference field.

    rt    - This resource has been temporarily re-directed. The re-directed
            URL is in the URI reference field.

 URI Object security realm (8)

    The security realm (if any) that applies to this resource.  You must
    remember to further define the realm (mode realm) and user (mode user)
    for correct www-authentication. Use '*' to enter a blank realm, which
    means 'no www security for this resource'. '*' is converted to spaces
    in the file.

URI Object IP security class (8)

    The security class to check for IP security provisions. If the client
    IP address does not have access then the appropriate HTTP error code
    is sent. You can define a maximum of 600 IP security entries. Use '*'
    to enter a blank security class. '*' is converted to spaces in the
    file.

*URI Object number of hits

    A six digit number which is the current counter for the number of times
    this resource has been accessed.


  Mode: mime  (20)

   Use: This record contains the definitions for the different MIME
        content types.

        You need to establish these records for QWEBS to operate correctly.

   Key: extension (as in html or gif)

Fields
------
Content-type (40)

    The content-type associated with the extension entered as the key.  For
    example: 'text/html' is the content type for the extension of html.

    There is a file which comes with the QWEBS distribution which contains
    some basic MIME content-type records that can be loaded into WEBCTL.

File type  (a,b)

    This is used to let QWEBS know that files loaded on your server which
    have this content-type are ascii or binary.  This is not used if you
    have set the 'Use MPE file specs' option to 'y'. This is needed because
    the typical MPE file is stored in fixed record format without cr/lf at
    the end of each record, but cr/lf needs to be transmitted to the
    browser if the file is ascii.


  Mode: sec  (30)

   Use: This record contains IP security settings that control connection
        and resource access by IP address.

        This record is optional.

   Key: Security class of the resource with spaces set to the
        '.' character and the last two characters set to ## where
        ## is 00-99. For example, if you have associated a URI with
        a security class of 'finance' then the security class key
        values would be 'finance.00' thru 'finance.99'.

        Note: Connection security uses 'connect-' as the class so the
              valid entries would be 'connect-00' thru 'connect-99'.


Fields
------
Security rule

    This is a string that defines one security rule.  You are allowed to
    enter up to 6 rules for each record.  This means you can have 600
    rules for connection security and 600 for each URI resource.  The
    format of the security rule is:
    abbb.bbb.bbb.bbb:ccc.ccc.ccc.ccc;ddd  where:

        a = i for include, x for exclude
        b = starting ip address
        c = ending ip address
        d = HTTP error to send when access is denied

    You should be aware of the following discussion regarding how security
    is determined when using the i/x flags.

    If the client IP address matches a security rule the authorization is
    based on the corresponding i/x flag. If the flag is 'i' the client is
    allowed (included) access. If the flag is 'x' the client is denied
    (excluded) access.

    If the client IP address does NOT match any security rule, the
    authorization is determined by the first rule. If the first rule is
    'i' the client is denied access. If the first rule is 'x' the client
    is allowed access. The thinking behind this is that by defining 'i'
    rules you are saying who CAN access your system. By defining 'x'
    rules you are saying who CANNOT access your system. Therefore, if
    the client's IP address does NOT match any specified rule they
    should be granted access the opposite of the defined rules.



  Mode: dir  (31)

   Use: This record contains directory security settings for HFS
        directories or MPE Accounts and Groups for mapped file access.

   Key: Directory name (/mydir)     when file-option = "h " or "ha"
        MPE Group name (pub)        when file-option = "ma"
        MPE Group.Account (pub.sys) when file-option = "mx"

        Note: MPE Group/Account names should be entered in lower-case.

Fields
------
 Directory security realm (8)

    The security realm (if any) that applies to this directory. You must
    remember to further define the realm (mode realm) and user (mode user)
    for correct www-authentication. Use '*' to enter a blank realm, which
    means 'no www security for this directory'. '*' is converted to spaces
    in the file.

Directory IP security class (8)

    The security class to check for IP security provisions. If the client
    IP address does not have access then the appropriate HTTP error code
    is sent. You can define a maximum of 600 IP security entries per class.

Disable all access (y,n)

    'y' is used to instruct QWEBS that no files can be accessed from this
    directory. The field 'HTTP err when disabled' defines the error code
    that will be sent to the client browser.

HTTP err when disabled

    The three digit HTTP error code to send to the client browser if this
    directory has been disabled for access. The most common error code
    to use would be '403'.


  Mode: user  (40)

   Use: This record contains the definition for a user who needs to
        be authenticated for a specific realm.

   Key: realm, user

Fields
------
Realm name (8)

    The name of the realm the user is associated with. This must match
    exactly with the value of the 'URI Object security realm' field of
    the mapping (ref) entry.

User name (30)

    This is the user who is being validated for access to an object which
    belongs to the realm described in the 'realm name' field. User security
    checking is case insensitive.

User password (12)

    This is the password for the user. This field is case sensitive.

*User data (76)

    This is a string of data which is made available to any script run
    after the user has been validated.


  Mode: realm (41)

   Use: This record contains the definition for a security realm.
        Realms are used to create security regions on the server. Users
        are associated with one or more realms.

   Key: realm

Fields
------
Realm name (8)

    The name of the security realm. This must be specified exactly
    as the value of the 'URI Object security realm' field of
    the mapping (ref) entry is specified.

Realm Description (20)

    This is the string of text displayed by the web browser when the
    dialog box is displayed to ask the user their name and password.
    This does not have to be unique, so multiple realms within the
    server can present a single security message to the user.

*Parse user data (y,n)

    'y' is used to instruct QWEBS to use the user data parse rules to
    create a series of MPE variables with values from the user data
    field of the user record entry. The user data parse rules are
    specified by the 'udn' and 'udp' record types.


  Mode: udn (42)

   Use: This record contains a list of up to 20 names (1-4 bytes) which
        are used in constructing MPE variable names after a user has been
        authenticated.

   Key: realm

Fields
------
Realm name (8)

    The name of the security realm. This must be specified exactly
    as the value of the 'URI Object security realm' field of
    the mapping (ref) entry is specified.

User data name

    There can be up to 20 data names specified for each realm. Each
    user data name can be from 1-4 bytes in length. You are prompted
    one at a time, with entry terminated by a blank name. Use '//'
    to abort data entry and cancel the update. These names should be
    unique because they are used to create MPE variables which can be
    used by scripts.



  Mode: udp (43)

   Use: This record contains a list of up to 20 parse rules which
        define how to sub-divide the user data field value into the
        20 possible MPE variable names.

   Key: realm

Fields
------
Realm name (8)

    The name of the security realm. This must be specified exactly
    as the value of the 'URI Object security realm' field of
    the mapping (ref) entry is specified.

User data rule

    There can be up to 20 data rules specified for each realm. Each
    user data rule is a 4 digit value which is 2 2-digit values. Digits
    1/2 are the starting position and digits 3/4 specify the length.
    These rules define how to parse the user data field into the
    individual MPE variable names. The user data rules are entered
    one at a time, with entry terminated by a blank name. Use '//'
    to abort data entry and cancel the update.



  Mode: err  (50)

   Use: This record is used to direct QWEBS to send a specific HTML
        document when an error occurs. If you do not define a HTML
        document for an error then QWEBS will format a standard
        error response.

        This record is optional.

   Key: HTTP error number

Fields
------
ERR uri (72)

    This is the HTML document located on your server that should be sent
    to the client when the specified error has occurred.

    The HTTP error numbers which are candidates for HTML documents are:

    400 - Bad request. The client didn't send a properly formatted message.

    403 - Forbidden. The resource (document/script) is not accessible.

    404 - Not found. The resource (document/script) was not found.

    500 - Internal server error. A fatal error in QWEBS occurred.

CGI Interface

QWEBS supports the ability to execute a script which returns formatted information to the client browser. The HTTP standards define the method in which servers interact with scripts as CGI (Common Gateway Interface). Using scripts you can interface existing database information to your client browser through the generation of dynamic (on-the-fly) HTML. QWEBS has a CGI interface that has been optimized for the MPE environment. It is modeled after the HTTP CGI/1.1 standards, but includes additional features not found in CGI/1.1. If you have written server scripts for other servers (unix) you will find a number of similarities. However, there are enough differences to warrant a close inspection of this material before embarking on writing your own scripts.

QWEBS supports two classes of scripts. Out-of-process scripts and in-process scripts. Out-of-process scripts are either MPE command files or compiled programs that are executed as a son process to QWEBS. In-process scripts are subroutines called by QWEBS. In-process scripts are an extension to the CGI/1.1 standard. Out-of-process scripts are easier to write and connect to QWEBS. In-process scripts are harder to write, but they will execute much faster and consume less resource than out-of-process scripts.

QWEBS determines the type of script by the directory in which it is referenced. Out-of-process scripts are always found in the /cgi-bin/ directory. In-process scripts can be found in the /cgi-lib/ or /cgi-ulb/ directory.

Query and Path Info in the URL

Those unfamiliar with the various HTML/HTTP specifications may not be aware of the different ways a URL can be formulated. For HTML documents it is pretty straightforward. When you get into forms/scripts it can be a bit more complicated. The components of the more complicated URL's are used to interface to scripts and sometimes are not typed directly by the user, but are generated by the browser after interpreting the HTML. In addition to the script name there can be query data and path information. The following examples help illustrate how query data and path info data is passed in the URL.

This sample URL has all possible components that will interface to a script. This style URL is only possible using HTML forms with the 'GET' method.

http://www.qss.com/cgi-bin/script/mypath/info.html ?parm1=abc&parm2=123

If the HTML is ISINDEX tagged, the corresponding URL would look like this:

http://www.qss.com/cgi-bin/script/mypath/info.html?abc+123

The script name in both examples is /cgi-bin/script. The optional path info is /mypath/info.html. The data following the '?' is defined as the query data. When the request is from HTML forms the query data has parameter names and values. When the request is from ISINDEX tagged HTML the query data is a list of parameter values separated by a delimiter (usually one of these: '+,&').

When a request comes from HTML forms using the 'POST' method there will be no '?' query information in the URL. However, there can be path info. The parameter names and values are not transmitted in the URL, but are sent by the browser after the URL.

/cgi-bin/ Scripts

These are similar to the scripts found on most web servers. QWEBS waits until the script has finished and then returns the script output to the client. The information made available to the script (prior to executing) is located in two places. The first, is a set of MPE variables based on the type of request. The second is an input file the script can read as its $stdin. Each script is executed with one parameter, which is a string representation of the pin (process identification number) of the QWEBS server process. $stdin and $stdlist are redirected to specific file names (SI######/SO######, where ######=pin) which are defined like this: File SI000101;REC=-256,1,F,ASCII.

QWEBS executes the script using the HPCICOMMAND intrinsic with the following syntax:

script "#####" > SO###### < SI######

This command will work correctly if 'script' is an MPE command file or a compiled program. If it's an MPE command file you must have one parameter (the pin). If it's a compiled program the pin string is passed in the ';info=' string which you can retrieve using the GETINFO intrinsic.

Because $stdin and $stdlist have been redirected to SI######/SO###### you can read and write these files as if they were your terminal. In Cobol this can be accomplished by using simple Accept and Display statements.

/cgi-bin/ Variables

Multiple QWEBS processes can be active at the same time and because MPE variables are shared by all processes for the same session/job there must be a way to uniquely identify the MPE variables for each running script. This is accomplished by appending a '_' followed by a five digit pin# to each variable that is associated with a QWEBS process. These are the MPE variables that are set prior to the exection of a /cgi-bin/ script:

These variables do not have the appended '_#####' because they are the same for all QWEBS processes.

These variables are always set. They are uniquely named for each QWEBS process.

These variables are set only if the request is from ISINDEX tagged HTML.

These variables are set if the request is a query (HTML form using 'GET').

These variables are set if the request is a query (HTML form using 'GET') and you have configured QWEBS to decode any query/form data.

These variables are set if the request method is POST.

These variables are set if the request method is POST and you have configured QWEBS to decode any query/form data.

One final note on QD_ and FD_ variables. It is possible to create an HTML form that allows multiple selections from a list box. This can result in the same parameter being repeated in the query/form data. If this case arises the 'xxxx' name will have '_' and a unique identifier appended. The unique identifiers are selected from this list in order: 123456789A..Z.

Optional Redirected $stdin (SI######)

QWEBS can be configured to build a file which is the redirected $stdin for /cgi-bin/ scripts. This file contains formatted request information which makes it easier for the script to obtain the data it needs to operate. Because this file is treated as $stdin the script can read the data as if it was coming from the terminal. The SI file is built in 256 byte, fixed ascii format. The first and last records are always the same type. The records in between are optional and depend on the nature of the request.

SI File Format

First Record - this is the request method. This will be either GET or POST. The method is stored in the first 16 bytes of the record.

Last Record - this is always '//' to signal end of file.

Therefore, a script request with no path info, no query and no POST form data will create a file with these two records:

GET
//

There are eight additional record types that QWEBS can write to the SI file. They are:

File Parsing Rules

There are logical sets of records which will always be found together in the SI file. In addition, there are mutually exclusive sets of records which will never be found together in the file. And finally, QWEBS always writes the records in a certain sequence. These basic rules have been outlined to help you write scripts which parse the SI file correctly:

The following examples show some of the more typical combinations of records that occur in the SI file.

Request: GET method, using HTML forms, with path info.

GET
application/x-www-query-urlencoded               00020
parm1=abc&parm2=1234
application/x-www-path-info                      00017
/mypath/data.html
QD 00005  00003
parm1
abc
QD 00005  00004
parm2
1234
//

Request: GET method, no path info, ISINDEX tagged HTML

GET
04
parm1val
parm2val
parm3val
parm4val
//

Request: POST method HTML form, path info included

POST
application/x-www-form-urlencoded                00066
myfirstparm=thevalue&mysecondparm=thesecondvalue&myparm3=morevalue
application/x-www-path-info                      00017
/opt_path/patharg
FD 00011  00008
myfirstparm
thevalue
FD 00012  00014
mysecondparm
thesecondvalue
FD 00007  00009
myparm3
morevalue
//

/cgi-lib/ and /cgi-ulb/ Scripts

These scripts are subroutines located in a NM XL file referenced by QWEBS. Instead of creating MPE vars and running the script as a son process, QWEBS builds a parameter list and calls the script as a subroutine.

/cgi-lib/ vs /cgi-ulb/

/cgi-lib/ scripts always call the same subroutine: CGILIB. This subroutine is included with QWEBS and is located in the NM library called CGILIB.LIBRARY.QWEBS. When a /cgi-lib/ script is called the script name is passed as one of the parameters. This allows you to use CGILIB as a virtual script, where you use one entry point to perform different tasks depending on the script name.

/cgi-ulb/ scripts are called by their script name and must be added to a NM library that QWEBS can access. You can add your /cgi-ulb/ scripts to the CGILIB library or you can use your own library. If you create your own library you will need to change the ;xl= parameter for QWEBS.PROGRAM.QWEBS to include this new library.

Parameter List for /cgi-lib/ and /cgi-ulb/ scripts

These scripts are called with the following parameter list:

STRING-LEN-TABLE has these five elements:

The STRING-BUFFER is composed of these elements:

The CONTENT-TYPE defines how you should interpret the DATA field. These are the values and their associated meaning:

Maintaining /cgi-lib/ and /cgi-ulb/ scripts

These scripts must be stored in a NM library listed in the QWEBS.PROGRAM XL list. We ship QWEBS with two libraries and the XL list set to 'CGILIB.LIBRARY,CGIULB.LIBRARY'. The object module CGILIB.OBJECT.QWEBS is loaded into CGILIB and TSTULB.OBJECT.QWEBS is loaded into CGIULB. At first glance this might look strange. Why not just load them into the same library?

Good question. It is not possible to update a NM library (XL) when it is being accessed by a running program. QWEBS calls CGILIB and at least one QWEBS process is always in existence. This means that you cannot update CGILIB while the server is operational.

However, calls to /cgi-ulb/ routines are dynamic so the library CGIULB will only be locked while a /cgi-ulb/ script is running. This allows you to maintain CGIULB while QWEBS is running. You might want to make a copy of CGIULB, make your changes, and then replace it. This will reduce the window of opportunity for a client to request a /cgi-ulb/ script while you have the library locked. If this were to happen the client would receive a 'not found (404)' error.

QWEBS Mapping and File Placement

QWEBS is designed to allow you to serve up regular MPE files without having to use Posix/HFS features of MPE/iX. There are some issues you should consider when using the 'm ', 'ma', 'mx' file options:

Determining the Extension (Mime type)

QWEBS parses the requested document to determine its extension which is used with MIME entries to determine the type of document. To allow for creative control of the server environment QWEBS scans the document name from the back and parses 2 extension names (if available) from right to left. The second extension is used only if the first is not found in the Mime database. QWEBS determines the extension (and therefore the MIME type) BEFORE any mapping is done.

'm ' Option

This option requires EVERY document/script to be mapped or the document/script cannot be accessed. This gives you a high degree of security and control over the information served up by your server. The map entry specifies the actual MPE file name to be processed, which can be any valid MPE file name resident on your system (that QWEBS has read access to).

'ma' Option

This option allows files to be accessed using their MPE file name if a map entry is not found. The directory is stripped and an MPE name is constructed. If there is an account name then it is stripped from the name before opening the file. Files must conform to MPE file name syntax and cannot be preceeded by '*'/'$'. For example, the following request: /myfiles/mydoc.html would be opened as the MPE file mydoc.html. And the request: /myfiles/mydoc.mygroup.html would be opened as MPE file mydoc.mygroup. Because there is no account this option restricts files to the account where QWEBS is being run (usually QWEBS).

'mx' Option

This option allows files to be accessed using their MPE file name and the complete file name is used. This option allows you to access files across accounts without mapping. Beware as this option can open your server up to severe security risks since anyone on the internet can then read any file on your HP system (depending on the capabilities of the user you use to run QWEBS.

QWEBS WWW Authorization

QWEBS supports WWW Authorization using the 'Basic' scheme. In addition, QWEBS extends this by allowing you to associate a string of data with each validated user. This data is made available to any script and can optionally be parsed into a set of MPE VARS.

How WWW Authorization Works

Any document/script (URI) can be secured such that a user name and password is required for access. QWEBS uses the map (ref) record entry to indicate that a document/script is secured. When a secured document is requested without a user name/pwd QWEBS will respond with a challenge to the web browser for a valid user name/pwd. The browser pops up a dialog box requesting this information from the user. The browser then transmits the same request including the newly discovered user name/pwd data. If the user name/pwd is valid (from QWEBS perspective) then the document/script is made available, otherwise an error is returned. Most web browsers will cache the user name/pwd for the duration of the session so if another document is encountered which requires a similar user name/pwd it can be transmitted without asking the user.

WWW Authorization is NOT SECURE TRANSMISSION

This type of security should not be confused with HTTPS or SSL which are secure transmission methods. WWW Authentication using the Basic scheme is a simple user name/pwd protocol that offers little actual security because the user name/pwd is not encrypted. The information is transmitted in BASE64 which while offering some visual protection from the casual viewer is easily converted to the actual text.

Setting Up WWW Authorization

This data must be setup to get WWW Authorization to work correctly:

Comments About 'realm'

Each 'realm' is assumed to be a separate secure area within the server. Therefore, each 'realm' has a set of users who have been given access to any object (document/script) that belongs to that 'realm'. QWEBS allows you to define a 20 character description for each 'realm' which is the text transmitted to the web browser as the 'realm'. The 'realm' name is used by the web browser in the heading of the dialog box, so you can use the description to craft a friendlier, more easily understood query for user name/pwd.

The Scheme (Basic)

HTTP specifications define only the 'Basic' scheme, which is the one implemented by QWEBS. When you define a 'realm' you must enter the scheme name as 'Basic' to use the user name/pwd data stored in the WEBCTL database. QWEBS is architected to support extensions to this by using different scheme names. Currently there are no other schemes implemented.

User Name Data and Parsing

QWEBS allows you to associate up to 76 characters of data to each user of a 'realm'. This data is made available to scripts as an MPE VAR with the name 'UD_#####' and the user name is made available as the MPE VAR 'UN_#####'. If you have specified for the user data to be parsed then you will get an additional set of MPE VARS (up to 20) which have the name 'UP_name_#####'. User data parsing is defined by setting up the 'udp' and 'udn' entries in the WEBCTL database.

##### is the PIN and 'name' is the name used when setting up the 'udn' record entry.

QWEBS Logging

QWEBS can log information using one of these options:

You establish the type of logging by setting the appropriate log id in the CTL settings using QWCMNT. The log id setting for file logging is the MPE group name you wish to use.

File Logging Architecture

The log id MPE group specified in the CTL settings will contain the following files:

Logging is handled by a separate log process, QWEBSLOG, which is running as a son process to QWEBL (listener). QWEBL and QWEBS processes write their log entries to a message file which QWEBSLOG reads and then writes to the current LGTR#### file. When the LGTR#### file is full a new LGTR#### file is created.

$stdlist Logging Format

This information is logged when logging to $stdlist:
prog   pin  ip-addr   [date    ,time      ]
prog   pin  orig-req
prog   pin  map-req   err-code   br/bs  ci/cr

prog      = Program name (QWEBL/QWEBS)
pin       = PIN of process
ip-addr   = ip address of the client
date      = date of the request
time      = time of the request
orig-req  = original request submitted by browser
map-req   = mapped request (when using 'm ', 'ma', 'mx' file-option)
err-code  = error code if an error. Otherwise not displayed
br        = bytes read from the client browser
bs        = bytes sent to the client browser
ci        = cpu time to initialize the server (millisecs)
cr        = cpu time to serve the request (millisecs)

These are some actual logs from a test run at QSS:

QWEBS   104 206.169.9.210     [96/10/07,13:28:27.0]
QWEBS   104 GET /
QWEBS   104 Map=home.html 141/1642 100/32

QWEBS    87 206.169.9.210     [96/10/07,13:28:27.4]
QWEBS    87 GET /ballg.gif
QWEBS    87 Map=ballg.gif 172/976 88/24

QWEBS    76 206.169.9.210     [96/10/07,13:28:31.9]
QWEBS    76 GET /qwebsdcg.html
QWEBS    76 Map=qwebsdcg.html 189/84921 87/281

$console Logging Format

The format for $console logging is similar to the $stdlist format, except the date/time fields are replaced by the orig-req field. This means the $console log is two lines, while the $stdlist log is three.

File Logging Formats

The log file is a variable length file and contains multiple record types. The log format is dependent on record type, with each record containing a fixed 22 byte header prefix. You can use the supplied program QLOG.PROGRAM.QWEBS to view/analyse your log files. The basic message format, with the header prefix is:
01  LOG-DATA-MESSAGE.
    03  LDM-HEADER          PIC X(22).
    03  LDM-DATA            PIC X(232).

01  LDM-HEADER-DETAIL.
    03  LDM-H-REC-TYPE      PIC S9(4) COMP.   Record identifier
    03  LDM-H-DATE          PIC S9(8) COMP.   Date server started yyyymmdd
    03  LDM-H-TIME          PIC S9(8) COMP.   Time server started hhmmssxx
    03  LDM-H-CLIENT-IP     PIC X(4).         IP address in byte format
    03  LDM-H-CLIENT-PORT   PIC S9(9) COMP.   Port# (not usually logged)
    03  LDM-H-PIN           PIC S9(9) COMP.   PIN of server process
The formats for LDM-DATA, based on message type are:
Record type = 0

This record is written whenever a process wishes to log status
information. Currently only QWEBL logs this record type (on
startup).

        Field Name                            Comments

01  D0-DATA.
    03  D0-MSG-LEN           PIC S9(9) COMP.  Len of the status message
    03  D0-MSG               PIC X(228).      Status message

Record type = 1

This record is written whenever a client (browser) is denied access
to the server because of connection IP security. The header record
contains the IP address of the client denied access.

        Field Name                            Comments

01  D1-DATA.
    03  D1-SERVER-PIN        PIC S9(9) COMP.  PIN of the logging server
    03  D1-CONN-SECURITY     PIC 99.          Err code. 02 = denied access


Record type = 2

This record is written whenever an internal error occurs.

        Field Name                            Comments

01  D2-DATA.
    03  D2-ERR-TYPE          PIC 99.          Error type
    03  D2-ERR-CODE          PIC S9(9) COMP.  Returned error code by
                                               external routine

     ERR-TYPE Values
     ---------------
     01  - Could not create a server process
     02  - Could not activate a server process


Record type = 100

This record is written for each server connection. It will be
usually followed by type 101/102 records.

        Field Name                            Comments

01  D100-DATA.
    03  D100-DATE-OFF        PIC S9(8) COMP.  Date server finished yyyymmdd
    03  D100-TIME-OFF        PIC S9(8) COMP.  Time server finished hhmmssxx
    03  D100-CPU-INIT        PIC 9(9) COMP.   Cpu (ms) for init (overhead)
    03  D100-CPU-REQUEST     PIC 9(9) COMP.   Cpu (ms) to process request
    03  D100-BYTES-READ      PIC 9(9) COMP.   # bytes read from browser
    03  D100-BYTES-SENT      PIC 9(9) COMP.   # bytes sent to browser
    03  D100-REQ-TYPE        PIC XX.          [a,b] a=G|H|P, b=' '|B|L|U
    03  D100-HTTP-VER        PIC X.           F=Full request, S=simple
    03  D100-SERVER-MODE     PIC X.           Configured server mode (a|n)
    03  D100-FILE-OPTION     PIC XX.          Configured file option
    03  D100-ERR             PIC 9(3).        HTTP error code
    03  D100-KEEP-ALIVE      PIC X.           Y=browser uses keep-alive
    03  D100-SCRIPT-OUT-OPT  PIC XX.          Script output-option
    03  D100-OBJ-LEN         PIC S9(9) COMP.  Length of file/script served
    03  D100-OBJECT          PIC X(192).      When mapping, this is the MPE
                                              file actually served
                                              When using HFS, this is the
                                              actual request as received
                                              from the client browser.

Record type = 101

This record is written for each server connection. It follows the
type 100 record. This record can occur multiple times depending on
the size of the string fields. If the record overflows then additional
records are logged. Len fields with a value of 0 indicate they are not
included in the D101-TEXT field.

        Field Name                            Comments

01  D101-DATA.
    03  D101-USER-AGENT-LEN  PIC S9(9) COMP.  Len of browser id text
    03  D101-REFERER-LEN     PIC S9(9) COMP.  Len of referer text
    03  D101-FROM-LEN        PIC S9(9) COMP.  Len of client email address
    03  D101-AUTH-USER-LEN   PIC S9(9) COMP.  Len of authenticated user
    03  D101-RFU-LEN-1       PIC S9(9) COMP.  rfu
    03  D101-RFU-LEN-2       PIC S9(9) COMP.  rfu
    03  D101-RFU-LEN-3       PIC S9(9) COMP.  rfu
    03  D101-RFU-LEN-4       PIC S9(9) COMP.  rfu
    03  D101-TEXT            PIC X(200).      Concatenated string in the
                                              same order as the len fields

Record type = 102

This record is written for each server connection. It contains the
original message received by the server up to (but not including) any
query string. For example: GET /home.html

        Field Name                            Comments

01  D102-DATA.
    03  D102-ORIG-MSG-LEN    PIC S9(9) COMP.  Len of the original message
    03  D102-ORIG-MSG        PIC X(228).      First 228 bytes of orig msg

Miscellaneous Ramblings

The information detailed in this section might come in handy as you begin to implement QWEBS. These are items that came to light while developing/testing/using QWEBS.

Server Domain Name

If you already have a Domain Name Server (DNS) that is accessible by desktops connected to your HP 3000, you will want to add an entry for your QWEBS intranet server. This way your users can access the HP 3000 just like any web server on the internet.


If you don't have a DNS available, then you need another way to relate your system name to the IP address. The most common way is to update the hosts file on each desktop system. Consult your desktop TCP/IP vendor documentation for help on updating this file.


As a last resort you can type in the IP address of your HP 3000 in place of the server name.

Enable Ethernet

We didn't have to worry about this, but you might have to enable ethernet in NMMGR. We already had it enabled and didn't bother to disable it to prove whether QWEBS would still work. So we are listing it here as something that might come up.

Fixed Length ASCII Records and HTML

Fixed length ascii files on the HP 3000 don't have a crlf at the end of each line. HTML expects such characters to be present so QWEBS inserts them when sending data back to the client browser. At the same time, QWEBS will scan backwards from the end to remove trailing blanks. This has some interesting consequences with regard to performance and HTML processing.

How QWEBS Handles File I/O

QWEBS opens files (documents,images,script output) MR,NOBUF and reads blocks which are 8,192 bytes. QWEBS can process fixed length and variable length files in this manner. QWEBS probably will not process byte-stream files correctly. When HFS support is added we will make sure QWEBS can handle byte-stream files properly.

Socket I/O

QWEBS sends data back to the client in blocks of 512 bytes unless you change the network buffer parameters. You can configure ascii and binary files differently. We found that using a larger binary buffer size helped improve performance when transmitting large images. You should determine whether this can work for you or not. Increasing the buffer sizes can cause adverse affects on an already busy network.

Performance Comments

We have a 937/LX with 232mb of main memory and 8.6gb of disk. Our typical load is 12-20 vt sessions. Sharing the same network we have a NTS 4.0 system and two networked printers (LJ5Si). When testing QWEBS we found immediate response to be the norm. The HTML documents included with the kit had transaction times of anywhere from .1 - .5 seconds except for this document which was typically .5 - 1.2 seconds. The performance exceeds our NTS 4.0 server when we use a good size server pool. With only 1 pooled server process QWEBS is not as fast as our NTS 4.0 system.

Command File Script Gotchas

The first command file we wrote had echo statements that attempted to write out HTML. Doesn't work! The < gets treated as file redirection! You have to be more creative. A good idea is to build header and trailer ascii files that you can print from the command file. Works better, less mess.


Another problem to watch out for is the collision of MPE variable names for simultaneously executing scripts. All script processes are sharing the same job/session variable/jcw space. So avoid using variable names that are not uniquely identified by pin. The pin is passed as a parameter to the command file/program for this reason.