X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fdingus.js;h=f060c18f00d251f610a97929fdce663c9f01de89;hb=5b18a1fa46ef9c41f6089e5db259af80f3e98b0a;hp=9bc428282b94c3f187563266377a370c65b38ccf;hpb=031c170bdaf1d9c331e6f6fc701ce6540c0e6941;p=squeep-api-dingus diff --git a/lib/dingus.js b/lib/dingus.js index 9bc4282..f060c18 100644 --- a/lib/dingus.js +++ b/lib/dingus.js @@ -19,7 +19,8 @@ const Router = require('./router'); const Template = require('./template'); // For logging. -const _fileScope = common.fileScope(__filename); +const { fileScope } = require('@squeep/log-helper'); +const _fileScope = fileScope(__filename); const defaultOptions = { ignoreTrailingSlash: true, @@ -34,6 +35,8 @@ const defaultOptions = { querystring, }; +const cookieSplitRE = /; */; + class Dingus { /** * @param {Object} logger object which implements logging methods @@ -117,6 +120,9 @@ class Dingus { /** * Common header tagging for all requests. * Add our own identifier, and persist any external transit identifiers. + * Sets requestId on ctx to a new uuid. + * If X-Request-Id or X-Correlation-Id exist on incoming headers, sets them + * on outgoing headers and sets on ctx. * @param {http.ClientRequest} req * @param {http.ServerResponse} res * @param {object} ctx @@ -163,7 +169,7 @@ class Dingus { /** - * + * Sets ctx.clientAddress and ctx.clientProtocol. * @param {http.ClientRequest} req * @param {http.ServerResponse} res * @param {object} ctx @@ -175,14 +181,40 @@ class Dingus { /** - * Called before every request handler. + * Sets ctx.cookie from Cookie header. * @param {http.ClientRequest} req * @param {http.ServerResponse} res * @param {object} ctx */ + static ingestCookie(req, res, ctx) { + ctx.cookie = {}; + req.getHeader(Enum.Header.Cookie)?.split(cookieSplitRE).forEach((cookie) => { + const [ name, value ] = common.splitFirst(cookie, '=', null).map((x) => { + try { + return decodeURIComponent(x.trim()); + } catch (e) { + return x; + } + }); + if (name && !(name in ctx.cookie)) { + const isQuoted = value?.startsWith('"') && value.endsWith('"'); + ctx.cookie[name] = isQuoted ? value.slice(1, -1) : value; // eslint-disable-line security/detect-object-injection + } + }); + } + + + /** + * Called before every request handler. + * Sets tracking identifiers and client information on ctx. + * @param {http.ClientRequest} req + * @param {http.ServerResponse} res + * @param {object} ctx + */ async preHandler(req, res, ctx) { - Dingus.tagContext(req, res, ctx); + this.constructor.tagContext(req, res, ctx); this.clientAddressContext(req, res, ctx); + this.constructor.ingestCookie(req, res, ctx); } @@ -410,6 +442,7 @@ class Dingus { /** * Read and parse request body data. + * Sets ctx.parsedBody, and optionally ctx.rawBody. * @param {http.ClientRequest} req * @param {http.ServerResponse} res * @param {object} ctx @@ -453,6 +486,7 @@ class Dingus { /** * Set the best content type for the response. + * Sets ctx.responseType, and Content-Type header. * @param {string[]} responseTypes default first * @param {http.ClientRequest} req * @param {http.ServerResponse} res @@ -474,7 +508,7 @@ class Dingus { /** - * Inserts an encoding + * Inserts an encoding into Content-Encoding header. * @param {http.ServerResponse} res * @param {string} encoding */ @@ -519,8 +553,8 @@ class Dingus { */ async _serveFileMetaHeaders(res, directory, fileName) { const _scope = _fileScope('_serveFileMetaHeaders'); - this.logger.debug(_scope, 'called', { directory, fileName }); + let added = false; const metaPrefix = '.'; const metaSuffix = '.meta'; const metaFileName = `${metaPrefix}${fileName}${metaSuffix}`; @@ -528,7 +562,7 @@ class Dingus { const [stat, data] = await this._readFileInfo(metaFilePath); if (!stat) { - return; + return added; } const lineBreakRE = /\r\n|\n|\r/; @@ -541,8 +575,10 @@ class Dingus { const result = headerParseRE.exec(line); const { groups: header } = result; res.setHeader(header.name, header.value); + added = true; } }); + return added; } @@ -635,7 +671,7 @@ class Dingus { res.setHeader(Enum.Header.CacheControl, 'public'); if (this.staticMetadata) { - await this._serveFileMetaHeaders(res, directory, fileName); + ctx.metaHeaders = await this._serveFileMetaHeaders(res, directory, fileName); } this.logger.debug(_scope, 'serving file', { filePath, contentType });