Skip to content

Commit

Permalink
chore: minor changes in client-h1, use subarray instead of slice (#3538)
Browse files Browse the repository at this point in the history
* chore: minor changes in client-h1, use subarray instead of slice

* only run llhttp_get_error_pos if we have an error
  • Loading branch information
Uzlopak committed Sep 3, 2024
1 parent ce1ef21 commit 46e27f8
Showing 1 changed file with 34 additions and 27 deletions.
61 changes: 34 additions & 27 deletions lib/dispatcher/client-h1.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class Parser {
}

assert(this.ptr != null)
assert(currentParser == null)
assert(currentParser === null)

this.llhttp.llhttp_resume(this.ptr)

Expand All @@ -217,22 +217,27 @@ class Parser {
}
}

execute (data) {
/**
* @param {Buffer} chunk
*/
execute (chunk) {
assert(currentParser === null)
assert(this.ptr != null)
assert(currentParser == null)
assert(!this.paused)

const { socket, llhttp } = this

if (data.length > currentBufferSize) {
// Allocate a new buffer if the current buffer is too small.
if (chunk.length > currentBufferSize) {
if (currentBufferPtr) {
llhttp.free(currentBufferPtr)
}
currentBufferSize = Math.ceil(data.length / 4096) * 4096
// Allocate a buffer that is a multiple of 4096 bytes.
currentBufferSize = Math.ceil(chunk.length / 4096) * 4096
currentBufferPtr = llhttp.malloc(currentBufferSize)
}

new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data)
new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(chunk)

// Call `execute` on the wasm parser.
// We pass the `llhttp_parser` pointer address, the pointer address of buffer view data,
Expand All @@ -242,9 +247,9 @@ class Parser {
let ret

try {
currentBufferRef = data
currentBufferRef = chunk
currentParser = this
ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length)
ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, chunk.length)
/* eslint-disable-next-line no-useless-catch */
} catch (err) {
/* istanbul ignore next: difficult to make a test case for */
Expand All @@ -254,34 +259,36 @@ class Parser {
currentBufferRef = null
}

const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr

if (ret === constants.ERROR.PAUSED_UPGRADE) {
this.onUpgrade(data.slice(offset))
} else if (ret === constants.ERROR.PAUSED) {
this.paused = true
socket.unshift(data.slice(offset))
} else if (ret !== constants.ERROR.OK) {
const ptr = llhttp.llhttp_get_error_reason(this.ptr)
let message = ''
/* istanbul ignore else: difficult to make a test case for */
if (ptr) {
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
message =
'Response does not match the HTTP/1.1 protocol (' +
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
')'
if (ret !== constants.ERROR.OK) {
const data = chunk.subarray(llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr)

if (ret === constants.ERROR.PAUSED_UPGRADE) {
this.onUpgrade(data)
} else if (ret === constants.ERROR.PAUSED) {
this.paused = true
socket.unshift(data)
} else {
const ptr = llhttp.llhttp_get_error_reason(this.ptr)
let message = ''
/* istanbul ignore else: difficult to make a test case for */
if (ptr) {
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
message =
'Response does not match the HTTP/1.1 protocol (' +
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
')'
}
throw new HTTPParserError(message, constants.ERROR[ret], data)
}
throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
}
} catch (err) {
util.destroy(socket, err)
}
}

destroy () {
assert(currentParser === null)
assert(this.ptr != null)
assert(currentParser == null)

this.llhttp.llhttp_free(this.ptr)
this.ptr = null
Expand Down

0 comments on commit 46e27f8

Please sign in to comment.