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

withContent middleware fails on BunJS #244

Open
lucas-pelton opened this issue May 9, 2024 · 1 comment
Open

withContent middleware fails on BunJS #244

lucas-pelton opened this issue May 9, 2024 · 1 comment
Labels
BUG Something isn't working

Comments

@lucas-pelton
Copy link

lucas-pelton commented May 9, 2024

Describe the Issue

Per oven-sh/bun#1381 the BunJS runtime does not support .clone()

The withContent() middleware relies on .clone().json() to throw an error if the body is not parsed as JSON (and subsequently as formData). Since .clone() does not properly clone the request body, all inbuilt parsings fail, resulting in the post body being returned by .text()

Example Router Code

router.post('/path',withContent, req=>{return typeof req.content}) // "string" no matter if the post body is JSON or formData

Request Details

This code is executed on BunJS runtime bun run app.js

Steps to Reproduce

Steps to reproduce the behavior:

  1. Post a request to an endpoint that's defined as above running on BunJS

Expected Behavior

withContent should parse the post body, but it can't because there is none after .clone()

Actual Behavior

the .catch() is executed every time because .json() and .formData() are being passed empty data due to .clone() failing to clone the post body

Environment (please complete the following information):

  • Environment: Bun
  • itty-router Version: >4.2

Additional Context

Maybe this is just something that goes into the ity-router documentation. I'm only reporting it because itty-router is so often linked with BunJS, it seems relevant to be published somewhere that this is a known limitation.

I ended up writing my own withContent middleware, but it's cast more in the approach of the pre-v4.2 to parsing post body. It's not itty, but it works.

const withContent = async t => {
    if (!t.body) throw new StatusError(400, "No body in the request");

    const contentType = t.headers.get('Content-Type');
    try {
        if (contentType.includes('json')) {
            t.content = await t.json();
        } else if (contentType.includes('form-data')) {
            t.content = Object.fromEntries([...(await t.formData()).entries()]);
        } else {
            t.content = await t.text();
            if (contentType.includes("x-www-form-urlencoded")) {
                t.content = Object.fromEntries(new URLSearchParams(t.content).entries());
            }
        }
    } catch (e) {
        throw new StatusError(400, e.message);
    }
};
@kwhitley
Copy link
Owner

Fantastic writeup - I'm considering adding environment-specific exports (e.g. itty-router/bun) for overrides that may require more verbosity... or just forcing withContent to check/honor content-type settings so it doesn't attempt more than one...

@kwhitley kwhitley added the BUG Something isn't working label May 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BUG Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants