Skip to content

feat(relay): add Accept-Encoding gzip to all https.request calls#1681

Open
koala73 wants to merge 5 commits intomainfrom
feat/relay-gzip-headers
Open

feat(relay): add Accept-Encoding gzip to all https.request calls#1681
koala73 wants to merge 5 commits intomainfrom
feat/relay-gzip-headers

Conversation

@koala73
Copy link
Owner

@koala73 koala73 commented Mar 15, 2026

Summary

Node.js https.request() does NOT send Accept-Encoding by default (unlike fetch() which does). The AIS relay had 22 external API call sites making uncompressed requests, wasting egress bandwidth.

  • Add Accept-Encoding: gzip, deflate to all 22 external https.get/request calls
  • Replace manual body collection (let body = ''; resp.on('data', ...)) with existing _collectDecompressed() helper
  • Net -32 lines (reusing existing decompression helper reduces boilerplate)

APIs affected

Yahoo Finance, Finnhub, GDELT, UCDP, CelesTrak TLE, AviationStack, ICAO NOTAM, World Bank, Polymarket, OpenSky auth, cyber threat feeds (OTX, URLhaus, Feodo, C2Intel, AbuseIPDB)

What was already gzip-enabled (unchanged)

  • YouTube live detection (proxy + direct)
  • OpenSky raw state fetches (proxy + direct)
  • RSS feed fetches
  • Upstash Redis calls (internal, tiny payloads)

Why not seed scripts?

Node.js fetch() (used by seed scripts) already sends Accept-Encoding: gzip by default and auto-decompresses. PR #1676 was closed after proving this empirically.

Test plan

  • node -c scripts/ais-relay.cjs syntax valid
  • Pre-push hooks pass
  • Post-deploy: verify relay health on Railway (all seed loops still write data)
  • Monitor logs for decompression errors

Node.js https.request() does NOT send Accept-Encoding by default
(unlike fetch()). Add gzip, deflate to 22 external API call sites
in the AIS relay and use the existing _collectDecompressed() helper
for transparent decompression.

This reduces Railway egress bandwidth for all relay upstream calls
(Yahoo Finance, Finnhub, GDELT, UCDP, CelesTrak, AviationStack,
ICAO, World Bank, Polymarket, OpenSky auth, cyber threat feeds).

4 calls already had gzip support (YouTube, OpenSky raw).
Redis/internal calls are unchanged.
@vercel
Copy link

vercel bot commented Mar 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
worldmonitor Ignored Ignored Preview Mar 21, 2026 5:39am

Request Review

@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

_collectDecompressed() now accepts optional maxBytes parameter that
aborts the decompression stream mid-flight when the limit is exceeded,
instead of buffering the full response first. CelesTrak fetch uses
2MB limit to prevent memory pressure in the long-running relay process.
koala73 added 2 commits March 15, 2026 21:43
…uard

10 tests covering the streaming size limit:
- Source contract: maxBytes param exists, size check before push,
  stream+response destroyed on limit, descriptive error message,
  CelesTrak uses 2MB limit
- Behavioral: under-limit resolves, unlimited resolves, over-limit
  rejects mid-stream, identity passthrough, corrupt gzip rejects
…nto test:sidecar

- Extract _collectDecompressed from ais-relay.cjs into scripts/_relay-decompress.cjs
  so tests can import the real function without triggering relay startup/process.exit
- Update ais-relay-gzip.test.cjs to require the real implementation instead of
  duplicating it (eliminates drift risk between test copy and production code)
- Add scripts/ais-relay-gzip.test.cjs to test:sidecar in package.json so the
  maxBytes regression test runs in pre-push and CI automatically
…ent behavior

proxyToCloud() strips the browser Origin then injects 'https://worldmonitor.app'
so the cloud API key validator doesn't reject the request with 401. The test
was written before this injection was added and still asserted null. Same
pattern as #1329 which fixed the equivalent assertion for local handlers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant