[Project] java-http-server - 1차 스프린트 후기

2025. 12. 9. 21:36·프로젝트
반응형

도서를 보다가 갑자기 나도 HTTP 서버를 구현하고 싶어졌다. 얼마전 스프링 mvc 구조, 톰캣 등 사용자 요청을 Spring이 어떻게 처리하는지 나름 공부했던게 계기가 되었다. 이 구조를 직접 구현해보면 완벽히 내 지식이 될 것 같은 생각이 들었다. 클라이언트의 HTTP 요청을 받아 적절한 처리 후 응답을 보내는 톰캣, 스프링과 유사한 구조의 서버를 만들기로하고 구현 계획을 작성해 10시간 스프린트를 진행했다.

구현 결과

  • 목표는 Dispatcher Servlet을 사용하는 구조까지 만들어 보는 것이었지만, 서블릿 형태를 구현하는 단계까지만 완료했다.
  • 간단히 정리한 구현 내용
    • 소켓의 바이트 스트림을 HttpRequest, HttpResponse 객체로 변환
    • HTTP 요청/응답을 처리하는 레이어와 비즈니스 로직을 처리하는 레이어를 분리하는 설계
    • 서블릿으로 TODO 리스트 기능 구현하기 : 등록/단건조회/목록조회
* [x] 환경 세팅 및 최소 HTTP 서버 구현
* [x] HTTP 요청/응답 파싱
* [x] RequestHandler 구현
* [x] Servlet / ServletContainer
* [ ] FrontController & 라우팅(DispatcherServlet 같은거)
* [x] TODO LIST 기능
* [ ] 로그인 & 세션

구현하며 배운 것

HTTP 파싱하기

이전에는 HTTP를 단순히 문자열을 주고받는 프로토콜 정도로 생각했지만 직접 파싱을 구현해 보니 요청과 응답은 모두 명확한 구조를 가진 메시지 포맷이라는 것을 새삼 깨달았다. 정해진 구조를 따르는 메시지를 주고 받아야 서버/클라이언트가 정확하게 내용을 해석하고 처리할 수 있다. RFC의 HTTP 응답/요청의 문서를 참고해 어떤 형식의 메시지를 주고 받는지 확인했다.

// 요청
Request Line: `METHOD SP PATH SP VERSION CRLF`
0개 이상의 헤더 라인: `Header-Name: value CRLF`
(빈 줄)
Body

// 응답도 비슷하게
Status Line: `VERSION SP STATUS-CODE SP REASON-PHRASE CRLF`
헤더들
(빈 줄)
Body

이걸 코드로 옮기는 과정에서 어떤부분까지 구현할지 범위를 정했다. 본 프로젝트의 핵심 목표는 구조 설계이기 때문에 최소한의 HTTP/1.1을 목표로 룰을 설정했다. 이외의 형식이 지켜지지 않은 요청은 잘못된 요청으로 간주했다.

  • \\\\r\\\\n만 줄바꿈으로 인정
  • 이번 단계에서는 Chunked Transfer-Encoding, Keep-Alive, HTTP/2 같은 것들은 제외
  • HTTP/1.1만 지원하며 Host, Content-Length, Connection 같은 헤더는 제대로 다루기
  • 잘못된 요청은 400으로 응답

구현 작업은 TDD 방식으로 진행했다. RequestHandler나 Servlet 등의 클래스들에서 HttpRequest/HttpResponse를 반복해서 사용하기 때문에 앞으로의 작업을 위해서는 현재 구현한 내용이 정확히 동작한다는 보장이 필요했다. 우선 여러 형태의 테스트 케이스들을 작성하고 모든 테스트가 통과하도록 구현을 반복했다. 이후 파싱이나 HttpRequest/HttpResponse의 코드를 자신있게 수정할 수 있는 근거를 만들 수 있었다.

설계에 대한 고민

클라이언트가 전송한 HTTP 요청에서 비즈니스 로직은 누가 어디서 처리해야하는가에 대해 고민했다. 역할을 계층으로 나누어 생각하니 누가 무슨 역할을 해야하는지 그려졌다.

  1. 소켓 관리(HttpServer) : 클라이언트의 소켓을 획득해 통신을 위한 InputStream/OutputStream 제공한다.
  2. HTTP 프로토콜(RequestHandler + HttpRequest/HttpResponse) : 클라이언트의 요청/응답 데이터를 HTTP 메시지로 파싱한다.
  3. 애플리케이션(Servlet, ServletContainer) : URL 매핑해 적절한 비즈니스 로직틀 처리한다.

각 계층에서는 자신의 역할에만 충실할 수 있었다. HttpServer에서는 클라이언트와 소켓을 연결하고 바이트 스트림 전달만 수행하기 때문에 HTTP에 대해서는 알 필요가 없다. RequestHandler도 파싱한 HttpRequest를 애플리케이션에 전달하고 받은 HttpResponse를 파싱하기만 하면된다. 즉 애플리케이션에서 무슨 일이 일어나는지 알 필요 없다. 이처럼 각자의 위치에서 명확한 역할을 수행하도록 나눔으로써 테스트도 쉽고 구조도 깔끔해졌다.

후속 작업

  • HTTP 스펙을 만족하는 객체 만들기
  • 작업 문서에서는 FrontController라 표현한 DispatcherServlet을 만들어보기
  • 멀티쓰레드 지원
  • (가능하다면) 비동기로 요청처리, 코틀린으로 migration 후 코루틴 사용해보기

REF

  • 자바 웹 프로그래밍 Next Step : https://product.kyobobook.co.kr/detail/S000001624682
  • RFC 9110 : https://datatracker.ietf.org/doc/html/rfc9110

최근에는 프론트엔드나 서비스 구현 작업이 많았는데 이렇게 프레임워크 내부를 공부하면서 코드를 작성해보니 재미있었다. 연말이 되기전에 계획했던 작업 목록을 모두 완료하고 싶은데, 시간이 돨진 모르겠다. 아쉬운점이 있다면 내가 새로운 설계를 고민하기 보다는 기존에 존재하는 설계를 답습한거라 임팩트가 부족하다는 생각이 든다. 그래도 프레임워크에 대한 이해도가 조금 높아졌으니 의미있는 프로젝트였다.

반응형
저작자표시 비영리 변경금지 (새창열림)
'프로젝트' 카테고리의 다른 글
  • [Project] 멀티모듈로 분리하기
  • [Project] 나혼자 해커톤 후기 - 2
  • [Project] 나혼자 해커톤 후기 - 1
  • [Project] 4dollar - 헥사고날 아키텍처에서 패키지 구조 전환
덴마크초코우유
덴마크초코우유
IT, 알고리즘, 프로그래밍 언어, 자료구조 등 정리
    반응형
  • 덴마크초코우유
    이것저것끄적
    덴마크초코우유
  • 전체
    오늘
    어제
    • 분류 전체보기 (134)
      • Spring Framework (16)
        • Spring (8)
        • JPA (6)
        • Spring Security (0)
      • Language (51)
        • Java (11)
        • Python (10)
        • JavaScript (5)
        • NUXT (2)
        • C C++ (15)
        • PHP (8)
      • DB (16)
        • MySQL (10)
        • Reids (3)
        • Memcached (2)
      • 개발 (3)
      • 프로젝트 (7)
      • Book (2)
      • PS (15)
        • 기타 (2)
        • 백준 (2)
        • 프로그래머스 (10)
      • 딥러닝 (8)
        • CUDA (0)
        • Pytorch (0)
        • 모델 (0)
        • 컴퓨터 비전 (4)
        • OpenCV (1)
      • 기타 (16)
        • 디자인패턴 (2)
        • UnrealEngine (8)
        • ubuntu (1)
        • node.js (1)
        • 블로그 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    파이썬
    JS
    웹
    PS
    블루프린트
    자바
    NUXT
    Unreal Engine
    게임 개발
    프로그래머스
    redis
    언리얼엔진4
    클래스
    select
    C++
    FPS
    딥러닝
    php
    memcached
    C
    게임
    CPP
    Unreal
    Python
    JavaScript
    mscoco
    알고리즘
    pytorch
    MySQL
    map
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
덴마크초코우유
[Project] java-http-server - 1차 스프린트 후기
상단으로

티스토리툴바