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

Couldn't make multipart/form-data requests with oak. #36

Closed
c0per opened this issue Nov 1, 2021 · 4 comments · Fixed by #37
Closed

Couldn't make multipart/form-data requests with oak. #36

c0per opened this issue Nov 1, 2021 · 4 comments · Fixed by #37

Comments

@c0per
Copy link
Contributor

c0per commented Nov 1, 2021

Issue

Setup:

  • Deno Version: 1.15.3 (release, x86_64-apple-darwin)
  • v8 Version: 9.5.172.19
  • Typescript Version: 4.4.2
  • SuperDeno Version: 4.6.0
  • Oak Version: v9.0.1

Details

I'm using oak server. I tried the following code to test a multipart/form-data endpoint, didn't seem to work.
Both superoak and superdeno seemed not to work properly.

await req
    .post(url)
    .field('form_key', 'form_value')
    .attach('form_key2', 'path_to_file', 'filename');

I can only receive an empty body text/plain request.
I've also tried using superagent with jspm. Still not working. Maybe its because nodejs package having some bugs on deno by jspm.

@asos-craigmorten
Copy link
Collaborator

asos-craigmorten commented Nov 1, 2021

Hey @c0per 👋

Hmm sorry multipart form data isn't working out 😅 do you have a simple oak server example code that you can share which can be used to test against for debugging this?

@c0per
Copy link
Contributor Author

c0per commented Nov 2, 2021

server.ts

import {
  Application,
  Router,
  RouterContext,
} from "https://deno.land/x/oak@v9.0.1/mod.ts";
import { assertEquals } from "https://deno.land/std@0.113.0/testing/asserts.ts";

export const app = new Application();
const router = new Router();

router.post("/endpoint", async (ctx: RouterContext) => {
  // Content-Type should be multipart/form-data
  console.log(ctx.request.headers.get("content-type"));

  // body should be "form-data"
  const body = ctx.request.body();
  assertEquals(body.type, "form-data");

  // printing form value
  console.log(await body.value);

  ctx.response.status = 200;
});

app.use(router.routes());
app.use(router.allowedMethods());

server.test.ts

import { app } from "./server.ts";
import { superoak } from "https://deno.land/x/superoak@4.4.0/mod.ts";
import { superdeno } from "https://deno.land/x/superdeno@4.6.0/mod.ts";
Deno.test("multipart/form-data", async (t) => {
  const pathToFile = "./test.jpg";

  await t.step("superoak", async () => {
    const req = await superoak(app);
    await req
      .post("/endpoint")
      .field("form_key", "form_value")
      .attach("file_key", pathToFile, "filename")
      .expect(200);
  });

  await t.step("superdeno", async () => {
    const controller = new AbortController();
    const { signal } = controller;
    app.addEventListener("listen", async ({ hostname, port, secure }) => {
      const protocol = secure ? "https" : "http";
      const url = `${protocol}://${hostname}:${port}`;

      await superdeno(url)
        .post("/endpoint")
        .field("form_key", "form_value")
        .attach("file_key", pathToFile, "filename")
        .expect(200);
    });

    await app.listen({ port: 0, signal });
  });
});

@c0per
Copy link
Contributor Author

c0per commented Nov 4, 2021

I took some time into it. I made a pr #37 to fix this.

superagent has 2 implementations: One for browser, one for nodejs. This project uses jspm.dev, which packs the browser version of superagent by default.

The browser version depends on XHR to handle form-data. And in xhrSham.js, form-data is stringified, so fetch doesn't process it the right way.

The fix is to pass FormData directly to fetch. Fetch is able to handle form-data by itself.

cmorten pushed a commit that referenced this issue Nov 5, 2021
* fix: process FormData correctly
* add test for multipart/form-data
@cmorten
Copy link
Owner

cmorten commented Nov 5, 2021

Released in https://github.com/asos-craigmorten/superdeno/releases/tag/4.6.1 - thanks for your contribution 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants