#include "http_server.h" #include "http_content_type.h" #include "http_request.h" #include "http_response.h" #include "http_status.h" #include #include #include #include #include HttpServerRunStatus http_server_setup(HttpServer *s) { int opt = 1; s->pid = 0; if ((s->server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return HTTP_SRS_SOCKET_FAILED; if (setsockopt(s->server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) return HTTP_SRS_SETSOCKOPT_FAILED; if (s->address == NULL) { printf("Setting server address\n"); s->address = malloc(sizeof(*s->address)); s->address->sin_family = AF_INET; s->address->sin_addr.s_addr = INADDR_ANY; s->address->sin_port = htons(s->port); } if (bind(s->server_fd, (struct sockaddr *)s->address, sizeof(*s->address)) < 0) return HTTP_SRS_BIND_FAILED; if (listen(s->server_fd, s->backlog) < 0) return HTTP_SRS_LISTEN_FAILED; return HTTP_SRS_SETUP; } HttpServerRunStatus http_server_run(HttpServer *s) { int client_fd; ssize_t valread; socklen_t addrlen = sizeof(*s->address); if ((client_fd = accept(s->server_fd, (struct sockaddr *)s->address, &addrlen)) < 0) return HTTP_SRS_ACCEPT_FAILED; // Après chaque acceptation, nous créons un processus enfant pour gérer la // requête, afin de pouvoir répondre à plusieurs requêtes simultanément. s->pid = fork(); if (s->pid < 0) { return HTTP_SRS_FORK_FAILED; } if (s->pid == 0) { char request[BUFSIZ] = {0}; if ((valread = recv(client_fd, request, 1024 - 1, MSG_PEEK)) < 0) exit(HTTP_SRS_READ_FAILED); // L'objectif est de parser la requête dans une structure afin de non // seulement récuperer les informations utiles, mais aussi pour les // manipuler aisément. HttpRequest *req = handle_request(request); if (req == NULL) exit(HTTP_SRS_HANDLE_REQUEST_FAILED); HttpResponse *res; // Si le chemin est la racine, nous retournons le fichier par défaut // HTML. if (!strcmp(req->path, "/")) { res = from_file("./" DEFAULT_HTML); } // Si on cherche à faire tourner un script python, nous pouvons le faire // en allant à http://:/cgi/