From 7ea819b4f40a771e59fafb57b3a60b14945f7397 Mon Sep 17 00:00:00 2001 From: Jannis R Date: Sat, 2 May 2020 03:36:19 +0200 Subject: request parser, response formatter --- lib/response.js | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 lib/response.js (limited to 'lib/response.js') diff --git a/lib/response.js b/lib/response.js new file mode 100644 index 0000000..ad27c75 --- /dev/null +++ b/lib/response.js @@ -0,0 +1,69 @@ +'use strict' + +const {Transform} = require('stream') +const {CODES} = require('./statuses') + +// https://gemini.circumlunar.space/docs/spec-spec.txt, 1.3.1 +// > Gemini response headers look like this: +// > +// > is a two-digit numeric status code, as described below in +// > 1.3.2 and in Appendix 1. +// > is any non-zero number of consecutive spaces or tabs. +// > is a UTF-8 encoded string of maximum length 1024, whose +// > meaning is dependent. + +const createResponse = () => { + let headerSent = false + const _sendHeader = () => { + if (typeof res.statusCode !== 'number') { + throw new Error('invalid res.statusCode') + } + const cat = Math.floor(res.statusCode / 10) + + if (cat === 2 && res.mimeType) { + res.meta = res.mimeType // todo: validate + } + + res.push(`${res.statusCode} ${res.meta}\r\n`) + headerSent = true + + if (cat !== 2) res.push(null) // end + } + + const sendHeader = (statusCode, meta = '') => { + if (headerSent) throw new Error('header already sent') + res.statusCode = statusCode + res.meta = meta + _sendHeader() + } + + const write = (chunk, _, cb) => { + if (!headerSent) _sendHeader() + res.push(chunk) + cb(null) + } + + const res = new Transform({write}) + res.statusCode = CODES.SUCCESS + res.meta = '' + res.mimeType = null + + // API + res.sendHeader = sendHeader + res.prompt = (promptMsg) => { + if (typeof promptMsg !== 'string') { + throw new Error('invalid promptMsg') + } + sendHeader(10, promptMsg) + res.push(null) + } + res.gone = () => { + sendHeader(51) + res.push(null) + } + // todo: redirect(), serverUnavailable(), slowDown(), badRequest() + + return res +} + +module.exports = createResponse -- cgit v1.3