#include "http_response.h" #include "http_server.h" #include #include #include #include #include #include bool construct_response(HttpResponse __res, char *out) { unsigned long length; if ((length = strlen(__res.body)) > __res.content_length) { fprintf(stderr, "[ERROR] %s: %lu > %lu", "The size of the body is greater than what was set in " "content_length.", length, __res.content_length); return false; } // char status_message[256]; // http_status_message(__res.status_code, status_message, 256); char content_type[256]; http_content_type(__res.content_type, content_type, 256); sprintf(out, "HTTP/1.1 %d\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n%s", __res.status_code, content_type, __res.content_length, __res.body); return true; } void http_respond(HttpResponse *__res, int clientfd) { if (__res == NULL) return; char response[BUFSIZ]; // TODO: Handle return construct_response(*__res, response); send(clientfd, response, strlen(response), MSG_EOR); } char *read_file(const char *__path) { // If the file does not exist if (access(__path, F_OK) != 0) { return NULL; } FILE *f = fopen(__path, "r"); if (f == NULL) { return NULL; } // Get the length of the file fseek(f, 0, SEEK_END); size_t length = ftell(f); rewind(f); // Initialize a value to get the content char *content = malloc(length * sizeof(char)); if (content == NULL) { fclose(f); return NULL; } // Read the file into content and set the last char to \0 size_t bytesRead = fread(content, sizeof(char), length, f); content[bytesRead] = 0; fclose(f); return content; } HttpResponse *from_file(const char *__path) { char *content = read_file(__path); if (content == NULL) return NULL; HttpResponse response = { .status_code = HTTP_OK, .content_length = strlen(content), .content_type = HTTP_CT_HTML, .body = content, .body_in_heap = true, }; HttpResponse *res = malloc(sizeof(response)); *res = response; return res; } void free_response(HttpResponse *__res) { if (__res->body != NULL && __res->body_in_heap) free(__res->body); free(__res); } HttpServerRunStatus cgi(const char *__path, int clientfd) { pid_t pid; pid = fork(); // Create a child process if (pid < 0) { // Error handling for fork failure perror("fork failed"); return HTTP_SRS_FORK_FAILED; } if (pid == 0) { // Redirect standard input to read from the pipe if (dup2(clientfd, STDOUT_FILENO) == -1) { perror("dup2"); exit(EXIT_FAILURE); } // Close the read end of the pipe (it's no longer needed after // redirection) char path[1024] = {0}; sprintf(path, ".%s", __path); execl("/usr/bin/python3", "python3", path, NULL); perror("Exec failed"); exit(EXIT_FAILURE); } else { wait(NULL); close(clientfd); return HTTP_SRS_RUNNING; } }