HTTP메시지

Posted by yunki kim on December 23, 2020

1. 메지시의 흐름

  in-bound: 메시지가 원 서버로 이동하는것

  out-bound: 데이터 처리가 끝난 후 메시지가 사용자 에이전트로 돌아오는것

  down-stream: 요청, 응답관련없이 메시지가 전송되는 방향

  up-stream: 메시지의 발송자

2. 메시지의 구조

메시지는 기본적으로

  1. 시작줄: 어떤 메시지인지를 서술한다.

      요청메시지의 시작줄: 무엇을 해야하는지를 서술

      응답 메시지의 시작줄: 무슨일이 일어나는지를 서술

  2. 헤더블록: 속성

  3. 본문: 데이터를 담고있다(optional)

이 세가지로 구성되있다. 

 시작줄과 헤더블록은 캐리지 리턴 과 개행문자로 구성된 두 글자의 줄바꿈 문자열로 끝난다. 이 줄바꿈 문자열을 CRLF라 부른다. 하지만 견고한 애플리케이션이라면 일반 개행문자도 받아들일 수 있어야한다. 

  본문(엔터티 본문 또는 메시지 본문)은 선택적인 데이터 덩어리 이므로 데이터를 포함해도 되고 안해도 된다. 

2.1 요청 메시지

요청 메시지의 경우 다음과 같은 구조를 따른다.

시작줄 <메서드> <요청 URL> <버전>
헤더  
엔터티 본문  

1. 메서드: 리소스에 대해 서버가 실행해주길 원하는 동작이다. 

2. 요청URL; 요청 대상이 되는 리소스의 URL이며 상대/절대 경로 둘 다 가능하다. 상대경로일 경우 서버는 생략된 호스트, 포트가 자신을 가리키는 것으로 간주한다

3. 버전: 메시지에서 사용중인 HTTP의 버전이다. 버전은 HTTP/<major>/<minor>형식을 따른다

2.2 응답 메시지

시작줄 <버전> <상태코드> <사유구절>
헤더  
엔터티 본문  

1. 상태코드: 요청중에 어떤일이 발생했는지를 명시한다.

2. 사유구절: 상태코드에 대한 간략한 설명이다. 사유구절은 단지 사람에게 제공되기 위해 존재한다. 

 

헤더: 이름, ':', 선택적인 공백, 값, CRIF가 순서대로 나타나는 0개 이상의 헤더들. 헤더는 CRFI로 끝나면 헤더의 끝과 엔터티 본문의 시작을 의미한다. 일부 HTTP버전의 경우 특정 헤더가 포함되야만 유효하다. 

엔터티본문: 임의의 데디터 블록

 

헤더나 엔터티 본문이 없어도 HTTP헤더 집합은 항상 CRIF로 끝나야한다. 하지만 이 규칙을 지키지않은 구현체와의 호환을 위해 클라이언트와 서버는 CRIF가 없는 메시지도 받을 수 있어야한다. 

3. 시작줄

3.1 요청줄

  1. 서버에서 일어나야할 동작에대한 메서드

  2. 동작에 대한 대상을 지칭하는 URL

  3. 클라이언트가 사용하고있는 HTTP버전

위의 모든 필드는 공백으로 구분된다. 

EX). GET /test/hi-there.txt HTTP/1.1

3.2 응답줄

  1. 응답 메시지에 쓰인 HTTP 버전

  2. 숫자로된 상태 코드

  3. 수행 상태에 대해 설명하는 사유구절

위의 모든 필드는 공백으로 구분된다.

EX). HTTP/1.0 200 OK

3.3 메서드

 

모든 서버가 위의 메서드를 모두 구현하고 있지 않는다는 것에 주의해야 한다. 또한 HTTP는 쉽게 확장할 수 있기 때문에 일부 서버는 그들만의 메서드를 구현해 사용하기도 한다. 이렇게 구현된 메서드를 확장 메서드라 한다.

3.4 상태코드 

  클라이언트에게 서버에서 리소스에 대한 동작을 하던 중 어떤 일이 발생했는지를 알려준다. 상태코드를 응답 메시지의 시작줄에 상태 사유구절과 함께 담겨져있다.

  상태코드는 100~599의 자연수로 이뤄져있으며 백의 자리에따라 5개의 카테고리로 나누어져있다. 또한 이 범위의 임의의 자연수가 모두 어느 상태를 가리키는것이 아니기 때문에 정의된 범위 외의 상태코드는 임의로 현재 프로토콜의 확장으로 변경할 수 있다.

전체 범위 정의된 범위 분류
100~199 100~101 정보
200~299 200~206 성공
300~399 300~305 리다이랙션
400~499 400~415 클라이언트 에러
500~599 500~505 서버 에러

3.5 버전 번호

  버전 번호는 HTTP/x.y형식으로 되어있고 요청, 응답의 시작줄에 명시되 있다. 이는 자신이 따르는 프로토콜의 버전을 상대에게 명시하기 위해 사용된다. 만약 클라이언트가 HTTP/1.0을 사용하고 서버가 HTTP/1.1을 사용한다면 애플리케이션은 HTTP/1.1에서 새롭게 구현된 기능을 사용할 수 없다. 

  버전 번호는 분수로 다루어지지 않는다. 즉, 각 숫자를 따로 보아야한다. 요컨데 HTTP/1.22는 HTTP/1.3보다 크다. 22 > 3이기 때문에.

4. 헤더

  헤더는 요청, 응답에 대한 추가적인 정보를 기술한다. 기본적으로 이름/값의 형태를 띄고있다. 

4.1 헤더의 종류

  HTTP헤더는 여러 헤더필드를 정의하며 자신만의 헤더를 만들 수 도 있다.

1. 일반헤더: 요청, 응답을 모두 나타낼 수 있다

2. 요청 헤더: 요청에 대한 부가정보

3. 응답 헤더: 응답에 대한 부가정보

4. Entity 헤더: 본문 크기와 콘텐츠, 혹은 리소스 그 자체를 서술

5. 확장 헤더: 명세에 정의되지 않은 새로운 헤더

 

헤더를 여러줄로 나누는 경우 추가줄 앞에는 최소 하나의 스페이스 또는 탭 문자가 와야한다.

5. 엔터티 본문

  엔터티 본문은 HTTP로 이미지, 비디오, HTML문서 등 여러종류의 파일을 실어 나을 수 있게 한다.

6. 메서드

  모든 서버가 모든 메서드를 구현하지 않는다. 서버가 모든 메서드를 구현하지 않아도 메서드는 대부분 제한적으로 사용될 수 있다. 이 제한의 정도는 서버 설정에 의해 정해진다.

6.1 안전한 메서드

  안전한 메서드는 메서드가 서버에서 작용을 할때 서버에서 리소스에 대한 아무런 수정도 이루어지지 않음을 의미한다. 하지만 사실 안전한 메서드가 서버에서 작용을 유발하지 않는다는 보장은 없다. 이는 웹 개발자에 의해 달라질 수 있다. 진정한 안전한 메서드의 목적은 서버에 영향을 주는 메서드가 사용될때 사용자들에세 그 사실을 알려주는 HTTP 어플리케이션을 만들 수 있게 하는것이다. 

6.2 GET

  가장 흔히 쓰이는 메서드이고 주로 서버에게 리소스를 요청할때 사용된다

6.3 HEAD

  GET처럼 행동하지만 응답으로 엔터티 본문을 제외한 헤더만을 돌려준다. 이 메서드를 사용하게 되면

  1. 헤더에서 알 수 있는 정보만을 필요로할때 리소스를 가져오지 않아도 된다

  2. 응답의 상태코드로 개체의 존재를 확인할 수 있다.

  3. 헤더를 확인해 리소스가 변경됬는지 확인 할 수 있다. 

  HEAD를 사용할때 개발자는 반드시 GET으로 얻는 것과 데이터가 일치함을 보장해야한다. 

6.4 PUT

  서버에 문서를 작성한다. 서버가 요청의 본문을 가지고 명시된 URL을통해 그 위치에 새 문서를 만들거나 문서가 이미 존재한다면 본문을 사용해 교체한다. 

  PUT은 서버에 존재하는 컨텐츠를 수정하기 때문에 많은 서버가 PUT 시행 전에 사용자 인증을 하게 한다.

6.5 POST

서버에 입력 데이터를 전송하기 위해 사용된다. 이때 보내지는 데이터는 서버에 있는 리소스에 데이터를 입력하는데 사용된다. 채워진 폼에 담긴 데이터는 서버로 보내지고 서버는 이를 모아 필요한 곳에 보낸다(데이터를 처리할 서버 게이트웨이 등).

6.6 TRACE

  클라이언트가 요청을할때 그 요청을 방화벽, 프락시, 게이트웨이 등의 애플리케이션을 통과할 수 있고 이들을 HTTP요청을 수정할 수 있다. 따라서 클라이언트에서 보낸요청과 서버에서 받은 요청이 다를 수 있다. 이때 클라이언트가 요청이 서버에서 어떻게 보여지는지를 TRACE를 통해 확인할 수 있다.

  TRACE로 요청을 하면 서버는 루프백 진단을 해서 요청 마지막단계의 서버는 받은 요청을 메시지 본문에 넣고 응답을 전송한다. 클라이언트는 이 응답을 통해 자신의 요청이 어떤식으로 변경되었는지 알 수 있다. 따라서 TRACE는 보통 진단을 해 프락시나 다른 애플리케이션이 요청에 어떤 영향을 미치는지 확인할때 사용된다. 

  하지만 TRACE의 경우 어떠한 요청도 모두 일관되게 다룬다는 문제가 있다. 많은 HTTP 애플리케이션은 요청에 따라 다른 동작을 한다. 이런 동작은 보통 중간 애플리케이션이 결정한다. ex). 프락시는 POST요청을 그냥 통과시키지만 GET웹 캐시로 전송한다. 또 한 TRACE는 엔터티 본문을 보낼 수 없다. 하지만 이에대한 요청에는 엔터티 본문이 포함되있다. 

6.7 OPTIONS

  일부 서버는 특정 종류의 객체에 대해 특정 동작만 동작한다. 따라서 웹 서버의 지원 범위를 확인할때는 OPTIONS메서드를 사용하면 된다. 이 메서드는 여러 리소스에 대해 실제로 접근하지 않고도 그것을 어떻게 접근할지를 알려준다. 

6.8 DELETE

  서버에게 URL에 해당하는 위치에 있는 파일을 지우는 것을 요청한다. 하지만 HTTP명세에 따르면 서버는 클라이언트의 요청을 무시할 수 있기 때문에 반드시 지워진다는 보장을 할 수 없다.