HTTPS request from nodejs responds with 503

Advertisements

I am serving a client frontend from a nodejs server. This client will communicate with an external target server. The target server which I don’t own uses Basic authentication. If I send requests to it using postman or the browser they are fine but what I want to achieve is sending the request from the browser to my nodejs server, do some processing there and only after that forward the request from nodejs to the actual server. When I try this, I get a 503 response form the external server.

- Client running on my server sends the request to /endpoint/*

- My server receives the request on /endpoint/* and forwards it to https://my.external.server.com/api/*

A simplified version of the nodejs server listener

import {Server} from "node:http";
import {request} from "node:https";

function listener(req, res) {
    if (req.url.startsWith("/endpoint")) {
        const options = {
            host: "my.external.server.com",
            method: req.method,
            headers: req.headers,
            path: req.url.replace("/endpoint", "/api"),
            rejectUnauthorized: false, 
        };
        const proxyReq = request(options, proxyRes => {
            res.writeHead(proxyRes.statusCode, proxyRes.headers);
            proxyRes.pipe(res, {end: true});
            return;
        });
        req.pipe(proxyReq, {end: true});
        return;
    }
    // Otherwise serve the client's html
}

new Server(listener).listen(8080, "0.0.0.0");

If the client sends the same exact request to https://my.external.server.com/api/* it works.

>Solution :

When proxying a request from localhost to my.external.server.com, you must avoid forwarding the request header Host: localhost unchanged if the external server relies on the Host header. For example, the Host header may be used to find the correct server among many that are reached via the same IP address.

If you delete options.headers.host before making the request, the request method will automatically set Host: my.external.server.com based on the URL it is calling, and the external server gets the value it expects.

Leave a ReplyCancel reply