[fix] Send response as buffer
AlcaYezzz opened this issue · comments
Describe the bug
Node.js version: v18.12.1
OS version: Ubuntu 22
Description: Send response as buffer isn't working unless wrapped in object
Actual behavior
provided the following code:
const fooFunction = async (ctx: Context) => {
ctx.response.set("Content-Type", "application/octet-stream");
ctx.response.set(
"Content-disposition",
`attachment;filename=foo.bar`
);
ctx.body = {
data: Buffer.from("test")
}
return ctx
}
The http request give me the following response:
{
"data":{
"type":"Buffer",
"data":[116,101,115,116]
}
}
If I change the object affected to body:
const fooFunction = async (ctx: Context) => {
ctx.response.set("Content-Type", "application/octet-stream");
ctx.response.set(
"Content-disposition",
`attachment;filename=foo.bar`
);
ctx.body = Buffer.from("test")
return ctx
}
the http response contains
test
Expected behavior
The response to contain the buffer set to the body
{
"type":"Buffer",
"data":[116,101,115,116]
}
Checklist
- I have searched through GitHub issues for similar issues.
- I have completely read through the README and documentation.
- I have tested my code with the latest version of Node.js and this package and confirmed it is still not working.
Just to be clear, you expect ctx.body = Buffer.from(...)
to result in a response body as:
{
"type":"Buffer",
"data":[116,101,115,116]
}
Because that's super opinionated? Koa doesn't do anything special when body is set to a buffer. This is how node:http works.
Hello @AlcaYezzz,
Koa doesn't do anything special, you should try this to get the behavior you're hoping for:
const fooFunction = async (ctx: Context) => {
// ...
ctx.body = Buffer.from('test').toJSON()
return ctx
}
I can only show you the door, you're the one who have to walk through it.
import {PassThrough, Readable} from 'node:stream'
function * _generate() {
yield 'test'
}
async function _stream(ctx) {
const stream = Readable.from(_generate())
ctx.type = 'application/octet-stream'
ctx.response.set('content-disposition', 'attachment; filename="via_stream.txt"')
ctx.body = stream.pipe(new PassThrough())
}
async function _json(ctx) {
ctx.response.set('content-disposition', 'attachment; filename="via_json.json"')
const _data = []
for (const data of _generate()) {
_data.push(data)
}
ctx.body = {
type: 'Uint8Array',
data: [...(new globalThis.TextEncoder().encode(_data.join('')))],
}
}
Using @koa/router
:
GET /json
curl -vJO 'http://localhost:5001/json
cat via_json.json
// => {"type":"Uint8Array","data":[116,101,115,116]}
GET /
curl -vJO 'http://localhost:5001/
cat via_stream.txt
// => test
Koa does something special in case body is set to a buffer. Changes the content type to bin.