text: // Generated by CoffeeScript 1.6.3
  (function() {
    var HttpServer, RackApplication, connect, dirname, fs, join, pause, request, url, version, _ref,
      __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
      __hasProp = {}.hasOwnProperty,
      __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
      __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  
    fs = require("fs");
  
    url = require("url");
  
    connect = require("connect");
  
    request = require("request");
  
    RackApplication = require("./rack_application");
  
    pause = require("./util").pause;
  
    _ref = require("path"), dirname = _ref.dirname, join = _ref.join;
  
    version = JSON.parse(fs.readFileSync(__dirname + "/../package.json", "utf8")).version;
  
    module.exports = HttpServer = (function(_super) {
      var o, renderResponse, renderTemplate, x;
  
      __extends(HttpServer, _super);
  
      o = function(fn) {
        return function(req, res, next) {
          return fn(req, res, next);
        };
      };
  
      x = function(fn) {
        return function(err, req, res, next) {
          return fn(err, req, res, next);
        };
      };
  
      renderTemplate = function(templateName, renderContext, yieldContents) {
        var context, key, template, value;
        template = require("./templates/http_server/" + templateName + ".html");
        context = {
          renderTemplate: renderTemplate,
          yieldContents: yieldContents
        };
        for (key in renderContext) {
          value = renderContext[key];
          context[key] = value;
        }
        return template(context);
      };
  
      renderResponse = function(res, status, templateName, context) {
        if (context == null) {
          context = {};
        }
        res.writeHead(status, {
          "Content-Type": "text/html; charset=utf8",
          "X-Pow-Template": templateName
        });
        return res.end(renderTemplate(templateName, context));
      };
  
      function HttpServer(configuration) {
        var _this = this;
        this.configuration = configuration;
        this.handleWelcomeRequest = __bind(this.handleWelcomeRequest, this);
        this.handleApplicationNotFound = __bind(this.handleApplicationNotFound, this);
        this.handleRvmDeprecationRequest = __bind(this.handleRvmDeprecationRequest, this);
        this.handleProxyRequest = __bind(this.handleProxyRequest, this);
        this.findRackApplication = __bind(this.findRackApplication, this);
        this.handleStaticRequest = __bind(this.handleStaticRequest, this);
        this.findHostConfiguration = __bind(this.findHostConfiguration, this);
        this.handlePowRequest = __bind(this.handlePowRequest, this);
        this.logRequest = __bind(this.logRequest, this);
        HttpServer.__super__.constructor.call(this, [o(this.logRequest), o(this.annotateRequest), o(this.handlePowRequest), o(this.findHostConfiguration), o(this.handleStaticRequest), o(this.findRackApplication), o(this.handleProxyRequest), o(this.handleRvmDeprecationRequest), o(this.handleApplicationRequest), x(this.handleErrorStartingApplication), o(this.handleFaviconRequest), o(this.handleApplicationNotFound), o(this.handleWelcomeRequest), o(this.handleRailsAppWithoutRackupFile), o(this.handleLocationNotFound)]);
        this.staticHandlers = {};
        this.rackApplications = {};
        this.requestCount = 0;
        this.accessLog = this.configuration.getLogger("access");
        this.on("close", function() {
          var application, root, _ref1, _results;
          _ref1 = _this.rackApplications;
          _results = [];
          for (root in _ref1) {
            application = _ref1[root];
            _results.push(application.quit());
          }
          return _results;
        });
      }
  
      HttpServer.prototype.toJSON = function() {
        return {
          pid: process.pid,
          version: version,
          requestCount: this.requestCount
        };
      };
  
      HttpServer.prototype.logRequest = function(req, res, next) {
        this.accessLog.info("[" + req.socket.remoteAddress + "] " + req.method + " " + req.headers.host + " " + req.url);
        this.requestCount++;
        return next();
      };
  
      HttpServer.prototype.annotateRequest = function(req, res, next) {
        var host, _ref1;
        host = (_ref1 = req.headers.host) != null ? _ref1.replace(/(\.$)|(\.?:.*)/, "") : void 0;
        req.pow = {
          host: host
        };
        return next();
      };
  
      HttpServer.prototype.handlePowRequest = function(req, res, next) {
        if (req.pow.host !== "pow") {
          return next();
        }
        switch (req.url) {
          case "/config.json":
            res.writeHead(200);
            return res.end(JSON.stringify(this.configuration));
          case "/env.json":
            res.writeHead(200);
            return res.end(JSON.stringify(this.configuration.env));
          case "/status.json":
            res.writeHead(200);
            return res.end(JSON.stringify(this));
          default:
            return this.handleLocationNotFound(req, res, next);
        }
      };
  
      HttpServer.prototype.findHostConfiguration = function(req, res, next) {
        var resume,
          _this = this;
        resume = pause(req);
        return this.configuration.findHostConfiguration(req.pow.host, function(err, domain, config) {
          if (config) {
            if (config.root) {
              req.pow.root = config.root;
            }
            if (config.url) {
              req.pow.url = config.url;
            }
            req.pow.domain = domain;
            req.pow.resume = resume;
          } else {
            resume();
          }
          return next(err);
        });
      };
  
      HttpServer.prototype.handleStaticRequest = function(req, res, next) {
        var handler, root, _base, _ref1;
        if ((_ref1 = req.method) !== "GET" && _ref1 !== "HEAD") {
          return next();
        }
        if (!((root = req.pow.root) && typeof root === "string")) {
          return next();
        }
        if (req.url.match(/\.\./)) {
          return next();
        }
        handler = (_base = this.staticHandlers)[root] != null ? (_base = this.staticHandlers)[root] : _base[root] = connect["static"](join(root, "public"));
        return handler(req, res, next);
      };
  
      HttpServer.prototype.findRackApplication = function(req, res, next) {
        var root,
          _this = this;
        if (!(root = req.pow.root)) {
          return next();
        }
        return fs.exists(join(root, "config.ru"), function(rackConfigExists) {
          var application, _base;
          if (rackConfigExists) {
            req.pow.application = (_base = _this.rackApplications)[root] != null ? (_base = _this.rackApplications)[root] : _base[root] = new RackApplication(_this.configuration, root, req.pow.host);
          } else if (application = _this.rackApplications[root]) {
            delete _this.rackApplications[root];
            application.quit();
          }
          return next();
        });
      };
  
      HttpServer.prototype.handleProxyRequest = function(req, res, next) {
        var headers, hostname, key, port, proxy, value, _ref1, _ref2;
        if (!req.pow.url) {
          return next();
        }
        _ref1 = url.parse(req.pow.url), hostname = _ref1.hostname, port = _ref1.port;
        headers = {};
        _ref2 = req.headers;
        for (key in _ref2) {
          value = _ref2[key];
          headers[key] = value;
        }
        headers['X-Forwarded-For'] = req.connection.address().address;
        headers['X-Forwarded-Host'] = req.pow.host;
        headers['X-Forwarded-Server'] = req.pow.host;
        proxy = request({
          method: req.method,
          url: "" + req.pow.url + req.url,
          headers: headers,
          jar: false,
          followRedirect: false
        });
        req.pipe(proxy);
        proxy.pipe(res);
        proxy.on('error', function(err) {
          return renderResponse(res, 500, "proxy_error", {
            err: err,
            hostname: hostname,
            port: port
          });
        });
        return req.pow.resume();
      };
  
      HttpServer.prototype.handleRvmDeprecationRequest = function(req, res, next) {
        var action, application, match;
        if (!(application = req.pow.application)) {
          return next();
        }
        if (match = req.url.match(/^\/__pow__\/rvm_deprecation(.*)/)) {
          action = match[1];
          if (!(action === "" || req.method === "POST")) {
            return next();
          }
          switch (action) {
            case "":
              true;
              break;
            case "/add_to_powrc":
              application.writeRvmBoilerplate();
              break;
            case "/enable":
              this.configuration.enableRvmDeprecationNotices();
              break;
            case "/disable":
              this.configuration.disableRvmDeprecationNotices();
              break;
            default:
              return next();
          }
          return renderResponse(res, 200, "rvm_deprecation_notice", {
            boilerplate: RackApplication.rvmBoilerplate
          });
        } else {
          return next();
        }
      };
  
      HttpServer.prototype.handleApplicationRequest = function(req, res, next) {
        var application;
        if (application = req.pow.application) {
          return application.handle(req, res, next, req.pow.resume);
        } else {
          return next();
        }
      };
  
      HttpServer.prototype.handleFaviconRequest = function(req, res, next) {
        if (req.url !== "/favicon.ico") {
          return next();
        }
        res.writeHead(200);
        return res.end();
      };
  
      HttpServer.prototype.handleApplicationNotFound = function(req, res, next) {
        var domain, host, name, pattern, _ref1;
        if (req.pow.root) {
          return next();
        }
        host = req.pow.host;
        pattern = this.configuration.httpDomainPattern;
        if (!(domain = host != null ? (_ref1 = host.match(pattern)) != null ? _ref1[1] : void 0 : void 0)) {
          return next();
        }
        name = host.slice(0, host.length - domain.length);
        if (!name.length) {
          return next();
        }
        return renderResponse(res, 503, "application_not_found", {
          name: name,
          host: host
        });
      };
  
      HttpServer.prototype.handleWelcomeRequest = function(req, res, next) {
        var domain, domains;
        if (req.pow.root || req.url !== "/") {
          return next();
        }
        domains = this.configuration.domains;
        domain = __indexOf.call(domains, "dev") >= 0 ? "dev" : domains[0];
        return renderResponse(res, 200, "welcome", {
          version: version,
          domain: domain
        });
      };
  
      HttpServer.prototype.handleRailsAppWithoutRackupFile = function(req, res, next) {
        var root;
        if (!(root = req.pow.root)) {
          return next();
        }
        return fs.exists(join(root, "config/environment.rb"), function(looksLikeRailsApp) {
          if (!looksLikeRailsApp) {
            return next();
          }
          return renderResponse(res, 503, "rackup_file_missing");
        });
      };
  
      HttpServer.prototype.handleLocationNotFound = function(req, res, next) {
        res.writeHead(404, {
          "Content-Type": "text/html"
        });
        return res.end("<!doctype html><html><body><h1>404 Not Found</h1>");
      };
  
      HttpServer.prototype.handleErrorStartingApplication = function(err, req, res, next) {
        var home, line, rest, root, stack, stackLines;
        if (!(root = req.pow.root)) {
          return next();
        }
        home = process.env.HOME;
        stackLines = (function() {
          var _i, _len, _ref1, _results;
          _ref1 = err.stack.split("\n");
          _results = [];
          for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
            line = _ref1[_i];
            if (line.slice(0, home.length) === home) {
              _results.push("~" + line.slice(home.length));
            } else {
              _results.push(line);
            }
          }
          return _results;
        })();
        if (stackLines.length > 10) {
          stack = stackLines.slice(0, 5);
          rest = stackLines.slice(5);
        } else {
          stack = stackLines;
        }
        return renderResponse(res, 500, "error_starting_application", {
          err: err,
          root: root,
          stack: stack,
          rest: rest
        });
      };
  
      return HttpServer;
  
    })(connect.HTTPServer);
  
  }).call(this);
  