handler.c:一个简单的http服务处理逻辑,可以查看服务器根目录的文件
/** * @file handler.c * @author your name (you@domain.com) * @brief 一个简单的http服务处理逻辑,可以查看服务器根目录的文件 * @version 0.1 * @date 2022-04-15 * * @copyright Copyright (c) 2022 * */ #include <stdio.h> #include <sys/stat.h> #include <stdlib.h> #include <unistd.h> #include "myls.c" void read_til_crnl(FILE *fin) { char buf[BUFSIZ]; while (fgets(buf, BUFSIZ, fin) != NULL && strcmp(buf, "\r\n") != 0) ; } void header(FILE *fout, char *contentType) { fprintf(fout, "HTTP/1.0 200 OK\r\n"); fprintf(fout, "Content-Type: %s;charset=utf-8\r\n", contentType); fprintf(fout, "\r\n"); } void bad_request(FILE *fout, int status, char *err) { fprintf(fout, "HTTP/1.0 %d %s\r\n", status, err); fprintf(fout, "Content-Type: text/html\r\n"); fprintf(fout, "\r\n"); fprintf(fout, "<h1>%s</h1>\r\n", err); } int not_exists(char *file) { struct stat info; return stat(file, &info) == -1; } int isdir(char *dir) { struct stat info; return stat(dir, &info) != -1 && S_ISDIR(info.st_mode); } void do_ls(FILE *fout, int connect, char *dir) { header(fout, "text/plain"); fflush(fout); ls(fout, dir); } void do_cat(FILE *fout, char *filename) { char buf[BUFSIZ]; FILE *file = fopen(filename, "r"); if (file == NULL) { perror(filename); sprintf(buf, "open file:%s fail!"); bad_request(fout, 500, buf); return; } header(fout, "text/plain"); while (fgets(buf, BUFSIZ, file)) { fputs(buf, fout); } fclose(file); } void process_req(char *request, int connect) { char cmd[BUFSIZ], arg[BUFSIZ] = "./", err[BUFSIZ]; void bad_request(FILE *, int, char *); int not_exists(char *); int isdir(char *); void do_ls(FILE *, int, char *); void do_cat(FILE *, char *); FILE *fout = fdopen(connect, "w"); if (fout == NULL) { perror("open connect to write error:"); return; } if (sscanf(request, "%s%s", cmd, arg + 2) != 2) { bad_request(fout, 500, "request error!"); } else if (strcmp(cmd, "GET") != 0) { bad_request(fout, 500, "METHOD NOT ALLOW!"); } else if (not_exists(arg)) { bad_request(fout, 404, "NOT FOUND!"); } else if (isdir(arg)) { do_ls(fout, connect, arg); } else { do_cat(fout, arg); } fclose(fout); } void *handle_call(void *arg) { int *fd = (int *)arg; int connect = *fd; // free(arg); char request[BUFSIZ]; FILE *fin = fdopen(connect, "r"); if (fin == NULL) { perror("open connect error:"); return NULL; } fgets(request, BUFSIZ, fin); printf("fd:%d request = %s\n", connect, request); read_til_crnl(fin); process_req(request, connect); fclose(fin); close(connect); return NULL; }