| /* |
| * core.js: Core functionality for the Flatiron HTTP (with SPDY support) plugin. |
| * |
| * (C) 2011, Charlie Robbins & the Contributors |
| * MIT LICENSE |
| * |
| */ |
| |
| var http = require('http'), |
| https = require('https'), |
| fs = require('fs'), |
| stream = require('stream'), |
| HttpStream = require('./http-stream'), |
| RoutingStream = require('./routing-stream'); |
| |
| var core = exports; |
| |
| core.createServer = function (options) { |
| var isArray = Array.isArray(options.after), |
| credentials; |
| |
| if (!options) { |
| throw new Error('options is required to create a server'); |
| } |
| |
| function requestHandler(req, res) { |
| var routingStream = new RoutingStream({ |
| before: options.before, |
| buffer: options.buffer, |
| // |
| // Remark: without new after is a huge memory leak that |
| // pipes to every single open connection |
| // |
| after: isArray && options.after.map(function (After) { |
| return new After; |
| }), |
| request: req, |
| response: res, |
| limit: options.limit, |
| headers: options.headers |
| }); |
| |
| routingStream.on('error', function (err) { |
| var fn = options.onError || core.errorHandler; |
| fn(err, routingStream, routingStream.target, function () { |
| routingStream.target.emit('next'); |
| }); |
| }); |
| |
| req.pipe(routingStream); |
| } |
| |
| // |
| // both https and spdy requires same params |
| // |
| if (options.https || options.spdy) { |
| if (options.https && options.spdy) { |
| throw new Error('You shouldn\'t be using https and spdy simultaneously.'); |
| } |
| |
| var serverOptions, |
| credentials, |
| key = !options.spdy |
| ? 'https' |
| : 'spdy'; |
| |
| serverOptions = options[key]; |
| if (!serverOptions.key || !serverOptions.cert) { |
| throw new Error('Both options.' + key + '.`key` and options.' + key + '.`cert` are required.'); |
| } |
| |
| credentials = { |
| key: fs.readFileSync(serverOptions.key), |
| cert: fs.readFileSync(serverOptions.cert) |
| }; |
| |
| if (serverOptions.ca) { |
| serverOptions.ca = !Array.isArray(serverOptions.ca) |
| ? [serverOptions.ca] |
| : serverOptions.ca |
| |
| credentials.ca = serverOptions.ca.map(function (ca) { |
| return fs.readFileSync(ca); |
| }); |
| } |
| |
| if (options.spdy) { |
| // spdy is optional so we require module here rather than on top |
| var spdy = require('spdy'); |
| return spdy.createServer(credentials, requestHandler); |
| } |
| |
| return https.createServer(credentials, requestHandler); |
| } |
| |
| return http.createServer(requestHandler); |
| }; |
| |
| core.errorHandler = function error(err, req, res) { |
| if (err) { |
| (this.res || res).writeHead(err.status || 500, err.headers || { "Content-Type": "text/plain" }); |
| (this.res || res).end(err.message + "\n"); |
| return; |
| } |
| |
| (this.res || res).writeHead(404, {"Content-Type": "text/plain"}); |
| (this.res || res).end("Not Found\n"); |
| }; |