/**
* @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;
}