CS Repo/HTTP 완벽 가이드

HTTP 메시지

조금씩 차근차근 2025. 3. 25. 18:34

본 내용은 "HTTP 완벽 가이드" 내용을 참고하여 기록한 정리본입니다.

게시할 내용

  • 메시지는 어떻게 흘러가는가
  • HTTP 메시지의 세 부분
    • 시작줄
    • 헤더
    • 바디
  • 요청과 응답 메시지의 차이
  • 요청 메시지가 지원하는 여러 메소드들
  • 응답 메시지가 반환하는 여러 상태 코드들
  • HTTP 헤더들은 각각 무슨일을 하는가

메시지는 어떻게 흘러가는가

  • 요청과 응답이라는 두 가지 형식으로 통신하며, 클라이언트-서버 간의 데이터를 교환한다.
  • 메시지는 크게 시작줄, 헤더, 바디 세 부분으로 이루어져 있다.
  • 요청 메시지응답 메시지는 기본 구조는 유사하지만, 시작줄에서 사용하는 구문이 다르다.
    • 요청 메시지는 메소드, URL, 버전으로 시작한다.
    • 응답 메시지는 버전, 상태코드, 사유구절로 시작한다.

HTTP 메시지의 세 부분

  • 시작줄
    • 요청 메시지: 메소드 URL HTTP 버전
    • 응답 메시지: HTTP 버전 상태코드 사유구절
  • 헤더
    • 요청 헤더와 응답 헤더는 유사한 구조를 가지나, 포함된 항목이 달라진다.
  • 바디
    • 실제 데이터를 담는 부분으로, 요청 시 전송할 내용 또는 응답 시 반환할 내용이 들어간다.

요청과 응답 메시지의 차이

  • 요청 메시지의 시작줄은 어떤 동작을 수행할지 결정하는 메소드URL을 포함한다.
  • 응답 메시지의 시작줄에는 서버가 처리한 결과를 나타내는 상태코드사유구절이 포함된다.

요청 메시지가 지원하는 여러 메소드들

  • GET, POST, HEAD, PUT, PATCH, TRACE, OPTIONS, DELETE 등이 있다.
  • 각 메소드는 안전성, 멱등성, 캐시 가능 여부 등에 차이가 있으므로 용도에 맞게 사용해야 한다.

응답 메시지가 반환하는 여러 상태 코드들

  • 1xx(정보), 2xx(성공), 3xx(리다이렉션), 4xx(클라이언트 오류), 5xx(서버 오류)와 같이 범주화된다.
  • 세부 코드에 따라 의미가 달라지므로, 시나리오에 맞게 정확한 상태 코드를 설정하는 습관이 중요하다.

HTTP 헤더들은 각각 무슨 일을 하는가

  • 일반 헤더, 요청 헤더, 응답 헤더, 표현 헤더 등으로 구분된다.
  • 캐시 제어, 인증 정보, 언어 및 인코딩 정보, 쿠키, 서버 정보 등을 주고받기 위해 사용한다.
  • 적절히 활용하면 네트워크 사용량 절감 및 보안, 성능 개선에 도움이 된다.

메시지의 흐름

인바운드(Inbound)

  • 클라이언트에서 서버로 요청이 들어가는 흐름이다.
  • 서버 입장에서는 “인바운드”로 요청을 받아 처리한다.

아웃바운드(Outbound)

  • 서버에서 클라이언트로 응답이 나가는 흐름이다.
  • 서버 입장에서는 “아웃바운드”로 결과를 전송한다.

업스트림(Upstream)

  • 메시지를 송신하는 주체를 의미한다.
  • 예를 들어, 클라이언트→서버로의 요청 흐름에서 업스트림은 클라이언트이다.

다운스트림(Downstream)

  • 메시지를 수신하는 주체를 의미한다.
  • 예를 들어, 클라이언트→서버로의 요청 흐름에서 다운스트림은 서버이다.

주의: 업스트림/다운스트림의 오해

  • 업스트림/다운스트림은 요청/응답 개념이 아니다.
  • 업스트림/다운스트림은 송신자/수신자 개념이다.
  • 클라이언트-서버 모델 간, 어떨 때는 업스트림이 될 수 있고, 어떨 때는 다운스트림이 될 수 있다.

메시지의 구조

출처: 김영한-모든 개발자를 위한 HTTP 기본 지식

시작줄

요청

  • 메소드
    • GET, POST 등과 같이 서버가 수행해야 할 동작을 정의한다.
  • URL
    • 서버 자원의 위치를 표시한다.
  • 버전
    • 예: HTTP/1.1
    • 요청 메시지의 HTTP 버전 정보를 나타낸다.

응답

  • 버전
    • 서버가 받을 수 있는 최대 버전을 기준으로 한다.
    • 실제 메시지는 요청자의 버전에 맞춰서 응답을 내보낸다.
  • 상태코드
    • 클라이언트 요청 처리 결과를 숫자로 표현한다.
  • 사유구절
    • 숫자 상태코드를 사람이 알아볼 수 있도록 간단히 설명한 문구다.
    • 클라이언트 측 로직에서 이 구절을 근거로 처리하면 안 된다. (예: 200 NOT OK라도 200이면 성공)

헤더 블록

  • 일반 헤더
    • 캐시, 연결 유지 여부 등과 같이 전반적인 정보를 다룬다.
  • 요청 헤더
    • 클라이언트가 서버에게 전달하는 추가 정보들을 포함한다 (Host, User-Agent 등).
  • 응답 헤더
    • 서버가 클라이언트에게 전달하는 추가 정보들을 포함한다 (Server, Retry-After 등).
  • 표현 헤더
    • 실제 데이터(컨텐츠)의 형식, 인코딩, 길이 등을 설명한다.
  • obs-folding
    • 오래된 사양에서 사용하는 헤더 접기 방식. 최신 사양에서는 권장되지 않는다.

본문

  • 요청 혹은 응답의 실제 데이터를 담는 영역이다.

CRLF

  • 시작줄/헤더/본문을 구분하기 위한 개행 문자(\r\n)를 의미한다.
  • 명세상으로는 캐리지 리턴+라인 피드(Windows 개행 방식)를 포함해야 하지만, 유연성을 고려하여 다양한 개행 방식을 수용하기도 한다.

요청 메시지 구조

출처: 김영한-모든 개발자를 위한 HTTP 기본 지식

응답 메시지 구조

출처: 김영한-모든 개발자를 위한 HTTP 기본 지식

버전

  • 서버가 받을 수 있는 최대 버전을 기준으로 동작하지만, 실제 메시지는 요청자의 버전에 맞춘다.
  • 메이저 / 마이너 버전으로 구성되며, 예를 들어 HTTP/2.0에서 2가 메이저, 0이 마이너에 해당한다.
  • 숫자가 하나의 정수로 판단되지 않고 독립적으로 비교되므로, HTTP/2.22HTTP/2.3보다 더 높은 버전이 된다.
  • 요청의 HTTP 버전과 응답의 HTTP 버전이 다를 수 있으므로 주의한다.

HTTP 메소드

안전한 메소드

  • 서버 자원에 아무런 변화를 일으키지 않는 메소드를 의미한다.
  • 여러 번 호출해도 서버 상태가 변하지 않는다.
  • GET, HEAD가 해당된다.

GET

  • 데이터 조회를 요청하는 메소드다.
  • 멱등성을 보장해야 하며, 캐시가 가능하다.

POST

  • 서버가 정의한 방식대로 데이터 처리를 요청하는 메소드다.
  • 멱등성을 보장하지 않는다.
  • 응답 결과를 캐시할 수 있으나, 본문까지 캐시 키로 고려해야 하므로 일반적으로 잘 사용되지 않는다.

HEAD

  • GET과 유사하되, 헤더만 응답으로 받는다.
  • 리소스를 실제로 가져오지 않고 존재 여부나 변경 여부를 확인하고자 할 때 유용하다.
  • HTTP/1.1 준수를 위해 반드시 구현되어야 한다.

PUT

  • 데이터 덮어쓰기를 요청하는 메소드다.
  • 리소스 전체를 업데이트하며, 멱등성을 보장해야 한다.
  • 클라이언트가 서버 내 파일의 정확한 위치를 알고 있어야 한다.

PATCH

  • 데이터의 부분 업데이트를 요청한다.
  • PUT과 달리 멱등성을 보장하지 않는다.
  • 캐시가 가능하지만, 본문까지 캐시 키로 봐야 해서 일반적으로 잘 쓰이지 않는다.

TRACE

  • 루프백(Loopback) 기능을 수행하기 위한 메소드다.
    • 메시지가 훼손되지 않았는지 그대로 되돌려받아 확인한다.
  • 보안 취약점이 있어 대부분의 서버에서는 비활성화되어 있다.
    • 악의적 사용자가 본문이나 헤더를 몰래 확인할 목적으로 쓸 수 있기 때문이다.

OPTIONS

  • 서버가 어떤 메소드, 통신 옵션 등을 지원하는지 확인하는 메소드다.
  • 주로 CORS(Cross-Origin Resource Sharing) 검증 시 사용된다.

DELETE

  • 데이터 삭제를 요청한다.
  • 멱등성을 보장해야 하므로, “마지막 데이터를 삭제”와 같은 불명확한 요청은 포함되면 안 된다.

참고: 캐시 가능 여부

  • 클라이언트가 요청 시, 서버로 직접 가지 않고 내부 캐시(로컬 혹은 중간 캐시)를 사용할 수 있는지 여부를 의미한다.
  • 서버 측 내부 캐싱과는 다른 개념이므로 혼동하지 않아야 한다.

참고 2: 멱등성

  • 함수를 한 번 적용하나 여러 번 적용하나 결과가 같다는 성질을 말한다.
  • 다른 메소드나 로직에 의한 변경은 고려 대상이 아니다.

상태 코드

100번대 (Informational)

  • 정보성 상태 코드로, 주로 커넥션 유지와 성능 최적화 목적을 가진다.
  • 예: 100 Continue
    • 프록시 서버 등이 다운 홉 서버와 통신 시, 요청의 일부만 먼저 전송받고 처리 가능 여부를 확인하는 용도로 사용한다.
  • 일반적인 클라이언트-서버 통신에서는 거의 사용되지 않는다.

200번대 (Success)

  • 성공을 의미하는 상태 코드.
  • 200
    • 요청이 정상 처리되었으며, 본문에는 요청한 리소스가 들어 있다.
  • 201
    • 자원(개체)을 성공적으로 생성했다는 의미.
    • POST 등으로 서버에 새 자원을 만들었을 때 사용한다.
  • 202
    • 요청을 받아들였으나, 아직 처리가 완료되지 않았음을 의미한다.
    • 처리가 언제 완료될지에 대한 정보를 함께 담는 경우가 많다.
  • 204
    • 요청은 정상 처리되었으나, 본문이 없다는 의미.
    • 브라우저 화면 전환 없이 간단한 갱신을 할 때 활용된다.

300번대 (Redirection)

  • 리다이렉션 관련 상태 코드.
  • 301
    • 영구적으로 리소스가 이동되었음을 나타낸다.
    • Location 헤더에 새 URL을 명시하고, 클라이언트는 향후 요청 시 이 새 주소를 사용한다.
  • 302
    • 일시적으로 다른 위치로 이동했다는 의미.
    • 원래는 메소드 유지가 원칙이나, 많은 브라우저가 GET으로 변경해 버린다.
    • HTTP/1.1에서 303(메소드 변경)과 307(메소드 유지)로 분화되었으나, 실제 현장에서는 302를 자주 쓴다.
  • 303
    • 리다이렉트 시 요청 메소드를 GET으로 바꿔서 재요청하도록 안내한다.
  • 304
    • 캐시 목적으로 사용된다.
    • 요청된 리소스가 수정되지 않았다고 응답할 때 사용하며, 본문을 포함해서는 안 된다.
  • 307
    • 리다이렉트 시 기존의 메소드와 본문을 유지해야 함을 명시한다.

400번대 (Client Error)

  • 클라이언트 측 오류 상태 코드.
  • 400
    • 요청 형식, 파라미터 등이 잘못되었을 때 사용한다.
  • 401
    • 인증이 되지 않았음을 의미한다. (Authorization 헤더가 없거나 잘못됨)
    • 응답에 WWW-Authenticate 헤더를 포함해 인증 방법을 안내해야 한다.
  • 403
    • 인증 자격은 있지만, 인가(권한)가 부족할 때 사용한다.
    • 접근 권한이 없는 자원에 대한 접근 시 발생한다.
  • 404
    • 요청 리소스가 존재하지 않을 때 사용한다.
    • 리소스 존재 여부를 숨기기 위해 의도적으로 404를 반환하기도 한다.
  • 405
    • 지원하지 않는 메소드를 요청받았음을 의미한다.
    • Allow 헤더에 가능한 메소드 목록을 안내해야 한다.
  • 406
    • 허용되지 않는 응답 형식일 때 발생한다.
    • 클라이언트의 Accept 헤더와 서버 응답이 불일치할 때 발생한다.
    • 또는, 서버 측에서 Json 응답 처리(@ResponseBody)를 안했을 때 발생할수도 있다.
  • 409
    • Conflict
    • 리소스 버전에 충돌이 발생했을 시 사용한다.
    • 낙관적 락 버전 충돌 시 응답 코드로 사용한다.

500번대 (Server Error)

  • 서버 측 오류 상태 코드.
  • 500
    • 서버 내부에서 오류가 발생했음을 의미한다.
    • 원인을 특정하기 어려울 경우 일단 500을 응답한다.
  • 502
    • 게이트웨이나 프록시 서버가 다음 링크로부터 잘못된 응답을 받았을 때 사용한다.
    • 상위 게이트웨이의 네트워크가 불가능하거나 응답이 비정상인 경우에 발생한다.
  • 503
    • 일시적으로 서버가 요청을 처리할 수 없음을 의미한다.
    • 과부하 혹은 점검 중일 때 사용하며, Retry-After 헤더로 재시도 시점을 안내하기도 한다.

헤더

헤더의 양식

출처: 김영한-모든 개발자를 위한 HTTP 기본 지식

일반 헤더

일반 정보 헤더

  • Connection
    • 클라이언트-서버 간 연결 유지 방식을 결정한다.
    • Connection: keep-alive로 설정하면 여러 요청을 끊김 없이 처리할 수 있다.
  • Date
    • 메시지가 언제 생성되었는지 알려준다.
    • 요청, 응답 모두에서 기록할 수 있으며, 로그나 캐시 처리 시 유용하다.
  • Transfer-Encoding
    • 본문 데이터를 인코딩하는 방식을 정의한다.
    • chunked 인코딩은 본문을 여러 덩어리로 잘라 전송하는 기법으로, 대용량 혹은 동적 데이터를 전송할 때 유리하다.

일반 캐시 헤더

  • Cache-Control
    • 캐싱 동작을 제어하는 지시자를 담는다.
    • Cache-Control: no-cache, no-store, must-revalidate 등을 통해 캐시 정책을 세밀히 조정할 수 있다.
  • Pragma
    • HTTP/1.0 하위 호환용으로, 캐시 제어에 쓰인다.
    • Pragma: no-cache가 대표 예시지만, 최신 환경에서는 Cache-Control이 더 우선된다.

요청 헤더

요청 정보 헤더

  • From
    • 사용자 이메일 주소 등을 표시하기 위한 헤더이지만, 보안 문제로 거의 사용되지 않는다.
  • Host
    • HTTP/1.1부터 필수이며, 요청 대상 서버 호스트명과 포트를 담는다.
    • 가상 호스팅(하나의 IP로 여러 도메인을 운영) 환경에서 반드시 필요하다.

하나의 IP에 여러 도메인이 호스트되는 상황을 나타내는 그림. 다음과 같이 도메인 주소가 있어야, 적절한 서버를 안내할 수 있다.

  • Referer
    • 현재 요청이 어떤 페이지에서 유입되었는지 나타낸다.
    • 트래픽 분석 등에 유용하지만, 보안 및 개인정보 문제로 빈 값 혹은 마스킹될 때도 있다.
  • User-Agent
    • 클라이언트 애플리케이션(브라우저 등)에 대한 정보를 담는다.
    • 브라우저별 사용자 경험 개선, 로그 분석 등에 활용된다.

Accept 관련 헤더

  • Accept
    • 클라이언트가 받을 수 있는 MIME 타입을 제시한다 (예: text/html, application/json).
  • Accept-Charset
    • 수용 가능한 문자 인코딩을 나타낸다 (예: utf-8, iso-8859-1;q=0.7).
  • Accept-Encoding
    • gzip, deflate 등 콘텐츠 인코딩 방식을 통해 전송 효율을 높일 수 있음을 알린다.
  • Accept-Language
    • 클라이언트가 선호하는 언어를 명시한다 (예: ko, en-US;q=0.8).

조건부 요청 헤더

  • If-Modified-Since
    • 지정된 시점 이후 수정되었을 때만 새로 다운로드하도록 유도해 트래픽을 절약한다.
  • If-Unmodified-Since
    • 특정 시점 이후 변경되지 않았다면 요청을 진행하고, 변경되었다면 412(Precondition Failed)로 처리한다.
  • If-Match
    • 리소스의 ETag 값과 일치하는 경우에만 작업을 진행하도록 제한한다.
  • If-None-Match
    • ETag와 일치하지 않을 경우에만 작업을 진행하도록 제한한다.
  • If-Range
    • 리소스가 변경되지 않았다면 Range 요청으로 부분만 받고, 변경되었다면 전체를 다시 받도록 한다.
  • Range
    • 대용량 파일 일부만 재전송하거나 스트리밍 시 특정 바이트 범위만 요청하기 위해 사용한다.

요청 보안 헤더

  • Authorization
    • HTTP 인증에 필요한 정보를 담는다 (Basic, Bearer 등).
    • 서버는 이 정보를 기반으로 사용자 인증을 수행한다.
  • Cookie
    • 클라이언트 측에 저장된 쿠키 데이터를 서버에 전송한다.
    • 보안 헤더는 아니나, 세션이나 사용자 추적 등에 영향이 크므로 주의해야 한다.

프록시 요청 헤더

  • Max-Forwards
    • 프록시를 지날 때마다 1씩 감소시키며, 요청이 몇 번 중계될지를 제한한다. 무한 루프 방지용이다.
  • Proxy-Authorization
    • 프록시 서버 접근 시 필요한 인증 정보를 제공한다.
  • Proxy-Connection
    • 프록시와의 연결 유지 여부를 제어한다. 최신 사양에서는 Connection 헤더와 함께 다루는 경우가 많다.

응답 헤더

응답 정보 헤더

  • Age
    • 캐시된 응답이 얼마나 오래됐는지(초 단위) 나타낸다.
    • 캐시 유효성 검증에 도움을 준다.
  • Retry-After
    • 재시도 전 대기 시간을 나타낸다. (예: Retry-After: 120)
    • 503(Service Unavailable) 등이 발생했을 때 재시도 시점 안내에 사용된다.
  • Server
    • 서버 애플리케이션 정보를 담는다.
    • 보안상 노출을 최소화하는 경우도 있다.

협상 헤더

  • Accept-Ranges
    • 부분 요청(Range 요청)을 지원하는지 여부를 나타낸다. (예: Accept-Ranges: bytes)

응답 보안 헤더

  • WWW-Authenticate
    • 401 Unauthorized 응답 시, 서버가 지원하는 인증 방식을 안내한다.
  • Proxy-Authenticate
    • 407 Proxy Authentication Required 응답 시, 프록시가 요구하는 인증 방식을 안내한다.
  • Set-Cookie
    • 서버에서 클라이언트에게 쿠키를 설정하도록 지시한다.
    • 쿠키 속성(만료, 경로, HttpOnly 등)을 함께 지정한다.

표현 헤더

표현 정보 헤더

  • Allow
    • 특정 리소스에서 지원하는 메소드를 나열한다.
    • 405 오류 응답 시, 사용할 수 있는 메소드를 안내하기 위해 사용된다.
  • Location
    • 3xx 리다이렉트 시 이동할 주소나, 201 응답 시 새로 생성된 리소스의 주소를 안내한다.

콘텐츠 헤더

  • Content-Encoding
    • 본문이 어떤 방식으로 압축 또는 인코딩되었는지 표시한다.
  • Content-Length
    • 응답 본문의 바이트 길이를 나타낸다.
  • Content-Range
    • 부분 요청에 대한 응답 시, 현재 전송 범위와 전체 크기를 표기한다.
  • Content-Type
    • 본문의 MIME 타입과 문자 인코딩 등을 나타낸다 (예: text/html; charset=UTF-8).

유효성 검사 헤더

  • Expires
    • 캐시가 만료되는 시점을 명시한다.
    • 정적 리소스 등에서 미리 기간을 설정하면, 해당 시간 전까지 클라이언트는 캐시를 재사용한다.
  • ETag
    • 리소스의 고유 버전 식별자 역할을 하며, If-None-Match 등과 함께 사용한다.
    • 변경 검증 로직을 서버가 주도적으로 관리할 수 있다는 장점이 있다.
  • Last-Modified
    • 리소스가 마지막으로 수정된 시점을 나타낸다.
    • If-Modified-Since와 함께 사용하며, 날짜 비교를 통해 캐시 적중 여부를 판단한다.

더욱 자세한 내용은 RFC 9110에서 확인 가능하다.

'CS Repo > HTTP 완벽 가이드' 카테고리의 다른 글

웹 서버  (0) 2025.04.04
HTTP 커넥션 관리 최적화 기법  (0) 2025.04.03
HTTP에서 바라본 TCP 커넥션 관리 방식  (0) 2025.03.27
URL과 리소스  (0) 2025.03.24
HTTP란?  (0) 2025.03.24