내용 협상과 트랜스코딩

ChoiYongHyeun·2024년 1월 30일
0

HTTP

목록 보기
14/17

종종 하나의 URL이 여러 리소스에 대응 할 필요가 있는 경우가 있다.

예를 들어 어떤 사이트에 클라이언트의 국적이 다양 할 경우

URL 은 동일하더라도 여러 국적의 클라이언트에게 맞는 언어로 구성된 페이지 (리소스)를 제공해야 하기 때문이다.

여러 국적 별로 URL 을 여러개로 분활해서 만들어두는 것보다 하나의 URL 에서 클라이언트에게 맞게 리소스를 제공하는 것이 더욱 효과적이다.


내용 협상 기법

위 예시를 그대로 가져와 사용하면

서버는 여러 국적의 클라이언트에게 맞는 리소스를 준비해뒀다고 가정해보자

영어 버전 , 한국어 버전 , 프랑스어 버전 .. 등등 말이다.

이 때 클라이언트에게 적합한 리소스를 제공하는 방법은 3가지 존재한다 .

기술 설명 장점 단점
클라이언트 주도 클라이언트는 요청 헤더에서 선호하는 콘텐츠 유형 또는 언어를 지정하며, 서버는 그에 따라 응답합니다.
  • 클라이언트는 자신의 선호도를 명시적으로 표현할 수 있습니다.
  • 클라이언트는 자신의 환경에 맞게 콘텐츠를 선택할 수 있습니다.
  • 서버에 대한 추가 요청이 필요할 수 있습니다.
  • 클라이언트의 요청이 무거운 경우 처리 비용이 증가할 수 있습니다.
서버 주도 서버는 클라이언트의 요청 헤더를 확인하고 사용 가능한 리소스를 기반으로 최적의 콘텐츠 유형 또는 언어로 응답합니다.
  • 서버는 사용 가능한 리소스를 고려하여 최적의 콘텐츠를 선택합니다.
  • 클라이언트가 특별한 설정 없이도 언어 또는 콘텐츠를 받을 수 있습니다.
  • 클라이언트의 명시적인 선호도를 반영하기 어려울 수 있습니다.
  • 서버에서 선택된 콘텐츠가 항상 클라이언트에게 적합한 것은 아닐 수 있습니다.
투명
(transparent)
중개자(프록시 서버 등)가 클라이언트와 서버 간의 콘텐츠 협상을 중재하고, 최적의 콘텐츠 유형 또는 언어를 결정하여 클라이언트에게 전달합니다.
  • 클라이언트와 서버 간의 콘텐츠 협상을 중재하여 최적의 결과를 얻을 수 있습니다.
  • 중개자의 추가 구현이 필요합니다.

클라이언트 주도 협상

서버 입장에서 가장 간편하고 클라이언트 입장에서도 본인에게 가장 맞는 리소스를 받을 수 있는 방법이다.

클라이언트가 서버측에게 요청을 보내면

서버는 클라이언트에게 자신이 가지고 있는 리소스들 리스트를 보낸다.

이건 한국어 버전 .. 이건 영어 버전 .. 이건 프랑스어 버전 .. 뭐할래 ?

그럼 클라이언트는 가장 자신에게 적합한 버전을 선택하여 다시 요청을 보낸다.

이는 클라이언트가 직접 선택하기 때문에 가장 본인에게 맞는 자료를 받을 수 있지만

리소스 리스트를 받고, 자신에게 맞는 리소스를 선택한다는 것에서 불필요한 트랜잭션이 2번 이상 일어난다는 단점이 존재한다.

또한 언어 별 리소스가 다르다면 www.example.com 은 한국어 버전일 때

www.example.com/english 는 영어버전 , www.example.com/french 는 프랑스어 버전 등 리소스 별 url 이 달라진다는 단점이 존재한다.

서버 주도 협상

이 방법은 클라이언트 주도 협상과 다르게 불필요한 트랜잭션이 일어나지 않는다.

첫 번째 요청 떄 클라이언트는 본인이 받고자 하는 리소스의 언어와 같은 메타정보를

헤더에 담아 서버에 요청한다.

서버는 클라이언트의 메타 요청 자료를 보고 리소스를 선택해 제공한다.

다만 이는 클라이언트의 요청에 적합한 리소스가 존재하지 않을 때

클라이언트 : 제주어로 된거 주세요

서버가 직접 적합한 리소스를 선택해 제공해야 한다는 단점이 있다.

메타 요청을 보내는 헤더는 다음과 같다.

내용 협상 헤더

헤더 설명 예제
Accept 클라이언트가 이해하거나 처리할 수 있는 미디어 유형을 지정합니다. text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
Accept-Language 응답에 대한 선호하는 자연어를 나타냅니다. en-US, en;q=0.5
Accept-Charset 응답에 대해 허용되는 문자 집합을 지정합니다. utf-8, iso-8859-1;q=0.5
Accept-Encoding 콘텐츠 압축에 대해 클라이언트가 이해할 수 있는 인코딩을 전달합니다. gzip, deflate, br

클라이언트는 다음과 같은 헤더를 서버에게 보낸다.

이것들은 기존 엔터티 헤더 와 비슷하거나 동일한 양식이지만
현재 말하는 헤더들은 협상 단계에서 쓰이는 헤더들이다.

표에 열거된 협상 헤더들을 클라이언트에게 받으면 서버는 요청과 적절한 엔터티를 선택하고

협상 내용과 관련된 엔터티 헤더들을 작성해 제공한다.

헤더 설명 예제 사용 용도
Content-Type 엔터티의 미디어 타입을 나타냅니다. application/json; charset=utf-8 응답 엔터티 헤더
Content-Language 엔터티의 자연어를 나타냅니다. en-US 응답 엔터티 헤더
Content-Encoding 엔터티의 콘텐츠 압축에 대한 인코딩을 나타냅니다. gzip 응답 엔터티 헤더
다만 위에서 설명했던 것 처럼 만약 클라이언트가 요구하는 리소스 버전을 서버가 가지고 있지 않다면 어떻게 해야 할까 ?

나는 영어버전, 한국어버전 , 프랑스어버전만 존재하는데 클라이언트가 스페인어만 주세요

이러고 있다면 말이다.

이런 경우 서버에게 차선책을 선택 할 수 있도록 품질값(quality value , q값) 이 존재한다.

내용 협상 헤더의 품질값

각 프로토콜은 클라이언트의 선호마다 q 값을 정의 할 수 있다.

q 값은 0~1 사이의 값을 갖는다.

예를 들어

Accept-Langauge : en;q = 0.5 , fr;q=0.0 , kr;q=1.0

이란 클라이언트의 헤더가 있다면

클라이언트 : 한국어 버전 줘 , 그런데 없다면 영어 버전도 괜찮아 프랑스어 버전은 필요 없어

처럼 요구하고 있는 것이다.

Accept 헤더들 말고도 사용되는 협상헤더

만약 유저가 사용하는 브라우저가 구식일 경우엔 버전에 맞춘 리소스를 제공해야 할 것이다. 이를 위해 User-Agent 를 협상 헤더로 서버가 사용하기도 한다.


투명 협상

투명 협상은 서버와 클라이언트간의 협상을 중개 프록시를 통해 서버 주도 협상을 하면서 서버와의 트랜잭션은 낮추는 방법이다.

이는 프록시에서 리소스들을 캐싱해두고 사용자들에게 협상 헤더에 맞는 리소스들을 담아 보내주는 것이다.

이를 위해 서버는 프록시가 마치 서버와 같은 기준으로 협상을 하도록 교육해야 한다.

이를 위해 처음 프록시 서버가 서버로부터 리소스를 받을 때

서버는 리소스와 함께 Vary 헤더에 서버가 리소스를 보내기 전 살펴보는 헤더들은 이것들이야 하고 알려준다.

캐시와 얼터네이트(alternate)

만일 캐시 서버에 저장된 리소스가 A 라고 해보자 . 이것은 한국어 버전으로 된 것이다.

이 때 영어권 클라이언트가 영어로 된 리소스를 달라고 서버에게 요청을 보냈다.

요청은 서버까지 가지 않고 프록시 서버에서 캐치한다.

이후 프록시 서버는 협상 헤더를 보고 서버 측에 영어로 된 버전을 달라고 요청한다.

이를 B 리소스라고 해보자

그럼 프록시 서버는 영어권 이용자에게는 B 리소스를 보내도록 캐싱해둔다.

이 때 기존 가지고 있던 리소스가 아닌, 협상에 맞춰 준비된 리소스들을 Variantalternate 라고 한다.

이 때 생성되는 Variant 들은 모두 서버측에서 프록시 서버에게 보낸 Vary 헤더의 내용에 맞춰 생성될 것이다.

만약 서버가 Vary 헤더에 Accept-Language : 뭐뭐뭐.. 이렇게 보냈다면

프록시 서버는 Accept-Language 별 수 많은 variant 들을 캐싱해둘 것이다.

만약 요청에 맞는 variant 가 없다면 서버에 있느냐 묻고, 만약 서버에도 없다면 q 값을 보고 보낼 것이다. 아니면 존재하지 않는다는 에러 상태 코드를 보내던지 말이다.


트랜스 코딩

트랜스 코딩은 여러 협상 헤더에 맞는 리소스들을 미리 만들어두는 것이 아니라

협상 헤더에 맞춰 리소스를 변경하는 것을 의미한다.

포맷 변환

포맷 변환은 데이터를 클라이언트가 온전히 볼 수 있도록 다른 포맷으로 변환하는 과정을 의미한다.

예를 들어 내 리소스는 높은 성능을 요구하는 데스크탑에서만 볼 수 있을 때

클라이언트가 성능이 낮은 데스크톱이나 모바일에서 서버에 리소스를 요청했다고 가정해보자

그렇다면 우리는 원본 리소스를 보내면 클라이언트는 우리가 보낸 정보를 모두 인식 할 수 없다.

그렇기에 클라이언트에 맞게 리소소들을 다운그레이드 시킨 후 보내줘야 한다.

높은 해상도의 이미지를 낮춘다거나 , 애니메이션 효과를 제거한다거나 .. 등등

포맷 변환을 통해 우리는 클라이언트에게 우리가 보내고자 하는 정보를 온전히 보낼 수 있다.

콘텐츠 주입

콘텐츠 주입의 가장 대표적인 예시는 광고 삽입이다.

요청한 리소스의 내용이나 클라이언트의 쿠키 등을 통해 리소스에

사용자 맞춤 광고를 추가하여 효과적인 홍보를 할 수 있다.

profile
빨리 가는 유일한 방법은 제대로 가는 것이다

0개의 댓글