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

index 110212f..d5ae1c5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: httpd.js,v 1.31 2006/08/19 11:43:12 mmondor Exp $ */
+/* $Id: httpd.js,v 1.32 2006/08/20 02:40:24 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.31 2006/08/19 11:43:12 mmondor Exp $';
+const SERVER_CVSID = '$Id: httpd.js,v 1.32 2006/08/20 02:40:24 mmondor Exp $';
 
 
 
@@ -1227,7 +1227,7 @@ FD.prototype.appserv_connect = function(sid, set)
                fd.set = set;
                fd.appserv = s;
 
-               poll_set_add(fd);
+               pollset.add(fd);
        } catch (x) {
                err.put(x + " in appserv_connect()\n");
                return false;
@@ -1506,63 +1506,84 @@ function property_add(obj, prop, val)
 
 
 /*
- * To know how many connections we are currently serving and limit them
- * XXX Could possibly also be integrated into the FD object prototype
+ * Connections limits management
  */
-var counters_connections = 0;
-var counters_addresses = {};
-
-function counters_inc(fd)
+function CLimits(maxtotal, maxaddr)
 {
-       var addr, addrcnt;
+       this.connections = 0;
+       this.addresses = {};
+       this.maxtotal = maxtotal;
+       this.maxaddr = maxaddr;
+}
 
-       if (counters_connections >= options.max_connections)
-               return false;
+CLimits.prototype = {
+       add: function(fd)
+       {
+               var addr, addrcnt;
 
-       addr = fd.client_addr;
-       if ((addrcnt = counters_addresses[addr]) != undefined &&
-           addrcnt >= options.max_connections_addr)
-               return false;
+               if (this.connections >= this.maxtotal)
+                       return false;
 
-       if (addrcnt == undefined)
-               addrcnt = 1;
-       else
-               addrcnt++;
-       counters_addresses[addr] = addrcnt;
+               addr = fd.client_addr;
+               if ((addrcnt = this.addresses[addr]) != undefined &&
+                   addrcnt >= this.maxaddr)
+                       return false;
 
-       return true;
-}
+               if (addrcnt == undefined)
+                       addrcnt = 1;
+               else
+                       addrcnt++;
+               this.addresses[addr] = addrcnt;
+               this.connections++;
 
-function counters_dec(fd)
-{
-       var addr = fd.client_addr;
-       if ((--counters_addresses[addr]) == 0)
-               delete counters_addresses[addr];
+               return true;
+       },
 
-       counters_connections--;
-}
+       remove: function(fd)
+       {
+               var addr;
+
+               addr = fd.client_addr;
+               if ((--this.addresses[addr]) == 0)
+                       delete this.addresses[addr];
 
+               this.connections--;
+       }
+};
 
+var climits = new CLimits();
 
-var fdidx_count = 0;
-var fdidx_min = 0;
 
-var poll_set = {};
 
-function poll_set_add(fd)
-{
+/*
+ * Descriptor polling set management
+ */
 
-       if (fdidx_count > 9999999)
-               fdidx_count = fdidx_min + 1;
-       fd.fdidx = fdidx_count++;
-       poll_set[fd.fdidx] = fd;
+function PollSet()
+{
+       this.count = 0;
+       this.min = 0;
+       this.set = {};
 }
 
-function poll_set_remove(fd)
-{
+PollSet.prototype = {
+       add: function(fd)
+       {
 
-       delete poll_set[fd.fdidx];
-}
+               if (this.count > 9999999)
+                       this.count = this.min + 1;
+               fd.fdidx = this.count++;
+               this.set[fd.fdidx] = fd;
+       },
+
+       remove: function(fd)
+       {
+
+               delete this.set[fd.fdidx];
+       }
+};
+
+var pollset = new PollSet();
 
 
 
@@ -1642,14 +1663,14 @@ function main() {
                         */
                        fd.events = FD.POLLIN;
                        fd.type = STYPE_LISTEN;
-                       poll_set_add(fd);
+                       pollset.add(fd);
                } catch (x) {
                        err.put(x + " preparing listening socket\n");
                }
        }
-       if (fdidx_count == 0)
+       if (pollset.count == 0)
                exit();
-       fdidx_min = fdidx_count;
+       pollset.min = pollset.count;
 
        /*
         * Main loop
@@ -1664,8 +1685,8 @@ function main() {
                var exp = cur + 3600;
                var old;
 
-               for (i in poll_set) {
-                       if ((fd = poll_set[i]) == undefined ||
+               for (i in pollset.set) {
+                       if ((fd = pollset.set[i]) == undefined ||
                            fd.type != STYPE_HTTP)
                                continue;
                        if (fd.expires <= cur) {
@@ -1674,8 +1695,8 @@ function main() {
                                 * descriptor, we must close it.
                                 */
                                fd.close();
-                               counters_dec(fd);
-                               poll_set_remove(fd);
+                               climits.remove(fd);
+                               pollset.remove(fd);
                                continue;
                        }
                        if (fd.expires < exp)
@@ -1684,10 +1705,17 @@ function main() {
                exp -= cur;
 
                /*
-                * Poll our set of descriptors for events
+                * Poll our set of descriptors for events.
+                * XXX We definitely should use libevent here.
+                * The polling set gets regenerated by the C code at every
+                * call, which is suboptimal.  I guess that we still could use
+                * poll while providing C primitives to add/remove descriptors
+                * from the set a-la select(2).  But libevent(3) is always
+                * superior while being able to run on various systems unlike
+                * BSD kqueue(2).
                 */
                try {
-                       e = FD.poll(poll_set, exp * 1000);
+                       e = FD.poll(pollset.set, exp * 1000);
                } catch (x) {
                        err.put(x + " for poll(2)\n");
                        continue;
@@ -1715,6 +1743,7 @@ 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) {
@@ -1738,7 +1767,7 @@ function main() {
                            (efd.revents & FD.POLLIN) != 0) {
                                try {
                                        fd = efd.accept();
-                                       if (!counters_inc(fd)) {
+                                       if (!climits.add(fd)) {
                                                http_error(fd, 403.9,
                                                    'Too Many Connections',
                                    'Your browser has exceeded its maximum ' +
@@ -1752,7 +1781,7 @@ function main() {
                                         * add FD to polling set
                                         */
                                        fd.state_http_init(cur);
-                                       poll_set_add(fd);
+                                       pollset.add(fd);
                                } catch (x) {
                                        err.put(x + " at accept(2)\n");
                                        fd.close();
@@ -1811,8 +1840,8 @@ function main() {
                                         * them to return a 500 error
                                         */
                                }
-                               counters_dec(efd);
-                               poll_set_remove(efd);
+                               climits.remove(efd);
+                               pollset.remove(efd);
                        }
                }
        }