elysiajs / elysia

Ergonomic Framework for Humans
https://elysiajs.com
MIT License
9.1k stars 193 forks source link

Failed to bind socket in linux #684

Closed IslamZaoui closed 2 weeks ago

IslamZaoui commented 3 weeks ago

What version of Elysia.JS is running?

1.0.24

What platform is your computer?

Microsoft Windows NT 10.0.19045.0 x64 and Linux 5.15.146.1-microsoft-standard-WSL2 x86_64 x86_64

What steps can reproduce the bug?

I have this API integrated with sveltekit to stream torrent files using webtorrent library:

import { getTrackerUrls, streamRequestSchema } from '../../index';
import mime from 'mime-types';
import rangeParser, { type Ranges } from 'range-parser';
import WebTorrent from 'webtorrent';
import { Elysia } from 'elysia';

export default new Elysia({ prefix: '/stream' }).get('/', async (req) => {
    try {
        const result = await streamRequestSchema.safeParseAsync(req.query);

        if (!result.success) {
            return new Response('Invalid request', { status: 400 });
        }

        const { filename, magnet } = result.data;

        const tracker = {
            announce: await getTrackerUrls()
        };

        const client = new WebTorrent({ utp: false, webSeeds: false, tracker });

        if (!magnet || !filename) {
            return new Response('Magnet link and filename are required', { status: 400 });
        }

        const filetype = mime.lookup(filename);

        const torrent = await new Promise<WebTorrent.Torrent>((resolve) => {
            client.add(magnet, (torrent) => resolve(torrent));
        });

        const file = torrent.files.find((file) => file.name === filename);
        if (!file) {
            return new Response('File not found in torrent', { status: 404 });
        }

        const range = req.headers['range'];
        const positions = range
            ? (rangeParser(file.length, range) as Ranges)[0]
            : { start: 0, end: file.length - 1 };
        const start = positions.start;
        const end = positions.end;
        const chunksize = end - start + 1;

        const head = {
            'Content-Range': `bytes ${start}-${end}/${file.length}`,
            'Accept-Ranges': 'bytes',
            'Content-Length': chunksize,
            'Content-Type': filetype ? filetype : 'application/octet-stream'
        };

        const stream = file.createReadStream({ start, end });

        stream.on('error', (err) => {
            console.error('Stream error:', err);
        });

        //@ts-ignore
        return new Response(stream, { headers: head, status: 206 });
    } catch (err) {
        console.error(err);
        return new Response('Internal Server Error', { status: 500 });
    }
});

What is the expected behavior?

this worked perfectly in my windows machine both in development and production

What do you see instead?

But when I tried to run it in WSL or docker in fly.io I got this error every time I fetched the API:

Listening on localhost:3000
298 |     address = typeof address_ === "function" ? "" : address_, exclusive = !1;
299 |   if (!address)
300 |     if (this.type === "udp4")
301 |       address = "0.0.0.0";
302 |     else
303 |   return state.handle.lookup(address, (err, ip) => {
                                            ^
error: Failed to bind socket
      at node:dgram:303:39
      at node:dns:24:36

Bun v1.1.14 (Linux x64)

Additional information

package.json

{
  "name": "elysiasvelte",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "dev": "vite dev",
    "build": "vite build",
    "preview": "HOST=127.0.0.1 bun ./build/index.js",
    "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
    "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
    "lint": "prettier --check . && eslint .",
    "format": "prettier --write ."
  },
  "devDependencies": {
    "@eslym/svelte-adapter-bun": "^0.5.9",
    "@flydotio/dockerfile": "^0.5.7",
    "@sveltejs/kit": "^2.0.0",
    "@sveltejs/vite-plugin-svelte": "^3.0.0",
    "@tailwindcss/typography": "^0.5.13",
    "@types/eslint": "^8.56.7",
    "@types/mime-types": "^2.1.4",
    "@types/range-parser": "^1.2.7",
    "@types/webtorrent": "^0.109.8",
    "autoprefixer": "^10.4.19",
    "eslint": "^9.0.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-svelte": "^2.36.0",
    "globals": "^15.0.0",
    "postcss": "^8.4.38",
    "prettier": "^3.1.1",
    "prettier-plugin-svelte": "^3.1.2",
    "prettier-plugin-tailwindcss": "^0.5.14",
    "svelte": "^4.2.7",
    "svelte-check": "^3.6.0",
    "tailwindcss": "^3.4.3",
    "tslib": "^2.4.1",
    "typescript": "^5.0.0",
    "typescript-eslint": "^8.0.0-alpha.20",
    "vite": "^5.0.3"
  },
  "type": "module",
  "dependencies": {
    "clsx": "^2.1.1",
    "elysia": "^1.0.24",
    "mime-types": "^2.1.35",
    "plyr": "^3.7.8",
    "range-parser": "^1.2.1",
    "tailwind-merge": "^2.3.0",
    "tailwind-variants": "^0.2.1",
    "webtorrent": "^2.4.1",
    "zod": "^3.23.8"
  },
  "trustedDependencies": [
    "core-js",
    "fs-native-extensions",
    "node-datachannel",
    "svelte-preprocess",
    "utp-native"
  ]
}