*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Sun, 20 Aug 2006 05:32:28 +0000 (05:32 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Sun, 20 Aug 2006 05:32:28 +0000 (05:32 +0000)
mmsoftware/js/js-sh/app/httpd/httpd.js

index d5ae1c5..2f83084 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: httpd.js,v 1.32 2006/08/20 02:40:24 mmondor Exp $ */
+/* $Id: httpd.js,v 1.33 2006/08/20 05:32:28 mmondor Exp $ */
 
 /*
  * Copyright (c) 2005-2006, Matthew Mondor
@@ -76,7 +76,7 @@
  * Server identification
  */
 const SERVER_VERSION = 'mmondor_js_httpd/0.1.0 (NetBSD)';
-const SERVER_CVSID = '$Id: httpd.js,v 1.32 2006/08/20 02:40:24 mmondor Exp $';
+const SERVER_CVSID = '$Id: httpd.js,v 1.33 2006/08/20 05:32:28 mmondor Exp $';
 
 
 
@@ -338,26 +338,27 @@ VHost.prototype = {
        host_appmatch: function(p)
        {
                var b, o;
+               var appserv = this.appserv;
 
                b = false;
 
-               if (this.appserv == undefined)
+               if (appserv == undefined)
                        return b;
 
-               o = this.appserv.paths;
+               o = appserv.paths;
 
-               if (this.paths_cache[p] != undefined)
-                       return this.paths_cache[p];
+               if (appserv.paths_cache[p] != undefined)
+                       return appserv.paths_cache[p];
 
-               if (++this.paths_cache_items == this.paths_cache_max) {
-                       this.paths_cache = {};
-                       this.paths_cache_items = 1;
+               if (++appserv.paths_cache_items == appserv.paths_cache_max) {
+                       appserv.paths_cache = {};
+                       appserv.paths_cache_items = 1;
                }
                for (i in o) {
-                       if (h.match(o[i]))
+                       if (p.match(o[i]))
                                b = true;
                }
-               this.paths_cache[p] = b;
+               appserv.paths_cache[p] = b;
 
                return b;
        }
@@ -701,7 +702,9 @@ FD.prototype.parseQuery = function(time)
        var lines;
        var words;
        var i;
+       /*
        var sessid, sess;
+       */
 
        /* Initial HTTP query state */
        this.http_protocol = '';
@@ -714,7 +717,9 @@ FD.prototype.parseQuery = function(time)
        this.http_agent = '';
        this.http_content_length = -1;
        this.http_modified_since = undefined;
+       /*
        this.http_sessid = undefined;
+       */
        this.http_range = undefined;
        this.http_old_get = false;
 
@@ -841,11 +846,13 @@ FD.prototype.parseQuery = function(time)
         * nothing to do otherwise other than make sure it's valid and be able
         * to associate SID->FD
         */
+       /*
        if (this.http_vhost.appserver != undefined &&
            (sessid = this.http_vars_cookies['SessionID']) != undefined &&
            (sess = sessions_table[sessid]) != undefined &&
            sess.expires > time)
                this.http_sessid = sessid;
+        */
 
        /*
         * Fill in associative array with any GET-style supplied
@@ -933,7 +940,10 @@ FD.prototype.parsePost = function(time)
  */
 FD.prototype.httpRespond = function(time)
 {
-       var path, fd, st, res, ext, mimetype, i, sess, size;
+       var path, fd, st, res, ext, mimetype, i, size, appserv_match, error;
+       /*
+       var sess;
+       */
 
        /*
         * Verify if requested path is valid
@@ -946,16 +956,18 @@ FD.prototype.httpRespond = function(time)
                return PSTAT_CLOSE_SUCCESS;
        }
 
+       appserv_match = this.http_vhost.host_appmatch(path.virtual);
+
        /*
         * General strategy:
-        * 1) Verify if path matches appserver, if so jump to appserver
-        *    forwarding code.
+        * 1) Verify if path matches appserver, if so ensure that client
+        *    supports cookies, then proceed with the forwarding code.
         * 2) Attempt to open file, return 404 or 403 on failure.
         *    On success, if it consists of a directory, apply index path,
         *    match again against appserver paths, close fd and forward to
         *    appserver also if so.  If not, close dir fd and attempt to open
         *    again after applying index.  On failure, return 404 or 403.
-        * 3) If file successfully opened, upliad it to client.
+        * 3) If file successfully opened, upload it to client.
         * 4) If to forward request to appserver, perform the following:
         *
         * 1) Verify if session cookie provided.  If not, invoke appserver
@@ -991,40 +1003,107 @@ FD.prototype.httpRespond = function(time)
         * keep it open and continue downwards with the stat info already
         * filled in.
         */
-       fd = new FD();
-
-       try {
-               fd.open(path.real, FD.O_RDONLY);
-               st = fd.fstat();
-       } catch (x) {
-               http_error(this, 404, 'Not Found',
-                   path.virtual + ' could not be found.');
-               return PSTAT_CLOSE_SUCCESS;
-       }
-
-       if ((st.st_mode & FD.S_IFDIR) != 0) {   /* Directory */
-               var error = false;
+       if (!appserv_match) {
+               fd = new FD();
 
-               /*
-                * XXX Refit URL to configured index,
-                * check if under appserver path and if so process accordingly
-                * else check if there's a file under it.
-                */
-               fd.close();
                try {
-                       fd.open(path.real + '/index.html', FD.O_RDONLY);
+                       fd.open(path.real, FD.O_RDONLY);
                        st = fd.fstat();
-                       path.real += '/index.html';
-                       path.virtual += '/index.html';
                } catch (x) {
-                       error = true;
-               }
-               if (error) {
-                       http_error(this, 403, 'Permission Denied',
-                           'You do not have the permission to access the ' +
-                           'resource ' + path.virtual + '.');
+                       http_error(this, 404, 'Not Found',
+                           path.virtual + ' could not be found.');
                        return PSTAT_CLOSE_SUCCESS;
                }
+
+               if ((st.st_mode & FD.S_IFDIR) != 0) {   /* Directory */
+                       error = false;
+
+                       /*
+                        * Refit URL to configured index,
+                        * check if under appserver path and if so process
+                        * accordingly, else check if there's a file under it.
+                        */
+                       try {
+                               fd.close();
+                       } catch (x) {}
+                       if (this.http_vhost.index.charAt(1) == '/') {
+                               /*
+                                * Index points to absolute path, so recompute
+                                * path
+                                */
+                               path = this.http_vhost.htdocs_root.
+                                   valid_virtual(this.http_vhost.index);
+                               if (!path)
+                                       error = true;
+                       } else {
+                               /*
+                                * We simply need to append the index path and
+                                * retry
+                                */
+                               path.real += this.http_vhost.index;
+                               path.virtual += this.http_vhost.index;
+                       }
+
+                       /*
+                        * Verify again if new index matches an appserv path
+                        */
+                       if (!error) {
+                               appserv_match = this.http_vhost.host_appmatch(
+                                   path.virtual);
+
+                               /*
+                                * Not under appserv, attempt to reopen file
+                                */
+                               if (!appserv_match) {
+                                       try {
+                                               fd.open(path.real,
+                                                   FD.O_RDONLY);
+                                               st = fd.fstat();
+                                       } catch (x) {
+                                               error = true;
+                                       }
+                               }
+                       }
+
+                       if (error) {
+                               http_error(this, 403, 'Permission Denied',
+                                   'You do not have the permission to ' +
+                                   'access the resource ' + path.virtual +
+                                   '.');
+                               return PSTAT_CLOSE_SUCCESS;
+                       }
+               }
+       }
+
+       /*
+        * If under appserv path, make sure client supports HTTP cookies.
+        * We do this by verifying that we are able to obtain a "cookie=yes"
+        * cookie, without which we send one to the client redirecting to the
+        * same URL.
+        */
+       if (appserv_match && this.http_vars_cookies['cookies'] == undefined) {
+               /* Ensure that client supports HTTP cookies */
+               doc = new HTTPReply(200, "OK",
+                   'text/html; charset=' + options.default_charset);
+               doc.addNoCacheHeaders();
+               doc.addHeader('Set-Cookie: cookies=yes; path=/');
+               doc.addContent('<html><head><META HTTP-EQUIV="refresh" ' +
+                   'CONTENT="5; URL=' + path.virtual + '"><title>Cookies' +
+                   '</title></head><body><h1>Cookies</h1><p>We are ' +
+                   ' verifying if your browser supports HTTP cookies.  ' +
+                   'These are required to keep persistent session data ' +
+                   'among your connections.  The destination page should ' +
+                   'load automatically in a few seconds.</p>' +
+                   ' <p>If it doesn\'t, please ensure that HTTP cookies ' +
+                   'are enabled on your HTTP client and are accepted ' +
+                   'from this server.</p>' +
+                   '<p>If the page still does not load properly after a ' +
+                   'few seconds, please click on <a href="' + path.virtual +
+                   '">this link</a>.</p><br><sub>' + SERVER_VERSION +
+                   '<br>' + SERVER_CVSID + '</sub></body></html>');
+               doc.flush(this, null);
+
+               return PSTAT_CLOSE_SUCCESS;
        }
 
        /*
@@ -1074,10 +1153,19 @@ FD.prototype.httpRespond = function(time)
        }
        */
 
+       /* XXX */
+       if (appserv_match) {
+               http_error(this, 500, 'Internal Server Error',
+                   'You have requested an application server handled path ' +
+                   'which cannot be handled at this time.  Please try ' +
+                   'again later.');
+               return PSTAT_CLOSE_SUCCESS;
+       }
+
        /*
         * Only continue if file is a regular file
         */
-       if ((st.st_mode & FD.S_IFREG) == 0) {
+       if (!appserv_match && (st.st_mode & FD.S_IFREG) == 0) {
                fd.close();
                http_error(this, 403, 'Permission Denied',
                    'You do not have the permission to access the resource ' +
@@ -1508,6 +1596,7 @@ function property_add(obj, prop, val)
 /*
  * Connections limits management
  */
+
 function CLimits(maxtotal, maxaddr)
 {
        this.connections = 0;
@@ -1592,7 +1681,9 @@ var pollset = new PollSet();
  */
 function main() {
        var i;
+       /*
        var sess_gc_secs = 0;
+       */
        var fd, e, efd, flush;
 
        /*
@@ -1745,11 +1836,13 @@ function main() {
                 * Verify if we should call the session gc, and if so, do so.
                 * XXX We probably shouldn't do this anymore
                 */
+               /*
                sess_gc_secs += cur - old;
                if (sess_gc_secs >= options.sess_gc_interval) {
                        sess_gc_secs = 0;
                        session_gc(cur);
                }
+               */
 
                /*
                 * Run through set of descriptors with pending events