본문 바로가기

CS/네트워크

[HTTP] 17. 내용 협상과 트랜스코딩

이 포스팅은 "HTTP-완벽 가이드" 책을 학습하고 정리한 것입니다.

https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=49731592

 

HTTP 완벽 가이드

HTTP 규약이 어떻게 동작하고 웹 기반 애플리케이션을 개발하는 데 어떻게 사용하는지 설명한다. 하지만 이 책은 단순히 HTTP에 대해서만 다루지는 않는다. HTTP가 효율적으로 동작하도록 함께 사

 

 

 

 


 

 

 HTTP에서는 클라이언트와 서버가 적합한 리소스를 협상할 수 있도록, 내용 협상(컨텐츠 네고시에이션) 방법을 제공한다. 이 방법을 이용해서 하나의 URL이 여러 가지 리소스 중 적합한 것에 대응되도록 할 수 있다.

 

17.1 내용 협상 기법

 내용 협상은 세 가지 방법으로 나눠진다.

  • 클라이언트 주도 : 클라이언트가 요청을 보내면, 서버는 클라이언트에게 선택지를 보내고, 클라이언트가 선택한다.
  • 서버 주도 : 서버가 클라이언트의 요청 헤더를 검증해서 어떤 버전을 제공할지 결정한다.
  • 투명 : 투명한 중간 장치(ex. 프록시 캐시)가 서버를 대신해서 협상을 한다.

 

17.2 클라이언트 주도 협상

 이 방법의 장점은 서버 입장에서 구현하기 쉽다는 것이다. 클라이언트가 선택할 것이기 때문에, 서버 는 요청된 것을 응답하기만 하면된다. 단점으로는 각 페이지에 두 번의 요청이 필요하여, 느린 성능을 갖는다는 것이다. 먼저 클라이언트가 요청을 전달하고, 서버가 협상 내용을 전달한 뒤, 클라이언트가 선택지에서 선택을 하여 서버에게 전달한다. 이처럼 두번의 사이클이 돌기 때문에, 느리다.

 

 기술적으로 위 협상을 구현하는 방법은, ‘여러 가지 버전에 대한 링크와 설명을 HTML 문서에 담아 전송’ , ‘300 Multiple Choices 응답 코드로 클라이언트에게 응답’하는 두가지 방법이 있다. 클라이언트는 수동으로 원하는 버전을 선택해야하며, 서버는 각 버전에 대한 URL을 제공해야 한다는 단점이 있다.

 

17.3 서버 주도 협상

 클라이언트 주도 협상이 갖는 느리다는 단점을 보완하기 위해, 서버 주도 협상 방법을 사용할 수 있다. 서버가 어떤 페이지를 응답할지 결정하므로써, 두 번의 요청 사이클을 한 번으로 줄일 수 있다. 다만, 이 경우 클라이언트는 서버에게 반드시 자신이 무엇을 선호하는지 알려줘야 한다. HTTP 에서 이러한 정보를 담기 위해 아래의 헤더들을 제공한다.

  • Accept : 서버는 클라이언트의 Accpt 관련 헤더들을 보고 알맞은 응답 헤더를 준비한다.
  • 내용 협상 헤더 이외의 다른 헤더 : 서버는 User-Agent와 같은 사용자 정보를 통해 적합한 리소스를 선택하여 클라이언트에게 제공할 수 있다.

 

17.3.1 내용 협상 헤더

헤더 설명
Accept 서버가 어떤 미디어 타입으로 보내도 되는지 알려준다.
Accept-Language 서버가 어떤 언어로 보내도 되는지 알려준다.
Accept-Charset 서버가 어떤 Charset으로 보내도 되는지 알려준다.
Accept-Encoding 서버가 어떤 인코딩으로 보내도 되는지 알려준다.

 

 위 헤더들은 ‘15장. 엔터티와 인코딩’에서 보았던 엔터티 헤더들(ex. Content-Type)과 유사하다. 하지만, 엔터티 헤더는 서버에서 클라이언트로 전송할때의 메시지 본문의 속성을 가리키는 반면, 내용 협상 헤더는 클라이언트와 서버가 선호 정보를 서로 교환하여 원하는 문서를 응답 및 수신하도록 도와준다는 점에서 다르다.

 

아래의 표는 서버 입장에서 Accept 관련 헤더와 적합한 엔터티 헤더를 매핑한 것이다.

 

Accept 관련 헤더들 엔터티 헤더
Accept Content-Type
Accept-Language Content-Language
Accept-Charset Content-Type
Accept-Encoding Content-Encoding

 

17.3.2 내용 협상 헤더의 품질값

 

 HTTP 프로토콜은 클라이언트가 각 선호의 카테고리마다 여러 선택 가능한 항목을 선호도와 함께 나열할 수 있도록 품질값을 정의하였다. 형식은 아래와 같다.

Accept-Language : en;q=0.5, fr;q=0.0, nl;q=1.0

 

q값은 0.0 부터 1.0까지의 값을 가질 수 있으며, 0.0에 가까울 수록 낮은 선호도 이며, 1.0에 가까우면 그 반대이다.

 

17.3.3 그 외의 헤더들에 의해 결정

 

 서버는 내용 협상 관련 헤더들로 적합한 문서 버전을 선택하기 어렵고, 또한 서버가 그러한 문서를 가지고 있지 않을 때, 다른 헤드들을 통해 추측해서 클라이언트에게 문서를 전달한다. HTTP 프로토콜은 서버가 응답에 넣어 보낼 수 있는 Vary 헤더를 정의하는데, 이 헤더는 캐시(혹은 그 외 다운스트림 노드)에게 서버가 내줄 응답의 버전을 선택하기 위해 HTTP 요청 헤더의 어떤 부분을 참고하고 있는 지 나타낸다.

 

 

17.4 투명 협상

 

투명 협상은 클라이언트 입장에서 협상하는 중개자 프록시를 둠으로써 클라이언트와의 메시지 교환을 최소화하는 동시에 서버 주도 협상으로 인한 부하를 서버에서 제거한다. 이를 지원하기 위해, 서버는 클라이언트의 요청에 가장 잘 맞는 것이 무엇인지 판별하려면 어떤 요청 헤더를 검사하면 되는지, 프록시에게 반드시 말해줄 수 있어야 한다.

 

17.4.1 캐시와 얼터네이트(alternate)

 캐시는 클라이언트에게 올바른 캐시된 응답을 돌려주기 위해, 서버가 응답을 돌려줄 때 사용했던 의사결정 로직의 상당 부분을 그대로 사용해야 한다. 이를 가능케하기 위해, 캐시는 캐시된 응답을 돌려보낼 때 반드시 엔터티 헤더들과 같은 헤더들을 사용해야 한다.

 

 만약 원 서버가 동일한 URL에 대해 두 가지 버전의 문서를 응답했다면, 캐시 또한 두 가지 버전의 응답을 가지고 있어야 한다. 또한, 캐시는 동일한 URL 요청이라도, 요청 헤더를 확인했을 때 적합한 캐시된 응답이 없다면, 해당 요청을 본인이 처리할 것이 아니라, 원 서버에게 클라이언트의 요청을 전달해야 한다.

 

17.4.2 Vary 헤더

 Vary 헤더는 Accept 요청 헤더 이후에 추가적으로 확인해야되는 사항(또는 필터)와 같은 역할을 수행한다. 클라이언트가 전송항 Accept 요청 헤더와 일치하는 캐시된 응답이 존재하더라도, 만약 원 서버가 응답했던 헤더에 Vary 헤더가 있고, 해당 Vary 헤더 필드에 지정된 정보가 현재 요청을 보낸 사용자의 정보와 적합하지 않는다면, 캐시 서버는 응답을 클라이언트에게 전송하는 것이 아닌, 원 서버에게 먼저 클라이언트의 요청을 전달해야 한다. 이미지로 확인하면 아래와 같다.

 

 

17.5 트랜스코딩

 앞에서 설명한 내용 협상 방식들에서는 명백하게 서버가 클라이언트에게 응답해줄 적합한 문서가 존재함을 가정했다. 하지만, 실세계에서는 그렇지 않을 수 있다. 서버가 클라이언트의 요구에 맞는 문서가 없다면, 서버는 에러를 응답해야 겠지만, 이론적으로 서버는 기본의 문서를 클라이언트가 사용할 수 있는 형태로 변환할 수 있다. 이러한 방식을 트랜스코딩이라고 말한다.

 

트랜스코딩은 ‘포맷 변환’, ‘정보 합성’, ‘내용 주입’의 세 종류가 있다.

 

17.5.1 포맷 변환

 포맷 변환은 데이터를 클라이언트가 볼 수 있도록 한 포멧에서 다른 포멧으로 변환하는 것이다. Accept 로 시작하는 내용 협상 헤더들을 통해 가능하다. 포멧 변환의 대표적인 예시로는, ‘HTML → WML’ , ‘고해상도 사진 → 저해상도 사진’ 등이 있다.

 

17.5.2 정보 합성

문서에서 정보의 요점을 추출하는 것을 정보 합성(information synthesis)이라고 말한다. 예시로는 ‘페이지 내의 제목에 기반한 개요 생성’ , ‘페이지에서 광고 추출’ 등이 있다.

 

17.5.3 콘텐츠 주입

 앞서 언급한 ‘포맷 변환’과 ‘정보 합성’은 내용을 줄이는데 주안점을 두었다면, 콘텐츠 주입은 내용을 늘려서 변환하는 방식이다. 예시로는 ‘자동 광고 생성’, ‘사용자 추적 시스템’이 있다.

 

17.5.4 트랜스코딩 vs 정적으로 미리 생성해두기

 트랜스코딩을 하지 않고, 미리 다양한 버전의 문서를 생성해두는 것을 고려해 볼 수 있다. 그러나 이는 현실적이지 못한 방법으로 여겨진다. 페이지에 대해 변화가 생길 경우, 정적으로 미리 생성된 문서들도 동일하게 변경해두어야 하는 비용이 들게 된다. 또한, 다양한 버전을 저장하기 위한 공간을 요구하기 때문에, 미리 생성해두지 않고, 필요할 때마다 그때그때 트랜스코딩해서 응답하는 것이 추천된다.