-/* $Id: httpd.js,v 1.13 2005/07/04 23:14:54 mmondor Exp $ */
+/* $Id: httpd.js,v 1.14 2005/07/06 20:33:28 mmondor Exp $ */
/*
* Copyright (c) 2005, Matthew Mondor
* priority at current time.
*
* TODO:
- * - Implement path sanity checking (or import mmpath(3))?
- * So that clients could invoke static files within vhosts
- * - We'll need a vhosts configuration file
* - We probably want to support proxy/cache queries that request if a
* document was modified, which would be ideal for static files, but
* would always return modified status for dynamic data.
}
eval(file_read('options.js')); /* Configuration */
-eval(file_read('ml.js')); /* MLTag object */
+eval(file_read('ml.js')); /* MLTag object for HTML generation */
+eval(file_read('root.js')); /* Root object for virtual chroot(2) */
/*
- * Configuration
+ * Server identification
*/
-LISTEN_ADDRESS = '0.0.0.0';
-const LISTEN_PORT = 8080;
-
SERVER_VERSION = 'mmondor_js_httpd/0.0.1 (NetBSD)';
-SERVER_CVSID = '$Id: httpd.js,v 1.13 2005/07/04 23:14:54 mmondor Exp $';
+SERVER_CVSID = '$Id: httpd.js,v 1.14 2005/07/06 20:33:28 mmondor Exp $';
+/*
+ * Quick lookup object from virtual hosts names and aliases to VHost objects
+ */
+var vhosts_table = {};
+var default_vhost = undefined;
+
+/*
+ * The VHost object
+ */
+function VHost(o)
+{
+ var scripts = false;
+
+ /*
+ * A few properties are definitely required
+ */
+ if (o.name == undefined || o.root == undefined)
+ throw ('name and root properties missing from vhost');
+ this.name = o.name;
+
+ if (o.scripts != undefined && o.scripts == true)
+ scripts = true;
+
+ /*
+ * Create VHost object
+ */
+ try {
+ this.htdocs_root = new Root(o.root + '/htdocs');
+ if (scripts)
+ this.jsinc_root = new Root(o.root + '/jsinc');
+ } catch (x) {
+ throw (x);
+ }
+
+ /*
+ * Link object to vhosts table
+ */
+ if (vhosts_table[o.name] != undefined)
+ throw ('Conflicting vhost name: ' + o.name);
+ vhosts_table[o.name] = this;
+
+ if (o.aliases != undefined) {
+ for (i in o.aliases) {
+ if (vhosts_table[o.aliases[i]] != undefined)
+ throw ('Conflicting vhost alias: ' +
+ o.aliases[i]);
+ vhosts_table[o.aliases[i]] = this;
+ }
+ }
+}
+
+
/*
* The HTTPReply object allows to cache addHeader() and addContent() requests,
* I.E. See rfc2109 for examples about Cookie:
*/
if (valid) {
- valid = false;
-
for (i in lines) {
words = lines[i].split(' ');
if (words[0] == 'Host:') {
if (words.length == 2) {
- this.http_vhost = lines[i].substr(6);
- valid = true;
+ var i2;
+
+ if ((i2 = words[1].indexOf(':')) != -1)
+ words[1] =
+ words[1].substr(0, i2);
+ this.http_vhost = words[1];
}
} else if (words[0] == 'Cookie:') {
words = (lines[i].substr(8)).split('=');
}
/*
+ * If no Host: line set the vhost, set the default one.
+ * If there is a vhost set, but is unknown, also set the default one.
+ * Also set the name of the vhost to the actual vhost name despite
+ * it possibly being resolved through an alias.
+ */
+ if (this.http_vhost == '' ||
+ vhosts_table[this.http_vhost] == undefined)
+ this.http_vhost = options.default_vhost;
+ this.http_vhost = vhosts_table[this.http_vhost].name;
+
+ /*
* Fill in associative array with any GET-style supplied
* variables (as part of the URL). We want this even for POST method.
*/
var i;
/*
+ * Populate vhosts database
+ */
+ for (i in vhosts) {
+ try {
+ var v = new VHost(vhosts[i]);
+ } catch (x) {
+ err.put(x + "\n");
+ }
+ }
+ /*
+ * Attempt to link default_vhost to a VHost object
+ */
+ if (options.default_vhost == undefined) {
+ err.put("No default_vhost property in options, exiting\n");
+ exit();
+ }
+ if (vhosts_table[options.default_vhost] != undefined)
+ default_vhost = vhosts_table[options.default_vhost];
+ else {
+ err.put('Default vhost ' + options.default_vhost +
+ " unkonwn, exiting\n");
+ exit();
+ }
+
+ /*
* Create polling array set
*/
var set = [];
-/* $Id: options.js,v 1.2 2005/07/04 23:14:54 mmondor Exp $ */
+/* $Id: options.js,v 1.3 2005/07/06 20:33:28 mmondor Exp $ */
var options = {
/* Maximum number of concurrent clients that we should serve */
- max_connections: 32,
+ max_connections: 32,
/* Maximum number of concurrent connections per client address */
- max_connections_addr: 4,
+ max_connections_addr: 4,
/* Transfer I/O timeout in seconds before dropping connection */
- io_timeout: 60,
+ io_timeout: 60,
/* Size of I/O buffer to transfer file/data blocks */
- readbuf_size: 16384,
+ readbuf_size: 16384,
/* Default virtual host site to use */
- default_vhost: "localhost"
+ default_vhost: "hal.xisop"
};
/* Address:port combinations to listen to */
var listen = [
{
- address: "127.0.0.1",
- port: 8080
+ address: "127.0.0.1",
+ port: 8080
},
{
- address: "192.168.1.11",
- port: 8080
+ address: "192.168.1.11",
+ port: 8080
}
];
var vhosts = [
/* Default virtual host */
{
- server_admin: "hostmaster@pulsar-zone.net",
- server_name: "hal.xisop",
- server_aliases: [
- "hal",
- "localhost"
- ],
- directory_index: "index.js",
- directory_root: "/home/www/localhost/htdocs",
- directory_include: "/home/www/localhost/jsinc",
- dynamic_scripts: true
+ name: "hal.xisop",
+ aliases: [ "hal", "localhost" ],
+ root: "/home/mmondor/jswww/welcome",
+ scripts: true
},
/* Dynamic application virtual host for ascpi.com */
{
- server_admin: "hostmaster@pulsar-zone.net",
- server_name: "ascpi.com",
- server_aliases: [
- "www.ascpi.com",
- "ascpi.hal.xisop",
- "ascpi.hal"
- ],
- directory_index: "index.js",
- directory_root: "/home/www/ascpi.com/htdocs",
- directory_include: "/home/www/ascpi.com/jsinc",
- dynamic_scripts: true
+ name: "ascpi.com",
+ aliases: [ "www.ascpi.com", "ascpi.hal.xisop",
+ "ascpi.hal" ],
+ root: "/home/mmondor/jswww/ascpi.com",
+ scripts: true
},
/* Static only test virtual host */
{
- server_admin: "hostmaster@pulsar-zone.net",
- server_name: "test.hal.xisop",
- directory_index: "index.html",
- directory_root: "/home/www/test/htdocs",
- dynamic_scripts: false
+ name: "test.hal.xisop",
+ root: "/home/mmondor/jswww/test/htdocs",
+ scripts: false
}
];