Skip to content

Client (web browser) hangs if body not consumed #246

@fishcakeday

Description

@fishcakeday

When trying to abort POST request when using Hono with node-server, it is impossible to abort without consuming the whole body (which is wasteful, especially for large uploads).

Tried with node versions:
v22.17.0
v24.3.0

Hono 4.8.2
Hono 4.8.3

Below is the simplest example:

import { serve } from "@hono/node-server";
import { HTTPException } from "hono/http-exception";
import { Hono } from "hono";

const app = new Hono();

// Works
app.post(
  "/upload1",
  async (ctx) => {
    if (!ctx.req.raw.body) {
      throw new HTTPException(400, { message: "No file data received" });
    }
    // Create "/dev/null" writeable stream, without this the client will hang
    const nullStream = createWriteStream("/dev/null");
    ctx.req.raw.body.pipeTo(Writable.toWeb(nullStream))

    return ctx.json({ ok: "ok" });
  },
);

// Works
app.post(
  "/upload2",
  async (ctx) => {
    return ctx.json({ ok: "ok" });
  },
);

// Hangs
app.post(
  "/upload3",
  async (ctx) => {
    if (!ctx.req.raw.body) {
      throw new HTTPException(400, { message: "No file data received" });
    }

    return ctx.json({ ok: "ok" });
  },
);

// Hangs
app.post(
  "/upload4",
  async (ctx) => {
    if (!ctx.req.raw.body) {
      throw new HTTPException(400, { message: "No file data received" });
    }
    ctx.req.raw.body.cancel();
    return ctx.json({ ok: "ok" });
  },
);

serve(
  {
    fetch: app.fetch,
    port: 3000,
  },
  (info) => {
    console.log(`Server is running on http://localhost:${info.port}`);
  },
);

I suspect it is because of the how it is done in the following part, but I am speculating here.

init.body = Readable.toWeb(incoming) as ReadableStream<Uint8Array>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions