--- tiny.origin.c 2017-11-09 02:57:43.651936112 +0000 +++ tiny.11.c 2017-11-09 02:57:43.651936112 +0000 @@ -7,9 +7,9 @@ void doit(int fd); void read_requesthdrs(rio_t *rp); int parse_uri(char *uri, char *filename, char *cgiargs); -void serve_static(int fd, char *filename, int filesize); +void serve_static(int fd, char *filename, int filesize, char *method); void get_filetype(char *filename, char *filetype); -void serve_dynamic(int fd, char *filename, char *cgiargs); +void serve_dynamic(int fd, char *filename, char *cgiargs, char *method); void clienterror(int fd, char *cause, char *errnum, char *shortmsg, char *longmsg); @@ -55,7 +55,7 @@ return; printf("%s", buf); sscanf(buf, "%s %s %s", method, uri, version); //line:netp:doit:parserequest - if (strcasecmp(method, "GET")) { //line:netp:doit:beginrequesterr + if (!(strcasecmp(method, "GET") == 0 || strcasecmp(method, "HEAD") == 0)) { clienterror(fd, method, "501", "Not Implemented", "Tiny does not implement this method"); return; @@ -76,7 +76,7 @@ "Tiny couldn't read the file"); return; } - serve_static(fd, filename, sbuf.st_size); //line:netp:doit:servestatic + serve_static(fd, filename, sbuf.st_size, method); //line:netp:doit:servestatic } else { /* Serve dynamic content */ if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { //line:netp:doit:executable @@ -84,7 +84,7 @@ "Tiny couldn't run the CGI program"); return; } - serve_dynamic(fd, filename, cgiargs); //line:netp:doit:servedynamic + serve_dynamic(fd, filename, cgiargs, method); //line:netp:doit:servedynamic } } @@ -136,7 +136,7 @@ /* * serve_static - copy a file back to the client */ -void serve_static(int fd, char *filename, int filesize) +void serve_static(int fd, char *filename, int filesize, char *method) { int srcfd; char *srcp, filetype[MAXLINE], buf[MAXBUF]; @@ -152,6 +152,9 @@ printf("Response headers:\n"); printf("%s", buf); + if (strcasecmp(method, "HEAD") == 0) + return; + /* Send response body to client */ srcfd = Open(filename, O_RDONLY, 0); //line:netp:servestatic:open srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmap @@ -180,7 +183,7 @@ /* * serve_dynamic - run a CGI program on behalf of the client */ -void serve_dynamic(int fd, char *filename, char *cgiargs) +void serve_dynamic(int fd, char *filename, char *cgiargs, char *method) { char buf[MAXLINE], *emptylist[] = { NULL }; @@ -193,6 +196,7 @@ if (Fork() == 0) { /* Child */ //line:netp:servedynamic:fork /* Real server would set all CGI vars here */ setenv("QUERY_STRING", cgiargs, 1); //line:netp:servedynamic:setenv + setenv("REQUEST_METHOD", method, 1); Dup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ //line:netp:servedynamic:dup2 Execve(filename, emptylist, environ); /* Run CGI program */ //line:netp:servedynamic:execve }