1 |
|
2 | 'use strict';
|
3 |
|
4 | module.exports = function (config) {
|
5 | var statsd = require('./statsd')(config);
|
6 | var outputFilter = require('./output-filter')(config);
|
7 | var contentType = require('./content-type');
|
8 | var http = require('http');
|
9 |
|
10 | var getErrorMessage = function (err) {
|
11 | return err.message || err.toString();
|
12 | };
|
13 |
|
14 | var api = {
|
15 | send: function (err, out, req, res, status) {
|
16 | var timer = config.timer();
|
17 | var mimeType;
|
18 |
|
19 | var logError = function (err, status) {
|
20 | config.log.error(err.stack ? err.stack : getErrorMessage(err));
|
21 | statsd.increment('errors_' + status);
|
22 | };
|
23 |
|
24 | var doSend = function (content) {
|
25 | var length = Buffer.byteLength(content);
|
26 | if (!mimeType) {
|
27 | mimeType = contentType(req.url, {charset: 'utf-8'});
|
28 | }
|
29 | statsd.classifiedTiming(req.url, 'writing', timer('Writing response ' + req.url));
|
30 | statsd.classifiedGauge(req.url, 'response_size', length);
|
31 | statsd.increment('requests');
|
32 |
|
33 | res.setHeader('Content-type', mimeType);
|
34 | res.setHeader('Content-length', length);
|
35 | res.writeHead(status);
|
36 | res.end(content);
|
37 | };
|
38 |
|
39 | var getErrorContent = function (err, req, res) {
|
40 | mimeType = contentType('anything.html', {charset: 'utf-8'});
|
41 | require('./error-pages')(config).getPage(err, req, res, function (content) {
|
42 | doSend(content || api.error(err, status));
|
43 | });
|
44 | };
|
45 |
|
46 | if (!status) {
|
47 | status = 200;
|
48 | }
|
49 |
|
50 | if (err) {
|
51 | status = err.status || 500;
|
52 | getErrorContent(err, req, res);
|
53 | logError(err, status);
|
54 | } else if (req.isJson) {
|
55 | mimeType = 'application/json; charset=utf-8';
|
56 | doSend(out);
|
57 | } else {
|
58 | doSend(outputFilter(out, contentType(req.url), req));
|
59 | }
|
60 | },
|
61 | error: function (err, status) {
|
62 | var statusMessage = http.STATUS_CODES[status] || 'Internal server error';
|
63 | var out = [
|
64 | '<!DOCTYPE html><html lang="en"><head><title>' + statusMessage + '</title>',
|
65 | '</head>',
|
66 | '<body><div style="font-family: sans-serif; color: gray; font-size: 20px; font-weight: bold; margin-top: 200px; text-align: center;">' + status + ' – ' + statusMessage + '</div>',
|
67 | '\n<!--\n\n',
|
68 | function () { |
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | }.toString().replace(/^[^\*]+\*/, '').replace(/\*\/.$/, ''),
|
76 | '\n\n\n',
|
77 | 'Error: ' + getErrorMessage(err) + '\n',
|
78 | '-->\n',
|
79 | '</body></html>'
|
80 | ].join('');
|
81 |
|
82 | return out;
|
83 | }
|
84 | };
|
85 |
|
86 | return api;
|
87 | };
|