login register Sysop! about ME  
qrcode
    최초 작성일 :    2005년 07월 18일
  최종 수정일 :    2006년 12월 26일
  작성자 :    Loner (유경상)
  편집자 :    Loner(유 경상)
  읽음수 :    25,525

강좌 목록으로 돌아가기

필자의 잡담~

지난 강좌에선 HTTP 압축을 써야하는 이유에 대해 썰을 풀어 봤씁니다. 뭐 우리나라 같이 네트워크 인프라가 좋은 상황에선 HTTP 압축이 씨가 안먹힐 가능성이 높지만 그래도 제 생각은 HTTP 압축이 유용하다는 겁니다. 최근에 100Mbps를 사용하는 사용자들도 많아졌지만 아직도 케이블모뎀(최고 10Mbps)이나 ADSL(2-4Mbps)을 사용하는 사람도 많기 때문이죠(좀더 효과를 보려면 이미지 파일들에 대한 캐시 역시 동반되어야 하겠지만...). 그래서 꾿꾿이 씨부려 볼렵니다.

현재 강좌의 원본 글의 링크는 http://www.simpleisbest.net/archive/2005/07/14/185.aspx 입니다.

HTTP Compression (II) - Principle

요번엔 HTTP 압축이란 것이 구체적으로 어케 작동하는가를 살펴보도록 하겠다. 이런거 다 때려치고 곧바로 HTTP 압축을 사이트에 적용해 보고자 하는 사람들에겐 마니 미안타... 원리를 모르고 뎀비는 것 처럼 용감한 것이 없다(XX 하면 용감하단 말을 이런 때 쓰는거 아뉠까?). 이런거 아무런 도움 안된다...

HTTP 1.1 Protocol

HTTP 1.1 프로토콜을 명세하고 있는 RFC2616을 찬찬히 살펴보면 복잡한 설명과 긴 내용에 한숨만 나올 것이다(물론 필자도 그렇다). HTTP 압축에 관련된 프로토콜 명세는 그다지 복잡하지도 많지도 않다. 간단히 꼭 필요한 거만 설명하겠다(사실 필자가 아는 것이 그것밖에 안되므로... -_-).

HTTP 압축은 (사실 HTTP 프로토콜은 HTTP 압축이란 용어를 사용하지 않는다. Content-Coding 이란 용어를 쓰며 이 Content-Coding이 주로 압축의 용도로 사용된다고 명시하고 있을 뿐이다) 두 개의 HTTP 헤더 필드에 의해 작동한다. Accept-Encoding 헤더와 Content-Encoding 헤더가 그것인데 이 두개의 HTTP 헤더 값을 통해 클라이언트(웹 브라우저)와 서버(웹 서버)가 압축을 할 것인가 말 것인가 그리고 압축에 사용되는 알고리즘을 쑈부치는 것이다.

Accept-Encoding은 클라이언트가 웹 서버에게 보내는 HTTP Request 메시지에 명세 하는 값으로서 클라이언트가 이 헤더에 명시된 인코딩(압축)을 이해하고 디코딩(압축 해제)을 수행할 수 있다는 것을 서버에 알리는데 사용한다. 즉, 클라이언트가 압축된 컨텐츠를 받아 압축을 해제할 수 있는 압축 알고리즘을 서버에 알리는 용도로 Accept-Encoding 헤더가 사용된다. IE 6.0에서 서버에 보내는 HTTP Request 메시지를 우리의 멋진 유틸리티인 Fiddler로 살짝 디비보면 Accept-Encoding이 다음과 같이 명시 되어 있음을 알 수 있다.


Accept-Encoding: gzip, deflate
 

요 헤더 값이 의미하는 것은 IE가 gzip 그리고 deflate 인코딩, 즉 압축 알고리즘을 이해하므로 웹 서버가 HTTP Response 메시지를 이들 알고리즘 중 하나로 압축해서 보내도 된다는 것을 서버에게 찔러 주는 것이다.

웹 서버는 Accept-Encoding의 값을 살펴보고 필요에 따라서 HTTP Response(HTML, CSS, 이미지 등의 결과물)를 압축 할 수 있다. 웹 서버가 HTTP Response를 압축했다면 서버는 결과가 어떤 알고리즘에 의해 인코딩(압축) 되었는가를 Content-Encoding 헤더를 통해 명시한다. 다음은 http://www.google.co.kr 에서 반환한 HTTP Response 헤더의 내용이다.

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html
Content-Encoding: gzip
Server: GWS/2.1
Content-Length: 1865
Date: Thu, 14 Jul 2005 14:21:24 GMT

구글은 Content-Encoding 헤더 값에 gzip에 명시하여, 컨텐츠가 gzip 알고리즘에 의해 압축되었음을 브라우저에게 알리고 있다.

Test

직접 테스트하여 눈으로 HTTP 압축이 수행되는 것을 살펴보자. 먼저 Fiddler를 수행시킨다. 그리고 IE를 수행시키고 http://www.yahoo.com 에 접속해 보자. 그러면 Fiddler에 IE가 전송하는 HTTP Request 헤더와 Yahoo 사이트가 반환하는 HTTP Response 헤더가 다음과 같이 표시될 것이다. 그리고 사이트가 반환하는 실제 컨텐츠(TextView 버튼을 클릭해 보라)는 HTML 이 아닌 바이너리 임을 알 수 있을 것이다. IE 브라우저가 압축을 풀고 그 결과를 표시하는 것이다.

<<IE의 Accept-Encoding 값 과 Yahoo 사이트의 Content-Encoding 값>>

이제 동일한 사이트에 대해 Accept-Encoding 을 명시하지 말아보자. Fiddler의 오른쪽 패널에서 Request Builder 탭을 선택하고 HTTP Request를 '생성'해 보자. URL 입력란에 Yahoo 사이트를 입력하고 Execute 버튼을 클릭하면 HTTP Request 가 만들어지고 이것이 수행될 것이다. 그리고 나서 HTTP Response 결과를 살펴보자. Request에서 Accept-Encoding이 명시되지 않았으므로, 웹 서버 역시 압축을 수행하지 않았음을 알 수 있다. 즉, Content-Encoding 이 명시되지 않았을 뿐더러 TextView 버튼을 눌러보면 HTML이 압축되지 않은 상태로 반환되었음을 확인하자.

<< HTTP 호출 만들기 >>

HTTP Compression Implementation

대략적으로 원리를 알아보았으니 구현을 어떻게 하면 될지 감이 잡힐 것이다. 웹 서버 구현이라면 클라이언트로부터 Accept-Encoding을 통해 클라이언트가 압축을 지원하는지 검사하고 지원한다면 컨텐츠를 압축한다. 그리고 Reponse 메시지에 Content-Encoding을 명시해 주면 될 것이다. 클라이언트의 경우, IE와 같은 브라우저를 사용한다면 이미 구현이 다 되어 있으므로 아무런 작업을 수행할 필요가 없다. 하지만 System.Net 네임스페이스의 HttpWebRequest 클래스 및 HttpWebResponse 클래스를 사용한다면 직접 구현이 필요할 것이다. HttpWebReqest 클래스에 Accept-Encoding을 명시해 주고 HttpWebResponse에서 Content-Encoding을 검사하여 압축되었다면 압축을 해제하면 된다. 다음 코드는 SharpZipLib 라이브러리를 이용하여 압축된 HTTP 컨텐츠를 압축 해제 하는 예제 코드이다.

using System;
using 
System.IO;
using 
System.Net;
using 
ICSharpCode.SharpZipLib.GZip;

class 
HttpDecompressTest
{
    
// HTTP 압축 해제 예제 코드
    
[STAThread]
    
static void Main(string[] args)
    {
        
string url "http://www.google.co.kr";

        
HttpWebRequest req (HttpWebRequest)WebRequest.Create(url);
        
// gzip 압축 허용
        
req.Headers["Accept-Encoding""gzip";

        
HttpWebResponse res (HttpWebResponse)req.GetResponse();
        string 
contentEncoding res.Headers["Content-Encoding"];
        
Stream httpStream, resultStream;
        
httpStream res.GetResponseStream();
        
// 압축 여부 확인
        if (contentEncoding == "gzip") {
            // SharpZipLib의 압축 해제 스트림 사용
            resultStream = new GZipInputStream(httpStream);
        
}
        
else {
            resultStream 
httpStream;
        
}
        
// 간단한 구현이므로 euc-kr로 하드 코딩.
        
System.Text.Encoding encoding System.Text.Encoding.GetEncoding("euc-kr");
        
// 결과 표시
        
StreamReader reader = new StreamReader(resultStream, encoding);
        
Console.WriteLine(reader.ReadToEnd());
        
resultStream.Close();
    
}
}

<< HTTP 압축 해제 예제 코드 >>

위 코드에서 Accept-Encoding을 설정하는 부분을 유심히 살펴볼 필요가 있다. 이 설정이 없는 경우 구글 사이트는 압축을 수행하지 않을 것이다. 또한 Accept-Ecoding을 설정해 놓은 상태에서 압축을 풀지 않도록 코드를 바꾸고 결과를 살펴보자. 압축을 풀지 않으면 HTML이 아닌 요상스런 문자들이 화면을 가득메우게 될 것이다.

대부분의 경우 클라이언트로 IE를 사용하기 때문에 클라이언트의 문제는 거의 없을 것이다. 사실 중요한 것은 웹 서버의 구현이다. 만약 CGI나 ISAPI Extension으로 사이트가 구성되어 있다면 압축을 어케 시도해 볼텐데, 당췌 ASP 나 ASP.NET으로 구현된 사이트에 압축을 적용할려치면 눈 앞이 답답하고 눈알이 튀어나올려고 할 것이다. 게다가 압축을 위해 기존 코드를 수정해야 한다면 더욱 미칠 노릇 아닌가?

다음 포스트에는 프로그램 소스를 전혀 수정하지 않고(당연히 그래야 할것이다) 웹 서버측에서 HTTP 압축을 수행하는 방법들에 대해 살펴보도록 하겠다. 특히 IIS 6.0의 압축 기능에 대해서 말이다. 궁금하지? 기둘리~~~


authored by


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})