도서기록/HTTP 완벽가이드
3장 HTTP 메서드
by 코엘리
2024. 12. 6.
3.1 메시지의 흐름
- HTTP 메시지는 데이터의 블록들이다.
- 이 데이터 블록은 메시지 내용과 의미를 설명하는 '텍스트 메타 정보'로 시작하고 '데이터'가 올 수 있다.
3.1.1 메시지는 원 서버 방향을 인바운드로 하여 송신
- 인바운드와 아웃바운드 용어는 트랜잭션 방향을 표현하기 위해 사용된다.
- 인바운드: 메시지가 원 서버로 향하는 것
- 아웃바운드: 모든 처리가 끝난 뒤 메시지가 사용자 에이전트로 돌아오는 것
3.1.2 다운스트림으로 흐르는 메시지
- 모든 메시지는 다운스트림으로 흐른다.
- 메시지의 발송자는 수신자의 업스트림이다.
- 업스트림, 다운스트림은 발송자와 수신자에 대한 것이다.
3.2 메시지의 각 부분
3.2.1 메시지의 문법
요청과 응답 모두 기본적으로 메시지 구조가 같다.
요청 메시지의 형식
<메서드> <요청 URL> <버전>
<헤더>
<엔터티 본문>
응답 메시지의 형식
<메서드> <상태 코드> <사유 구절>
<헤더>
<엔터티 본문>
key |
detail |
메서드 |
클라이언트 측에서 서버가 리소스에 대해 수행해주길 바라는 동작이다 |
사유 구절 |
오로지 사람에게 읽히기 위한 목적으로 존재하는 짧은 문구로, 상태 코드의 의미를 사람이 이해할 수 있게 설명해준다 |
헤더들 |
이름, 콜론(:), 선택적 공백, 값, CRLF 가 순서대로 나타나는 0개 이상 헤더들 |
HTTP 헤더의 집합은 항상 빈줄(그냥 CRLF)로 끝나야 함에 주의
3.2.2 시작줄
- 모든 HTTP 메시지는 시작줄로 시작한다.
- 요청 메시지의 시작줄은 무엇을 해야하는지 말해준다.
- 응답 메시지의 시작줄은 무슨 일이 일어났는지 말해준다.
3.2.3 헤더
- HTTP 헤더 필드는 요청/응답 메시지에 추가 정보를 더한다.
종류 |
설명 |
일반 헤더 |
요청/응답 양쪽에 모두 나타날 수 있음 |
요청 헤더 |
요청에 대한 부가 정보 제공 |
응답 헤더 |
응답에 대한 부가 정보 제공 |
Entity 헤더 |
본문 크기와 콘텐츠, 혹은 리소스 그 자체 서술 |
확장 헤더 |
명세에 정의되지 않은 새로운 헤더 |
헤더를 여러 줄로 나누기
3.2.4 엔터티 본문
3.2.5 버전 0.9 메시지
- HTTP 0.9 메시지의 요청은 메서드와 요청 URL만 갖고, 응답은 오직 엔터티만 있었다.
- 상태 코드/사유 구절/헤더가 없었다.
- 지나친 단순함으로 다양한 상황에 대응할 수 없다.
3.3 메서드
3.3.1 안전한 메서드(Safe Method)
- GET과 HEAD 메서드는 안전하다고 할 수 있다.
- HTTP의 요청의 결과로 서버에 어떤 작용도 없음을 의미한다.
3.3.2 GET
- 서버에게 리소스 달라고 요청하기 위해 쓰인다.
3.3.3 HEAD
- GET 과 비슷하지만, 서버는 응답으로 헤더만 돌려주고, 엔터티 본문은 반환되지 않는다.
- 리소스 조회 없이 헤더만 조사할 수 있다.
3.3.4 PUT
- GET 메서드가 서버로부터 문서를 읽어들이지만, PUT은 문서를 쓴다.
- 요청 URL의 이름대로 새 문서를 만들거나, URL 이 이미 존재한다면 본문을 사용해서 교체하는 것이다.
3.3.5 POST
- 서버에 입력 데이터를 전송하기 위해 설계되었다.
- 폼을 지원하기 위해 흔히 사용된다.
3.3.6 TRACE
- 클라이언트에게 자신의 요청이 서버에 도달했을 때 어떻게 보이는지 알려준다.
- 목적지 서버에서 '루프백'진단을 시작하는데, 요청 전송 마지막 서버는 자신이 받은 요청 메시지를 본문에 넣어서 TRACE 응답을 돌려준다.
- 클라이언트는 요청/응답 연쇄를 따라가면서 중간에 메시지 오류가 발생했는지 진단할 수 있다.
- 어떠한 엔터티 본문도 보낼 수 없다.
3.3.7 OPTIONS
- 서버에게 특정 리소스에 대해 어떤 메서드가 지원되는지 물어볼 수 있다.
3.3.8 DELETE
3.3.9 확장 메서드
- HTTP는 필요에 따라 확장 시 문제가 없도록 설계되어 있다.
- 확장 메서드는 HTTP/1.1 명세에 정의되지 않은 메서드이다.
- 모든 확장 메서드가 형식을 갖춘 명세로 정의된 것은 아니다.
- 확장 메서드에 대해서는 관용적인 것이 좋다. "be conservative in what you send, be liberal what you accept" Postel의 법칙을 따르는 것이 좋다.
- 예를 들어 프락시는, 알려지지 않은 메서드가 종단 간 행위를 망가뜨리지 않을 수 있다면 다운스트림 서버로 전달, 그렇지 않다면 501 Not Implemented 상태 코드로 응답한다.
- 확장 메서드 예시
메서드 |
설명 |
LOCK |
사용자가 리소스를 잠글 수 있다. |
MKCOL |
사용자가 문서를 생성할 수 있게 해준다 |
COPY |
서버에 있는 리소스를 복사한다 |
MOVE |
서버에 있는 리소스를 옮긴다 |
3.4 상태 코드
3.4.1 100-199: 정보성 상태 코드
- 비교적 새로운 것들
상태코드 |
사유 구절 |
의미 |
100 |
Continue |
요청의 시작 부분 일부가 받아들여짐, 클라이언트는 나머지를 계속 이어서 보낼 것 |
101 |
Switching Protocols |
Upgrade 헤더에 나열한 것 중 하나로 서버가 프로토콜을 바꾸었음을 의미한다. |
클라이언트와 100 Continue
- 만약 클라이언트가 100 Continue 응답을 기다리겠다면, 클라이언트는 값을 '100-Continue'로 하는 Expect 요청 헤더를 보낼 필요가 있다.
- 만약 엔터티를 보내지 않으려 한다면 위 헤더를 보내면 안된다.
서버와 100 Continue
- 서버가 100-Continue'로 하는 Expect 요청 헤더 요청을 받는다면, 100 Continue 응답 혹은 에러 코드로 답해야 한다.
- 서버가 100 Continue 응답을 보내기 전에 엔터티의 일부(혹은 전체)를 수신하였다면 이 상태 코드를 보낼 필요가 없다.
- 클라이언트는 이미 계속 전송하기로 결정하였기 때문이다.
- 서버가 요청을 끝까지 읽은 후에는 그 요청에 대한 최종 응답을 보내야 한다.
- 만약 서버가 엔터티 본문을 읽기 전 요청을 끝내기로 결정했다면, 응답을 보내고 그냥 연결을 끊으면 안된다. 클라이언트가 응답을 받을 수 없기 때문이다.
프락시와 100 Continue
- 만약 다음 홉 서버가 HTTP/1.1을 따르거나 어떤 버전을 따르는지 모른다면, Expect 헤더를 포함시켜서 요청을 다음으로 전달해야 한다.
- 서버가 1.1 이전이라는 걸 알고 있다면 417 Expectation Failed 에러를 응답해야 한다.
- 만약 프락시가 100-continue 값을 요청에 포함시키기로 결정했다면 클라이언트에게 100 Continue 응답을 전달하면 안된다.
3.4.2 200-299: 성공 상태 코드
상태코드 |
사유 구절 |
의미 |
200 |
OK |
정상 |
202 |
Accepted |
요청은 받아들여졌으나, 그에 대한 어떤 동작도 수행하지 않았음. 요청이 받아들여지기 적법해 보인다는 의미일 뿐이다. |
204 |
No Content |
헤더와 상태줄을 포함하지만, 엔터티 본문은 포함하지 않는다. |
206 |
Partial Content |
부분 혹은 범위 요청이 성공했다. 응답은 반드시 Content-Rage와 Date 헤더를 포함해야 하며, Etag와 Content-Location 중 하나의 헤더도 반드시 포함해야 한다. |
3.4.3 300-399: 리다이렉션 상태 코드
- 리소스에 대해 다른 위치를 사용하라고 말해주는 코드
- 예를 들어, HTTP 애플리케이션은 리소스에 대한 로컬 복사본이 여전히 최신인지 혹은 원래 서버에 있는 리소스가 수정되었는지 검사할 수 있다.
- 클라이언트는 문서가 1997년 10월 이후에 수정된 경우에만 문서를 가져오기 위해 'If-Modified-Since' 헤더를 전송한다.
- 문서가 그 날짜 이후 변한 게 없다면, 304 상태 코드로 응답한다.
- 리다이렉션 상태 코드를 포함한 응답을 할 때, 리다이렉트될 URL/설명을 포함시키도록 하자.
상태코드 |
사유 구절 |
의미 |
301 |
Moved Permanently |
요청한 URL이 옮겨졌을 때 사용 |
302 |
Found |
클라이언트는 Location 헤더로 주어진 URL을 리소스를 임시로 가리키기 위한 목적으로 사용한다 이후의 요청은 원래 URL을 사용한다 |
303 |
See Other |
클라이언트에게 리소스를 다른 URL에서 가져와야 한다고 말할 때 쓰인다. 주 목적은 POST 요청에 대한 응답으로 클라이언트에게 리소스 위치를 알려주는 것이다 |
304 |
Not Modified |
클라이언트는 헤더를 이용해 조건부 요청을 만들 수 있다 |
307 |
Temporary Redirect |
클라이언트는 Location 헤더로 주어진 URL을 리소스를 임시로 가리키기 위한 목적으로 사용한다 |
302, 303, 307 상태 코드는 주로 HTTP/1.0과 HTTP/1.1가 다루는 방식의 차이점에 기인한다.
- HTTP/1.0 클라이언트가 POST 요청을 보내고 302 리다이렉트 상태 코드가 담긴 응답을 받으면, 클라이언트는 Location 헤더에 들어있는 리다이렉트 URL을 GET 요청으로 따라간다.
- HTTP/1.1 은 위 상황에 대해서 303 상태 코드를 사용한다. 그러나 일시적인 리다이렉트에서는 307 상태 코드를 사용한다.
- 결국, 서버는 클라이언트의 HTTP 버전을 검사하여 리다이렉트 응답 코드를 선택해야 한다.
3.4.4 400-499 클라이언트 에러 상태 코드
상태코드 |
사유 구절 |
의미 |
400 |
Bad Request |
클라이언트가 잘못된 요청을 보냈다고 말해준다 |
401 |
Unauthorized |
인증하라고 요구하는 내용의 응답을 헤더와 함께 반환한다. |
403 |
Forbidden |
요청이 거부되었음을 보여준다. |
404 |
Not Found |
서버가 요청한 URL을 찾을 수 없음을 알려주기 위해 사용한다. |
405 |
Method Not Allowed |
요청한 URL에 대하여 지원하지 않는 메서드를 요청으로 받았을 때 사용한다. |
406 |
Not Acceptable |
주어진 URL에 대한 리소스 중 클라이언트가 받아들일 수 있는 것이 없는 경우 사용한다. |
407 |
Proxy Authentication Required |
401과 비슷하지만 리소스에 대한 인증을 요구하는 프락시 서버를 위해 사용한다 |
3.4.5 500-599 서버 에러 상태 코드
상태코드 |
사유 구절 |
의미 |
500 |
Internal Server Error |
서버가 요청을 처리할 수 없게 만드는 에러를 만들었을 때 사용한다. |
502 |
Bad Gateway |
프락시나 게이트웨이처럼 행동하는 서버가 그 요청 응답 연쇄에 있는 다음 링크로부터 가짜 응답에 맞닥뜨렸을 때 사용한다.(예. 만약 자신의 부모 게이트웨이에 접속하는 것이 불가능할 때) |
503 |
Service Unavailable |
서버가 요청을 처리해 줄 수 없지만 나중에는 가능함을 의미하고자 할 때 사용한다. |
504 |
Gateway Timeout |
다른 서버에게 요청을 보내고 응답을 기다리다 타임아웃이 발생한 응답이다. |
3.5 헤더
3.5.1 일반 헤더
헤더 |
설명 |
Connection |
클라이언트와 서버가 요청/응답 연결에 대한 옵션을 정할 수 있게 해준다. |
Date |
메시지가 언제 만들어졌는지 날짜/시간을 제공한다. |
Upgrade |
발송자가 업그레이드하길 원하는 새 버전이나 프로토콜을 알려준다. |
일반 캐시 헤더
헤더 |
설명 |
Cache-Control |
메시지와 함께 캨시 지시자를 전달하기 위해 사용된다. |
Pragma |
메시지와 함께 지시자를 전달하는 또 다른 방법으로, 캐시에 국한되지 않는다. 엄밀히 말하면 요청 헤더이다 그러나 Pragma는 Cache-Control로 인하여 더이상 사용되지 않을 예정이다. |
3.5.2 요청 헤더
헤더 |
설명 |
Host |
요청의 대상이 되는 서버의 호스트 명과 포트를 준다. |
Accept 관련
헤더 |
설명 |
Accept |
서버에게 서버가 보내도 되는 미디어 종류를 말해준다. |
Accept-Charset |
서버가 보내도 되는 문자 집합을 말해준다. |
Accept-Encoding |
서버가 보내도 되는 인코딩을 말해준다. |
조건부 요청 헤더
헤더 |
설명 |
Expect |
클라이언트가 요청에 필요한 서버의 행동을 열거할 수 있게 해준다. |
If-Match |
문서의 엔터티 태그가 주어진 엔터티 태그와 일치하는 경우에만 문서를 가져온다 |
If-Modified-Since |
주어진 날짜 이후 리소스가 변경되지 않았다면 요청을 제한한다. |
요청 보안 헤더
헤더 |
설명 |
Authorization |
클라이언트가 서버에게 제공하는 인증 자체 정보를 갖고 있다 |
Cookie |
서버에게 토큰을 전달할 때 사용한다. |
Cookie2 |
요청자가 지원하는 쿠키 버전을 알려줄 때 사용한다. |
프락시 요청 헤더
헤더 |
설명 |
Proxy-Authentication |
Authorization과 같으나 프락시 인증용이다. |
Proxy-Connection |
Connection과 같으나 프락시에서 연결을 맺을 때 쓰인다. |
Max-Forwards |
원 서버에서 다른 프락시/게이트웨이로 전달 될 수 있는 최대 횟수로, TRACE 메서드와 함께 사용된다. |
3.5.3 응답 헤더
헤더 |
설명 |
Age |
응답이 얼마나 오래 되었는지 |
Retry-After |
현재 리소스가 사용 불가능한 상태일 때, 언제 가능해지는지 날짜/시각 |
협상 헤더
- 프랑스어/독일어로 번역된 HTML 문서가 있는 경우와 같이 여러 표현이 가능한 상황일 때, 서버와 클라이언트가 어떤 표현을 택할 것인가에 대한 협상을 지원한다.
헤더 |
설명 |
Accept-Ranges |
서버가 자원에 대해 받아들일 수 있는 범위의 형태 |
Vary |
서버가 확인해 보아야 하고 응답에 영향을 줄 수 있는 헤더들의 목록. 예) 서버가 클라이언트에게 보내줄 리소스의 가장 적절한 버전을 선택하기 위해 살펴보아야 하는 목록 |
응답 보안 헤더
헤더 |
설명 |
Proxy-Authenticate |
프락시에서 보내는 인증 요구 목록 |
Set-Cookie |
서버가 클라이언트를 인증할 수 있도록 클라이언트 측에 토큰을 설정하기 위해 사용된다. |
Set-Cookie2 |
RFC 2965로 정의된 쿠키 |
WWW-Authenticate |
서버에서 클라이언트로 보내는 인증 요구 목록 |
3.5.4 엔터티 헤더
헤더 |
설명 |
Allow |
엔터티에 수행될 수 있는 요청 메서드 나열 |
Location |
클라이언트에게 엔터티가 실제로 어디 위치하는지 말해준다. |
콘텐츠 헤더
헤더 |
설명 |
Content-Type |
이 본문이 어떤 종류 객체인지 |
Content-Encoding |
본문에 적용된 인코딩 |
Content-Length |
본문 길이/크기 |
엔터티 캐싱 헤더
- 언제 어떻게 캐시가 되어야 하는지 지시자를 제공한다.