소켓을 이용해서 HTTP을 구현시 질문
안녕하세요.
회사에서 필요해서 간단히 HTTP를 흉내내서 해당 파일을 웹서버에 접속해서 가져오고자 프로그램을 짜는데 이해가 되지 않는 부분이 있어서 질문 올려드립니다.
먼저 테스트 한다고 아래처럼 코드를 짜서 예를 들어 www.google.com 웹서버에 접속해서 아래 전문을 보냅니다.
char *msg = "GET index.htm HTTP/1.1\r\n\r\n"; if (0 > (rc = write(sd, msg, strlen(msg))) ) { perror("cannot send data "); exit(1); } printf("%d data sent\n", rc); while(0 < read(sd, &ch, 1)) { printf("%c", ch); }
그러면 결과를 아래와 같이 화면에 프린트 합니다.
26 data sent
HTTP/1.1 400 Bad Request
Date: Thu, 07 Jul 2005 18:03:14 GMT
Server: Apache Web Server
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-117d
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): index
.htm<P>
<HR>
<ADDRESS>Apache/1.3.33 Server at pulsar.lunarpages.com Port 80</ADDRESS>
</BODY></HTML>0
문제는 위에서 보시는 바와 같이 헤더와 바디사이에 17d 라는 숫자와 마지막에 0이 찍히는데 도무지 이 값이 왜생기는지 모르겠네요.
rfc 문서를 봐도 특별히 언급이 없는것 같은데.... 어쩜 저의 무식의 소치로 발견을 못했을 수도...
위의 두 숫자를 없애야 될것 같은데... 도무지 방안이 떠오르지 않아서 질문 올려드립니다.
고수님들의 의견 부탁드릴께요.
<><
http://www.w3.org/Protocols/rfc2616/rfc2
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html
에서 chunked 로 찾기 해보시면 답이 나옵니다.
17d 는 16진수이고 17d 는 앞으로 전송될 데이터 양의 크기를 나타냅니다.
0 은 앞으로 전송될 데이터가 없으므로 EOF 를 의미합니다.
보통은 Content-length 라는 헤더를 통해서 클라이언트가 받을 데이터의 양을 전달하는데 CGI의 경우에는 데이터를 계속 생성해야 하기 때문에 데이터의 양을 산출하기 힘듭니다. 그래서 chunked encoding이라는 방식으로 클라이언트에게 받을 데이터의 양을 알려주는 것입니다. (꼭 CGI가 아니더라도 사용하는 경우도 있긴 합니다)
keep-alive 가 지원되는 서버에서 HTTP/1.1 프로토콜 하에서는 Content-length 또는 Transfer-Encoding: chunked 두가지 중 하나는 와야 합니다. 아니면 접속을 끊어줘 버리던가..
감사합니다.
:D
먼저 결과 감사합니다.
결과 내용을 파일에 담아서 사이즈를 맞추어 보니 말씀하신바 처럼 크기가 맞네요.
이제는 이 숫자들을 없앨 방법을 찾아 봐야 되는데, 일반 HTML 문서는 대충 숫자를 없앨 수 있을것 같은데...
가지고 올 데이터가 이미지나 혹은 오디오 파일인 경우에 좋은 의견 있으시면 부탁드릴께요.
다시 한번 감사드립니다.
<><
Linux rules!!!
chunk
Transfer-Encoding: chunked
청크엔코딩 되었음을 의미합니다.
16진수 형태로 되어 있는 chunk size 입니다. 이 chunk size는 여러번 출현할수도 있습니다.즉
맨 마지막의 0도 chunk 입니다.0은 앞으로 더 이상 읽을 chunk가 없음을 의미 합니다.사실상 contents의 마지막임을 알리는 겁니다.
chunk 엔코딩을 하는 이유는 contents가 정확히 도착했는지를 판단하는 수단으로 사용하기 위해서 입니다.
즉 님 말씀처럼 청크 사이즈를 개별적으로 지운다는건 데이터 무결서을 훼손하는 상당히 비효율적인 방법이구요.
일단 헤더와 바디를 분리한다음.바디의 맨 처음 부분에서 맨처음 chunksize1 을 추출하시고 하면서...
연결리스트를 만들어서 청크사이즈를 발견할때마다 chunk노드를 추가시킨다음 chunk 노드들을 merging하면 하나의 완벽한 contents가 되겠지요..
화장실이 급하군요 -- :oops:
Transfer-Encoding: chunked 를 없애려면...
저도 같은 경험을 했습니다..
저는
<?ob_start();?>
HTML...
..
..
<?
$ob_conent = ob_get_content();
header( 'Content-Length:' . strlen($ob_content) );
ob_end_flush();
?>
이렇게 하면 Transfer-Encoding: chunked형태로 넘어오지 않더군요...
함수들이 정확하게 적었는지 모르겠네요... 그럼 수고...
댓글 달기