웹 공부하기/HTTP

[인프런] 모든 개발자를 위한 HTTP 웹 기본 지식 (HTTP 헤더 - 표현, 협상, 전송 방식)

HTTP 헤더가 무엇인지와 HTTP 헤더의 종류 중 일반헤더에 대해 알아보자.

HTTP 헤더 개요

헤더 필드는 field-name: field-value 형태이며, field-name은 대소문자 구분하지 않는다.

HTTP 헤더에는 HTTP 전송에 필요한 모든 부가정보를 담는다. ex) 메세지 바디의 크기, 압축, 인증, 서버 정보 ...

표준 헤더가 엄청 많고, 필요 시에는 임의의 헤더도 추가 가능하다.

 

헤더 분류

  • General 헤더: 메세지 전체에 적용되는 정보 ex) Connection: close
  • Request 헤더: 요청 정보 ex) User-Agent: Mozilla/5.0
  • Response 헤더: 응답 정보 ex) Server: Apache
  • Entity 헤더 → 표현 헤더: 엔티티 바디 → 표현 데이터 정보 ex) Content-Type: text/html

RFC2616 → RFC7230 ~ 7235로 바뀌면서 Entity 라는 용어가 사라지고 표현이라는 용어가 생김

표현(Representation) = 표현 메타데이터 + 표현 데이터로, 요청이나 응답에서 전달할 실제 데이터이다.

표현 헤더는 표현 데이터를 해석할 수 있는 정보를 제공한다.

 

표현

표현 헤더는 요청, 응답 시에 모두 사용 가능하다.

  • Content-Type: 표현 데이터의 형식을 설명 (미디어 타입, 문자 인코딩) ex) application/json, image/png ...
  • Content-Encoding: 표현 데이터의 압축 방식을 나타냄 → 데이터를 읽는 쪽에서 인코딩 헤더 정보를 보고 해당 방식으로 압축 해제함 ex) gzip, deflate, identity(동일하다는 뜻으로 압축하지 않음을 의미)
  • Content-Language: 표현 데이터의 자연 언어를 표현 ex) ko, en, en-US ...
  • Content-Length: 표현 데이터의 길이를 바이트 단위로 나타냄, 그런데 전송 방식이 분할 전송(Transfer-Encoding)일 경우에는 Content-Length 사용하면 안됨

 

콘텐츠 협상

협상 헤더는 요청시에만 사용 가능하다. 협상 헤더에는 클라이언트가 선호하는 표현을 서버에 요청하는 내용이 담긴다.

  • Accept: 클라이언트가 선호하는 미디어 타입 전달
  • Accept-Charset: 클라이언트가 선호하는 문자 인코딩 전달
  • Accept-Encoding: 클라이언트가 선호하는 압축 인코딩 전달
  • Accept-Language: 클라이언트가 선호하는 자연 언어 전달

하나의 예시를 살펴보자.

클라이언트는 한국어 브라우저를 사용하고 있는 상황에 어떤 이벤트 페이지에 들어가려는 요청을 보냈다. 해당 요청을 받은 서버는 다중 언어를 지원하는 서버인데, 클라이언트가 어떤 언어를 선호하는지 알려주지 않아 기본 언어인 영어로 응답했다. 이럴 때, Accept-Language에 한국어를 선호한다고 전달해주면 서버는 그 요청을 보고 해당 언어로 응답할 것이다.

그런데, 만약 서버가 지원하는 언어 중에 클라이언트가 선호하는 언어가 없다면? 이 때도, 기본 언어로 응답할 것이다.

그래서 클라이언트는 한가지 언어만 작성하기 보다는 여러 언어를 작성하되, 우선 순위를 정해서 전달해주면 자신이 선호하는 콘텐츠를 얻게 될 것이다.

우선순위는 0~1 사이의 Quality Values(q) 값을 사용하며, 숫자가 클수록 높은 우선순위를 갖는다. 아무것도 적혀있지 않으면 q=1이 생락되어 있는 것이다.

그리고 Accept에도 여러가지 미디어 타입을 전달할 수 있는데, 더 구체적인 것이 우선순위가 높다.

이 때는 text/plain;format=flowed → text/plain → text/* → */* 순이 되는 것이다.

 

전송 방식

  • 단순 전송
    • 단순히 Content-Length만큼의 데이터를 전송하는 방식
  • 압축 전송
    • 데이터를 압축해서 전송하는 방식으로, Content-Encoding 방식을 나타내줘야함
  • 분할 전송
    • Transfer-Encoding: chunked → 데이터를 분할하여 전송함
      5바이트 Hello → 5바이트 World → 0 엔터 (끝)
    • 분할해서 전송하기 때문에 Content-Length를 작성하지 않음
  • 범위 전송
    • 데이터를 전송하던 중에 오류로 인해 전송이 중단되었을 때, 다시 요청을 해야하는 상황에서 이미 받은 데이터를 제외하고 받지 못한 데이터만 받고 싶을 때 범위를 지정하여 요청하면, 해당 범위의 데이터만 전송함 (Content-Range: bytes 1001-2000 / 2000)

출처: [인프런] 모든 개발자를 위한 HTTP 웹 기본 지식