UNPKG

@tinyhttp/res

Version:

response extensions for tinyhttp

64 lines 2.2 kB
import { encodeUrl } from '@tinyhttp/encode-url'; import { getRequestHeader } from '@tinyhttp/req'; import { vary } from '@tinyhttp/vary'; import mime from 'mime'; const charsetRegExp = /;\s*charset\s*=/; const schemeAndHostRegExp = /^(?:[a-zA-Z][a-zA-Z0-9+.-]*:)?\/\/[^\\/?#]+/; export const setHeader = (res) => (field, val) => { if (typeof field === 'string') { let value = Array.isArray(val) ? val.map(String) : String(val); // add charset to content-type if (field.toLowerCase() === 'content-type') { if (Array.isArray(value)) { throw new TypeError('Content-Type cannot be set to an Array'); } if (!charsetRegExp.test(value)) { value += '; charset=utf-8'; } } res.setHeader(field, value); } else { for (const key in field) { setHeader(res)(key, field[key]); } } return res; }; export const setLocationHeader = (req, res) => (url) => { let loc = url; // "back" is an alias for the referrer if (url === 'back') loc = getRequestHeader(req)('Referrer') || '/'; const match = schemeAndHostRegExp.exec(loc); const pos = match ? match[0].length + 1 : 0; // Only encode after the host to avoid turning authority backslashes into // encoded bytes that can bypass redirect allowlists. res.setHeader('Location', loc.slice(0, pos) + encodeUrl(loc.slice(pos))); return res; }; export const getResponseHeader = (res) => { return (field) => { return res.getHeader(field); }; }; export const setLinksHeader = (res) => (links) => { let link = res.getHeader('Link') || ''; if (link) link += ', '; res.setHeader('Link', link + Object.keys(links) .map((rel) => `<${links[rel]}>; rel="${rel}"`) .join(', ')); return res; }; export const setVaryHeader = (res) => (field) => { vary(res, field); return res; }; export const setContentType = (res) => (type) => { const ct = type.indexOf('/') === -1 ? mime.getType(type) : type; setHeader(res)('Content-Type', ct); return res; }; //# sourceMappingURL=headers.js.map