reply-from

npm: @fastify/reply-from

const fastify = require('fastify')();
const replyFrom = require('@fastify/reply-from');

fastify.register(replyFrom, { undici: true });

fastify.all('*', (request, reply) => {
  const hostHeader = request.headers['host'];

  if (!hostHeader) {
    reply.status(400).send({ error: '요청에 Host 헤더가 없습니다.' });
    return;
  }

  const [hostname, port] = hostHeader.split(':');
  const targetPort = port || '80';
  const requestPath = request.url || '/';
  const targetUrl = `http://${hostname}:${targetPort}${requestPath}`;

  return reply.from(targetUrl, {
    onError: (request, reply, error) => {
      console.error('프록시 요청 중 에러 발생:', error);
    },
  });
});

fastify.listen({ port: 3000 }, (err, address) => {
  if (err) throw err;
  console.log(`프록시 서버가 ${address}에서 실행 중입니다.`);
});

FastifyRequest

// FastifyRequest 주요 속성과 메서드
interface FastifyRequest {
    // URL과 라우팅 관련
    url: string;              // 요청 URL
    method: string;          // HTTP 메서드 (GET, POST 등)
    protocol: string;        // 'http' 또는 'https'
    
    // 헤더와 데이터
    headers: {               // HTTP 헤더
        host?: string;
        'user-agent'?: string;
        'content-type'?: string;
        [key: string]: string | undefined;
    };
    body: any;              // 요청 본문 (POST 데이터 등)
    query: any;             // URL 쿼리 파라미터
    params: any;            // URL 경로 파라미터

    // 클라이언트 정보
    ip: string;             // 클라이언트 IP
    hostname: string;       // 호스트 이름

    // 유틸리티 메서드
    log: FastifyLoggerInstance;  // 로깅
}

// 사용 예시
fastify.get('/example', async (request: FastifyRequest) => {
    // URL 정보 접근
    console.log(request.url);        // '/example?id=123'
    console.log(request.method);     // 'GET'
    
    // 헤더 접근
    const userAgent = request.headers['user-agent'];
    
    // 쿼리 파라미터 접근
    const id = request.query.id;     // '123'
    
    // 로깅
    request.log.info('처리 중인 요청');
});

FastifyReply

// FastifyReply 주요 메서드와 속성
interface FastifyReply {
    // 응답 상태 코드와 헤더 설정
    code(statusCode: number): FastifyReply;
    status(statusCode: number): FastifyReply;
    header(name: string, value: string): FastifyReply;
    headers(headers: { [key: string]: string }): FastifyReply;
    
    // 응답 전송
    send(data?: any): FastifyReply;
    type(contentType: string): FastifyReply;
    
    // 리다이렉션
    redirect(url: string): FastifyReply;
    redirect(statusCode: number, url: string): FastifyReply;
    
    // 기타
    log: FastifyLoggerInstance;
}

// 사용 예시
fastify.get('/example', async (request: FastifyRequest, reply: FastifyReply) => {
    // 상태 코드 설정
    reply.code(200);
    
    // 헤더 설정
    reply.header('Content-Type', 'application/json');
    
    // 응답 전송
    reply.send({ message: '성공' });
});

프록시 서버 개발 일지: 모듈 선택 과정

1. 최초 접근 방식

1.1 선택했던 모듈

1.2 직면한 문제점