denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
94.05k stars 5.23k forks source link

`fs.createReadStream` to fetch upload is string instead of binary in Deno #21454

Open Swimburger opened 9 months ago

Swimburger commented 9 months ago

I have a Node module that I'm trying to make compatible with Deno. In this module I'm passing a stream from fs.createReadStream to the body of a fetch POST request. The API I'm submitting this file to only can only process audio and video files. In Node it works fine, but in Deno, the API gives this error "File does not appear to contain audio. File type is text/plain (ASCII text, with no line terminators)"

If this is not enough information, I'll try to create a minimal repro.

How can I make sure the behavior is the same on Node as Deno?


deno 1.38.4 (release, aarch64-apple-darwin) v8 12.0.267.1 typescript 5.2.2

bartlomieju commented 9 months ago

@Swimburger could you please provide a reproduction? It will make it easier to debug.

Swimburger commented 3 months ago

I'm using the following code to upload a file to AssemblyAI:

import { createReadStream } from "node:fs";

const file = createReadStream("/path/to/file");
fetch("https://api.assemblyai.com/v2/upload", {
  headers: {
    "Authorization": "MY_API_KEY"
  },
  method: "POST",
  body: file as unknown as BodyInit
});

You can see that I have to cast file to BodyInit because the Node stream isn't supported by default, however, a Node stream is supported by Fetch in Node.

When I use Proxyman, I can see the body is this:

POST /v2/upload HTTP/1.1
authorization: xxx
content-type: text/plain;charset=UTF-8
accept: */*
accept-language: *
user-agent: Deno/1.44.0
accept-encoding: gzip, br
host: api.assemblyai.com
content-length: 15

[object Object]

Instead of uploading the file, it did a .toString() on it.

The same code properly uploads the file in Node.js.