Files
cweb/http/http_response.c
cdricms 7b52f5de7d CGI
2024-11-19 16:28:54 +01:00

132 lines
2.8 KiB
C

#include "http_response.h"
#include "http_server.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
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;
}
}