+2
-1
@@ -4,4 +4,5 @@
|
||||
/config.example.json
|
||||
/data
|
||||
/test_data
|
||||
/git_secret
|
||||
/access.log
|
||||
/error.log
|
||||
@@ -203,6 +203,8 @@ Any URL like `/year/month/day/anything/` will redirect to this article (and link
|
||||
the Express view engine used to render pages from templates
|
||||
* `access_log` (default: access.log)
|
||||
log file where to save access requests (empty to disable)
|
||||
* `error_log` (default: error.log)
|
||||
log file where to save all server errors (empty to disable)
|
||||
* `modules`
|
||||
* `rss` (default: true)
|
||||
activate the RSS endpoint and its features
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"nodePort": 5000,
|
||||
"name": "gitblog.md",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"description": "A static blog using Markdown pulled from your git repository.",
|
||||
"main": "src/server.js",
|
||||
"dependencies": {
|
||||
|
||||
+10
-4
@@ -102,7 +102,7 @@ module.exports = (config) => {
|
||||
const end = res.end;
|
||||
res.end = (chunk, encoding) => {
|
||||
fs.appendFile(config['access_log'],
|
||||
res.statusCode + ' ' + req.method + ' ' + req.url + ' ' + new Date().toUTCString() + ' ' + (req.ips.join(' ') || req.ip) + '\n',
|
||||
`${res.statusCode} ${req.method} ${req.url} ${new Date().toUTCString()} ${req.ips.join(' ') || req.ip}\n`,
|
||||
{encoding: 'UTF-8'}, () => {
|
||||
res.end = end;
|
||||
res.end(chunk, encoding);
|
||||
@@ -235,10 +235,16 @@ module.exports = (config) => {
|
||||
res.status(400).send('bad request');
|
||||
});
|
||||
|
||||
//log all server errors
|
||||
app.use((err, req, res, next) => {
|
||||
console.log(cons.error, `error when handling ${req.path} request : ${err}`);
|
||||
console.error(err.stack);
|
||||
next(err);
|
||||
console.log(cons.error, `error when handling ${req.method} ${req.path} request : ${err}`);
|
||||
if (!config['error_log'])
|
||||
next(err);
|
||||
fs.appendFile(config['error_log'],
|
||||
`500 ${req.method} ${req.url} ${new Date().toUTCString()} ${req.ips.join(' ') || req.ip}\n${err.stack}\n`,
|
||||
{encoding: 'UTF-8'}, () => {
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
|
||||
// must be use in a server.js to start the server
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"data_dir": "data",
|
||||
"view_engine": "ejs",
|
||||
"access_log": "access.log",
|
||||
"error_log": "error.log",
|
||||
"modules": {
|
||||
"rss": true,
|
||||
"webhook": true,
|
||||
@@ -20,7 +21,7 @@
|
||||
"template": "template.ejs",
|
||||
"thumbnail_tag": "thumbnail",
|
||||
"default_title": "Untitled",
|
||||
"default_thumbnail": null
|
||||
"default_thumbnail": ""
|
||||
},
|
||||
"rss": {
|
||||
"title": "mygitblog RSS feed",
|
||||
|
||||
+40
-1
@@ -21,6 +21,7 @@ config['rss']['endpoint'] = '/rsstest';
|
||||
config['rss']['length'] = 2;
|
||||
config['webhook']['endpoint'] = '/webhooktest';
|
||||
config['access_log'] = path.join(dataDir, 'access.log');
|
||||
config['error_log'] = path.join(dataDir, 'error.log');
|
||||
|
||||
const app = require('../src/app')(config);
|
||||
|
||||
@@ -36,7 +37,16 @@ afterAll(() => {
|
||||
}
|
||||
});
|
||||
|
||||
describe('Test logging', () => {
|
||||
describe('Test request logging', () => {
|
||||
test('test no log', (done) => {
|
||||
const tmp = config['access_log'];
|
||||
config['access_log'] = '';
|
||||
request(app).get('/rsstest').then(() => {
|
||||
config['access_log'] = tmp;
|
||||
expect(fs.existsSync(path.join(dataDir, 'access.log'))).toBe(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('test get 200', (done) => {
|
||||
request(app).get('/rsstest').then(() => {
|
||||
fs.readFile(path.join(dataDir, 'access.log'), {encoding: 'UTF-8'}, (err, data) => {
|
||||
@@ -69,6 +79,35 @@ describe('Test logging', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test error logging', () => {
|
||||
test('test no log', (done) => {
|
||||
const tmp = config['home']['hidden'];
|
||||
config['home']['hidden'] = null;
|
||||
const tmp2 = config['errpr_log'];
|
||||
config['error_log'] = '';
|
||||
request(app).get('/somefile.txt').then(() => {
|
||||
config['home']['hidden'] = tmp;
|
||||
config['error_log'] = tmp2;
|
||||
expect(fs.existsSync(path.join(dataDir, 'error.log'))).toBe(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
test('test null error ', (done) => {
|
||||
const tmp = config['home']['hidden'];
|
||||
config['home']['hidden'] = null;
|
||||
request(app).get('/somefile.txt').then(() => {
|
||||
config['home']['hidden'] = tmp;
|
||||
fs.readFile(path.join(dataDir, 'error.log'), {encoding: 'UTF-8'}, (err, data) => {
|
||||
expect(err).toBeNull();
|
||||
const start = data.split('\n').slice(0, 2).join('\n');
|
||||
const expected = '500 GET /somefile.txt ' + new Date().toUTCString() + ' ::ffff:127.0.0.1\nTypeError: Cannot read property \'includes\' of null';
|
||||
expect(start).toBe(expected);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test root path', () => {
|
||||
test('404 no index no error', (done) => {
|
||||
request(app).get('/').then((response) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* jshint -W117 */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const configFile = 'config.json';
|
||||
const tmpConfigFile = 'config.temp.json';
|
||||
@@ -29,6 +30,18 @@ test('no config', () => {
|
||||
expect(config['data_dir']).toBe('data');
|
||||
});
|
||||
|
||||
test('example config', () => {
|
||||
if (fs.existsSync(configFile))
|
||||
fs.unlinkSync(configFile);
|
||||
fs.copyFileSync(path.join('src', 'config.default.json'), configFile);
|
||||
const data = fs.readFileSync(configFile, {encoding: 'UTF-8'});
|
||||
fs.writeFileSync(configFile, data.replace('3000', '3333'), {encoding: 'UTF-8'});
|
||||
const config = require('../src/config')();
|
||||
expect(config).toBeDefined();
|
||||
expect(config['node_port']).toBe(3333);
|
||||
expect(config['data_dir']).toBe('data');
|
||||
});
|
||||
|
||||
test('invalid config ignored', () => {
|
||||
fs.writeFileSync(configFile, 'invalid JSON');
|
||||
const config = require('../src/config')();
|
||||
|
||||
+20
-15
@@ -117,9 +117,10 @@ describe('Test index article reading', () => {
|
||||
`);
|
||||
fw.readIndexFile(file, 'custom_thumbnail', (err, info) => {
|
||||
expect(err).toBeNull();
|
||||
expect(info).toBeDefined();
|
||||
expect(info.title).toBe('This is an awesome title !?¤');
|
||||
expect(info.thumbnail).toBe('./thumbnail.jpg');
|
||||
expect(info).toEqual({
|
||||
title: 'This is an awesome title !?¤',
|
||||
thumbnail: './thumbnail.jpg'
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -132,9 +133,10 @@ describe('Test index article reading', () => {
|
||||
`);
|
||||
fw.readIndexFile(file, 'custom_thumbnail', (err, info) => {
|
||||
expect(err).toBeNull();
|
||||
expect(info).toBeDefined();
|
||||
expect(info.title).not.toBeDefined();
|
||||
expect(info.thumbnail).toBe('./thumbnail.jpg');
|
||||
expect(info).toEqual({
|
||||
title: undefined,
|
||||
thumbnail: './thumbnail.jpg'
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -143,9 +145,10 @@ describe('Test index article reading', () => {
|
||||
fs.writeFileSync(file, '#title');
|
||||
fw.readIndexFile(file, 'custom_thumbnail', (err, info) => {
|
||||
expect(err).toBeNull();
|
||||
expect(info).toBeDefined();
|
||||
expect(info.title).toBe('title');
|
||||
expect(info.thumbnail).not.toBeDefined();
|
||||
expect(info).toEqual({
|
||||
title: 'title',
|
||||
thumbnail: undefined
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -158,9 +161,10 @@ describe('Test index article reading', () => {
|
||||
`);
|
||||
fw.readIndexFile(file, 'thumbnail', (err, info) => {
|
||||
expect(err).toBeNull();
|
||||
expect(info).toBeDefined();
|
||||
expect(info.title).toBe('This is an awesome title !?¤');
|
||||
expect(info.thumbnail).not.toBeDefined();
|
||||
expect(info).toEqual({
|
||||
title: 'This is an awesome title !?¤',
|
||||
thumbnail: undefined
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -174,9 +178,10 @@ describe('Test index article reading', () => {
|
||||
`);
|
||||
fw.readIndexFile(file, 'custom_thumbnail', (err, info) => {
|
||||
expect(err).toBeNull();
|
||||
expect(info).toBeDefined();
|
||||
expect(info.title).toBe('This is an awesome title !?¤');
|
||||
expect(info.thumbnail).toBe('./thumbnail.jpg');
|
||||
expect(info).toEqual({
|
||||
title: 'This is an awesome title !?¤',
|
||||
thumbnail: './thumbnail.jpg'
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
+11
-2
@@ -4,12 +4,21 @@ const path = require('path');
|
||||
const deleteFolderSync = (dir) => {
|
||||
if (!fs.existsSync(dir))
|
||||
return;
|
||||
fs.readdirSync(dir, {withFileTypes: true}).forEach((item) => {
|
||||
let items;
|
||||
const deleteItem = (item) => {
|
||||
if (item.isDirectory())
|
||||
deleteFolderSync(path.join(dir, item.name));
|
||||
else
|
||||
fs.unlinkSync(path.join(dir, item.name));
|
||||
});
|
||||
};
|
||||
do {
|
||||
items = fs.readdirSync(dir, {withFileTypes: true});
|
||||
try {
|
||||
items.forEach(deleteItem);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
} while (items.length > 0);
|
||||
fs.rmdirSync(dir);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user