oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.17k stars 2.77k forks source link

Using http:/https:/Agent causes a ConnectionRefused #2274

Open mpodwysocki opened 1 year ago

mpodwysocki commented 1 year ago

What version of Bun is running?

0.5.8

What platform is your computer?

Darwin 22.3.0 arm64 arm

What steps can reproduce the bug?

When creating a request to a backend service, I get a ConnectionRefused error with a default node Agent:

import * as dotenv from "dotenv";
import * as https from "node:https";
import { createToken } from "./auth/sasTokenProvider.js";
import { parseNotificationHubsConnectionString } from "./auth/connectionStringUtils.js";

// Load the .env file if it exists
dotenv.config();

// Define API version
const API_VERSION = "2020-06";

// Define connection string and hub name
const connectionString = process.env.NOTIFICATIONHUBS_CONNECTION_STRING || "<connection string>";
const hubName = process.env.NOTIFICATION_HUB_NAME || "<hub name>";

// Define message constants
const DUMMY_DEVICE = "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0";
const deviceHandle = process.env.APNS_DEVICE_TOKEN || DUMMY_DEVICE;

async function main() {
  const connectionStringInfo = parseNotificationHubsConnectionString(connectionString);
  const url = getRequestUrl(connectionStringInfo);

  const headers = createHeaders(connectionStringInfo);

  const body = `{ "aps" : { "alert" : "Hello" } }`;
  const method = "POST";

  const { trackingId, correlationId } = await sendRequest(url, headers, body, method);

  console.log(`Tracking ID: ${trackingId}`);
  console.log(`Correlation ID: ${correlationId}`);
}

main().catch((err) => {
  console.log("Sample: Error occurred: ", err);
  process.exit(1);
});

async function sendRequest(url, headers, body, method) {
  const agent = new https.Agent({

  });

  const options = {
    agent,
    hostname: url.hostname,
    path: `${url.pathname}${url.search}`,
    port: url.port,
    method: method,
    headers: headers
  };

  return new Promise((resolve, reject) => {
    const request = https.request(url, options, (response) => {
      const res = processResponse(response);
      res.body = "";

      response.on("data", (data) => {
        res.body += data;
      });

      response.on("end", () => {
        resolve(res);
      });
    });

    request.on("error", (err) => {
      reject(err);
    });

    request.write(body);
    request.end();
  });
}

function createHeaders(connectionStringInfo) {
  const authorization = createToken(
    connectionStringInfo.sharedAccessKeyName,
    connectionStringInfo.sharedAccessKey,
    connectionStringInfo.endpoint);
  const headers = {
    "Authorization": authorization.token,
    "x-ms-version": API_VERSION,
    "Content-Type": "application/json",
    "apns-priority": "10",
    "apns-push-type": "alert",
    "ServiceBusNotification-Format": "apple",
    "ServiceBusNotification-DeviceHandle": deviceHandle
  };

  return headers;
}

function getRequestUrl(connectionStringInfo) {
  const url = new URL(connectionStringInfo.endpoint.replace("sb://", "https://"));
  url.pathname = `${hubName}/messages`;
  url.searchParams.set("api-version", API_VERSION);
  url.searchParams.set("direct", "true");
  return url;
}

function processResponse(response) {
  return {
    correlationId: response.headers["x-ms-correlation-request-id"],
    trackingId: response.headers["trackingid"],
    statusCode: response.statusCode
  }
}

What is the expected behavior?

I should get the results such as the following:

Tracking ID: efdb6e84-b4d9-4a6c-b8e0-c6823ade8713
Correlation ID: 5ee4908e-0fa3-483a-a457-a8f8ec9c1c57

What do you see instead?

I get that there was an error where the connection was refused:

Sample: Error occurred:  ConnectionRefused: fetch() failed
 path: "https://azuresdktestns.servicebus.windows.net:80/azuresdktesthub/messages?api-version=2020-06&direct=true"

Additional information

Full snippet can be found here with azure-sdk-bun. Please contact for more details for any connection strings should you not be able to reproduce with a more minimal repro.

ThatOneBro commented 1 year ago

Ah yeah I know what's going on here.

Like I stated in #2273, we really need to port Node's tests to catch little things like this so you don't have to 😜

For now I'll get this and the headers issue fixed so you can continue in your quest

sibelius commented 1 year ago

can we disable native bun fetch and use isomorphic-fetch until this if fixed?

Matzielab commented 5 months ago

Bump, would love to have a fix for this temporary or not. Currently spinning up a whole separate node api just to be able to make https agent requests.