Performance of POST body parsing of HTTP server #228
-
Hello, I got some strange bench results from OS: //create-post-server-uws.js
const uws = require('uWebSockets.js')
const MAX_BODY_SIZE = 2 ** 20 // 1MB
async function requestListener (req, res, handler) {
res.writeHeader('Access-Control-Allow-Origin', '*')
res.writeHeader('Access-Control-Allow-Headers', 'content-type')
res.writeHeader('Content-Type', 'application/json')
let aborted = false
res.onAborted(() => {
aborted = true
})
// let data = ''
let data = Buffer.from([])
res.onData(async (chunk, isLast) => {
if (aborted) {
return
}
data = Buffer.concat([data, Buffer.from(chunk)])
// data += Buffer.from(chunk).toString('utf8')
if (data.length > MAX_BODY_SIZE) {
res.writeStatus('413 Payload Too Large')
res.end(`{"code":413,"message":"Payload Too Large"}`)
aborted = true
return
}
if (isLast) {
let params
try {
params = data.length ? JSON.parse(data) : {}
} catch (e) {
res.writeStatus('400 Invalid Request')
res.end(`{"code":400,"message":"Invalid Request"}`)
}
if (!aborted) {
if (result && typeof result === 'object') {
res.end(JSON.stringify(result))
} else {
res.writeStatus('404 Not Found')
res.end(`{"code":404,"message":"Not Found"}`)
}
}
} catch (e) {
if (e && e.statusCode) {
res.writeStatus(e.statusCode)
res.end(`{"code":${e.statusCode},"message":"${e.message}"}`)
} else {
res.writeStatus('500 Internal server error')
res.end(`{"code":413,"message":"Payload Too Large"}`)
}
}
}
})
}
function methodNotAllowedResponse (res) {
res.writeStatus('405 Method Not Allowed')
.writeHeader('Allow', 'POST')
.end(`{"code":405,"message":"Method Not Allowed"}`)
}
module.exports = (handler = () => console.log('Handler is not defined')) => {
const server = uws.App()
server.post('*', (res, req) => {
requestListener(req, res, handler).catch(e => console.error(e))
})
server.get('*', methodNotAllowedResponse)
return server
} const createApi = require('./create-post-server-uws')
const customServer = createApi(data => {
return { hello: 'world' }
})
customServer.listen(8080, () => console.log('server started on port 8080')) Result with body
Result without body
For comparison, the results of the same server based on the native node HTTP server
|
Beta Was this translation helpful? Give feedback.
Replies: 5 comments
-
You're probably hitting a bug of some kind, see all those errors. Posted bodies should perform just like normal non-body requests. Does autocannon send the body as chunked-transfer? This library does not support that yet, so maybe it just keeps closing the connection since it cannot parse it? I don't know, will test at some point. |
Beta Was this translation helpful? Give feedback.
-
autocannon is coughing with 2 types of errors: first one
second one
I think autocannon uses default nodejs requests. I am not sure, are they |
Beta Was this translation helpful? Give feedback.
-
The connection (s) is/are getting closed for some reason by some end. |
Beta Was this translation helpful? Give feedback.
-
autocannon is broken and sends invalid HTTP. The numbers for Node.js are really bad as well, since it closes the connection every time since autocannon sends two extra bytes at the end of the body, breaking the protocol. uWebSockets does not close the connection immediately, as it has a different parsing strategy. You have to test with a client that isn't garbage. |
Beta Was this translation helpful? Give feedback.
-
Ok, thank you, I'll create an issue in autocannon repo. Can you advise me some clients to bench http-post with passing body? P.S. Thank you for research |
Beta Was this translation helpful? Give feedback.
autocannon is broken and sends invalid HTTP. The numbers for Node.js are really bad as well, since it closes the connection every time since autocannon sends two extra bytes at the end of the body, breaking the protocol. uWebSockets does not close the connection immediately, as it has a different parsing strategy. You have to test with a client that isn't garbage.