HTTP
HTTP 완벽 가이드 (3)
kchabin
2024. 10. 2. 16:43
HTTP 메시지
https://drive.google.com/file/d/1V0bXmiauWJoRQYdQHnxw6krC2GuVYSIn/view?usp=drive_link
이번 장에선 HTTP 메시지의 흐름과 상태코드에 대해서 공부했다.
원 서버 방향 = 인바운드, 사용자 에이전트 방향 = 아웃바운드
트랜잭션 방향을 표현
- HTTP 메시지는 강물처럼 흐른다.
메시지 부분
- 시작줄, 헤더 : 줄 단위로 구분된 아스키 문자열
- 각 줄은 캐리지 리턴, 개행문자로 구성된 두 글자의 줄바꿈 문자열(
CRLF
)로 끝난다. - 견고한 앱이라면 그냥 개행 문자도 받아들일 수 있어야 한다.
- 엔티티 본문이 없더라도 HTTP 헤더의 집합은 항상 빈 줄로 끝나야 한다.
- 각 줄은 캐리지 리턴, 개행문자로 구성된 두 글자의 줄바꿈 문자열(
- 엔티티 본문/메시지 본문 : 텍스트 or 이진 데이터 가능
요청 메시지와 응답 메시지
<메서드> <요청 URL> <버전>
<헤더>
<엔티티 본문>
<버전> <상태 코드> <사유 구절>
<헤더>
<엔티티 본문>
- 사유 구절은 인간이 읽기 위한 용도 → HTTP/1.0 200 NOT OK와 HTTP/1.0 200 OK는 동등하게 성공을 의미하는 것으로 처리되어야 한다.
- 상태코드의 사람이 읽기 쉬운 버전.
- 사유에 대한 엄격한 규칙 제공 x
상태 코드
전체 범위 | 정의된 범위 | 분류 |
---|---|---|
100-199 | 100-101 | 정보 |
200-299 | 200-206 | 성공 |
300-399 | 300-305 | 리다이렉션 |
400-499 | 400-415 | 클라이언트 에러 |
500-599 | 500-505 | 서버 에러 |
정의되지 않은 범위는 누군가가 확장한 코드일 수 있음.
- 그 코드가 포함되는 범주의 일반적인 구성원으로 가정하고 다루어야 함.
- 예)
515
코드 : 다른 5XX 메시지처럼 서버 에러를 의미하는 것으로 간주한다.
많이 쓰이는 상태 코드
상태 코드 | 사유 구절 | 의미 |
---|---|---|
200 | OK | 성공! 요청한 모든 데이터는 응답 본문에 들어있다. |
401 | Unauthorized | 사용자 이름과 비밀번호를 입력해야 한다. |
404 | Not Found | 서버는 요청한 URL에 해당하는 리소스를 찾지 못했다. |
버전 번호
HTTP/x.y
형식
- HTTP 애플리케이션들이 자신이 따르는 프로토콜 버전을 상대방에게 말해주기 위한 수단.
- 어떤 애플리케이션이 지원하는 가장 높은 HTTP 버전을 가리킴.
- 응답의 프로토콜 버전이
HTTP/1.1
→ 응답을 보낸 애가 여기까지 이해할 수 있다.
- 응답의 프로토콜 버전이
- HTTP/2.22 가 HTTP/2.3 보다 크다. → 소수 아님.
헤더
시작줄 다음엔 0개 혹은 그 이상의 HTTP 헤더가 온다.
- 이름/값 쌍의 목록으로 추가 정보를 더함.
Content-length: 19
- 일반 헤더 : 요청과 응답 양쪽에 모두 나타날 수 있음.
- 요청(응답) 헤더 : 요청(응답)에 대한 부가 정보를 제공
- Entity 헤더 : 본문 크기와 콘텐츠, 혹은 리소스 그 자체 서술
- 확장 헤더 : 명세에 정의되지 않은 새로운 헤더
- 간단한 문법 → 이름, 쉼표, 공백(없어도 됨), 필드 값, CRLF
예시 | 설명 |
---|---|
Date: Tue, 3 Oct 1997 02:16:03 GMT | 서버가 응답을 만들어낸 시각 |
Content-length: 15040 | 15,040 바이트의 데이터를 포함한 엔티티 본문 |
Content-type: image/gif | 엔티티 본문은 GIF 이미지다. |
Accept: image/gif, image/jpeg, text/html | 클라이언트는 GIF, JPEG 이미지와 HTML을 받아들일 수 있다. |
상태 코드
정보성 상태 코드
- HTTP/1.1에서 도입됨
100 continue
: 요청의 시작 부분 일부가 받아들여졌으며, 클라이언트는 나머지를 계속 이어서 보내야 함을 의미함. 이것을 보낸 후, 서버는 반드시 요청을 받아 응답해야 함.
클라이언트와100 Continue
- 클라이언트는 값을 100-continue로 하는 Expect 요청 헤더를 보내야함.
- 엔티티를 보내지 않으려 하면 이 헤더를 보내면 안됨.
- 클라이언트가 서버가 다루거나 사용할 수 없는 큰 엔티티를 서버에게 보내지않으려는 목적으로만 사용해야 함
- 서버가 응답을 보내주기만을 기다리지말고 약간의 타임아웃 후 그냥 엔티티를 보내야 함
서버와 100 continue
- 100-continue 값이 담긴 Expect 헤더를 받았다면, 100-continue 응답 혹은 에러코드로 응답해야 함.
- 응답받을 것을 의도하지 않은 클라이언트에게 100-Continue 상태 코드를 보내선 안됨(몇몇 잘못 만들어진 서버)
- 100 Continue 응답을 보내기 전에 클라이언트로부터 엔티티의 일부 혹은 전체를 수신하였다면, 상태 코드를 보낼 필요 없음.
- 서버가 100 Continue 응답을 받을 것을 의도한 요청을 받고 난 상태에서 엔티티 본문을 읽기 전에 요청을 끝내기로 결정(에러 등) 했다면 그냥 응답을 보내고 연결을 닫아서는 안됨 -> 4장 TCP 끊기와 리셋 에러
프락시와 100 Continue
정보성 상태코드는 HTTP/1.1에서만 동작한다.
- 프락시는 다음 hop에 있는 서버가 1.1 버전이 아닐 경우 클라이언트에게
417 Expectation Failed
상태 코드로 응답해야 함. - 프락시가 HTTP/1.0이나 이전 버전을 따르는 클라이언트를 대신해 100 Continue 응답을 의도한 요청을 보낸다면 서버에서 오는 100 Continue 응답을 클라이언트로 전달해서는 안된다.
그외 상태코드들 중 주요 상태코드
- 200-299 : 성공 상태 코드
- 300-399 : 리다이렉션 상태 코드
- 400-499 : 클라이언트 에러 상태 코드
- 500-599 : 서버 에러 상태 코드
멘토님 피드백
멱등성
Idempotenced method
멱등성이 있는 메서드 : 여러 번 호출해도 리소스 자체에 대한 변경은 없다.
GET /user/123
: 여러 번 호출해도 동일한 결과를 얻는다.PUT /users/123 userName: "Kchabin"
: 리소스에 변경이 일어난다고 생각할 수 있지만, 멱등성은 여러 번 호출해서 변경이 있는지 없는지를 따진다. userName을 매번 바꾸면 모르겠지만 똑같은 요청을 여러번 보내도 userName은 계속 Kchabin이다.POST /users
: 서버에 데이터 변경이 일어난다. DB에 동일한 유저 정보로 생성이 안된다. PK 오류DELETE /users/123
: 삭제된 row수를 출력하면 첫번째 호출에는 1, 두번째 호출에는 응답이 0 -> 호출하면서 변경이 발생한다.
URI 생성 규칙
REST API URI Naming Conventions and Best Practices
RESTful API 네이밍
host -> uri -> method -> Content-type -> queryString/body
GET /users/12345/histories?count=1&sort=desc
504 코드 예시
서버에서의 요청 처리 시간이 게이트웨이가 응답을 기다리는 시간인 10초보다 오래 걸리면 게이트웨이는 클라이언트에게 504 Gateway Timeout 코드와 사유 문구를 반환한다.
게이트웨이와 서버 사이에는 Broken Pipe가 발생한다.
AWS의 CloudFront는 CDN(Content Delivery Network) 서비스이다. 위 링크에는 CloudFront가 504 코드를 반환하는 경우의 상황을 두 가지로 나누어 설명하고 있다.
- 오리진(서버)가 cloudfront에게 504를 반환했다.
- 요청이 만료되기 전에 오리진이 응답하지 않았다.
위 그림 예시는 상황 2에 속하는 방식이다.