;;; mhttpd.conf: -*- Meta-HTML -*- Server configuration file for MHTTPD.
;;;
;;; Author: Brian J. Fox (bfox@ai.mit.edu) Sat Nov 11 08:21:43 1995.
;;;
;;; This file is part of <Meta-HTML>(tm), a system for the rapid
;;; deployment of Internet and Intranet applications via the use
;;; of the Meta-HTML language.
;;; 
;;; Copyright (c) 1995, 1996, Brian J. Fox (bfox@ai.mit.edu).
;;; Copyright (c) 1996, Universal Access Inc. (http://www.ua.com).
;;; 
;;; Meta-HTML is free software; you can redistribute it and/or modify
;;; it under the terms of the UAI Free Software License as published
;;; by Universal Access Inc.; either version 1, or (at your option) any
;;; later version.
;;; 
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; UAI Free Software License for more details.
;;; 
;;; You should have received a copy of the UAI Free Software License
;;; along with this program; if you have not, you may obtain one by
;;; writing to:
;;; 
;;; Universal Access Inc.
;;; 129 El Paseo Court
;;; Santa Barbara, CA
;;; 93101

;;; Use cookies that don't bug.
<set-var mhtml::permanent-cookies = true>

;;; The user that you would like the server to run under.
;;; This only has an effect if the server is already running as the
;;; root user.
;;; <set-var mhtml::default-user = nobody>

;;; Allow a local parameter file to override the following definitions.
<include local.conf>

;;; The name of the file to write the PID of this server into on startup.
;;; The file is stored in the same directory as this config file.
;;; If not set, the name defaults to "mhttpd.pid".
;;; <defvar mhttpd::pid-filename mhttpd.pid>

;;; If you wish to allow your users to store documents underneath
;;; their home directories, then set this variable to be the name of
;;; the subdirectory under which users store their documents.  For
;;; example, if the URL "/~bfox/welcome.mhtml" should be served from
;;; a subdirectory of Brian Fox's home directory called "public_html",
;;; then you would do:
;;;
;;; <defvar mhtml::~directory  public_html>

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Variables which control the behaviour of the server.
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; MHTML::SERVER-NAME is the name that this server should advertise.
;;; If you do not set it, the value of gethostname () is used.
<defvar mhtml::server-name  localhost>

;;; MHTML::SERVER-PORT is the port on which this server should listen.
;;; If you do not set it, the value is "80".
<defvar mhtml::server-port <if <get-var mhttpd::ssl-server> 443 80>>

;;; MHTML::SSL-PORT is a convenience for letting this configuration file
;;; be useful for both non-SSL and SSL servers.  If the server is started
;;; in SSL mode, the value of mhtml::ssl-port is used for the port, else
;;; the value of mhtml::server-port is used, else the value is 443.
;;; <set-var mhtml::ssl-port = 80>

;;; MHTML::SERVER-ROOT is the root location for your server.  You might
;;; store the configuration, logging, and server specific files there,
;;; for example.  You currently cannot store your CGIs there, because
;;; that directory must be underneath MHTML::DOCUMENT-ROOT.
;;; The pathname should not end in a slash.
<defvar mhtml::server-root "/www/localhost">

;;; MHTML::DOCUMENT-ROOT is a complete path to the directory from
;;; which your documents are to be served.  The final slash should not
;;; be present.
<defvar mhtml::document-root "<get-var mhtml::server-root>/docs">

;;; MHTTPD::ADMIN-ROOT is the complete path to the directory tree
;;; which contains server administration pages.  Usually set to
;;; ".../conf/admin".
;;; <set-var mhttpd::admin-root = "<get-var mhtml::include-prefix>/admin">

;;; MHTTPD::ADMIN-PORT is the port number on which this server should
;;; listen for administration requests.  Generally set to 8008.
;;; If no such port is specified, then the server will not listen for
;;; administration requests at all.
;;; <set-var mhttpd::admin-port = 8008>

;;; MHTTPD::SESSION-DATABASE-FILE is a complete path to the file which
;;; will be used to store per-session information for users which have
;;; sessions.  If it is not set, it defaults to `/tmp/sessions.db'.
<defvar mhttpd::session-database-file <get-var mhtml::server-root>/sessions.db>

;;; MHTTPD::GET-REMOTE-IDENT when set says to use the IDENT protocol to
;;; attempt to find out the username associated with the connecting
;;; browser.  This only has a minor effect on server performance, but
;;; isn't especially useful for non-Meta-HTML sites.
;;; <set-var mhttpd::get-remote-ident = true>

;;; If MHTTPD::CACHE-DNS is non-empty, it indicates that the server should
;;; first try to resolve the names of hosts from addresses stored in a
;;; local database (usually, /tmp/mhttpd-dns.cache).  Otherwise, if the
;;; variable MHTTPD::GET-REMOTE-HOST does not exist, or is set to "true",
;;; then each request will be resolved via DNS lookup.
<set-var mhttpd::cache-dns = true>

;;; MHTML::MHTTPD-PAGES is the directory containing various pages used
;;; by the server for displaying error conditions, directory files, etc.
;;; This is a complete path to the directory, without the
;;; trailing slash.
<defvar mhtml::mhttpd-pages <get-var mhtml::server-root>/mhttpd-pages>

;;; MHTML::REQUIRE-DIRECTORIES is an array of directory names in webspace
;;; where the <require> command should look.  If it is not specified, only
;;; "." (i.e., the current directory) is used.  Otherwise, it contains
;;; the directories to search for files matching the stem passed in
;;; <require STEM>.  The following value has been chosen because it matches
;;; almost every case we've encountered.
<defvar mhtml::require-directories[]
  <concat ".\ntagsets\nmacros\nincludes\n"
	  "../\n../tagsets\n../macros\n../includes\n"
	  "../../\n../../tagsets\n../../macros\n../../includes\n"
	  "/tagsets\n/macros\n/includes">>

;;; MHTML::ACCESS-LOG is the full path to a file to which the server
;;; logs document accesses.
<if <string-eq <get-var mhtml::access-log> false>
    <unset-var mhtml::access-log>
  <defvar mhtml::access-log "<get-var mhtml::server-root>/logs/access_log">>

;;; MHTML::ERROR-LOG is the full path to a file to which the server
;;; logs errors.
<if <string-eq <get-var mhtml::error-log> false>
    <unset-var mhtml::error-log>
  <defvar mhtml::error-log "<get-var mhtml::server-root>/logs/error_log">>

;;; MHTML::DEBUG-LOG is the full path to a file to which the server
;;; logs debugging information.  Don't turn this on.  It's presence
;;; makes the server run slow.  Without the source to the server, this
;;; does you no good anyway.
<if <string-eq <get-var mhtml::debug-log> false>
    <unset-var mhtml::debug-log>>

;;; When MHTML::LOG-PERFORMANCE is non-null, MHTML::DEBUG-LOG gets
;;; messages about the performance of the server.
;;; <set-var mhtml::log-performance=true>

;;; MHTML::REFERER-LOG is the full path to a file to which the server
;;; logs non-image, external reference information.  This is only
;;; provided for direct compatibility with some other servers, since
;;; you could do a lot better writing the functionality in Meta-HTML,
;;; and storing that in the prologue.  However, it works for
;;; non-Meta-HTML documents, so there may be some benefit.
<if <string-eq <get-var mhtml::referer-log> false>
    <unset-var mhtml::referer-log>
  <defvar mhtml::referer-log "<get-var mhtml::server-root>/logs/referer_log">>

;;; MHTML::AGENT-LOG is the full path to a file to which the server
;;; logs the User-Agent header of connections.  Like MHTML::REFERER-LOG,
;;; this is only provided for direct compatibility with some other
;;; servers, since you could do a lot better writing the functionality
;;; in Meta-HTML.
;;; <set-var mhtml::agent-log = "<get-var mhtml::server-root>/logs/agent_log">

;;;
;;; Most of this logging stuff is for the birds.  Using the Meta-HTML
;;; server allows the configurer to write code that executes within
;;; the server process.  Define MHTTPD::PER-REQUEST-FUNCTION as the
;;; name of a Meta-HTML defsubst, and that subst will be run with
;;; no arguments for each document fetch.  The following variables
;;; are defined just prior to running the function:
;;;
;;;    mhttpd::method			GET, POST, HEAD, etc.
;;;    mhttpd::protocol			HTTP, HTTPS, SHTTP, etc.
;;;    mhttpd::protocol-version		1.0, 2.0, etc.
;;;    mhttpd::location			The URL that the user requested.
;;;    mhttpd-received-headers::	Package containing variable names
;;;					made up of the received headers,
;;;					set to the values they were given.
;;;
;;; Here is an example function which keeps track of the number of
;;; different browsers which connect.
<defun mhttpd::browser-stats>
  <when <get-var mhttpd-received-headers::User-Agent>>
    <with-open-database
     db <get-var mhtml::server-root>/logs/browser.db mode=write-create>
      <database-load-record db <get-var mhttpd-received-headers::User-Agent>>
      <if <not <get-var browser>>
	  <set-var browser=<get-var mhttpd-received-headers::User-Agent>>>
      <increment times-hit>
      <database-save-record db <get-var browser> browser times-hit>
    </with-open-database>
  </when>
</defun>

;;; And then, to install it:
;;; <set-var mhttpd::per-request-function = mhttpd::browser-stats>

;;; MHTML::PROLOGUE-DOCUMENT is a per-connection file of code to be
;;; run just before processing any Meta-HTML document.
<defvar mhtml::prologue-document "<get-var mhtml::server-root>/prologue.mhtml">

;;; Analogous to MHTML::PROLOGUE-DOCUMENT is MHTML::PER-PAGE-FUNCTION.
;;; You probably only need one or the other, but not both.  If this
;;; variable is set to the name of a defun, defsubst, or defmacro,
;;; then that function is called with no arguments.  Here is the
;;; default that we recommend -- it makes all posted data innocuous.
;;;
;;; If you turn this off, you will have to make sure that your pages
;;; are written in a secure fashion.  Please see the manual
;;; description of <get-var-once> for more details.
;;;

;;;
;;; THIS FUNCTION IS NOW DEFINED IN /libmhtml/tagsets/mhttpd.mhtml
;;;
;;; <defun mhtml::post-secure>
;;;   <set-var names[]=<package-vars posted strip=true>>
;;;   <set-var i=0>
;;;   <while <get-var-once names[i]>>
;;;     <when <match <symbol-info posted::<get-var-once names[i]>> STRING>>
;;;       <copy-var POSTED::<get-var-once names[i]>
;;; 		DEFAULT::<get-var-once names[i]>>
;;;       <subst-in-var <get-var-once names[i]>
;;;			 "&" "&amp;" "<" "&lt;" ">" "&gt;">
;;;     </when>
;;;     <increment i>
;;;   </while>
;;; </defun>

<set-var mhtml::per-page-function = mhtml::post-secure>

;;; MHTML::EPILOGUE-DOCUMENT is a per-connection file of code to be
;;; appended to the page just before processing any Meta-HTML document.
<defvar mhtml::epilogue-document "<get-var mhtml::server-root>/epilogue.mhtml">

;;; MHTML::RESPONSE-TIMEOUT is the maximum number of seconds a
;;; connection may last.  The default value is 120 (i.e., 2 minutes).
;;; Empirically, this looks like the right amount.
;;;
;;; If you make this small, then browsers which send the request
;;; header "Connection: Keep-Alive" may be shut off before all of
;;; their requests are answered.  If you make it large, then Meta-HTML
;;; documents which loop internally (such as <page-subst-in-page "" "a">)
;;; can cause the  client to wait a long time.
<defvar mhtml::response-timeout 120>

;;; Used to control the maximum loop iterations within a WHILE, or
;;; other looping construct.  When not set, defaults to 500.
<defvar mhtml::iteration-limit 500>

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; There are two ways to do path translation, mutually exclusive of
;;; each other.
;;;
;;; The first (and recommended way) is to set the variable
;;; mhtml::path-translations to a comma separated string.  The even
;;; elements of the string are substrings to search for in the
;;; incoming URL, and the odd elements are the replacements.
;;; For example:
;;;
;;;    <set-var mhtml::path-translations = "/~,/home-pages/,perl-bin,cgi-bin">
;;;
;;; says that if the incoming URL is:
;;;
;;;    /project/~bfox/progs/perl-bin/foo
;;;
;;; the actual physical location will be:
;;;
;;;   /project/home-pages/bfox/progs/cgi-bin/foo
;;;
;;; The second way is to define a function `mhtml::path-translate'
;;; which handles path translations.  The input is the incoming URL,
;;; and the output is the translation.  Here is an example of a
;;; path-translation function which changes the path based on browser
;;; type:
;;;
;;; <defun mhtml::path-translate path>
;;;   <set-var temp=<get-var-once path>>
;;;   <subst-in-var temp "/browser/" <get-var env::http_user_agent>>
;;;   <if <mhtml::file-exists-p <get-var temp>>
;;;       <get-var temp>
;;;     <get-var path>>
;;; </defun>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; How to tell if an URL prefix is executable or not.
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; MHTML::EXEC-PATH is what gets passed in the environment to CGI
;;; programs as PATH.  Choose carefully.
<defvar mhtml::exec-path
  <concat /opt/metahtml/bin:/www/bin:/<get-var mhtml::document-root>/cgi-bin
	  :<get-var mhtml::server-root>/bin:/bin:/usr/bin:/usr/local/bin
	  :/usr/ucb>>

;;; The array `MHTML::CGI-DIRECTORIES[]' is a list of physical
;;; paths relative to the document root which are directories
;;; containing CGI programs.  The paths are checked *after* path
;;; translation has been performed.  The final slash must be
;;; specified.
<set-var mhtml::cgi-directories[]="" mhtml::cgi-directories-index=0>

<defun mhtml::add-cgi-directory dir>
  <set-var mhtml::cgi-directories[mhtml::cgi-directories-index]=<get-var dir>>
  <increment mhtml::cgi-directories-index>
</defun>

;;;
;;; The default setting is <document-root>/cgi-bin/.
<mhtml::add-cgi-directory /cgi-bin/>

;;;
;;; Another way to specify that a particular file is executable is use
;;; of a special filename extension.  You specify those extensions in
;;; the array `mhtml::cgi-extensions[]'.  I personally find this a
;;; little grotesque, but your mileage may vary.
<set-var mhtml::cgi-extensions[]="" mhtml::cgi-extensions-index=0>

<defun mhtml::add-cgi-extension ext>
  <set-var mhtml::cgi-extensions[mhtml::cgi-extensions-index]=".<get-var ext>">
  <increment mhtml::cgi-extensions-index>
</defun>

;;; <mhtml::add-cgi-extension cgi>
;;; <mhtml::add-cgi-extension pl>
;;; <mhtml::add-cgi-extension exe>
;;;

;;;
;;; Finally, CGI's can be specified by exact name.  We don't highly
;;; recommend this method, as the lookup table can grow quite large,
;;; and this could impact server performance.  However, sometimes this
;;; is the most aesthetic way of specifying a particular CGI.
;;;
;;; The array mhtml::cgi-urls contains the physical pathnames of these
;;; executables, after path translation and SID removal.
;;;
;;; <set-var mhtml::cgi-urls[0]="/Welcome">

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; If a directory is specified as the URL, and you would like
;;; the server to simply select a particular document to satisfy
;;; that URL, place the name of the file here.
;;;
;;; The array `mhtml::default-filenames[]' contains the names of the
;;; files to try, in order.

<set-var mhtml::default-filenames-index=0 mhtml::default-filenames[]="">

<defun mhtml::add-default-filename name>
  <set-var mhtml::default-filenames[mhtml::default-filenames-index] =
    <get-var name>>
  <increment mhtml::default-filenames-index>
</defun>

<mhtml::add-default-filename Welcome.mhtml>
<mhtml::add-default-filename welcome.mhtml>
<mhtml::add-default-filename Welcome.html>
<mhtml::add-default-filename welcome.html>

<mhtml::add-default-filename Index.mhtml>
<mhtml::add-default-filename index.mhtml>
<mhtml::add-default-filename Index.html>
<mhtml::add-default-filename index.html>

<mhtml::add-default-filename Home.mhtml>
<mhtml::add-default-filename home.mhtml>
<mhtml::add-default-filename Home.html>
<mhtml::add-default-filename home.html>

;;; <mhtml::add-default-filename Begin.mhtml>
;;; <mhtml::add-default-filename begin.mhtml>

<mhtml::add-default-filename Directory.mhtml>
<mhtml::add-default-filename directory.mhtml>

;;; Access Restriction.
;;;
;;; Access restriction is controlled by the contents of the server
;;; packages MHTTPD-ALLOW and MHTTPD-DENY.  If these packages exist,
;;; then each URL is checked for as a symbol in both packages.  The
;;; value of that symbol is a regular expression which allows/denies
;;; access to that particular URL.
;;;
;;; The URL is looked in the space of what the client sees, not in the
;;; physical space of the server.  It is prefixed with the access
;;; method and a vertical bar, as in "get|/foo/bar/password.cgi".
;;;
;;; The access method may be "*", in which case all methods are a
;;; match.
;;;
;;; For example, if you want to restrict access to GET "/foo/bar.cgi"
;;; to only the hosts in the foobar.com domain, you would set the
;;; variable /foo/bar.cgi in the MHTTPD-ALLOW package:
;;;
;;;    <set-var mhttpd-allow::get|/foo/bar.cgi = ".*foobar.com">
;;; 
;;; And, to deny both AOL and COMPUSERV users access to /porn/*
;;;
;;;    <set-var mhttpd-deny::*|/porn/.* = "(.*AOL\\.com|.*COMPUSERV\\.com)">
;;;
;;; Note particularly that the method specifier is plain text or
;;; "*", not a regular expression, while the URL specifier is always a
;;; regular expression.  This means that you should escape special
;;; characters in the URL that you allow/deny, such as "\\.".
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Mime-Types, and disposition of certain document types.
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Array of mime-type to file name extension mappings.
;;;
;;; To make a particular file be interpreted by Meta-HTML, the
;;; filename extension should map to metahtml/interpreted.
;;; Note that by default, files ending in .html are not run through
;;; the interpreter, only files ending in .mhtml are.
;;;
;;; The most basic way to install a mime-type mapping is to set the
;;; filename extension variable in the `MIME-TYPES' package to be the
;;; mime-type to return.  For example:
;;;
;;;  <set-var mime-type::.html=metahtml/interpreted>
;;;
;;; causes a file whose name ends in ".html" to be run through the
;;; Meta-HTML interpreter.
;;;
<defmacro mhtml::mime-type-mappings package=local>
  <set-var temp[]="%body" i=0 m=0 mhtml::metahtml-extensions[]="">
  <while <get-var temp[i]>>
    <set-var mapping=<get-var temp[i]>>
    <subst-in-var mapping "[ \t]+" "\n">
    <set-var mapping[]=<get-var mapping> j=1>
    <while <get-var mapping[j]>>
      <if <match <get-var mapping[0]> "metahtml/interpreted">
	  <prog
	    <set-var mhtml::metahtml-extensions[m]=".<get-var mapping[j]>">
	    <increment m>>>
      <set-var mime-type::.<get-var mapping[j]> = "<get-var mapping[0]>">
      <increment j>
    </while>
    <increment i>
  </while>
</defmacro>

<mhtml::mime-type-mappings>
  metahtml/interpreted		mhtml
  application/activemessage
  application/andrew-inset
  application/applefile
  application/atomicmail
  application/dca-rft
  application/dec-dx
  application/x-java		class
  application/x-javascript	js
  application/mac-binhex40	hqx
  application/macwriteii	mii
  application/msword		Microsoft-Sux
  application/news-message-id
  application/news-transmission
  application/octet-stream	bin
  application/oda		oda
  application/data		exe
  application/pdf		pdf
  application/postscript	ai eps ps
  application/remote-printing
  application/rtf		rtf
  application/slate
  application/x-mif		mif
  application/wita
  application/wordperfect5.1
  application/x-csh		csh
  application/x-dvi		dvi
  application/x-hdf		hdf
  application/x-latex		latex
  application/x-netcdf		nc cdf
  application/x-sh		sh
  application/x-tcl		tcl
  application/x-tex		tex
  application/x-texinfo		texinfo texi
  application/x-troff		t tr roff
  application/x-troff-man	man
  application/x-troff-me	me
  application/x-troff-ms	ms
  application/x-wais-source	src
  application/zip		zip
  application/x-bcpio		bcpio
  application/x-cpio		cpio
  application/x-gtar		gtar
  application/x-shar		shar
  application/x-sv4cpio		sv4cpio
  application/x-sv4crc		sv4crc
  application/x-tar		tar tgz gz
  application/x-ustar		ustar
  audio/basic			au snd
  audio/x-aiff			aif aiff aifc
  audio/x-wav			wav
  audio/midi			mid
  image/gif			gif
  image/ief			ief
  image/jpeg			jpeg jpg jpe
  image/tiff			tiff tif
  image/x-cmu-raster		ras
  image/x-portable-anymap	pnm
  image/x-portable-bitmap	pbm
  image/x-portable-graymap	pgm
  image/x-portable-pixmap	ppm
  image/x-rgb			rgb
  image/x-xbitmap		xbm
  image/x-xpixmap		xpm
  image/x-xwindowdump		xwd
  message/external-body
  message/news
  message/partial
  message/rfc822
  metahtml/verbatim		vmhtml
  multipart/alternative
  multipart/appledouble
  multipart/digest
  multipart/mixed
  multipart/parallel
  text/html			html htm
  text/html			default
  text/plain			txt java
  text/richtext			rtx
  text/tab-separated-values	tsv
  text/x-setext			etx
  video/mpeg			mpeg mpg mpe
  video/quicktime		qt mov
  video/x-msvideo		avi
  video/x-sgi-movie		movie
  application/x-director	dcr dir dxr
</mhtml::mime-type-mappings>
