mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Merge pull request #698 from WoLfulus/fix/response-event
Fix & improvements in the response hook
This commit is contained in:
16
api/package-lock.json
generated
16
api/package-lock.json
generated
@@ -6475,6 +6475,11 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7505,6 +7510,11 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
@@ -10396,9 +10406,9 @@
|
||||
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
"version": "6.9.4",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
|
||||
"integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
|
||||
},
|
||||
"querystring": {
|
||||
"version": "0.2.0",
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
"otplib": "^12.0.1",
|
||||
"pino": "^6.4.1",
|
||||
"pino-colada": "^2.1.0",
|
||||
"qs": "^6.9.4",
|
||||
"rate-limiter-flexible": "^2.1.10",
|
||||
"resolve-cwd": "^3.0.0",
|
||||
"sharp": "^0.25.4",
|
||||
|
||||
@@ -14,7 +14,6 @@ import rateLimiter from './middleware/rate-limiter';
|
||||
import cache from './middleware/cache';
|
||||
import extractToken from './middleware/extract-token';
|
||||
import authenticate from './middleware/authenticate';
|
||||
import responseHook from './middleware/response-hook';
|
||||
import activityRouter from './controllers/activity';
|
||||
import assetsRouter from './controllers/assets';
|
||||
import authRouter from './controllers/auth';
|
||||
@@ -55,7 +54,6 @@ app.disable('x-powered-by');
|
||||
app.set('trust proxy', true);
|
||||
|
||||
app.use(expressLogger({ logger }));
|
||||
app.use(responseHook);
|
||||
|
||||
app.use((req, res, next) => {
|
||||
bodyParser.json()(req, res, (err) => {
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import { RequestHandler } from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import emitter from '../emitter';
|
||||
import logger from '../logger';
|
||||
|
||||
const responseHook: RequestHandler = asyncHandler((req, res, next) => {
|
||||
res.on('close', afterResponse);
|
||||
|
||||
const startTime = process.hrtime();
|
||||
|
||||
return next();
|
||||
|
||||
function afterResponse() {
|
||||
res.removeListener('close', afterResponse);
|
||||
|
||||
const info = {
|
||||
request: {
|
||||
method: req.method,
|
||||
uri: req.path,
|
||||
url: req.protocol + '://' + req.get('host') + req.originalUrl,
|
||||
size: req.socket.bytesRead,
|
||||
query: req.query,
|
||||
headers: req.headers,
|
||||
},
|
||||
response: {
|
||||
status: res.statusCode,
|
||||
size: (res as any)['_contentLength'] || res.getHeader('content-length'),
|
||||
headers: res.getHeaders(),
|
||||
},
|
||||
ip: req.headers['x-forwarded-for'] || req.connection.remoteAddress,
|
||||
duration: (process.hrtime(startTime)[1] / 1000000).toFixed(),
|
||||
};
|
||||
|
||||
emitter.emitAsync('response', info).catch((err) => logger.warn(err));
|
||||
}
|
||||
});
|
||||
|
||||
export default responseHook;
|
||||
@@ -1,12 +1,80 @@
|
||||
import logger from './logger';
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
import qs from 'qs';
|
||||
import { URL } from 'url';
|
||||
import { createTerminus, TerminusOptions } from '@godaddy/terminus';
|
||||
import http from 'http';
|
||||
import { Request } from 'express';
|
||||
import logger from './logger';
|
||||
import emitter from './emitter';
|
||||
import database from './database';
|
||||
import app from './app';
|
||||
import { once } from 'lodash';
|
||||
|
||||
const server = http.createServer(app);
|
||||
|
||||
server.on('request', function (req: http.IncomingMessage & Request, res: http.ServerResponse) {
|
||||
const startTime = process.hrtime();
|
||||
|
||||
const complete = once(function (finished: boolean) {
|
||||
const elapsedTime = process.hrtime(startTime);
|
||||
const elapsedNanoseconds = elapsedTime[0] * 1e9 + elapsedTime[1];
|
||||
const elapsedMilliseconds = elapsedNanoseconds / 1e6;
|
||||
|
||||
const previousIn = (req.connection as any)._metrics?.in || 0;
|
||||
const previousOut = (req.connection as any)._metrics?.out || 0;
|
||||
|
||||
const metrics = {
|
||||
in: req.connection.bytesRead - previousIn,
|
||||
out: req.connection.bytesWritten - previousOut,
|
||||
};
|
||||
|
||||
(req.connection as any)._metrics = {
|
||||
in: req.connection.bytesRead,
|
||||
out: req.connection.bytesWritten,
|
||||
};
|
||||
|
||||
// Compatibility when supporting serving with certificates
|
||||
const protocol = server instanceof https.Server ? 'https' : 'http';
|
||||
|
||||
const url = new URL(
|
||||
(req.originalUrl || req.url) as string,
|
||||
`${protocol}://${req.headers.host}`
|
||||
);
|
||||
const query = url.search.startsWith('?') ? url.search.substr(1) : url.search;
|
||||
|
||||
const info = {
|
||||
finished,
|
||||
request: {
|
||||
aborted: req.aborted,
|
||||
completed: req.complete,
|
||||
method: req.method,
|
||||
url: url.href,
|
||||
path: url.pathname,
|
||||
protocol,
|
||||
host: req.headers.host,
|
||||
size: metrics.in,
|
||||
query: qs.parse(query),
|
||||
headers: req.headers,
|
||||
},
|
||||
response: {
|
||||
status: res.statusCode,
|
||||
size: metrics.out,
|
||||
headers: res.getHeaders(),
|
||||
},
|
||||
ip:
|
||||
req.headers['x-forwarded-for'] ||
|
||||
req.connection?.remoteAddress ||
|
||||
req.socket?.remoteAddress,
|
||||
duration: elapsedMilliseconds.toFixed(),
|
||||
};
|
||||
|
||||
emitter.emitAsync('response', info).catch((err) => logger.warn(err));
|
||||
});
|
||||
|
||||
res.once('finish', complete.bind(null, true));
|
||||
res.once('close', complete.bind(null, false));
|
||||
});
|
||||
|
||||
const terminusOptions: TerminusOptions = {
|
||||
timeout: 1000,
|
||||
signals: ['SIGINT', 'SIGTERM', 'SIGHUP'],
|
||||
|
||||
Reference in New Issue
Block a user