*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Sat, 9 Jul 2005 05:47:01 +0000 (05:47 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Sat, 9 Jul 2005 05:47:01 +0000 (05:47 +0000)
tests/js-test/js/httpd/httpd.js
tests/js-test/js/httpd/options.js

index d980a5d..9a1bf2a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: httpd.js,v 1.32 2005/07/08 17:57:28 mmondor Exp $ */
+/* $Id: httpd.js,v 1.33 2005/07/09 05:44:53 mmondor Exp $ */
 
 /*
  * Copyright (c) 2005, Matthew Mondor
@@ -85,6 +85,30 @@ function file_read(file)
        return contents;
 }
 
+/*
+ * Similar to the above function, but works with an already open FD object
+ * and closes it.
+ */
+function file_read2(fd)
+{
+       var contents = '';
+       var data;
+
+       try {
+               for (;;) {
+                       data = fd.read(8192);
+                       if (data.length == 0)
+                               break;
+                       contents += data;
+               }
+       } catch (x) {
+               err.put(x + "\n");
+       }
+       fd.close();
+
+       return contents;
+}
+
 eval(file_read('options.js'));         /* Configuration */
 eval(file_read('ml.js'));              /* MLTag object for HTML generation */
 eval(file_read('root.js'));            /* Root object for virtual chroot(2) */
@@ -95,7 +119,7 @@ eval(file_read('root.js'));          /* Root object for virtual chroot(2) */
  * Server identification
  */
 SERVER_VERSION                 = 'mmondor_js_httpd/0.0.1 (NetBSD)';
-SERVER_CVSID   = '$Id: httpd.js,v 1.32 2005/07/08 17:57:28 mmondor Exp $';
+SERVER_CVSID   = '$Id: httpd.js,v 1.33 2005/07/09 05:44:53 mmondor Exp $';
 
 
 
@@ -232,6 +256,22 @@ var mimetypes_table = {};
 
 
 /*
+ * And our pre-evaluated scripts cache
+ */
+var jso_cache = {};
+
+function JSO(path, time, script)
+{
+       this.path = path;
+       this.time = time;
+       this.script = script;
+
+       jso_cache[this.path] = this;
+}
+
+
+
+/*
  * The HTTPReply object allows to cache addHeader() and addContent() requests,
  * and to eventually flush the whole reply to an arbitrary FD afterwards.
  */
@@ -245,6 +285,7 @@ function HTTPReply(code, desc, type)
        this.desc = desc;
        this.headers = [];
        this.contents = [];
+       this.type = type;
 
        /*
         * Insert our standard headers.
@@ -253,13 +294,17 @@ function HTTPReply(code, desc, type)
        this.headers.push('Date: ' + this.gmttime);
        this.headers.push('Server: ' + SERVER_VERSION);
        this.headers.push('Connection: close');
-       if (type != null)
-               this.headers.push('Content-Type: ' + type);
 }
 /*
  * HTTPReply prototype object
  */
 HTTPReply.prototype = {
+       setType: function(type)
+       {
+
+               this.type = type;
+       },
+
        addHeader: function(data)
        {
 
@@ -295,6 +340,8 @@ HTTPReply.prototype = {
                headers += 'HTTP/1.1 ' + this.code + ' ' + this.desc + "\r\n";
                for (i = 0; i < this.headers.length; i++)
                        headers += this.headers[i] + "\r\n";
+               if (this.type != null)
+                       headers += 'Content-Type: ' + this.type + "\r\n";
                headers += "\r\n";
 
                fd.write(headers + contents);
@@ -839,6 +886,84 @@ FD.prototype.httpRespond = function(time)
                        this.http_vars_session.count++;
 
        /*
+        * Verify if document consists of an .jso (server javascript module)
+        * file, part of a dynamic HTTP application.
+        * Extract file extension, as well as its mime type.
+        */
+       if ((i = path.virtual.lastIndexOf('.')) != -1) {
+               ext = (path.virtual.substr(i + 1)).toLowerCase();
+               if (ext.lastIndexOf('/') == -1 &&
+                   mimetypes_table[ext] != undefined)
+                       mimetype = mimetypes_table[ext];
+               else
+                       mimetype = options.default_mimetype;
+       }
+       mimetype += '; charset=' + (this.http_vhost.charset == undefined ?
+           options.default_charset : this.http_vhost.charset);
+
+       /*
+        * JavaScript Object (JSO) files are processed especially.
+        * We interpret them, providing them with an environment to
+        * access the needed resources (_GET/_POST/_COOKIE variables,
+        * as well as the document object they can use.
+        * We flush the document once the script returns, or fire up
+        * an error if something fails.
+        */
+       if (ext == 'jso') {
+
+               /* Create document object */
+               var obj = new HTTPReply(200, 'OK', mimetype);
+               obj.addNoCacheHeaders();
+               if (cookie != undefined)
+                       obj.addHeader(cookie);
+
+               /* XXX Add other objects to export as necessary */
+               obj._GET = this.http_vars_get;
+               obj._POST = this.http_vars_post;
+               obj._COOKIES = this.http_vars_cookies;
+               obj._SESSION = this.http_vars_session;
+
+               /*
+                * Check if object in our cache already and file not modified
+                * since cached entry.  Reuse function then.  Otherwise,
+                * load in function from file, store a cache entry for it
+                * and launch it.
+                */
+
+               var data, s, o;
+
+               if (((o = jso_cache[path.real]) != undefined) &&
+                   o.time == st.st_mtime)
+                       obj.script = o.script;
+               else {
+                       try {
+                               data = file_read2(fd);
+                               s = 'obj.script = function() {' + data + '}';
+                               eval(s);
+                               o = new JSO(path.real, st.st_mtime,
+                                   obj.script);
+                       } catch (x) {
+                               err.put(x + "\n");
+                               http_error(this, 500, 'Internal Server Error',
+                                   'Please try again later.');
+                               return true;
+                       }
+               }
+
+               try {
+                       if (obj.script != undefined)
+                               obj.script();
+                       obj.flush(this, null);
+               } catch (x) {
+                       err.put(x + "\n");
+                       http_error(this, 500, 'Internal Server Error',
+                           'Please try again later.');
+               }
+
+               return true;
+       }
+
+       /*
         * If client only wanted the document if it wasn't modified since
         * a certain time, report that it wasn't if it is the case.
         */
@@ -861,18 +986,9 @@ FD.prototype.httpRespond = function(time)
        this.events = FD.POLLOUT;
 
        /*
-        * Obtain mimetype for file and flush HTTP header.
-        * Then return with close=false, to delegate operations to
-        * process_transfer().
+        * Flush HTTP header.  Then return with close=false, to delegate
+        * operations to process_transfer().
         */
-       if ((i = path.virtual.lastIndexOf('.')) != -1) {
-               ext = (path.virtual.substr(i + 1)).toLowerCase();
-               if (ext.lastIndexOf('/') == -1 &&
-                   mimetypes_table[ext] != undefined)
-                       mimetype = mimetypes_table[ext];
-       }
-       mimetype += '; charset=' + (this.http_vhost.charset == undefined ?
-           options.default_charset : this.http_vhost.charset);
        res = new HTTPReply(200, 'OK', mimetype);
        if (cookie != undefined)
                res.addHeader(cookie);
@@ -1128,6 +1244,8 @@ function main() {
                        mimetypes_table[ext] = i;
                }
        }
+       if (mimetypes_table['jso'] == undefined)
+               mimetypes_table['jso'] = 'text/html';
 
        /*
         * Create polling array set
index 931d305..2012c0f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: options.js,v 1.8 2005/07/07 20:48:41 mmondor Exp $ */
+/* $Id: options.js,v 1.9 2005/07/09 05:47:01 mmondor Exp $ */
 
 var options = {
        /* Maximum number of concurrent clients that we should serve */
@@ -58,7 +58,8 @@ var vhosts = [
 ];
 
 var mimetypes  = {
-       'text/html':                            [ "html", "htm", "dhtml" ],
+       'text/html':                            [ "html", "htm", "dhtml",
+                                                   "jso" ],
        'text/plain':                           [ "txt" ],
        'text/css':                             [ "css" ],
        'application/pdf':                      [ "pdf" ],