node-fetch / got 네트워크 이슈 리포트 (TLS & Proxy 관점)

 

✅ 목적

  • node-fetch와 got을 사용한 파일 다운로드 또는 HTTP 통신에서 발생 가능한
    TLS 핸드셰이크 실패, 속도 저하, 프록시 우회 실패 등의 이슈를 정리하여
    실제 서비스 환경에서 사용할 때의 안정성을 검토한다.

1️⃣ 기본 구조 비교

항목 node-fetch got

TLS 처리 Node.js 내장 https 모듈 사용 http2-wrapper 등 자체 모듈 사용
Agent 설정 사용자가 직접 설정해야 함 내부적으로 성능 최적화된 Agent 포함
Proxy 지원 ❌ 기본 미지원 (직접 구현 필요) ✅ global-agent, tunnel, hpagent 등과 호환성 좋음
HTTP/2 지원 ❌ 미지원 ✅ 지원 (v11+부터 기본 내장)

2️⃣ 문제 현상 유형

2-1. TLS Handshake 실패 or 지연

현상:

  • 외부 HTTPS URL로 fetch 호출 시, 연결이 무한 대기되거나 ETIMEDOUT, ECONNRESET 오류 발생
  • 동일한 URL을 curl, axios로 호출 시 정상 동작
  • 공공기관, 교육청망, 프록시 망 등에서 빈번히 발생

가능한 원인:

  • TLS handshake 중 프록시 서버나 중간 장비가 SNI, ALPN, CA를 검사
  • node-fetch (또는 got)가 이를 통과하지 못하고 connection hang 상태 진입

2-2. Proxy 환경에서 동작 실패

현상:

  • 회사 내부망, VPN, 공공망에서 fetch() 또는 got() 호출 시 요청이 아예 나가지 않거나, 응답 없음
  • 오류 없이 멈춘 것처럼 보이는 경우도 존재

가능한 원인:

  • node-fetch: 시스템 프록시 설정을 사용하지 않음 (환경변수 무시)
  • got: 자체 프록시 지원이 있지만, 특정 버전에서 HTTP/2 통신 시 handshake 실패 가능성 존재

3️⃣ 관련 이슈 및 근거 자료

node-fetch

  • node-fetch/issues/1311
    "TLS handshake gets stuck on certain networks (Node.js 18+)"
  • node-fetch/issues/1446
    "long delay on fetch with HTTPS in Node.js"
  • 사용자 의견 요약:
    • 공공망에서 fetch가 수십 초간 멈춤
    • 브라우저 fetch, axios는 정상 작동
    • TLS 인증서 문제, keep-alive 설정 없음이 원인일 수 있음

got

  • got/issues/1288
    "Got stuck on TLS handshake on certain servers"
  • got/issues/1822
    "Socket hang up with corporate proxy"
  • 사용자 의견 요약:
    • got은 HTTP/2 handshake 중 프록시와 호환되지 않아 끊김
    • 일부 네트워크에서 socket hang up, read ECONNRESET 빈번 발생
    • HTTP/2를 비활성화하면 해결됨 (http2: false 옵션 필요)

4️⃣ 요약 및 가이드

구분 node-fetch got

TLS 호환성 ❌ 불안정 (특정 망에서 handshake 실패 사례) ❌ HTTP/2로 인한 handshake 실패 존재
Proxy 호환성 ❌ 기본 미지원 (직접 Agent 설정 필요) ⚠️ 기본 지원하지만 복잡한 망에선 불안정
회피 방법 - https.Agent 수동 설정- fetch 대신 axios 사용 - http2: false 옵션 설정- proxy 설정 명시

5️⃣ 권장 방안 (실 서비스 기준)

  • 공공기관 / 학교 / 프록시 망 대응이 필요하다면 → axios 사용이 가장 안정적
    • TLS 처리 방식이 보수적
    • 프록시 환경에서도 안정적인 동작
    • 취소/진행률/stream 등도 충분히 대응 가능

6️⃣ 부록: 문제 회피 코드 예시

// node-fetch에서 TLS 문제 회피용 Agent 설정
import fetch from 'node-fetch';
import https from 'https';

const agent = new https.Agent({
  keepAlive: true,
  rejectUnauthorized: false, // TLS 우회 (주의!)
});

await fetch('https://example.com/file.zip', { agent });
// got에서 HTTP/2 비활성화
import got from 'got';

await got('https://example.com/file.zip', {
  http2: false,
  agent: {
    https: new https.Agent({ keepAlive: true })
  }
});

📌 최종 결론

  • node-fetch, got은 개발자 친화적이고 강력한 기능을 갖고 있지만,
    TLS / Proxy 호환성 면에서는 불안정한 사례가 실존합니다.
  • 다양한 네트워크 환경에서의 최대 호환성과 안정성이 필요할 경우,
    axios가 가장 보수적이고 실전 검증이 된 선택입니다.

 

'개발 > node' 카테고리의 다른 글

자바스크립트를 처음 배운게...  (1) 2024.10.13
로또 (lotto) 데이터 수집/분석 - node.js  (0) 2023.10.27