]> git.cworth.org Git - obsolete/notmuch-web/blobdiff - node_modules/express/node_modules/connect/lib/http.js
Install the "express" node module via npm
[obsolete/notmuch-web] / node_modules / express / node_modules / connect / lib / http.js
diff --git a/node_modules/express/node_modules/connect/lib/http.js b/node_modules/express/node_modules/connect/lib/http.js
new file mode 100644 (file)
index 0000000..6ffc5cc
--- /dev/null
@@ -0,0 +1,218 @@
+
+/*!
+ * Connect - HTTPServer
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var http = require('http')
+  , parse = require('url').parse
+  , assert = require('assert');
+
+// environment
+
+var env = process.env.NODE_ENV || 'development';
+
+/**
+ * Initialize a new `Server` with the given `middleware`.
+ *
+ * Examples:
+ *
+ *     var server = connect.createServer(
+ *         connect.favicon()
+ *       , connect.logger()
+ *       , connect.static(__dirname + '/public')
+ *     );
+ *
+ * @params {Array} middleware 
+ * @return {Server}
+ * @api public
+ */
+
+var Server = exports.Server = function HTTPServer(middleware) {
+  this.stack = [];
+  middleware.forEach(function(fn){
+    this.use(fn);
+  }, this);
+  http.Server.call(this, this.handle);
+};
+
+/**
+ * Inherit from `http.Server.prototype`.
+ */
+
+Server.prototype.__proto__ = http.Server.prototype;
+
+/**
+ * Utilize the given middleware `handle` to the given `route`,
+ * defaulting to _/_. This "route" is the mount-point for the
+ * middleware, when given a value other than _/_ the middleware
+ * is only effective when that segment is present in the request's
+ * pathname.
+ *
+ * For example if we were to mount a function at _/admin_, it would
+ * be invoked on _/admin_, and _/admin/settings_, however it would
+ * not be invoked for _/_, or _/posts_.
+ *
+ * This is effectively the same as passing middleware to `connect.createServer()`,
+ * however provides a progressive api.
+ *
+ * Examples:
+ *
+ *      var server = connect.createServer();
+ *      server.use(connect.favicon());
+ *      server.use(connect.logger());
+ *      server.use(connect.static(__dirname + '/public'));
+ *
+ * If we wanted to prefix static files with _/public_, we could
+ * "mount" the `static()` middleware:
+ *
+ *      server.use('/public', connect.static(__dirname + '/public'));
+ *
+ * This api is chainable, meaning the following is valid:
+ *
+ *      connect.createServer()
+ *        .use(connect.favicon())
+ *        .use(connect.logger())
+ *        .use(connect.static(__dirname + '/public'))
+ *        .listen(3000);
+ *
+ * @param {String|Function} route or handle
+ * @param {Function} handle
+ * @return {Server}
+ * @api public
+ */
+
+Server.prototype.use = function(route, handle){
+  this.route = '/';
+
+  // default route to '/'
+  if ('string' != typeof route) {
+    handle = route;
+    route = '/';
+  }
+
+  // multiples
+  if (arguments.length > 2) {
+    return Array.prototype.slice.call(arguments, 1).forEach(function(fn){
+      this.use(route, fn);
+    }, this);
+  }
+
+  // wrap sub-apps
+  if ('function' == typeof handle.handle) {
+    var server = handle;
+    server.route = route;
+    handle = function(req, res, next) {
+      server.handle(req, res, next);
+    };
+  }
+
+  // wrap vanilla http.Servers
+  if (handle instanceof http.Server) {
+    handle = handle.listeners('request')[0];
+  }
+
+  // normalize route to not trail with slash
+  if ('/' == route[route.length - 1]) {
+    route = route.substr(0, route.length - 1);
+  }
+
+  // add the middleware
+  this.stack.push({ route: route, handle: handle });
+
+  // allow chaining
+  return this;
+};
+
+/**
+ * Handle server requests, punting them down
+ * the middleware stack.
+ *
+ * @api private
+ */
+
+Server.prototype.handle = function(req, res, out) {
+  var writeHead = res.writeHead
+    , stack = this.stack
+    , removed = ''
+    , index = 0;
+
+  function next(err) {
+    req.url = removed + req.url;
+    req.originalUrl = req.originalUrl || req.url;
+    removed = '';
+
+    var layer = stack[index++];
+
+    // all done
+    if (!layer) {
+      // but wait! we have a parent
+      if (out) return out(err);
+
+      // otherwise send a proper error message to the browser.
+      if (err) {
+        var msg = 'production' == env
+          ? 'Internal Server Error'
+          : err.stack || err.toString();
+
+        // output to stderr in a non-test env
+        if ('test' != env) console.error(err.stack || err.toString());
+
+        res.statusCode = 500;
+        res.setHeader('Content-Type', 'text/plain');
+        res.end(msg);
+      } else {
+        res.statusCode = 404;
+        res.setHeader('Content-Type', 'text/plain');
+        res.end('Cannot ' + req.method + ' ' + req.url);
+      }
+      return;
+    }
+
+    try {
+      var pathname = parse(req.url).pathname;
+      if (undefined == pathname) pathname = '/';
+
+      // skip this layer if the route doesn't match.
+      if (0 != pathname.indexOf(layer.route)) return next(err);
+
+      var nextChar = pathname[layer.route.length];
+      if (nextChar && '/' != nextChar && '.' != nextChar) return next(err);
+
+      // Call the layer handler
+      // Trim off the part of the url that matches the route
+      removed = layer.route;
+      req.url = req.url.substr(removed.length);
+
+      // Ensure leading slash
+      if ('/' != req.url[0]) req.url = '/' + req.url;
+
+      var arity = layer.handle.length;
+      if (err) {
+        if (arity === 4) {
+          layer.handle(err, req, res, next);
+        } else {
+          next(err);
+        }
+      } else if (arity < 4) {
+        layer.handle(req, res, next);
+      } else {
+        next();
+      }
+    } catch (e) {
+      if (e instanceof assert.AssertionError) {
+        console.error(e.stack + '\n');
+        next(e);
+      } else {
+        next(e);
+      }
+    }
+  }
+  next();
+};
\ No newline at end of file