by Alfonso Ranieri

DISCLAIMER:
THIS SOFTWARE AND INFORMATION ARE PROVIDED "AS IS".
ALL USE IS AT YOUR OWN RISK, AND NO LIABILITY OR
RESPONSIBILITY IS ASSUMED.
NO WARRANTIES ARE MADE.





1. Introduction

    Hserv was born as an example of rxsocket.library archive, but it become
    so big and cute that I decide to release it as a stand alone application.

    It is a HTTP 1.0 ARexx server, very configurable and funny.

    The main features are:
    - run alone or as inetd service;
    - accepts GET, HEAD and POST methods
    - "If-Modified-Since" supported, with a lot of date formats;
    - rfc1945 Auth supports;
    - rejected-ips;
    - mime types read from file, so you can had your mime;
    - text parsing;
    - in line ARexx functions in html documents;
    - ARexx, CGI and execs macros;
    - may require client ident service running.


2. Installation

    The server can run stand-alone or as inetd service.

    This is the *basic* installation:

    copy rxsocket.library to LIBS:   (from rxsocket.lha or better fix)
    copy rmh.library TO LIBS:        (from rmh.lha or better fix)
    copy rxs to C:                   (from rxsocket.lha or better fix)
    write in a shell
      rx "call addlib('rexxsupport.library',0,-30)"
      rx "call addlib('rxsocket.library',0,-30)"
      rx "call addlib('rmh.library',30,-30)"

    make a directory called hserv in ram:
    copy hserv TO ram:hserv
    assign hserv: ram:hserv

    To install it as inetd service:

        If running on AmiTCP
            open AmiTCP:db/service and the line (if not already present)
            http 80/tcp
            open AmiTCP:inetd.conf and add the line
            http stream tcp nowait root c:rxs c:rxs hserv:hserv/main/hserv.rexx

        If running on Miami
            open Miami/DataBase/service window
            press "Add" gadget
            add the line (if not already present)
                Name: http
                ID: 80
                Protocol: tcp
                open Miami/DataBase/InetD window
                press "Add" gadget
                add the line:
                Service: http
                Socket: stream
                Protocol: tcp
                Wait: nowait
                User: root
                Server: c:rxs
                Name: c:rxs
                Args: hserv:hserv/main/hserv.rexx

    To install it as stand alone:
        run >NIL: <NIL: rx hserv:main/hserv
        (or just rx hserv:main/hserv)


2. Requirements

    hserv needs:

    - AmigaOS >=3.0
    - ARexx
    - a TCP/IP stack
    - rxsocket.library 4.1 (Aminet comm/tcp/rxsocket.lha)
    - rmh.library      3.1 (Aminet util/rexx/rmh.lha)


4. Author

   The author is:

    Alfonso Ranieri

   His e-mail address is:

   alfier@iol.it

    You can find him at:

   - #amichat    dalnet;
   - #amigaita   ircnet;
   - #amyita     ircnet.

   You can find last version of hserv at:

    http://users.iol.it/alfier/


5. Distribution

                                  hserv is FreeWare.

   You are free to detribute it as long as the original archive is kept intact.
   Commercial use or its inclusion in other software package is prohibited
   without prior consens from the Author.


6. Configuration

    Configuration options are read from a file, which is the only argument
    hserv needs to run.
    If no file name is given, hserv tries to open hserv:conf/hserv.conf

    Each line of the configuration file is in the form:
    <option> <value>

    Empty lines and lines beginning with # are discarded.
    Words can be separeted by space(s) and tab.

    All options have a default value.

    The options are:

    HostName        the host name, if none given, hserv tries to obtain it.
                    If offline, auto hostname is "127.0.0.1", for
                    compatibility with TermiteTCP and because AWeb does not
                    use the cache if hostname is "localhost".

    Port            the port to use, default 80 (of course, only valid if
                    running as stand alone and can't be changed on the fly)

    DocumentDir     the dir where documents are.

    DocumentIndex   any request with a null file name is replaced with this
                    default hserv:htdocs

    CGIDir          the directory where CGI macros are. It is used if and only if
                    a "/cgi-bin/<file>" is received
                    deault hserv:cgi-bin

    ErrorLog        a flag that indicates if errors must be logged
                    values are ON OFF SYS
                    deafult SYS

    ErrorFile       if ErrorLog is ON, log error in this file

    TransferLog     a flag that indicates if requests must be logged
                    values are ON OFF SYS
                    default OFF

    TransferFile    if TransferLog is ON, log requests int this file

    Auth            the auth file

    RejectedIP"     the rejected ip

    MimeFile        the mime file

    Timeout         timeout in seconds for the receive request phase
                    default 300

    HostnameLookups a flags that indicates if the server should do a
                    GetHostByName() on the client ip
                    values are ON OFF
                    default OFF

    Ident           a flag that indicates if the client must have the
                    ident service running; the server will connect it
                    and get client ident
                    values are ON OFF
                    default OFF

    OnlyAmigaClient only Amiga client accepted; clients without the word
                    "Amiga" in User-Agent field are rejected
                    values are ON OFF
                    default OFF


7. Auth

    The Auth file consists of lines in the form:
    <pattern> <realm> <login> <pass>

    - pattern is an AmigaDOS pattern, that will be applied to the complete
      file name requested.

    - realm is a symbolic name for the protected space the file(s) belongs to

    - login is the login

    - pass is the password

    Anytime a file is requested, after it was parsed in a complete path to a file,
    and matches pattern in a line of Auth file, an autentication request is send
    to the client.
    Try to join <Tiziana> in the index.html in the archive.

    Empty lines and lines beginning with # are discarded.
    Words can be separeted by space(s) and tab.



8. RejectedIP

    The RejectedIP  file consists of lines in the form:
    <pattern> <reasone>

    - pattern is an AmigaDOS pattern, that will be applied to the ip
      of the client

    - reasone is the reasone for the k-line. It is send to the client

    If the pattern matches the ip, the connection is not accepted.

    If a non empty Rejectedip file is given, HostNameLookups is set.
    Empty lines and lines beginning with # are discarded.
    Words can be separeted by space(s) and tab.


9. Mime

    The Mimefile consists of lines in the form:
    <mime> <ext> {SP ext}

    - mime is a mime type, e.g. <text/html>
    - ext is the extension of the file.

    Any file with an extension present in the left part of a mime line
    is considered to be of that mime.

    Default mime is <text/plain>.

    Empty lines and lines beginning with # are discarded.
    Words can be separeted by space(s) and tab.


10. RunTime

    If the server runs as stand alone:
    - configuration file is read and its values stored in ARexx clips
    - it opens a port called "HSERV"
      this port accepts 2 messagges:
      - QUIT              quit the server
      - CONF [file]       reload the old file, or a new one.

      If the config file is modified, the server auto reloads it.


    If the server runs as inedt service:
    - configuration file is read and its values stored in ARexx clips
    - any time the server is used configuration file is reload.

    hserv (or better hs.rexx) do these controlls before sending a file:
    - good request
    - peer info
    - Ident
    - OnlyAmigaClient
    - k-lined ip
    - file contains "//" or ":"
    - file exists
    - Auth
    - good request method

11. Parsing

    Any time a file of mime <text/*> is encontered, the server makes this parsing
    on its' *LINES*:

    changes the string <!ip> with the peer name

    changes the string <!user> with the user name, if ident is ON, or unknown
    if ident is OFF

    changes the string <!userat> with the user user@ip, if ident is ON, or
    ip if ident is OFF

    changes the string <!power> with the string ""

    changes the string <!ver> with the string ""

    changes the string <!this> with the current file name

    changes the string <!InetDate> with the current date in GMT Internet format

    changes the string <!REXX fun> with the output of the function fun, an Arexx
    function called on the fly

    changes the string <!CGI fun> with the result of the file created by the CGI fun
    with the first 2 lines discarded

    The parsing is made for all but !CGI then for !CGI, but never recursively for !CGI.

12. CGI

    The term CGI refers to:
    - ARexx macros
    - perl macros
    - AmigaOS execs

    The *type* of the macro is parsed from its file name extension:
    - ARexx macros must have the extension *rexx*
    - perl CGI macros must have the extension *cgi*
    - AmigaOS execs must have *no extension*

    The directory CGIDir contains all the macro that are called in the form
    "/cgi-bin/macro". It is a default directory for general porpouse macros.

    Of course, a CGI macro of type cgi will work if and only if you have perl
    in your path, e.g. you have GeekGadgets installed.

    CGI are called with the same arguments in the request.

    They must write to stdout:
    - first line:       "Content-Type:" mime
    - second line:      (empty)
    - rest:             mime specific data

    Macros have their real directory as CurrentDir.

    If they are called from a <!CGI fun> the first 2 lines are discarded and
    the rest is inserted.
    ONLY file with mime text/* are parsed.


13. Archive

    main contains:
    - authfun.rexx            ident service client
    - checkAuth.rexx          check for Authorization
    - checkIP.rexx            check if an ip is k-lined
    - checkSince.rexx         check If-Modified-Since
    - errLog.rexx             log errors
    - getHeadString.rexx      returns an HTTP/1.0 error head from an error code
    - getMime.rexx            returns the mime of a file
    - GMTInetCurrentDate.rexx returns an Internet date string in GMT time of the
                              current system date
    - GMTInetDate.rexx        returns an Internet date string in GMT time
    - GMTInetFileDate.rexx    returns an Internet date string in GMT time of a
                              file date
    - hostname.rexx           returns the current HostName
    - hs.rexx                 the one connection handler, called by hserv for
                              each connection to handle
    - hserv.rexx              the main macro
    - readConfig.rexx         read hserv config files and set ARexx clips
    - transferLog.rexx        log transers

    htdocs contains:
    - contactAlfonso.html
    - counterData
    - def.gif                 the default gif that is inserted in any error
                              responce from server
    - doc.html
    - form.html
    - index.html
    - tiziana.html

    cgi-bin contains:
    - counter.rexx            ARexx cgi counter
    - digits/                 contain an utility and the digits for the counter
    - gmtfiledate.rexx cgi    ARexx function that returns
                              the date of the file passed in Internet format
    - post1.rexx              example of an ARexx cgi, handler of a GET or POST
                              request
    conf contains:
    - auth                    auth example file
    - hserv.conf              default configuration file
    - mime                    mime file
    - rejected                rejected ip example file


14. Bug

    - no way to pass cgi macros local vars, like the ip of the client,
      the arguments of a get or a post and so on, e.g. like apache does.

    That's not a bug:
    "If-Modified-Since" works just on AWeb, ask V and IB why, not me.


15 Changes

    Changes from version < :
    - general rewritten of the request parsing function in hs.rexx
    - general rewritten of the inet date functions
    - no more def.prefs, maybe the server is slower, but that's pretty
      better.