Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot correctly output binary data in server/api for Cloudflare Worker #13586

Closed
linnil1 opened this issue Mar 31, 2022 · 1 comment
Closed

Comments

@linnil1
Copy link

linnil1 commented Mar 31, 2022

Environment

- Operating System: `Linux`
- Node Version:     `v17.5.0`
- Nuxt Version:     `3.0.0-27477996.646c2f6`
- Package Manager:  `yarn@1.22.17`
- Builder:          `vite`
- User Config:      `-`
- Runtime Modules:  `-`
- Build Modules:    `-`
/app # yarn list --pattern unenv
yarn list v1.22.17
└─ unenv@0.4.3

Reproduction

Reproduce the bug

After init the repo described in https://v3.nuxtjs.org/getting-started/installation

Add this api script to server/api/image.ts

export default async (req, res, next) => {
    const name = req.url.slice(1)
    // const value = await KV.get(name, {type: "arrayBuffer"});  // Uncomment when deploy on Cloudflare
    const value = new Uint8Array([255, 216, 255, 224]).buffer;  // The first four characters of jpeg
    res.setHeader('Content-Type', 'image/jpeg');
    res.end(Buffer.from(new Uint8Array(value)));  // Return a binary data
}

Result

$ NITRO_PRESET=cloudflare yarn build
$ npx miniflare .output/server/index.mjs --site .output/public
$ curl localhost:8787/api/image -s | xxd
00000000: efbf bdef bfbd efbf bdef bfbd            ............

Both miniflare and Cloudflare given same result

Expected result

$ yarn dev
$ curl localhost:3000/api/image -s | xxd
00000000: ffd8 ffe0                                ....

$ yarn build
$ yarn start
$ curl localhost:3000/api/image -s | xxd
00000000: ffd8 ffe0                                ....

Describe the bug

The result efbf bdef in miniflare indicate the binary has been decoded, probably .toString() method is triggered in somewhere.

After tracing the code, I found that nitro use unenv to handle the response body of h3 server for Cloudflare deployment, where
the response body has been decoded by .toString() in https://github.com/unjs/unenv/blob/main/src/runtime/fetch/call.ts

To temporary fix it, I remove .toString() in unenv and rebuild it for my project, it works, so I'm sure this is why the bug happened.

But I'm not sure the intention of adding .toString() for response in nuxt or unenv, thus I report this issue here, or shall we handle text and json ONLY on server/api?

Additional context

The code that related to this bugs:

    return handle(req, res).then(() => {
      const r = {
        body: (res._data as any)?.toString() ?? '',
        headers: res._headers,
        status: res.statusCode,
        statusText: res.statusMessage
      }
      ...
      return r
    })

Logs

No response

@pi0
Copy link
Member

pi0 commented Apr 12, 2022

Thanks for nice written issue @linnil1 💚 I'm moving it to the relevant nitro repository in order to track orum.mikrotik.com/viewtopic.php?t=177984

@pi0 pi0 closed this as completed Apr 12, 2022
@danielroe danielroe added the 3.x label Jan 19, 2023
@danielroe danielroe transferred this issue from nuxt/framework Jan 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants