커피닉스, 시스템 엔지니어의 쉼터 커피향이 나는 *NIX
커피닉스
시스템/네트웍/보안을 다루는 곳
* HanIRC의 #coffeenix 방
[ 장비 및 회선 후원 ]
HOME > 네트워크(network) > 웹 서버(web, httpd, apache) 도움말
검색 : 사이트 WHOIS 웹서버 종류

WebDAV (7, 글 1, 자료 4)
웹서버 튜닝 (5, 글 4, 자료 2)
웹서버 사용 통계 자료 (2, 자료 1)
Apache SSL / mod_ssl (4, 글 3, 자료 2)

  HTTP 1.1의 Content Length와 Transfer Encoding 작성일 : 2005/12/04 04:29
 
  • 글쓴이 : 좋은진호 ( http://coffeenix.net/ )
  • 조회수 : 42762
          [ 이전화면 / 수정 ]   비밀번호 :     인쇄용 화면
      제  목 : HTTP 1.1의 Content Length와 Transfer Encoding
    작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
    작성일 : 2005.12.2~3(금~토)

    HTTP 1.1 에서는 커넥션이 끊어지지 않고 유지되는 Keep Alive connection(persistent connection)
    을 지원한다. apache 에서 httpd.conf 에 Keepalive on으로 설정하면 Keep alive connection을 지원
    하게 된다.

    웹페이지를 가져오는 프로그램을 만들 때(php에서 fsockopen을 사용하는 경우도)를 생각해보자.
    하나의 커넥션이 계속 유지된 상태라면 정확한 본문의 내용이 어디까지인지, 그리고 길이는 얼마인지
    어떻게 확인해야할까? 또한 connection close형태로 요청을 하더라도 HTTP 1.1에서는 본문내용을
    chunked enconig(이게 뭔지는 글 중간에 설명한다.) 형식으로 표시하는 경우도 있다.
    이런 것처럼 HTTP 1.1로 요청을 할 때는 Content Length헤더로 표시되는 경우와 chunked encoding
    을 사용하는 경우 등 2가지 response 형식을 잘 구분해서 처리해주어야 한다.

    1. Content Length 헤더를 보여주는 경우

     
    $ telnet coffeenix.net 80
    Trying 211.xxx.xxx.xx...
    Connected to coffeenix.net (211.xxx.xxx.xx).
    Escape character is '^]'.
    GET /truefeel/files/mail_log.pl.txt HTTP/1.1      <-- HTTP/1.1 형태로 요청
    Host: coffeenix.net
    Connection: close
                                     <-- 요청 후 접속을 바로 끊음

    HTTP/1.1 200 OK                                   <-- 여기 부터는 서버의 응답
    Date: Sat, 03 Dec 2005 15:10:17 GMT               <-- RFC 1123을 따르는 날짜 표시
    Server: Secured                                   <-- 웹서버명 ^^
    Last-Modified: Sun, 18 Jan 2004 20:26:49 GMT
    ETag: "64151-7dc-400aec09"
    Accept-Ranges: bytes
    Content-Length: 2012                              <-- contents의 길이. 2012bytes
    Connection: close
    Content-Type: text/plain

    #!/usr/bin/perl                                   <-- 여기 부터는 contents
    #
    # procmail을 통해 넘겨온 메일 수신 정보를 DB로.
    #
    ... 생략 ...
    Connection closed by foreign host.
     


    한가지 더 보자. 아래와 같이 요청하면 connection은 계속 유지된 상태로 있게 된다.

     
    $ telnet www.cyworld.nate.com 80
    Trying 211.115.11.30...
    Connected to www.cyworld.nate.com (211.115.11.30).
    Escape character is '^]'.
    GET /main2/index.htm HTTP/1.1                     <-- HTTP/1.1 형태로 요청
    Host: www.cyworld.nate.com


    HTTP/1.1 200 OK                                   <-- 여기 부터는 서버의 응답
    Cache-Control: max-age=31536000
    Content-Length: 162368                            <-- contents의 길이. 162368bytes
    Content-Type: text/html
    Last-Modified: Sat, 03 Dec 2005 14:58:50 GMT
    Accept-Ranges: bytes
    ETag: "fee1c0111af8c51:d63"
    Server: Microsoft-IIS/6.0
    Date: Sat, 03 Dec 2005 15:24:06 GMT
     


    위처럼 'Content-Length' 헤더가 있다면 body부분에서 해당 길이만큼만 받아오고, close하면 된다.


    2. Transfer Encoding 헤더 (Chunked enconding 방식)

    Chunked enconding은 php나 CGI등에서 주로 사용하며, 헤더에는 Transfer-Encoding: chunked가
    표시되고, 본문은 chunk size+내용+chunk size+내용... 형식으로 표시된다.

     
    $ telnet coffeenix.net 80
    Trying 211.xxx.xxx.xx...
    Connected to coffeenix.net (211.xxx.xxx.xx).
    Escape character is '^]'.
    GET / HTTP/1.1                                    <-- HTTP/1.1 형태로 요청
    Host: coffeenix.net


    HTTP/1.1 200 OK                                   <-- 여기 부터는 서버의 응답
    Date: Sat, 03 Dec 2005 16:29:25 GMT
    Server: Secured
    Transfer-Encoding: chunked                        <-- chunked encoding
    Content-Type: text/html

    e22                         <-- chunked 된 size. 16진수로 표시되며, bytes 단위
    ... 내용 ...                <-- 해당 e22(3618 bytes) 길이의 contents
    192                         <-- 16진수 192
    ... 내용 ...                <-- 192(402 bytes) 길이의 contents
    f76
    ... 내용 ...
    101
    ... 이하 생략 ..
    0                           <-- 끝을 표시한다
     


    보다 정확하게 보자면 chunk size+CRLF문자(CRLF는 ASCII코드 16진수로 0d0a)가 표시되고,
    내용+CRLF문자가 오는 형태가 반복되며 0+CRLF문자로 마무리를 한다.
    따라서 웹페이지 읽어올 때는 처음 chunk size를 알아낸 후 해당 길이만큼 내용을 분리하고
    다시 chunk size을 확인, 내용 분리하는 과정을 반복한 후 내용만 합치는 과정이 필요하다.

    3. php에서 Content-Length 헤더 사용

    윈도의 응용프로그램과 php로 된 웹페이지간의 통신이 필요한 경우 chunked encoding된 페이지
    보다는 Content-Length 헤더를 따르도록 하면 응용 프로그램쪽 개발이 보다 쉬워질 것이다.

    이처럼 필요한 페이지만 Content-Length 헤더가 표시하고 싶다면 php에서 출력 버퍼링을 사용하도록
    하면 된다. php 시작에 ob_start()를 넣고 마지막에 ob_end_flush()를 사용하면 그 사이에 출력되는
    모든 내용을 버퍼에 쌓아 둔 후 마지막에 출력을 하게 된다.
    물론 버퍼에 저장된 내용 길이를 파악한 후 Content-Length: 헤더를 뿌려주는 것도 잊지 말자.

     
    < ?
    ob_start();

    ... 프로그램 코드 ...
    ... HTML ...

    $length=ob_get_length();
    header("Content-Length: $length");
    ob_end_flush();
    ?>
     



    4. 참고 자료

    * Content Length & Transfer Encoding
      http://www.simtec.ltd.uk/httpgallery/chunked/

    * HTTP/1.1표준(안) (김용운 역)
      http://coffeenix.net/doc/network/http11.txt

    * php ob_start() function
      http://kr.php.net/manual/kr/function.ob-start.php
      커피닉스 카페 최근 글
    [08/25] #gpt_question_subje
    [08/20] From what I've seen
    [08/14] сайт
    [06/16] [질문]SAN 스위치 브로드케이드 dcx8510-4 장비관련입니다.
    [04/22] Re: 영화속에 컴퓨터 이야기 ~스워드피쉬(2001)
    [10/20] Cross Compiler 깔
    [07/14] SSL АО
    [04/26] Re: 도스화면 원격조종 여부
    [04/25] 도스화면 원격조종 여부
    [10/30] Cshell에서 난수 설정
    [10/23] 공항철도주식회사 SE 구인 件
    [01/26] Re: wget으로 다른서버에있는 디렉토리를 가져오려고합니다.
    [01/25] wget으로 다른서버에있는 디렉토리를 가져오려고합니다.
    [01/11] 특정 안드로이드 WebView 버전에서 SSL 문제 (WebView 버그)
    [08/01] DNS forwarder (전달자) 서버를 통해서 쿼리하면 역방향을 받아오질 못합니다.
      New!   최근에 등록한 페이지
      KiCad EDA Suite project (Free/Libre/Open-Source EDA Suite) (CAD)
      오픈캐스케이드 캐드 (OpenCASCADE CAD)
      QCad for Windows --- GNU GPL (Free Software)
      The Hello World Collection
      IPMI를 활용한 리눅스 서버관리
      DNS 설정 검사
      nagiosgraph 설치 방법
      Slony-I 설치 방법 (postgresql replication tool)
      Qmail기반의 Anti spam 시스템 구축하기
      clusterssh

    [ 함께하는 사이트 ]




    운영진 : 좋은진호(truefeel), 야수(yasu), 범냉이, sCag
    2003년 8월 4일~