From fba05cff142c04c1aea98d3da2fd315c20a27386 Mon Sep 17 00:00:00 2001 From: zmknox Date: Thu, 19 Mar 2026 11:08:11 -0400 Subject: [PATCH 1/3] fix: HTTPS for non-Let's Encrypt uses --- lib/proxy.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/proxy.ts b/lib/proxy.ts index aca6eb7..96fbb57 100755 --- a/lib/proxy.ts +++ b/lib/proxy.ts @@ -343,7 +343,7 @@ export class Redbird { opts?: any; } = { SNICallback: async (hostname: string, cb: (err: any, ctx?: any) => void) => { - if (!certs[hostname]) { + if (this.opts?.letsencrypt && !certs[hostname]) { if (!this.opts?.letsencrypt?.path) { console.error('Missing certificate path for Lets Encrypt'); return cb(new Error('No certs for hostname ' + hostname)); @@ -376,8 +376,6 @@ export class Redbird { console.error('Error getting LetsEncrypt certificates', err); return cb(err); } - } else if (!certs[hostname]) { - return cb(new Error('No certs for hostname ' + hostname)); } if (cb) { From 831a58479b4c78eb93757d7b7a1bca6a3288e62d Mon Sep 17 00:00:00 2001 From: zmknox Date: Thu, 19 Mar 2026 11:56:16 -0400 Subject: [PATCH 2/3] chore: update workflow actions versions --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e1c5d74..1ec34a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,12 +11,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [16.x, 18.x, 20.x] + node-version: [16, 18, 20, 22, 24] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v6 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} cache: 'npm' From baafad58b6da294fc73732a2784385e245804b0a Mon Sep 17 00:00:00 2001 From: zmknox Date: Wed, 1 Apr 2026 13:50:16 -0400 Subject: [PATCH 3/3] test: add tests for using HTTPS with a custom certificate --- test/fixtures/test_crt.pem | 29 ++++++ test/fixtures/test_crt.ts | 23 +---- test/fixtures/test_key.pem | 52 ++++++++++ test/fixtures/test_key.ts | 32 +----- test/https_custom_certificates.spec.ts | 133 +++++++++++++++++++++++++ 5 files changed, 220 insertions(+), 49 deletions(-) create mode 100644 test/fixtures/test_crt.pem create mode 100644 test/fixtures/test_key.pem create mode 100644 test/https_custom_certificates.spec.ts diff --git a/test/fixtures/test_crt.pem b/test/fixtures/test_crt.pem new file mode 100644 index 0000000..76afc5e --- /dev/null +++ b/test/fixtures/test_crt.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIFCTCCAvGgAwIBAgIUJUC0eDhJha4VRcTWhqS3LuAPkkwwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDQwMTE0NDczOVoXDTM2MDMy +OTE0NDczOVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAshfjprzv2RMEwSRo2AWm69DhoWT425SVxNGIuIwq1lQ7 +9kNRrFN3hTUTE42roTv8BtqbIOQzTK8ajbYVMZpH0sMiGLIOSTAVKltLLvn9FcCO +fyzl5qwzqOWZMSJ4l8lNeCFBa9WtIUpQiBHMqxYIOyal06puthbs20aiecacpd3i +Ydmf3wxecSpmDHxdguLtRl8g8cdFDkKvnFmNWFhb+2lP1t7Y5d4t9g0JZtbUwF2t +rCCYxaLhl91lruDEzO60PvqimqJLcRJhs3kvcgYQ9rO4ZmV3kON6xA+2PWLGi0MP +fqyHKj3TUTFDu9FowHHN/Qb9dwVJ2eLbcSJGOAwC+nWVobaAR2VH2Ee4wabFKntt +BKO6PcUCiCaYSWK9hYT6m//CLi+weLoRLjP08e0iaEWZVDshRk1b1moWsCpPlV19 +kHevztPONVncT0/42eqZJXLjqd8F9lb91TGuTjw/AjS4R++vLivreseETxAaj5vY +YHa1mEeb9YHOBaswP4zX6DDjWBCKlq3EqETl1Ie54PEgrpZcMb2FepXJ7HHWYb2C +aAG1fMahNtUNsjDOu+yNVx7zq7gtXr8bDBy1vNw7A1m5Ql7cD6FZyvVvJH9hv1Ap +NhmtpgwWgYSzJqBmOyLKp5Uv+qaqIfAlHCXBYjyvXNOPmhkqGX5CH+Ify/MMNycC +AwEAAaNTMFEwHQYDVR0OBBYEFNp1+0JAA7lH4l43E+foG2SL0rmmMB8GA1UdIwQY +MBaAFNp1+0JAA7lH4l43E+foG2SL0rmmMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggIBAFgnLsMLPWNXdi2V2PQ4xrekZQHy0oaQjIXKgRhtCPpKN0Ew +XYet2N9YPIuM3NqAeCQ2mmjwTbKt98ahVZmeYBUH6HifLN3DpNUApugYAHeFrkkk +ls2cBoV0aOeXX4tkMfpkOIZF+Tkhu+zS27Q0dGJCRkwXd4E3wN0nOU1o8NmTH6C9 ++NZ1/i9LEUZSTCFa7VUKVAS9bGS+yMAmxB78kURvW9eS8X7nYQ5KQaPhizTw5ncl +jMn7rRZydf+OrMyK0jyrPYKsRdtp6mX1RNS41JLQqWMaZQAOzKUuHPyEJ36L+fj4 +oIKAIRpWe/UmXL+YOt6G36gyY/Qow8mKBxg0HgFa27IEkPJWkyVK9LxarTg4+zDW +S2L7ZysJFz6Gm2NF+mliV5ARaZ2gTQGA94oyaMYqhyAOUjMfMeWRcjWIDLEduJVI ++KiAQqGLQtHol2b9bA8VHAXd/y3ODqB/qSyNTFeeWheB+81SuDgx5k1AfuQcDOKr +jMiEddY0jqphmqbzGTaCPGAfDoRRWtEnNlVFNMalBowUSI1g7n/r2sdVJjwtNc/6 +C397wFRharWeNO5NphHW85CO7zB1S5vhn4zoKcg2Gs+XQORwa2YGzdD86pG5zI9B +3hCWHP3gx+aMiU/gSEuEsi0BrAnlYf38wLuwBPKnCLpzJ4zVgyAXetLBT/zE +-----END CERTIFICATE----- diff --git a/test/fixtures/test_crt.ts b/test/fixtures/test_crt.ts index 7019159..f8be23e 100644 --- a/test/fixtures/test_crt.ts +++ b/test/fixtures/test_crt.ts @@ -1,20 +1,3 @@ -export const certificate = `-----BEGIN CERTIFICATE----- -MIIDCTCCAfGgAwIBAgIUAu5McVFExA+FNcHq3unnP7d24SEwDQYJKoZIhvcNAQEL -BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDkxNDA5NTA1NVoXDTI0MTAx -NDA5NTA1NVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA2vPEL6vNbihGhLH0H0IkkIbBXJsH5AeGFX07LAc6gIym -W0244D0ZkOStxbRfUSgiH9Vf0Z+Qp1ufDlFjB98vbwgy68WFU7mESovuDbTKbNRm -eURgex9VleHIBddqzpHkv8bhbdxrHkgrgbPl14Waa+AxZ1FMcDeJUwkujKKBFFv2 -SF8ScogRBTOznA2ITIbFHs/n6d8F3FF/Vx6tZzCX3ziccoD2JROs4RAZqZ1eTdar -4KZPJ3VyX6WSDvmB5xEE5JeKlCHxNV2qBflXNPIccwVYhNzKVfogwh3XsVElL0GX -GCXhDtSkaWn/BNOo9HQpAy3flBn33mQWbmdnVpqeYwIDAQABo1MwUTAdBgNVHQ4E -FgQU6KMWMiUa2ECYY4VE06h/1f+IObYwHwYDVR0jBBgwFoAU6KMWMiUa2ECYY4VE -06h/1f+IObYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAA8jp -cX6CeiFm46SyD/w1bFIFEBAI6f+vDOUIh8B0mU2cuZJ8axhA6jw1kztJmDVEUd8+ -/NnSUlVwpi6/pOoIe35gZzK1nNKvvkHp6PT03cf+rV9iJaZseVENs0AQAisq544o -drTgZVmyFlvKr/J6lxRvB8fxRD3EQIVEbGFa45UnEwjOl8+E0gWpI3TR6GkbsHIe -iR6NeyjlWue6icpVfK8lsbRV/ynZI2KfcEB10bmhVLE8Ihq4fUFECn+p8lwO4xkV -pUyfES3f5G7PbujBQyVJcgXZlZZoeBdaHOgSMi8dUNx3Rj6iiMxEGf/L8WGy6C5C -ghp2U+x6nMeXLm2C2w== ------END CERTIFICATE----- -`; +import { readFileSync } from "fs"; + +export const certificate = readFileSync(__dirname + '/test_crt.pem'); diff --git a/test/fixtures/test_key.pem b/test/fixtures/test_key.pem new file mode 100644 index 0000000..072da92 --- /dev/null +++ b/test/fixtures/test_key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +wbC+UnAOlDS/ZZ9RqLi61XaIMcH+H0c= +-----END PRIVATE KEY----- diff --git a/test/fixtures/test_key.ts b/test/fixtures/test_key.ts index 9bf2ae8..e36a78e 100644 --- a/test/fixtures/test_key.ts +++ b/test/fixtures/test_key.ts @@ -1,29 +1,3 @@ -export const key = `-----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDa88Qvq81uKEaE -sfQfQiSQhsFcmwfkB4YVfTssBzqAjKZbTbjgPRmQ5K3FtF9RKCIf1V/Rn5CnW58O -UWMH3y9vCDLrxYVTuYRKi+4NtMps1GZ5RGB7H1WV4cgF12rOkeS/xuFt3GseSCuB -s+XXhZpr4DFnUUxwN4lTCS6MooEUW/ZIXxJyiBEFM7OcDYhMhsUez+fp3wXcUX9X -Hq1nMJffOJxygPYlE6zhEBmpnV5N1qvgpk8ndXJfpZIO+YHnEQTkl4qUIfE1XaoF -+Vc08hxzBViE3MpV+iDCHdexUSUvQZcYJeEO1KRpaf8E06j0dCkDLd+UGffeZBZu -Z2dWmp5jAgMBAAECggEAMD9eIGkZ1Cfg3jW+hzLSjtx6+HabJwb3Z33Yj6uqGxCj -SeRXFGayXwjdN/82r9IJrv0cZ7tjK1XXt1Z83YuzTqK+YdD9P8VWHv01wGRx5Mhr -KlbEce0mNWhy5MKi4REqGI5xN33GRv59Q9AKGlNxA0t8Z3l1QBck1hzkWo4mpn7y -obYYKEYfU4AE7DybJG5GqmY/jJT/B4ESAOYwwqMkyjvV1UZc3FvrriIrwhyJcplr -svbtwFzO3Z9YrtAT3GQDOT/NH0era+CY/3wvrzMi8S1MWlBX47+PmtTPfctfc4i/ -wxgfNhYQi2tg2pt46q7iu0lSlY0m1GauxrwJz2sG/QKBgQD/hLBQNFpSD+f6R7Mp -LstBgWvzcgDHky48McScVCu6cGTMQxSAm3iv5JeJUkH+KrJVWGjuhxi/XDwXiAxK -4KMCXKSMQnQ+fxDs5Kkpv5WiwlU5VPatTHTSFN+5r9Q3OKMyGSsw1bYiA8OlzsAt -T8uIw7jY2TJX/1i3POJcaOU8jQKBgQDbXW5cKoPMYkzJ9iKYvrXClfSkIAFHM8Q2 -LetTQovEMTmUulyrzclBEs8pH2EynNsRfR9zcm5i7yoVIuz9gu0wINmul4H0M9lE -81g49MrvzC2FGIpdhnfa+f3qDk6LFeTYEA+b/AKojdZrHY3nMDKlwgEfY+FZ8ojh -7eMFGymirwKBgGs61P8jqU/M6w5GbrJ2t8fKt3HXwun+IyYRwK/WRu+b4UEzWXRL -So+OP+XaBmXSpzpXutl3CnSsEW/SoU3/DYmdNVTDQqNDkefIYhFqHDLMmRVRSaAa -eN/88JKtbkKqWxpYI57/4MpPiBiaNl4NoZ3IfVdLduwk9acYPuqG/sS1AoGBAJ8H -SdVpQOkvrkmPtZ8USsKJYbSGO0b6IVnBymMu0BJoOT04KaynYCpbz3EZfaZqjmpM -UjuojpwMlG6ERli2zOriNc1bqut1lyJkY+XOmTxkwe9GTjDlJgjKySggPRKZybBV -XGuRs/+r6/D1mQUsLNt8HMI774f8yv03Lyhpe7KjAoGAONwTSqi/uKa5sAMzExS8 -w+ZwglPY0eGAzAfQ94QIqtZTs2uxqGNXv6GBGFLREIdPPht/4fTX3yf1oOsXOpIj -N8sbrq/qwPqk4V6YFynjbsRay35OzHE308Uj0shn3eagtyXtVp1g4JRQ3h05q+yX -ZhCLoRph0ojjH/pIpkjtHzs= ------END PRIVATE KEY----- -`; +import { readFileSync } from "fs"; + +export const key = readFileSync(__dirname + '/test_key.pem'); diff --git a/test/https_custom_certificates.spec.ts b/test/https_custom_certificates.spec.ts new file mode 100644 index 0000000..c8e2975 --- /dev/null +++ b/test/https_custom_certificates.spec.ts @@ -0,0 +1,133 @@ +import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest'; +import http, { Server } from 'http'; +import https from 'https'; +import { Redbird } from '../lib/index.js'; +import { certificate, key } from './fixtures/index.js'; + +const proxyPort = 8085; +const sslPort = 8445; +const testPort = 54681; + +function makeHttpRequest(options) { + return new Promise<{ status: number; headers: any; data: string }>((resolve, reject) => { + const req = http.request(options, (res) => { + let data = ''; + res.on('data', (chunk) => { + data += chunk; + }); + res.on('end', () => { + resolve({ status: res.statusCode!, headers: res.headers, data }); + }); + }); + req.on('error', (err) => { + console.error('ERROR', err); + reject(err); + }); + req.end(); + }); +} + +function makeHttpsRequest(options) { + return new Promise<{ status: number; headers: any; data: string }>((resolve, reject) => { + options.rejectUnauthorized = false; // For self-signed certificates + const req = https.request(options, (res) => { + let data = ''; + res.on('data', (chunk) => { + data += chunk; + }); + res.on('end', () => { + resolve({ status: res.statusCode!, headers: res.headers, data }); + }); + }); + req.on('error', (err) => { + reject(err); + }); + req.end(); + }); +} + +const responseMessage = 'Hello from target server'; + +describe("HTTPS with custom certificates", () => { + let proxy: Redbird; + let targetServer: Server; + + beforeAll(async () => { + targetServer = http.createServer((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(responseMessage); + }); + + await new Promise((resolve) => { + targetServer.listen(testPort, () => { + resolve(null); + }); + }); + + proxy = new Redbird({ + port: proxyPort, + ssl: { + port: sslPort, + key: key, + cert: certificate, + }, + }); + + await proxy.register({ + src: 'example.com', + target: `http://localhost:${testPort}`, + }); + }); + + afterAll(async () => { + await proxy.close(); + await new Promise((resolve) => targetServer.close(() => resolve(null))); + }); + + it('should proxy HTTPS requests to the correct target', async () => { + const options = { + hostname: 'localhost', + port: sslPort, + path: '/', + method: 'GET', + headers: { + Host: 'example.com', + }, + }; + + const response = await makeHttpsRequest(options); + expect(response.status).toBe(200); + expect(response.data).toBe(responseMessage); + }); + + it('should fail for HTTPS requests to a non-configured host', async () => { + const options = { + hostname: 'localhost', + port: sslPort, + path: '/', + method: 'GET', + headers: { + Host: 'not-configured.example.com', + }, + }; + + const response = await makeHttpsRequest(options); + expect(response.status).toBe(404); + }); + + it('should proxy HTTP requests to the correct target', async () => { + const options = { + hostname: 'localhost', + port: proxyPort, + path: '/', + method: 'GET', + headers: { + Host: 'example.com', + }, + }; + + const response = await makeHttpRequest(options); + expect(response.status).toBe(200); + expect(response.data).toBe(responseMessage); + }) +});