본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
이론/HTTP

HTTP 웹 기본 지식 - HTTP 일반 헤더(1)

by 방구석 대학생 2022. 2. 23.

"인프런 - 모든 개발자를 위한 HTTP 웹 기본 지식 강의를 듣고 작성한 글입니다."

https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/dashboard

 

모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의

실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...

www.inflearn.com

 

HTTP 일반 헤더

HTTP 헤더 개요

HTTP 헤더 필드는 필드 이름 ":" 필드 값 형식으로 구분된다.

- field-name ":" OWS field-value OWS (OWS : 띄어쓰기 허용)

- field-name 은 대소문자 구분이 없다.

 

* HTTP 헤더의 용도

- HTTP 전송에 필요한 모든 부가정보가 담긴다.

예시 : 메시지 바다의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트, 서버 정보, 캐시 관리 정보 등등...

- 표준 헤더가 너무 많다.

- 필요시 임의의 데이터를 추가할 수 있다.

 

과거의 HTTP 헤더는 어땠을까?

분류 - RFC2616(과거)

* 헤더 분류

- General 헤더 : 메시지 전체에 적용되는 정보, 예시) Connection: close

- Request 헤더 : 요청 정보, 예시) User-Agent: Mozila/5.0

- Response 헤더 : 응답 정보, 예시) Server: Apache

- Entity 헤더 : 엔티티 바디 정보, 예시) Content-Type: text/html, Content-Length: 3423

 

HTTP BODY : message body - RFC2616(과거)

- 메시지 본문(message body) 은 엔티티 본문(entity body) 을 전달하는데 사용한다.

- 엔티티 본문은 요청이나 응답에서 전달할 실제 데이터이다.(메시지 본문에 엔티티 본문을 담는다.)

- 엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보를 제공해준다.

    - 데이터 유형(html, json), 데이터 길이, 압축 정보 등

 

그런데 위와 같은 스펙이 변하게 된다.

2014년 RFC7230 ~ 7235 가 등장했기 때문이다. 

이로 인해 엔티티 본문(entity body) 라는 말이 사라지게 된다.

 

RFC723x 변화

- 엔티티(Entity) -> 표현(Representation)

- Representation = representation Metadata + Representation Data

- 표현 = 표현 메타데이터 + 표현 데이터

 

HTTP BODY : message body - RFC7230(최신 스펙)

- 메시지 본문(message body) 을 통해 표현 데이터를 전달한다.

- 메시 본문 = 페이로드(payload)

- 표현은 요청이나 응답에 전달할 실제 데이터이다.

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

    - 데이터 유형(html, json), 데이터 길이, 압축 정보 등등

+ 참고 : 표현 헤더는 표현 메타데이터와, 페이로드 메시지를 구분해야 하지만 여기서는 생략한다.

 

그렇다면 왜 여기서 표현이라는 말을 사용할까?

만약 회원 리소스가 있다고 할 때, 이 리소스를 html 이라는 표현으로 전송할 지, json 이라는 표현으로 전송할 지 결정해야 한다.

또한 클라이언트와 서버간에 리소스 교환이 있을 때는 서로간에 이해할 수 있는 형식으로 리소스를 변환해서 전송해야 한다.

그렇기 때문에 리소스들을 각종 형식으로 변환하는데, 이를 html 로 표현한다, 또는 json 으로 표현한다, xml 로 표현한다 와 같은 식으로 정의를 내릴 수 있기 때문이다.

 

 

표현

- Content-Type : 표현 데이터의 형식

- Content-Encoding : 표현 데이터의 압축 방식

- Content-Language : 표현 데이터의 자연 언어(한국어인지, 영어인지 등등)

- Content-Length : 표현 데이터의 길이 (명확하게 따지자면 표현 헤더가 아니라 페이로드에 해당하지만, 이렇게 까지 따지면 너무 복잡해지기 때문에 그냥 표현 헤더로 묶자.)

- 표현 헤더는 전송, 응답 둘 다 사용한다.

 

* Content-Type : 표현 데이터의 형식 설명

- 미디어 타입, 문자 인코딩을 표현한다.(message body 에 들어가는 컨텐츠의 타입에 대해 표현한다.)

예시 : text/html; charset=utf-8, application/json, image/png

 

* Content-Encoding : 표현 데이터 인코딩

- 표현 데이터를 압축하기 위해 사용한다.

예시 : gzip, deflate, identity

 

* Content-Language : 표현 데이터의 자연 언어

- 표현 데이터의 자연 언어를 표현한다.

예시 : ko, en, en-US

 

* Content-Length : 표현 데이터의 길이

- 바이트 단위, Transfer-Encoding(전송 인코딩) 을 사용하면 Content-Length 를 사용하면 안된다.

 

 

협상 헤더(Content Negotiation) : 클라이언트가 선호하는 표현 요청

- Accept : 클라이언트가 선호하는 미디어 타입 전달

- Accept-Charset : 클라이언트가 선호하는 문자 인코딩

- Accept-Encoding : 클라이언트가 선호하는 압축 인코딩

- Accpet-Language : 클라이언트가 선호하는 자연 언어

- 협상 헤더는 요청시에만 사용한다.

 

* Accept-Language 적용 전

한국어 브라우저에서 다중 언어를 지원하는 서버에 요청을 보냈을 때, 응답을 보내주는 서버의 기본 언어가 영어로 되어있고, 부가적으로 지원하는 언어가 한국어 일 때, Accept-Language 가 적용되어 있지 않다면 서버 측은 응답을 한국어로 보내는 것이 아니라, 서버의 기본 언어인 영어로 보내주게 된다.

 

반면 Accept-Language 가 적용되어 있을 경우, 서버가 해당 언어를 지원해 줄 수 있으면 응답 메시지의 내용을 해당 언어로 번역하여 전달해준다.

 

* Accept-Language 복잡한 예시

한국어 브라우저에서 다중 언어를 지원하는 서버에 요청을 보냈을 때, 응답을 보내주는 서버의 기본 언어가 독일어로 되어 있고 부가적으로 지원하는 언어가 영어일 때, 여기서 언어를 영어로 하여 응답을 받고 싶다고 해보자.

이럴 경우 Accept-Language 가 적용되어 있지 않다면, 서버 측은 클라이언트의 브라우저가 한국어 인것을 확인하고 자신이 지원해줄 수 있는 언어인지를 먼저 파악한다.

이때 자신이 지원해 줄 수 없는 언어인 경우 그냥 기본 언어인 독일어로 응답을 반환해주게 된다.

 

* 협상과 우선순위 1 : Quality Values(q)

- Quality Values(q) : 값을 사용한다.

- 0 ~ 1 까지 value 값이 정해지며, 숫자가 클수록 높은 우선순위를 가진다.

- value 값을 생략하면 1로 지정된다.

- 다음과 같이 Accept-Language 가 입력 되었을 경우 우선순위는 아래와 같다.

- Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7

    - 1. ko-KR;q=1 (q 생략)
    - 2. ko;q=0.9
    - 3. en-US;q=0.8
    - 4. en;q=0.7

 

위와 같이 Accept-Language 가 적용 되었을 경우 앞전의 복잡한 경우 예시에서, 서버는 클라이언트가 선호하는 언어들 중에서 자신이 지원하지 않는 한국어를 제외하고, 가장 우선순위가 높은 언어가 영어인 것을 확인한다.

이를 통해 서버는 응답 메시지를 영어로 구성하여 클라이언트에게 보내 줄 수 있게 된다.

* 협상과 우선순위 2 : Quality Values(q)

- 구체적인 것이 우선한다.

- Accept: text/*, text/plain, text/plain;format=flowed, */*

    - 1. text/plain;format=flowed
    - 2. text/plain
    - 3. text/*
    - 4. */*

 

* 협상과 우선순위 3 : Quality Values(q)

- 구체적인 것을 기준으로 미디어 타입을 맞춘다.

- Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,text/html;level=2;q=0.4, */*;q=0.5

Media Type Quality
text/html;level=1 1
text/html 0.7
text/plain 0.3
image/jpeg 0.5
text/html;level=2 0.4
text/html;level=3 0.7

 

 

HTTP 메소드 전송 방식(헤더 옵션)

- Transfer-Encoding

- Range, Content-Range

 

전송 방식은 다음과 같이 4가지로 구성되어 있다.

- 단순 전송, 압축 전송, 분할 전송, 범위 전송

 

* 단순 전송 : Content-Length

단순 전송은 요청이 들어왔을 때 돌려주는 응답에서 메시지 바디에 대한 Content-Length 를 지정한다. 즉, 컨텐츠의 길이를 알 수 있을 때 사용한다.

 

* 압축 전송 : Content-Encoding

압축 전송은 서버에서 클라이언트로 전송되는 메시지 바디의 내용을 압축 시켜서 전송되는 데이터의 용량을 줄인 후 해당 메시지를 전송해주는 방식이다.

다만 이때는 Content-Encoding 옵션을 통해 데이터가 어떤 형식으로 압축 되어있는지 알려줘야 한다.

 

* 분할 전송 : Transfer-Encoding

Transfer-Encoding: chunked 와 같은 내용이 헤더에 작성되면 메시지 바디의 내용을 쪼개서 보낸다는 의미로, 

이 경우 분할되서 쪼개지는 데이터의 크기에 대한 정보와 해당 데이터 자체가 순차적으로 클라이언트로 보내지게 되고, 마지막엔 크기 정보로 0바이트와 \r\n 이라는 메시지를 보내 더 이상 보낼 메시지가 없음을 알려준다.

 

보통 용량이 큰 데이터를 보내야 할 경우 꽤나 시간이 걸리게 되는데, 이렇게 데이터를 분할해서 순차적으로 보내주면 클라이언트에서는 긴 시간동안 기다릴 필요 없이 분할되어 넘어오는 데이터들을 순차적으로 하나씩 하나씩 받아 볼 수 있게 된다.

+ 참고 : 분할 전송때는 Content-Length 정보를 넣으면 안된다. 데이터의 전체 길이가 예상되지 않기 때문이다.

 

* 범위 전송 : Range, Content-Range

서버로부터 이미지를 받는데, 중간에 전송이 끊기게 되는 경우 서버는 처음부터 다시 클라이언트에게 데이터를 전송해야 한다.

그러나 범위 전송을 활용하면 중간에 전송이 끊겨서 데이터가 다시 보내지는 경우를 방지하기 위해 전체 데이터 중 일부의 범위만을 정해서, 정해진 범위 별로 데이터를 전송 받을 수 있게 된다.