Files
power/lib/http_server.js
2014-06-25 06:51:35 +08:00

246 lines
7.9 KiB
JavaScript

// Generated by CoffeeScript 1.6.2
(function() {
var HttpServer, connect, dirname, fs, harp, 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");
harp = require("harp");
request = require("request");
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-Power-Template": templateName
});
return res.end(renderTemplate(templateName, context));
};
function HttpServer(configuration) {
this.configuration = configuration;
this.handleWelcomeRequest = __bind(this.handleWelcomeRequest, this);
this.handleApplicationNotFound = __bind(this.handleApplicationNotFound, this);
this.handleProxyRequest = __bind(this.handleProxyRequest, this);
this.handleStaticRequest = __bind(this.handleStaticRequest, this);
this.findHostConfiguration = __bind(this.findHostConfiguration, this);
this.handlePowerRequest = __bind(this.handlePowerRequest, this);
this.logRequest = __bind(this.logRequest, this);
HttpServer.__super__.constructor.call(this, [o(this.logRequest), o(this.annotateRequest), o(this.handlePowerRequest), o(this.findHostConfiguration), o(this.handleStaticRequest), o(this.handleProxyRequest), o(this.handleApplicationNotFound), o(this.handleWelcomeRequest), o(this.handleLocationNotFound)]);
this.staticHandlers = {};
this.requestCount = 0;
this.accessLog = this.configuration.getLogger("access");
}
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.power = {
host: host
};
return next();
};
HttpServer.prototype.handlePowerRequest = function(req, res, next) {
if (req.power.host !== "power") {
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.power.host, function(err, domain, config) {
if (config) {
if (config.root) {
req.power.root = config.root;
}
if (config.url) {
req.power.url = config.url;
}
req.power.domain = domain;
req.power.resume = resume;
} else {
resume();
}
return next(err);
});
};
HttpServer.prototype.handleStaticRequest = function(req, res, next) {
var handler, root, _base, _ref1, _ref2;
if ((_ref1 = req.method) !== "GET" && _ref1 !== "HEAD") {
return next();
}
if (!((root = req.power.root) && typeof root === "string")) {
return next();
}
if (req.url.match(/\.\./)) {
return next();
}
handler = (_ref2 = (_base = this.staticHandlers)[root]) != null ? _ref2 : _base[root] = harp.mount(root);
return handler(req, res, next);
};
HttpServer.prototype.handleProxyRequest = function(req, res, next) {
var headers, hostname, key, port, proxy, value, _ref1, _ref2;
if (!req.power.url) {
return next();
}
_ref1 = url.parse(req.power.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.power.host;
headers['X-Forwarded-Server'] = req.power.host;
proxy = request({
method: req.method,
url: "" + req.power.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.power.resume();
};
HttpServer.prototype.handleApplicationNotFound = function(req, res, next) {
var domain, host, name, pattern, _ref1;
if (req.power.root) {
return next();
}
host = req.power.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.power.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.handleLocationNotFound = function(req, res, next) {
res.writeHead(404, {
"Content-Type": "text/html"
});
return res.end("<!doctype html><html><body><h1>404 Not Found</h1>");
};
return HttpServer;
})(connect.HTTPServer);
}).call(this);