从Web服务器获取简单请求

时间:2015-01-16 21:53:17

标签: c sockets web server

我这里有一个非常简单的网络服务器(来自学校的作业)。问题是我的老师要我修复当前的问题:从我的服务器获取一个简单的请求。所以基本上他在我的终端上写了这个

$: ./wserver
^Z
[1]+  Stopped                 ./wserver
$: bg
$: nc localhost 8181
GET /
HTTP/1.0 404 Not Found

正如您所看到的,我没有得到一个简单的请求,而是来自我的服务器的错误代码。我想知道的是来自服务器的简单请求是什么?我抬头看了rfc 1945并得到了这个信息:Simple-Request =“GET”SP Request-URI CRLF

以下是我的以下代码(对不起,但我的一些printf是瑞典语,但我想你知道最新情况):

#include "funktioner.h"

#define BUFSIZE 4096
#define MAX_QUEUE 20

void start_server(struct sockaddr_in address, int *port, int *listener);
void wait_for_connection(struct sockaddr_in address, int *listener);
void handle_request(int new_socket);


//Main!
int main(int argc, char* argv[])
{
    struct sockaddr_in address;
    char *wsroot = NULL, wsroot_folder[32];
    int port;
    int daemon = 0;
    char* log_file = NULL;
    int listener;
    int lfp, efp;

    openlog ("wserver", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0);


    read_config_file(&port, wsroot_folder);

    wsroot = get_full_path(wsroot_folder);

    check_ws_root(wsroot);

    parse_arguments(argc, argv, &port, &daemon, &log_file);

    lfp = write_log(log_file, 0, NULL, NULL, NULL, 0, 0); 

    efp = get_content_type(NULL, NULL);


    chdir(wsroot);
    if(chroot(wsroot) != 0)
    {
        perror("chroot");
        exit(1);
    }
    setuid(1000);

    if(daemon)
    {
        daemonize(lfp, efp);
    }

    start_server(address, &port, &listener);

    wait_for_connection(address, &listener);

    close(listener);

    return 0;
}


void start_server(struct sockaddr_in address, int *port, int *listener)
{
    int opt = 1;

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(*port);

    *listener = socket(AF_INET, SOCK_STREAM, 0);
    setsockopt(*listener, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    bind(*listener, (struct sockaddr *) &address, sizeof(address));

    listen(*listener, MAX_QUEUE);
}

void wait_for_connection(struct sockaddr_in address, int *listener)
{
    int new_socket;
    pid_t pid;
    signal(SIGCHLD, SIG_IGN);
    int addrlen = sizeof(address);
    while(1)
    {
        new_socket = accept(*listener, (struct sockaddr*) &address, &addrlen);

        if((pid = fork()) < 0)
        {

            close(new_socket);
        }
        else if(pid == 0)
        {

            close(*listener);
            handle_request(new_socket);
            exit(0);
        }
        else
        {
            close(new_socket);
        }
    }
}


void handle_request(int new_socket)
{
    char buffer[BUFSIZE];
    char *temp = malloc(BUFSIZE);
    char *temp2 = malloc(BUFSIZE);
    char *logger_line = NULL;
    char *type = NULL;
    char *uri = NULL;
    char *httpv = NULL;
    char *rp = NULL;
    int openfile;
    int bytes_sent = 0;
    recv(new_socket, buffer, BUFSIZE, 0);


    strcpy(temp, buffer);
    type = strtok(temp, " ");             
    uri = resolve_path(strtok(NULL, " "));        
    httpv = strtok(NULL, "\r\n");             

    strcpy(temp2, buffer);
    logger_line = strtok(temp2, "\r");

    if(httpv != NULL)
    {


        if (strcmp(httpv, "HTTP/1.0") != 0 && strcmp(httpv, "HTTP/1.1") != 0)
        {
            strcpy(buffer, "HTTP/1.0 400 Bad Request\r\n");
            bytes_sent = send(new_socket, buffer, strlen(buffer), 0);
            write_log(NULL, new_socket, "-", "-", logger_line, 400, bytes_sent);
            goto closing_down;
        }
    }
    rp = realpath(uri, NULL);

    if(rp == NULL)
    {
        create_ok_header(uri, buffer);
        strcpy(buffer, "HTTP/1.0 404 Not Found\r\n");
        //strcpy(buffer, "HTTP/1.0 200 OK\r\n");
        bytes_sent = send(new_socket, buffer, strlen(buffer), 0);
        write_log(NULL, new_socket, "-", "-", logger_line, 404, bytes_sent);
        goto closing_down;
    }

    //GET requests
    if(strcmp(type, "GET") == 0)
    {
        if((openfile = open(uri, O_RDONLY)) != -1)
        {
            create_ok_header(uri, buffer);
            bytes_sent = send(new_socket, buffer, strlen(buffer), 0);
            struct stat st;
            stat(uri, &st);
            if((bytes_sent += sendfile(new_socket, openfile, NULL, (int)st.st_size)) == -1)
            {

                strcpy(buffer,"HTTP/1.0 500 Internal Server Error\r\n");
                bytes_sent = send(new_socket, buffer, strlen(buffer), 0);
                write_log(NULL, new_socket, "-", "-", logger_line, 500, bytes_sent);
            }
            else
            {
                write_log(NULL, new_socket, "-", "-", logger_line, 200, bytes_sent);
            }
        }
        else
        {

            strcpy(buffer, "HTTP/1.0 403 Forbidden\r\n");
            bytes_sent = send(new_socket, buffer, strlen(buffer), 0);
            write_log(NULL, new_socket, "-", "-", logger_line, 403, bytes_sent);
        }        
    }


    //HEAD requests
    else if(strcmp(type, "HEAD") == 0)
    {
        if((openfile = open(uri, O_RDONLY)) != -1)
        {
            create_ok_header(uri, buffer);
            bytes_sent = send(new_socket, buffer, strlen(buffer), 0);
            write_log(NULL, new_socket, "-", "-", logger_line, 200, bytes_sent);
        }
        else
        {
            strcpy(buffer, "HTTP/1.0 403 Forbidden\r\n");
            bytes_sent = send(new_socket, buffer, strlen(buffer), 0);
            write_log(NULL, new_socket, "-", "-", logger_line, 403, bytes_sent);
        }
    }
    else
    {
        strcpy(buffer, "HTTP/1.0 501 Not Implemented\r\n");
        bytes_sent = send(new_socket, buffer, strlen(buffer), 0);
        write_log(NULL, new_socket, "-", "-", logger_line, 501, bytes_sent);
    }



    closing_down:
    free(rp);
    free(temp);
    free(temp2);
    close(openfile);
    close(new_socket);
}

我的职能:

#include "funktioner.h"

void read_config_file(int *port, char *wsroot)
{
    FILE *config_file = fopen(".server-config", "r");
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    if(config_file == NULL)
    {
        exit(1);
    }

    while((read = getline(&line, &len, config_file)) != -1)
    {
        if(line[0] == '#')
        {
            continue;
        }

        if(strncmp(line, "port", 4) == 0)
        {
            sscanf(line, "%*s %d", port);
        }
        else if(strncmp(line, "root", 4) == 0)
        {
            sscanf(line, "%*s %s", wsroot);
        }
    }

    fclose(config_file);
    if(line)
    {
        free(line);
    }
}

char *get_full_path(char *folder)
{
    char *executing_directory = getenv("PWD");
    return strcat(executing_directory, folder);
}





void check_ws_root(char *wsroot)
{
    struct stat l_stat = {0};
    if (stat(wsroot, &l_stat) == -1)
    {
        mkdir(wsroot, 0700);
    }
}


void parse_arguments(int argc, char **argv, int *port, int *daemon, char **log_file)
{
    int opt;
    while((opt = getopt(argc, argv, "p:dl:")) != -1)
    {
        switch(opt)
        {
            case 'p':
                *port = atoi(optarg);
                break;
            case 'd':
                *daemon = 1;
                break;
            case 'l':
                *log_file = malloc(32*4);
                strcpy(*log_file, optarg);  
                break;
        }
    }
}

int write_log(char *file_name, int sockfd, char *ident, char *auth, char *request, int status, int bytes) 
{
    static FILE *file = NULL;
    if(file == NULL) 
    {
        if(file_name != NULL)
        {
            file = fopen(file_name, "a+");
            return fileno(file);
        }
    } 

    if(sockfd == 0) 
    {
        return;
    }

    struct sockaddr_in client;
    int c_len = sizeof(client);
    char buf[80];   




    time_t result;
    result = time(NULL);
    struct tm* brokentime = localtime(&result);
    char now[32];

    getpeername(sockfd, (struct sockaddr*)&client, &c_len);

    inet_ntop(AF_INET, (struct sockaddr*)&client.sin_addr, buf, sizeof(buf));

    strftime(now, 32, "%d/%b/%Y:%T %z", brokentime);
    if(file == NULL && file_name == NULL)
    {
        syslog(LOG_NOTICE, "%s %s %s [%s] \"%s\" %d %d \n", buf, ident, auth, now, request, status, bytes);
    }
    else
    {
        fprintf(file, "%s %s %s [%s] \"%s\" %d %d \n", buf, ident, auth, now, request, status, bytes);
        fflush(file);   
    }   

    }

void daemonize(int lfp, int efp)
{
    pid_t pid;


    umask(0);






    if((pid = fork()) < 0)
    {
        exit(1);
    }
    else if(pid > 0)
    {

        exit(0);
    }


    setsid();


    if((pid = fork()) < 0)
    {
        exit(1);
    }
    else if(pid > 0)
    {
        exit(0);
    }

    printf("Barnprocess = %d \n", getpid());
}





char *resolve_path(char *uri)
{
    if(strncmp(uri, "/\0", 2) == 0)
    {
        return "index.html";
    }
    else if(strncmp(uri, "/", 1) == 0)
    {
        return uri + 1;
    }
}



void create_ok_header(char *uri, char *buffer)
{
    char content_type[32];
    char *file_extension;
    file_extension = get_extension(uri);
    get_content_type(file_extension, content_type);
    strcpy(buffer,"HTTP/1.0 200 OK\r\nContent-Type: ");
    strcat(buffer, content_type);
    strcat(buffer, "\r\n\r\n");
}




char *get_extension(char *path)
{
    char *dot = strrchr(path, '.');
    if(!dot || dot == path)
    {
        return "";
    }
    return dot + 1;
}




int get_content_type(char *extension, char *content_type)
{
    static FILE *extension_file;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;

    if(extension == NULL)
    {
        extension_file = fopen("supported.extensions", "r");
        return fileno(extension_file);
    }
    else
    {
        while((read = getline(&line, &len, extension_file)) != -1)
        {
            if(line[0] == '#')
            {
                continue;
            }

            if(strncmp(line, extension, strlen(extension)) == 0) 
            {
                sscanf(line, "%*s %s", content_type); 
                break;
            }
        }
        rewind(extension_file);
    }
    free(line);
}

对不起,如果我没有评论我的代码,但我希望你能跟进并帮助我完成最后一步,我将永远感激(除了这个小错误,我的代码完美无缺)。在此先感谢,Viktor

0 个答案:

没有答案