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;
}

 

posted @ 2022-04-15 14:12  风的低吟  阅读(129)  评论(0编辑  收藏  举报