fluffy – Diff between revs 4 and 5

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