Skip to content

Instantly share code, notes, and snippets.

@lightningspirit
Created October 26, 2023 23:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lightningspirit/c41e9f43eb41423cb98e08185714ac21 to your computer and use it in GitHub Desktop.
Save lightningspirit/c41e9f43eb41423cb98e08185714ac21 to your computer and use it in GitHub Desktop.
Parses HTTP header based on format of RFC-9110
import parseHttpHeader from "./parseHttpHeader"
describe("functions/parseHttpHeader", function () {
it.each([
[
"users=0-10/100",
{
users: "0-10/100",
},
],
[
"next=nextCursor=, prev=prevCursor=",
{
prev: "prevCursor=",
next: "nextCursor=",
},
],
[
"</api/3>; rel=next, </api/1>; rel=prev",
[
{
$: "</api/3>",
rel: "next",
},
{
$: "</api/1>",
rel: "prev",
},
],
],
[
"text/html, application/xhtml+xml, application/xml;q=0.9",
[
"text/html",
"application/xhtml+xml",
{
$: "application/xml",
q: "0.9",
},
],
],
])("%s, %j", function (value, expected) {
expect(parseHttpHeader(value)).toEqual(expected)
})
})
/**
* Parses HTTP header based on format of RFC-9110
*
* Range: users=0-10/100
* Link: </api/3>; rel=next, </api/1>; rel=prev
* Accept: text/html, application/xhtml+xml, application/xml;q=0.9
*
* @param header string
* @return
*/
const parseHttpHeader = (header: string) => {
const values = header.split(",").map((value) => {
const parts = value.trim().split(/;/)
if (parts.length == 1 && !value.includes("=")) {
return parts[0].trim()
} else {
const params: Record<string, string | null> = {}
parts.forEach((value) => {
const index = value.indexOf("=")
const parsed =
index > 0 ? [value.slice(0, index), value.slice(index + 1)] : [value]
if (parsed[1]) {
params[parsed[0].trim()] = parsed[1].trim()
} else {
params["$"] = parsed[0].trim()
}
})
return params
}
})
return values.length == 1
? values[0]
: values.every(
(v) =>
typeof v === "object" && Object.keys(v).length === 1 && !("$" in v),
)
? values.reduce((o, i) => Object.assign(o, i), {})
: values
}
export default parseHttpHeader
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment