

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.cA = 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요청시 헤더만을 리턴받는 모습을 확인할 수 있다!