3.0 배우게 될 것
- 메시지가 어떻게 흘러가는가
- HTTP 메시지의 세 부분(시작줄, 헤더, 본문)
- 요청과 응답 메시지의 차이
- 요청 메시지가 지원하는 여러 기능(메서드)들
- 응답 메시지가 반환하는 여러 상태 코드들
- 여러 HTTP 헤더들은 무슨 일을 하는가
3.1 메시지의 흐름
- 메시지는 원 서버 방향을 인바운드로 하여 송신된다.
- 인바운드와 아웃바운드는 트랜잭션 방향을 표현하기 위해 사용
- 클라이언트 -> 서버: 인바운드
- 서버 -> 클라이언트: 아웃바운드
- 다운 스트림으로 흐르는 메시지
- 모든 메시지는 다운스트림으로 흐른다. 발송자는 수신자의 업스트림이다.
3.2 메시지의 각 부문
- 메시지는 시작줄, 헤더 블록, 본문으로 나뉜다.
- 시작줄은 어떤 메시지인지 서술하며, 헤더 블록은 속성, 본문은 데이터를 담고 있다.
- 시작줄: HTTP/1.0 200 Ok , 헤더: Content-type: text/plain Content-length: 19, 본문: Hi! I’m a message!
- 메시지 문법
- 모든 HTTP 메시지는 요청, 응답으로 분류된다.
- 요청 메시지 형식 <메서드> <요청 URL=""> <버전> <헤더> <엔터티 본문=""> 엔터티>헤더>버전>요청>메서드>
- 응담 메시지 형식 <버전> <상태 코드=""> <사유 구절=""> <헤더> <엔터티 본문=""> 엔터티>헤더>사유>상태>버전>
- 메서드
- 클라이언트 측에서 서버가 리소스에 대해 수행해주길 바라는 동작으로 POST, GET, PATCH, DELETE 등이 있다.
- 요청 URL
- 요청 대상이 되는 리소스를 지칭하는 완전한 URL 혹은 URL의 경로 구성 요소
- 버전
- 메시지의 사용중인 HTTP의 버전
- HTTP/<메이저>.<마이너>마이너>메이저>
- 상태 코드
- 요청 중에 무엇이 일어났는지 설명하는 세 자리의 숫자
- 사유 구절
- 숫자로 된 상태 코드의 의미를 사람이 이해할 수 있도록 설명해주는 짧은 문구로, 상태 코드 이후부터 줄바꿈 문자열까지가 사유 구절이다.
- 헤더들
- 이름, 콜론(:), 선택적인 공백, 값, CRLF가 순서대로 나타나는 0개 이상의 헤더들
- 이 헤더의 목록은 빈 줄(CRLF)로 끝나 헤더 목록의 끝과 엔터티 본문의 시작을 표시
- 엔터티 본문
- 엔터티 본문은 임의의 데이터 블록을 포함한다.
- 헤더나 엔터티 본문이 없더라도 HTTP 헤더의 집합은 항상 빈줄(그냥 CRLF)로 끝나야 한다. 하지만 호환을 위해 클라이언트와 서버에서는 마지막 CRLF가 없어도 받아들일 수 있어야 한다.
- 시작줄
- 모든 HTTP 메시지는 시작줄로 시작한다.
- 요청 메시지의 시작줄은 무엇을 해야 하는지 말해준다.
-
응답 메시지의 시작줄은 무슨 일이 일어났는지 말해준다.
- 요청줄
- 요청 메시지는 서버에게 리소스에 대해 무언가를 해달라고 부탁한다.
- 메서드, 요청 URL, HTTP 버전이 포함되며 공백으로 구분된다.
- 응답줄
- 응답 메시지는 수행 결과에 대한 상태 정보와 결과 데이터를 클라이언트에게 돌려준다.
- HTTP 버전, 상태코드, 사유구절이 포함되며 공백으로 구분한다.
- 메서드
- 요청의 시작줄의 메서드로 시작하며, 서버에게 무엇을 해야 하는지 말해준다.
- 상태 코드
- 응답의 시작줄에 위치하며 클라이언트에게 무엇이 일어났는지 말해준다.
- 사유 구절
- 상태 코드에 대한 글로된 설명을 제공
- 버전 번호
- HTTP/x.y 형식으로 요청과 응답 메시지 양쪽 모두에 기술된다.
- HTTP 애플리케이션들이 자신이 따르는 프로토콜의 버전을 상대방에게 말해주기 위한 수단
- 버전 번호는 분수로 다뤄지지 않는다.
- HTTP/1.0 에서 1과 0은 분리된 숫자로 다뤄진다.
- HTTP/2.22 는 HTTP/2.3보다 크다 22가 3보다 크기 때문이다.
- 헤더
- 시작줄 다음에는 0개, 1개 또는 여러 개의 HTTP 헤더가 온다.
- 헤더 분류
- 일반 헤더: 요청과 응답 양쪽에 모두 나타낼 수 있다.
- 요청 헤더: 요청에 대한 부가 정보 제공
- 응답 헤더: 응답에 대한 부가 정보 제공
- Entity 헤더: 본문 크기와 콘텐츠 혹은 시소스 그 자체 서술
- 확장 헤더: 명세에 정의되지 않은 새로운 헤더
- 헤더를 여러 줄로 나누기
- 긴 헤더 줄은 여러 줄로 쪼갤 수 있는데, 추가 줄앞에는 최소 하나의 스페이스 또는 탭 문자가 와야 한다.
- 엔터티 본문
- 엔터티 본문은 HTTP 메시지의 화물이라고 할 수 있으며 HTTP가 수송하도록 설계된 것들이다.
3.3 메서드
- 안전한 메서드
- HTTP는 안전한 메서드라 불리는 메서드의 집합을 정의한다.
- 안전하다는 것은 HTTP 요청의 결과로 서버에서 일어나는 일이 없다는 의미로, GET, HEAD 등이 속한다.
- 안전한 메서드의 목적은 서버에 어떤 영향을 줄 수 있는 안전하지 않은 메서드가 사용될 때 사용자들에게 그 사실을 알려주는 HTTP 애플리케이션을 만들 수 있도록 하는 것에 있다.
- GET
- 주로 서버에게 리소스를 달라고 요청하기 위해 사용
- 예시
요청 메시지: GET /seasonal/index-fall.html HTTP/1.1 HOST: www.joes-hardware.com Accept: * 응답 메시지: HTTP/1.1 200 OK Content-Type: text/html Context-Length: 617 <HTML>...</HTML>
- HEAD
- GET처럼 행동하지만, 서버는 음답으로 헤더만 돌려준다. 본문은 결코 반환되지 않는다.
- HEAD를 사용하면
- 리소스를 가져오지 않고도 그에 대해 무엇인가(타입 등)을 알아 낼 수 있다.
- 응답과 상태 코드를 통해 개체가 존재하는 지 확인할 수 있다.
- 헤더를 확인하여 리소스가 변경되었는지 검사할 수 있다.
- 예시
요청 메시지: HEAD /seasonal/index-fall.html HTTP/1.1 HOST: www.joes-hardware.com Accept: * 응답 메시지: HTTP/1.1 200 OK Content-Type: text/html Context-Length: 617
- PUT
- 서버에 문서를 쓴다.
- PUT 메서드의 의미는 서버가 요청의 본문을 가지고 요청 URL의 이름대로 새 문서를 만들거나, 이미 URL이 존재한다면 본문을 사용해서 교체하는 것
- 안전하지 않기 때문에 인증이 필요하다.
- 예시
요청 메시지: PUT /product-list.txt HTTP/1.1 HOST: www.joes-hardware.com Content-Type: text/plain Content-length: 34 Updated product list coming soon! 응답 메시지: HTTP/1.1 201 Created Location: http://www.joes-hardware.com/product-list.txt Content-Type: text/plain Context-Length: 47 http://www.joes-hardware.com/product-list.txt
- POST
- 서버에 입력 데이터를 전송하기 위해 설계
- 예시
요청 메시지: POST /inventory-check.cgi HTTP/1.1 HOST: www.joes-hardware.com Content-Type: text/plain Content-length: 18 item=bandsaw 2647 응답 메시지: HTTP/1.1 200 OK Content-Type: text/plain Context-Length: 37 The bandsaw model 2647 is in stock!
- TRACE
- 클라이언트에 대한 요청에 대해 방화벽, 프락시, 게이트웨이 등의 애플리케이션을 통과할 수 있다.
- TRACE 요청은 목적지 서버에서 loopback(루프백) 진단을 시작한다.
- 진단을 목적으로 사용한다. HTTP 애플리케이션의 요청/응답 연쇄를 따라가면서 메시지의 변형이 이뤄졌는지 확인할 수 있다.
- 요청/응답에 엔터티 본문을 보낼 수 없다.
- OPTIONS
- 웹 서버에게 여러 종류의 지원 범위에 대해 물어본다.
- 서버에게 특정 리소스에 대해 어떤 메서드가 지원되는지 물어볼 수 있다.
- 예시
요청 메시지: OPTOINS * HTTP/1.1 HOST: www.joes-hardware.com Accept: * 응답 메시지: HTTP/1.1 200 OK Allow: GET, POST, PUT< OPTIONS Context-length: 0 // OPTIONS 요청이 모든 리소스에 대한 것으로 서버는 자신의 리소스에 대해 지원하는 메서드의 목록 반환
- DELETE
- 서버에게 요청 URL로 지정한 리소스를 삭제할 것을 요청
- 예제
요청 메시지: DELETE /product-list.txt HTTP/1.1 HOST: www.joes-hardware.com 응답 메시지: HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 54 I have your delete request, will take time to process.
3.4 상태 코드
- 100 ~ 199: 정보성 상태 코드
- 정보성 상태 코드는 HTTP/1.1 부터 도입됐다.
- 100 Continue
- 요청의 시작 부분 일부가 받아들여졌으며, 클라이언트는 나머지를 계속 이어서 보내야 함을 의미
- 클라이언트에서 100 Continue 응답을 기다리겠다면, Expect 요청 헤더에 100-continue를 포함하여 보내야 한다.
- 클라이언트에서 100 Continue 응답이 올 때까지 타임아웃을 두고 후에는 그냥 엔터티를 보내야 한다.
- 서버에서 100-continue 값이 담긴 Expect 헤더가 포함된 요청을 받는다면, 100 Continue 응답 혹은 에러 코드로 답해야 한다.
- 서버에서 100-continue 값이 담긴 Expect 헤더가 포함된 요청을 받은 후에 엔터티를 받으면 100 Continue에 대한 응답을 보낼 필요는 없다. 하지만 최종 응답은 보내야 한다.
- 프록시 서버에서는 100-contniue가 담긴 Expect 헤더를 포함시켜서 요청을 다음으로 전달해야 한다.
- 프록시 서버에서 만약 다음 홉이 HTTP/1.1 이전 버전을 사용한다는 것을 알고 있다면 417 Expectation Failed 에러로 응답해야 한다.
- 200 ~ 299: 성공 상태 코드
- 200 OK: 요청은 정상이며 엔티티 본문은 요청에 대한 리소스가 담겨 있다.
- 201 Created: 서버 개체를 생성하라는 요청에 대한 성공적인 응답으로 생성된 리소스에 대한 Location을 함께 보낸다.
- 300 ~ 399: 리다이렉션 상태 코드
- 리다이렉션 상태 코드는 클라이언트가 관심있어 하는 리소스에 대해 다른 위치를 사용하라고말해주거나 그 리소스의 내용 대신 다른 대안 응답을 제공한다.
- HTTP/1.0
- 클라이언트가 POST 요청을 보낸 후 302 리다이렉션 상태 코드를 받는 경우
- 클라이언트는 Location에 담겨 있는 redirection url을 GET 요청으로 따라간다.
- HTTP/1.1
- HTTP/1.1은 HTTP/1.0에서의 302 리다이렉션 상태 코드가 아닌 303 상태 코드를 사용한다.
- 서버에서는 리다이렉션 응답에 들어갈 적절한 상태 코드를 선택하기 위해 클라이언트의 HTTP 버전을 검사할 필요가 있다.
- 400 ~ 499: 클라이언트 에러 상태 코드
- 잘못 구성된 요청메시지 같은 것에 의한 에러 상태 코드
- 401 Unauthorized: 리소스를 얻기 전에 인증을 요구하는 응답
- 404 Not Found: 요청한 URL이 찾을 수 없는 경우 발생
- 500 ~ 599: 서버 에러 상태 코드
- 클라이언트가 올바른 요청을 보냈음에도 서버 자체에서 에러가 발생하는 경우
- 게이트웨이 리소스와 같은 서버 보조 구성요소에서 발생할 수도 있다.
3.5 헤더
- HTTP 헤더 필드는 요청/응답 메시지에 추가 정보를 더한다.
-
key: value 형태로 이뤄진다.
- 일반 헤더
-
요청과 응답 쪽 모두에 나타날 수 있다.
헤더 설명 Connection 현재 트랜잭션이 끝난 후에 네트워크 연결을 열린 상태로 둘지 여부를 제어한다. Date 메시지가 언제 만들어졌는지에 대한 날짜와 시간을 제공한다. MIME-Version 발송자가 사용한 MIME의 버전을 알려준다. Trailer chunked transfer 인코딩으로 인코딩된 메시지의 끝 부분에 위치한 헤더들의 목록을 나열한다. Transfer-Encoding 수신자에게 안전한 전송을 위해 메시지에 어떤 인코딩이 적용되었는지 말해준다. Upgrade 발송자가 ‘업그레이드’하길 원하는 새 버전이나 프로토콜을 알려준다. Via 이 메시지가 어떤 중개자(프록시, 게이트웨이)를 거쳐 왔는지 보여준다. -
일반 캐시 헤더
헤더 설명 Cache-Control 메시지와 함께 캐싱 매커니즘을 전달하기 위해 사용한다. Pragma 메시지와 함께 지시자를 전달하는 또 다른 방법. 캐시에 국한되지 않는다. (이 헤더는 Cache-Control로 대체되어 사용되지 않을 예정)
-
- 요청 헤더
-
요청데 대한 부가 정보를 제공한다.
헤더 설명 Client-IP 클라이언트가 실행된 컴퓨터의 IP를 제공한다. From 클라이언트 사용자의 메일 주소를 제공한다.(RFC 822 이메일 주소 포맷) Host 요청의 대상이 되는 서버의 호스트 명과 포트를 준다. Referer 현재 페이지로 연결되는 링크가 있던 이전 웹 페이지의 주소이다.(바로 직전에 있었던 URL) User-Agent 요청을 보낸 애플리케이션의 이름을 서버에게 제공한다. - Accept 관련 헤더
- 클라이언트가 무엇을 원하고 무엇을 할 수 있는지, 그리고 무엇보다 원치 않은 것을 알려줄 수 있다.
- 서버는 이 추가 정보를 활용해 무엇을 보낼 것인지 결정할 수 있다. |헤더|설명| |—|—| |Accept|서버에게 서버가 보내도 되는 미디어 종류(MIME 타입)를 말해준다.| |Accept-Charset|서버에게 서버가 보내도 되는 문자집합을 말해준다.| |Accept-Encoding|서버에게 서버가 보내도 되는 인코딩을 말해준다.| |Accept-Language|서버에게 서버가 보내도 되는 언어를 말해준다.| |TE|서버에게 서버가 보내도 되는 확장 전송 코딩을 말해준다.|
- 조건부 요청 헤더
-
클라이언트는 요청 메시지에 제약을 둘 수 있다.
헤더 설명 Expect 클라이언트가 요청에 필요한 서버의 행동을 열거할 수 있게 해준다. If-Match 문서의 엔티티 태그(Etag)가 주어진 엔티티 태그와 일치하는 경우에만 문서를 가져온다. If-Modified-Since 주어진 날짜 이후에 리소스가 변경된 경우에만 요청한다. If-None-Match 문서의 Etag가 주어진 Etag와 일치하지 않는 경우에만 문서를 가져온다. If-Range 문서의 특정 범위에 대한 요청을 할 수 있게 해준다. If-Unmodified-Since 주어진 날짜 이후에 리소스가 변경되지 않은 경우에 요청한다. Range 서버가 범위 요청을 지원한다면, 리소스에 대한 특정 범위를 요청한다.
-
- 요청 보안 헤더
-
요청을 위한 간단한 인증요구/응답 체계를 가지고 있다.
헤더 설명 Authorization 클라이언트가 서버에게 제공하는 인증 그 자체에 대한 정보를 담고 있다. Cookie 클라이언트가 서버에게 토큰을 전달할 때 사용한다. 진짜 보안 헤더는 아니지만 보안에 영향을 줄 수 있다. Cookie2 요청자가 지원하는 쿠키의 버전을 알려줄 때 사용한다.
-
-
- 응답 헤더
- 응답에 대한 부가 정보를 제공한다.
-
클라이언트에게 부가 정보 제공
헤더 설명 Age 응답이 얼마나 오래되었는지 알려준다.(응답이 중개자를 통해 왔음을 암시) Public 서버가 특정 리소스에 대해 지원하는 요청 메서드의 목록(최신에는 정의되지 않음) Retry-After 현재 리소스가 사용 불가능한 상태일 때, 언제 가능해지는지에 대한 날짜 또는 시각 Server 서버 애플리케이션의 이름과 버전 Title HTML 문서에서 주어진 것과 같은 제목(RFC 2616에는 정의되지 않음) Warning 사유 구절에 있는 것보다 더 자세한 경고 메시지 - 협상 헤더
- 서버에 여러 언어를 제공한다면 클라이언트가 어떤 언어를 선택할지 협상을 할 수 있도록 지원 |헤더|설명| |—|—| |Accept-Ranges|서버가 자원에 대해 받아들일 수 있는 범위의 형태| |Vary|서버가 확인해 보아야 하고 그렇기 때문에 응답에 영향을 줄 수 있는 헤더들의 목록|
- 응답 보안 헤더 |헤더|설명| |—|—| |Proxy-Authenticate|프락시에서 클라이언트로 보낸 인증요구의 목록| |Set-Cookie|서버가 클라이언트를 인증할 수 있도록 클라이언트 측에 토큰을 설정하기 위해 사용한다.(쿠키 정보 전송)| |Set-Cookie2|Set-Cookie와 비슷하게 RFC 2965로 정의된 쿠키| |WWW-Authenticate|서버에서 클라이언트로 보낸 인증요구의 목록|
- Entity 헤더
- 본문 크기, 콘텐츠, 리소스 그 자체를 서술한다.
- 확장 헤더
-
명세에 정의되지 않은 새로운 헤더
헤더 설명 Allow 이 엔티티에 대해 수행될 수 있는 요청 메서드들을 나열한다. Location 클라이언트에게 엔티티가 실제로 어디에 위치하는지 알려준다. 일반적으로 수신자에게 리소스에 대한 위치(URL)을 알려줄 때 사용한다. - 콘텐츠 헤더
- 엔티티 콘텐츠에 대한 자세한 정보를 제공한다. |헤더|설명| |—|—| |Content-Base|본문에서 사용된 상대 URL을 계산하기 위한 기저 URL(RFC 2616에 정의되지 않음)| |Content-Encoding|본문에 적용된 인코딩 정보| |Content-Language|본문을 이해하는데 가장 적절한 자연어| |Content-Length|본문의 길이나 크기| |Content-Location|리소스가 실제로 어디에 위치하는지 정보| |Content-MD5|본문의 MD5 체크섬(checksum)| |Content-Range|전체 리소스에서 이 엔티티가 해당하는 범위를 바이트 단위로 표현| |Content-Type|이 본문이 어떤 종류의 객치인지에 대한 정보|
- 엔티티 캐싱 헤더
- 일반 개싱 헤더는 언제 어떻게 캐시가 되어야 하는지에 대한 지시자 제공
- 엔티티 개싱 헤더는 엔티티에 대한 캐싱 정보 제공 |헤더|설명| |—|—| |ETag|이 엔티티에 대한 엔티티 태그, 기본적으로 리소스의 특정 버전에 대한 식별자이다.| |Expires|이 엔티티가 더 이상 유효하지 않아 원본을 다시 받아와야 하는 일시| |Last-Modified|가장 최근 이 엔티티가 변경된 일시|
-
** 출처 HTTP 완벽 가이드