Tiny
를 확장하여 동영상 파일을 처리할 수 있도록 한다. 실제 브라우저를 통해 결과를 체크하시오.<video muted autoplay loop>
<source src="Narea.mp4" type="video/mp4">
<strong>Your browser does not support the video tag.</strong>
</video>
서버의 디렉토리에 동영상 파일을 넣어주고, 간단한 video
태그를 추가하여 쉽게 해결할 수 있는 문제!
물론 책에는 무려 고대의 MPG
형식을 처리하라고 되어 있지만, 동영상을 변환하는 건 귀찮으니까 패스..
Tiny
를 수정해서 정적 컨텐츠를 처리할 때 요청한 파일을 mmap
과 rio_readn
대신에 malloc
, rio_readn
, rio_writen
을 사용해서 연결 식별자에게 복사하도록 하시오.이 문제는 mmap
을 대체해야 하는 문제이기에, mmap
이 무엇인지 부터 알아야 한다!
mmap
는 UNIX
와 UNIX-LIKE
시스템에서 사용하는 메모리 매핑 함수로, 파일을 메모리에 매핑하여 파일을 메모리로 읽거나 쓸 수 있게 해 주는 역할을 한다. 또한, 더 이상 매핑이 필요 없어지면 munmap
함수를 통해 매핑을 해제 해 주어야 한다.
어? 이 녀석 낯설지 않다.. 바로 C
의 malloc
와 free
!! 전 주차에서 지겹도록 봤던 이 친구들을 이용하면 대체할 수 있겠다. 실제로 책에서도 malloc
으로 대체하라고 하기도 하고.
srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);
Close(srcfd);
Rio_writen(fd, srcp, filesize);
Munmap(srcp, filesize);
malloc
으로 대체한 코드srcfd = Open(filename, O_RDONLY, 0);
srcp = (char *)malloc(sizeof(filesize));
Rio_readn(srcfd, srcp, filesize);
Close(srcfd);
Rio_writen(fd, srcp, filesize);
free(srcp);
두 함수의 동작이 크게 다르지 않지만, malloc
은 mmap
과 달리 그냥 메모리 공간만을 비워줄 뿐! 따라서 Rio_readn
을 통해 포인터를 매핑해주는 작업을 추가 해 주었다. 또한 Munmap
을 통한 매핑 해제를 free
로 바꿔주었다.
CGI adder
함수에 대한 HTML
형식을 작성하고, 두 개의 숫자로 채우는 텍스트 상자를 포함하도록 한다. 또한 GET
메소드를 사용하여 컨텐츠를 요청하도록 한다. 생각보다 쉽지 않았던 문제였다. 코드가 어떤 식으로 굴러가는 지 이해하고 있어야 해결할 수 있었던 문제! 우선 입력을 처리할 HTML
형식을 작성해보았다.
<form action="/cgi-bin/adder" method="GET">
<p>a: <input name="A" /></p>
<p>b: <input name="B" /></p>
<input type="submit" value="Add"/>
</form>
간단한 from
태그를 통해 GET
메서드를 사용하여 adder.c
를 호출하고, 두 인자를 전달해 주도록 했다.
이후, adder.c
의 두 인자를 URL
에서 받아오는 부분을 수정하여, 전달받은 두 인자를 처리하도록 수정하였다!
p = strchr(buf, "&");
*p = "\0";
strcpy(arg1, buf);
strcpy(arg2, p+1);
adder.c
A = strchr(buf, 'A');
B = strchr(buf, 'B');
*A = '\0';
*B = '\0';
strcpy(arg1, A+2);
strcpy(arg2, B+2);
버퍼의 첫 부분과 &+1
에서 인자를 받아오던 것을 A+2
, B+2
에서 받아오도록 변경하여 해결했다.
GET
요청시 http://3.39.23.174:4000/cgi-bin/adder?A=332&B=456
와 같이 URL
이 전달되기 때문!
Tiny
를 확장하여 HTTP HEAD
메소드를 지원하도록 하라. telnet
을 통해 결과를 체크하시오.HEAD
메서드는 GET
과 동일하지만, 헤더+본문이 아닌 헤더만을 리턴받는 메서드이다.
if(strcmp(method, "GET") && strcmp(method, "HEAD"))
doit
함수 내에서 GET
뿐만이 아닌 HEAD
메서드도 에러 없이 받아들이게 수정해주고,
if (!strcmp(method, "GET")) {
srcfd = Open(filename, O_RDONLY, 0);
srcp = (char *)malloc(sizeof(filesize));
Rio_readn(srcfd, srcp, filesize);
Close(srcfd);
Rio_writen(fd, srcp, filesize);
free(srcp);
}
컨텐츠를 처리하는 부분에서 GET
메서드일 때만 본문을 처리해주도록 하였다.
HEAD
요청시 헤더만을 리턴받는 모습을 확인할 수 있다!