node-http-server – Blame information for rev 38
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #!/usr/bin/env node |
2 | |||
9 | office | 3 | /*************************************************************************/ |
4 | /* Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 */ |
||
5 | /*************************************************************************/ |
||
6 | |||
1 | office | 7 | // Import packages. |
38 | office | 8 | const https = require('https') |
9 | const http = require('http') |
||
10 | const path = require('path') |
||
11 | const fs = require('fs') |
||
12 | const url = require('url') |
||
13 | const moment = require('moment') |
||
14 | const winston = require('winston') |
||
15 | const yargs = require('yargs') |
||
16 | const dns = require('dns') |
||
17 | const HttpCache = require("http-cache") |
||
1 | office | 18 | |
8 | office | 19 | // Local imports. |
31 | office | 20 | const Handler = require( |
8 | office | 21 | path |
38 | office | 22 | .resolve( |
23 | path.dirname(require.main.filename), |
||
24 | 'src', |
||
25 | 'handler' |
||
26 | ) |
||
27 | ) |
||
28 | |||
8 | office | 29 | const certs = require( |
30 | path |
||
38 | office | 31 | .resolve( |
32 | path.dirname(require.main.filename), |
||
33 | 'src', |
||
34 | 'certs' |
||
35 | ) |
||
36 | ) |
||
8 | office | 37 | |
12 | office | 38 | // Load configuration file. |
8 | office | 39 | const config = require( |
40 | path |
||
38 | office | 41 | .resolve( |
42 | path.dirname(require.main.filename), |
||
43 | 'config' |
||
44 | ) |
||
45 | ) |
||
8 | office | 46 | |
1 | office | 47 | // Get command-line arguments. |
48 | const argv = yargs |
||
49 | .version() |
||
50 | .option('root', { |
||
51 | alias: 'd', |
||
52 | describe: 'Path to the document root', |
||
53 | demandOption: true |
||
54 | }) |
||
55 | .help() |
||
56 | .argv |
||
57 | |||
58 | // Create various logging mechanisms. |
||
29 | office | 59 | // RFC5424 - { emerg: 0, alert: 1, crit: 2, error: 3, warning: 4, notice: 5, info: 6, debug: 7 } |
38 | office | 60 | winston.setLevels(winston.config.syslog.levels) |
1 | office | 61 | const log = new winston.Logger({ |
62 | transports: [ |
||
63 | new winston.transports.File({ |
||
64 | level: 'info', |
||
14 | office | 65 | filename: path.resolve( |
66 | path.dirname(require.main.filename), |
||
67 | config.log.file |
||
68 | ), |
||
1 | office | 69 | handleExceptions: true, |
70 | json: false, |
||
71 | maxsize: 1048576, // 1MiB. |
||
72 | maxFiles: 10, // Ten rotations. |
||
73 | colorize: false, |
||
14 | office | 74 | timestamp: () => moment() |
75 | .format('YYYYMMDDTHHmmss') |
||
1 | office | 76 | }), |
77 | new winston.transports.Console({ |
||
78 | level: 'info', |
||
79 | handleExceptions: true, |
||
80 | json: false, |
||
81 | colorize: true, |
||
14 | office | 82 | timestamp: () => moment() |
83 | .format('YYYYMMDDTHHmmss') |
||
1 | office | 84 | }) |
85 | ], |
||
86 | exitOnError: false |
||
38 | office | 87 | }) |
1 | office | 88 | |
8 | office | 89 | fs.realpath(argv.root, (error, root) => { |
7 | office | 90 | if (error) { |
38 | office | 91 | log.error('Could not find document root: ' + argv.root) |
92 | process.exit(1) |
||
7 | office | 93 | } |
94 | |||
36 | office | 95 | // Create server-side cache. |
38 | office | 96 | const httpcache = new HttpCache() |
36 | office | 97 | |
7 | office | 98 | // Start HTTP server. |
99 | http.createServer( |
||
100 | // authentication, |
||
37 | office | 101 | (request, response) => { |
102 | // Configuration path requested, so send the server configuration if allowed. |
||
38 | office | 103 | if (config.configuration.enable === true && |
104 | url.parse(request.url, true).path === |
||
37 | office | 105 | config.configuration.path) { |
38 | office | 106 | const address = request.socket.address() |
37 | office | 107 | log.info('HTTP Server configuration requested by: ' + |
108 | address.address + ':' + |
||
109 | address.port |
||
38 | office | 110 | ) |
111 | response.setHeader('Content-Type', 'application/json') |
||
112 | response.end(JSON.stringify(config)) |
||
113 | return |
||
37 | office | 114 | } |
38 | office | 115 | |
37 | office | 116 | // Process and cache the resource. |
117 | httpcache(request, response, () => { |
||
118 | new Handler().process(config, request, response, root) |
||
119 | .on('log', (data) => { |
||
38 | office | 120 | log.log(data.severity, data.message) |
37 | office | 121 | }) |
122 | .on('data', (result) => { |
||
38 | office | 123 | response.setHeader('Content-Type', result.type) |
124 | response.writeHead(result.status) |
||
125 | result.data.pipe(response) |
||
126 | }) |
||
127 | }) |
||
37 | office | 128 | } |
7 | office | 129 | ).listen(config.net.port, config.net.address, () => { |
12 | office | 130 | log.info('HTTP Server accessible at: http://' + |
7 | office | 131 | config.net.address + |
12 | office | 132 | ':' + |
7 | office | 133 | config.net.port + |
13 | office | 134 | ' and serving files from directory: ' + |
8 | office | 135 | root |
38 | office | 136 | ) |
137 | }) |
||
7 | office | 138 | |
139 | // Start HTTPs server if enabled. |
||
8 | office | 140 | if (config.ssl.enable) { |
7 | office | 141 | // Generate certificates for HTTPs. |
10 | office | 142 | certs.generate( |
7 | office | 143 | config.site.name, |
144 | config.net.address, |
||
8 | office | 145 | config.ssl.privateKeySize, |
146 | (certificates) => { |
||
147 | https.createServer( |
||
148 | // authentication, |
||
149 | { |
||
150 | key: certificates.privateKey, |
||
151 | cert: certificates.certificate, |
||
152 | }, |
||
37 | office | 153 | (request, response) => { |
38 | office | 154 | |
37 | office | 155 | // Configuration path requested, so send the server configuration if allowed. |
38 | office | 156 | if (config.configuration.enable === true && |
157 | url.parse(request.url, true).path === |
||
37 | office | 158 | config.configuration.path) { |
38 | office | 159 | const address = request.socket.address() |
37 | office | 160 | log.info('HTTP Server configuration requested by: ' + |
161 | address.address + ':' + |
||
162 | address.port |
||
38 | office | 163 | ) |
164 | response.setHeader('Content-Type', 'application/json') |
||
165 | response.end(JSON.stringify(config)) |
||
166 | return |
||
37 | office | 167 | } |
38 | office | 168 | |
37 | office | 169 | httpcache(request, response, () => { |
170 | new Handler().process(config, request, response, root) |
||
171 | .on('log', (data) => { |
||
38 | office | 172 | log.log(data.severity, data.message) |
37 | office | 173 | }) |
174 | .on('data', (result) => { |
||
38 | office | 175 | response.setHeader('Content-Type', result.type) |
176 | response.writeHead(result.status) |
||
177 | result.data.pipe(response) |
||
178 | }) |
||
179 | }) |
||
37 | office | 180 | } |
8 | office | 181 | ).listen(config.ssl.port, config.ssl.address, () => { |
12 | office | 182 | log.info('HTTPs Server accessible at: https://' + |
183 | config.ssl.address + |
||
184 | ':' + |
||
185 | config.ssl.port + |
||
13 | office | 186 | ' and serving files from directory: ' + |
8 | office | 187 | root |
38 | office | 188 | ) |
8 | office | 189 | }) |
190 | } |
||
38 | office | 191 | ) |
8 | office | 192 | } |
38 | office | 193 | }) |