웹 브라우저가 서버로 요청을 보내고 서버가 응답을 돌려주는 과정은 “HTTP 메시지”라는 텍스트 규칙 위에서 돌아간다.
이 메시지는 겉으로는 단순해 보이지만, 내부 구조를 정확히 잡아두면 웹서버 구현이나 디버깅 로그를 읽는 게 훨씬 쉬워진다.
HTTP 요청 메시지 구조
HTTP 요청(Request)은 크게 3~4개의 덩어리로 구성된다.
- 요청라인(Request Line): 첫 번째 줄
- 요청헤더(Request Headers): 두 번째 줄부터, 빈 공백 문자열 라인(빈 줄) 전까지
- 빈 공백 문자열 라인(Blank Line): 헤더의 끝을 표시하는 빈 줄
- 요청본문(Request Body): 빈 줄 다음부터 끝까지 (필수 아님)
즉, GET 요청처럼 Body가 없는 요청도 매우 흔하다는 뜻이다.
요청라인(Request Line)
요청 메시지의 첫 번째 줄을 요청라인(Request Line) 이라고 부른다.
요청라인은 다음 3요소로 구성된다.
- HTTP 메소드
- URL(또는 URI)
- HTTP 버전
형식은 이런 형태이다.
<HTTP-메소드> <URL> <HTTP-버전>
예시로 쓰면 이런 느낌이다.
GET / HTTP/1.1
GET /favicon.ico HTTP/1.1
GET /user/create?userId=javajigi HTTP/1.1
각 요소가 의미하는 바는 다음과 같다.
HTTP 메소드
HTTP 메소드는 “요청의 종류”를 의미한다.
- GET: 조회(요청본문 없는 경우가 많음)
- POST: 전송/생성(요청본문이 붙는 경우가 많음)
- PUT/PATCH/DELETE 등도 있지만, 기본은 GET/POST부터 잡으면 된다.
URL(또는 URI)
URL은 클라이언트가 서버에 요청하는 자원(resource)의 경로를 의미한다.
서버 입장에서는 “무엇을 달라는 요청인지”를 식별하는 핵심 정보이다.
URI와 URL은 혼용되는 경우가 많고, 학습 단계에서는 거의 같은 의미로 생각해도 흐름 이해에 문제 없다는 정도로 잡아도 된다.
HTTP 버전
요청이 어떤 HTTP 규약 버전을 따르는지 표시한다.
현실에서는 아직도 HTTP/1.1이 널리 사용된고한다.
요청 헤더(Request Headers)
요청라인 다음 줄부터는 요청 헤더가 온다.
요청 헤더는 여러 줄로 이루어져 있고, 각 줄은 기본적으로 다음 형식이다.
<필드 이름>: <필드 값>
예를 들면 이런 식이다.
Host: localhost:8080
User-Agent: ...
Accept: text/html
그리고 하나의 필드 이름에 여러 값을 보내고 싶으면 쉼표(,) 로 나열할 수 있다.
<필드 이름>: <필드 값1>, <필드 값2>
실제 브라우저 요청을 보면 Accept 같은 헤더에서 이 형태를 자주 본다.
빈 공백 문자열 라인(Blank Line)의 의미
요청 헤더가 끝났다는 것을 표시하기 위해 빈 줄이 반드시 한 줄 들어간다.
서버가 요청을 라인 단위로 읽을 때, 이 빈 줄이 나오면 “헤더 끝”으로 판단하는 경우가 많다.
즉, HTTP 메시지에서 빈 줄은 그냥 공백이 아니라 구조를 구분하는 문법 요소이다.
요청 본문(Request Body)은 필수가 아니다
요청 본문은 빈 줄 이후에 등장하며, 모든 요청에 붙는 게 아니다.
- GET은 보통 Body 없이 요청라인 + 헤더만으로 끝나는 경우가 많다.
- POST/PUT 같은 경우는 Body로 데이터를 실어 보내는 경우가 많다.
그래서 “요청라인/헤더/빈 줄은 필수, Body는 선택”이라는 표현이 나온다.
HTTP 응답 메시지 구조
클라이언트가 요청을 보내면 서버는 그에 대한 HTTP 응답(Response) 을 돌려준다.
응답도 요청과 거의 비슷하게 구성된다.
- 상태라인(Status Line): 첫 번째 줄
- 응답헤더(Response Headers): 두 번째 줄부터 빈 줄 전까지
- 빈 줄(Blank Line): 헤더 끝 표시
- 응답본문(Response Body): 빈 줄 이후 (필수 아님. 상황에 따라 없음)
즉, 전체 문법은 요청과 유사하고, 가장 큰 차이는 “첫 줄”이 요청라인이 아니라 상태라인이라는 점이다.
상태라인(Status Line)
응답 메시지의 첫 번째 라인을 상태라인(Status Line) 이라고 부른다.
상태라인은 다음 3요소로 구성된다.
- HTTP 버전
- 상태코드(Status Code)
- 응답구문(Reason Phrase)
형식은 이렇다.
<HTTP-버전> <상태코드> <응답구문>
예시는 이런 식이다.
HTTP/1.1 200 OK
HTTP/1.1 404 Not Found
상태코드
상태코드는 서버가 요청을 처리한 결과가 “성공인지 실패인지, 어떤 상황인지”를 숫자로 표현한 것이다.
- 200: 성공
- (추가로 흔한 것들: 302 리다이렉트, 404 없음, 500 서버 오류 등)
여기서 중요한 건, 상태코드가 “응답의 상태”를 판단하는 핵심 신호라는 점이다.
응답구문(Reason Phrase)
응답구문은 상태코드에 대한 사람이 읽기 쉬운 설명 문자열이다.
- 200이면 보통 OK
- 404면 Not Found
즉 “200은 성공을 의미하고, OK는 그 성공 상태에 대한 설명” 같은 관계이다.
응답 헤더와 응답 본문
응답도 요청과 마찬가지로
- 헤더는 <필드이름>: <필드값> 형식이며
- 헤더 끝에는 빈 줄이 들어가고
- 그 뒤에 본문이 오면 그게 응답 바디이다.
정적 파일 서버를 만들 때 자주 다루는 응답 헤더는 보통 이런 것들이다.
- Content-Type: 어떤 종류의 데이터인지(html, css, js, png…)
- Content-Length: 바디 길이
- 그리고 헤더 끝의 빈 줄
왜 이 구조를 알아야 하나
HTTP 요청/응답 메시지를 구조로 이해하면,
- 서버에서 readLine()로 읽을 때 어디까지가 헤더인지
- 왜 빈 줄이 중요한지
- 요청 첫 줄만으로도 어떤 자원을 요청했는지
- 응답 첫 줄(상태라인)로 성공/실패를 어떻게 판단하는지
이런 것들이 로그를 보면서 바로 연결된다.
출처 : 《자바 웹 프로그래밍 Next Step》, 박재성, 로드북
'Book > 자바 웹 프로그래밍 Next Step' 카테고리의 다른 글
| 3장_ 요구사항 4: 302 status code 적용 (0) | 2026.02.01 |
|---|---|
| 3장_ 요구사항3: POST방식으로 회원가입 (0) | 2026.02.01 |
| 3장_ 메모: HTTP 요청 라인 파싱과 멀티 스레드 처리 (0) | 2026.01.31 |
| 3장_ 요구사항2 : GET 방식으로 회원가입하기 (0) | 2026.01.31 |
| 3장_ 요구사항1: index.html 응답하기 (0) | 2026.01.30 |
