Socket Programming으로 간단한 HTTP Client를 만들고, HTTP 서버로 요청을 보내고 응답을 받아보자. (사실, 웹브라우저를 통해 요청을 보내고 Packet Snipping 해서 잡아보면 간단한 문제다;)
GET으로 요청을 보내는 것은 간단한데, (명시적으로 확인하기 위해 Newline을 \r\n로 표기했다.)
GET chk.html?variable=checked&... HTTP/1.1\r\n
Host: 192.168.0.100:8080\r\n
User-Agent: MyAgent-0.0.1\r\n
\r\n
대략 이런 형식이면 되겠다.
주의할 것은, HTTP Header 라인 마지막에 아무 문자도 없는 New Line이 들어와야 Header가 종료되었다는 것을 인식하고 HTTP Server가 동작 한다.
POST로 요청을 보내는 것은 조금 복잡한 문제가 있다.
첫번째로는 Request가 Body에 들어가기 때문에, Content-Length를 명시해줘야 한다. 그리고 두번째로는, Content-Type이 명시되어야 하는 것 같다.
이와 같이 처리되어 실제로 동작이 확인된 예제이다.
POST chk.html HTTP/1.1\r\n
Host: 192.168.0.100:8080\r\n
Content-Type: application/x-www-form-urlencoded\r\n
User-Agent: MyAgent-0.0.1\r\n
Connection: Keep-Alive\r\n
Content-Length: 25\r\n
\r\n
variable=checked&....
Connection 항목은 제거해도 될 듯 하고, 다른 Content-Type으로 동작시키는 것은 확인해보지 않았다.
(모든 것은 HTTP Protocol 정의서에 나와있겠지만!)
응답을 받는데 대해서 겪었던 문제점은, php같은 스크립트 언어의 경우에는 항상 이런 헤더를 가지고 들어오게 된다.
Transfer-Encoding: chunked
참고 사이트 :
소켓을 이용해서 HTTP을 구현시 질문 | KLDP (chunked 형태일때 받게 되는 Message Body의 예제와 설명을 볼 수 있다.)물론 chunked일 때와 정상적으로 Content-Length 항목을 받았을 때와 두가지 처리를 해 주면 되겠지만 이것이 여의치가 않을 경우, php의 경우는 스크립트 상에서 아래와 같은 처리를 해 주면 정상적으로 Content-Length를 주게 된다.
<?
ob_start();
... (로직 처리)
$length=ob_get_length();
header("Content-Length: $length");
ob_end_flush();
?>
이제 남은 것은 문자열을 자르는 일이다.
(OTL;)