Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 701x 701x 701x 701x 701x 701x 701x | /**
* Request-target parsing for the router.
*
* @module @coherent.js/api/request-target
*/
import { parse as parseQueryString } from 'node:querystring';
/**
* Split a request target (`req.url`) into its pathname and parsed query, as
* `url.parse(target, true)` did, without that deprecated parser (DEP0169).
*
* Deliberately not `new URL()`: it resolves dot segments (`/a/../b` becomes
* `/b`) and reads `//host/x` as a host, so a raw path could reach a route it
* never named. What `url.parse` did is kept:
*
* - the path is neither normalized nor decoded (the router decodes params);
* - backslashes before the query become slashes;
* - an absolute-form target (`http://host/p`) contributes only its path, and
* an empty one reads as `/`;
* - an empty path is `null`;
* - the query comes from `querystring.parse`, so repeated keys give arrays
* and the object has no prototype.
*
* @param {string} target - The request target, as in `req.url`
* @returns {{ pathname: string|null, query: Object }}
*/
export function parseRequestTarget(target) {
const hash = target.indexOf('#');
const beforeHash = hash === -1 ? target : target.slice(0, hash);
const q = beforeHash.indexOf('?');
let pathname = (q === -1 ? beforeHash : beforeHash.slice(0, q)).replace(
/\\/g,
'/'
);
const authority = /^[a-z][a-z0-9+.-]*:\/\/[^/]*/i.exec(pathname);
if (authority) pathname = pathname.slice(authority[0].length) || '/';
return {
pathname: pathname || null,
query: parseQueryString(q === -1 ? '' : beforeHash.slice(q + 1)),
};
}
|