| const constMaxPairs = 100; | |
| const constMaxSize = 16 * 1024; | |
| var State; | |
| (function (State) { | |
| State[State["key"] = 0] = "key"; | |
| State[State["whitespace"] = 1] = "whitespace"; | |
| State[State["value"] = 2] = "value"; | |
| })(State || (State = {})); | |
| const constContinue = { | |
| _tag: "Continue" | |
| }; | |
| const constNameChars = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1]; | |
| const constValueChars = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; | |
| export function make() { | |
| const decoder = new TextDecoder(); | |
| const state = { | |
| state: State.key, | |
| headers: Object.create(null), | |
| key: "", | |
| value: undefined, | |
| crlf: 0, | |
| previousChunk: undefined, | |
| pairs: 0, | |
| size: 0 | |
| }; | |
| function reset(value) { | |
| state.state = State.key; | |
| state.headers = Object.create(null); | |
| state.key = ""; | |
| state.value = undefined; | |
| state.crlf = 0; | |
| state.previousChunk = undefined; | |
| state.pairs = 0; | |
| state.size = 0; | |
| return value; | |
| } | |
| function concatUint8Array(a, b) { | |
| const newUint8Array = new Uint8Array(a.length + b.length); | |
| newUint8Array.set(a); | |
| newUint8Array.set(b, a.length); | |
| return newUint8Array; | |
| } | |
| function error(reason) { | |
| return reset({ | |
| _tag: "Failure", | |
| reason, | |
| headers: state.headers | |
| }); | |
| } | |
| return function write(chunk, start) { | |
| let endOffset = 0; | |
| let previousCursor; | |
| if (state.previousChunk !== undefined) { | |
| endOffset = state.previousChunk.length; | |
| previousCursor = endOffset; | |
| const newChunk = new Uint8Array(chunk.length + endOffset); | |
| newChunk.set(state.previousChunk); | |
| newChunk.set(chunk, endOffset); | |
| state.previousChunk = undefined; | |
| chunk = newChunk; | |
| } | |
| const end = chunk.length; | |
| outer: while (start < end) { | |
| if (state.state === State.key) { | |
| let i = start; | |
| for (; i < end; i++) { | |
| if (state.size++ > constMaxSize) { | |
| return error("HeaderTooLarge"); | |
| } | |
| if (chunk[i] === 58) { | |
| state.key += decoder.decode(chunk.subarray(start, i)).toLowerCase(); | |
| if (state.key.length === 0) { | |
| return error("InvalidHeaderName"); | |
| } | |
| if (chunk[i + 1] === 32 && chunk[i + 2] !== 32 && chunk[i + 2] !== 9) { | |
| start = i + 2; | |
| state.state = State.value; | |
| state.size++; | |
| } else if (chunk[i + 1] !== 32 && chunk[i + 1] !== 9) { | |
| start = i + 1; | |
| state.state = State.value; | |
| } else { | |
| start = i + 1; | |
| state.state = State.whitespace; | |
| } | |
| break; | |
| } else if (constNameChars[chunk[i]] !== 1) { | |
| return error("InvalidHeaderName"); | |
| } | |
| } | |
| if (i === end) { | |
| state.key += decoder.decode(chunk.subarray(start, end)).toLowerCase(); | |
| return constContinue; | |
| } | |
| } | |
| if (state.state === State.whitespace) { | |
| for (; start < end; start++) { | |
| if (state.size++ > constMaxSize) { | |
| return error("HeaderTooLarge"); | |
| } | |
| if (chunk[start] !== 32 && chunk[start] !== 9) { | |
| state.state = State.value; | |
| break; | |
| } | |
| } | |
| if (start === end) { | |
| return constContinue; | |
| } | |
| } | |
| if (state.state === State.value) { | |
| let i = start; | |
| if (previousCursor !== undefined) { | |
| i = previousCursor; | |
| previousCursor = undefined; | |
| } | |
| for (; i < end; i++) { | |
| if (state.size++ > constMaxSize) { | |
| return error("HeaderTooLarge"); | |
| } | |
| if (chunk[i] === 13 || state.crlf > 0) { | |
| let byte = chunk[i]; | |
| if (byte === 13 && state.crlf === 0) { | |
| state.crlf = 1; | |
| i++; | |
| state.size++; | |
| byte = chunk[i]; | |
| } | |
| if (byte === 10 && state.crlf === 1) { | |
| state.crlf = 2; | |
| i++; | |
| state.size++; | |
| byte = chunk[i]; | |
| } | |
| if (byte === 13 && state.crlf === 2) { | |
| state.crlf = 3; | |
| i++; | |
| state.size++; | |
| byte = chunk[i]; | |
| } | |
| if (byte === 10 && state.crlf === 3) { | |
| state.crlf = 4; | |
| i++; | |
| state.size++; | |
| } | |
| if (state.crlf < 4 && i >= end) { | |
| state.previousChunk = chunk.subarray(start); | |
| return constContinue; | |
| } else if (state.crlf >= 2) { | |
| state.value = state.value === undefined ? chunk.subarray(start, i - state.crlf) : concatUint8Array(state.value, chunk.subarray(start, i - state.crlf)); | |
| const value = decoder.decode(state.value); | |
| if (state.headers[state.key] === undefined) { | |
| state.headers[state.key] = value; | |
| } else if (typeof state.headers[state.key] === "string") { | |
| state.headers[state.key] = [state.headers[state.key], value]; | |
| } else { | |
| ; | |
| state.headers[state.key].push(value); | |
| } | |
| start = i; | |
| state.size--; | |
| if (state.crlf !== 4 && state.pairs === constMaxPairs) { | |
| return error("TooManyHeaders"); | |
| } else if (state.crlf === 3) { | |
| return error("InvalidHeaderValue"); | |
| } else if (state.crlf === 4) { | |
| return reset({ | |
| _tag: "Headers", | |
| headers: state.headers, | |
| endPosition: start - endOffset | |
| }); | |
| } | |
| state.pairs++; | |
| state.key = ""; | |
| state.value = undefined; | |
| state.crlf = 0; | |
| state.state = State.key; | |
| continue outer; | |
| } | |
| } else if (constValueChars[chunk[i]] !== 1) { | |
| return error("InvalidHeaderValue"); | |
| } | |
| } | |
| if (i === end) { | |
| state.value = state.value === undefined ? chunk.subarray(start, end) : concatUint8Array(state.value, chunk.subarray(start, end)); | |
| return constContinue; | |
| } | |
| } | |
| } | |
| if (start > end) { | |
| state.size += end - start; | |
| } | |
| return constContinue; | |
| }; | |
| } | |
| //# sourceMappingURL=headers.js.map |
Xet Storage Details
- Size:
- 7.38 kB
- Xet hash:
- b787dd81887dcfefae8f512086abe7868615e5d9197068f017a318c22b3778c3
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.