From 7b52f5de7d7a4c1f20231692935d261a32115310 Mon Sep 17 00:00:00 2001
From: cdricms <36056008+cdricms@users.noreply.github.com>
Date: Tue, 19 Nov 2024 16:28:54 +0100
Subject: [PATCH] CGI
---
.gitignore | 1 +
cgi/hello.py | 9 ++++++++
http/http_response.c | 51 +++++++++++++++++++++++++++++++++++---------
http/http_response.h | 3 +++
http/http_server.c | 33 +++++++++++++---------------
http/http_server.h | 3 ++-
main.c | 4 ----
7 files changed, 71 insertions(+), 33 deletions(-)
create mode 100644 cgi/hello.py
diff --git a/.gitignore b/.gitignore
index 43ebf64..95d1efc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ bin
obj
*.make
Makefile
+core.*
diff --git a/cgi/hello.py b/cgi/hello.py
new file mode 100644
index 0000000..db6708b
--- /dev/null
+++ b/cgi/hello.py
@@ -0,0 +1,9 @@
+
+code = 200
+ct = "text/html"
+content = "
Bonjour!
"
+print(f"HTTP/1.1 {code}")
+print(f"Content-Type: {ct}")
+print(f"Content-Length: {len(content)}")
+print()
+print(content)
diff --git a/http/http_response.c b/http/http_response.c
index 0bb799b..dcb473e 100644
--- a/http/http_response.c
+++ b/http/http_response.c
@@ -1,6 +1,5 @@
#include "http_response.h"
-#include "http_content_type.h"
-#include "http_status.h"
+#include "http_server.h"
#include
#include
#include
@@ -18,15 +17,13 @@ bool construct_response(HttpResponse __res, char *out) {
return false;
}
- char status_message[256];
- http_status_message(__res.status_code, status_message, 256);
+ // 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 %s\r\nContent-Type: %s\r\nContent-Length: %lu\r\n\r\n%s",
- __res.status_code, status_message, content_type, __res.content_length,
- __res.body);
+ 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;
}
@@ -38,7 +35,7 @@ void http_respond(HttpResponse *__res, int clientfd) {
// TODO: Handle return
construct_response(*__res, response);
- send(clientfd, response, strlen(response), 0);
+ send(clientfd, response, strlen(response), MSG_EOR);
}
char *read_file(const char *__path) {
@@ -98,3 +95,37 @@ void free_response(HttpResponse *__res) {
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;
+ }
+}
diff --git a/http/http_response.h b/http/http_response.h
index 746cbc5..a35de32 100644
--- a/http/http_response.h
+++ b/http/http_response.h
@@ -2,9 +2,11 @@
#define HTTP_RESPONSE_H
#include "http_content_type.h"
+#include "http_server.h"
#include "http_status.h"
#include
#include
+#include
typedef struct {
HttpStatus status_code;
@@ -26,5 +28,6 @@ char *read_file(const char *__path);
// Given a path will return a HttpResponse
HttpResponse *from_file(const char *__path);
void free_response(HttpResponse *__res);
+HttpServerRunStatus cgi(const char *__path, int clientfd);
#endif
diff --git a/http/http_server.c b/http/http_server.c
index db3d192..7c3e01b 100644
--- a/http/http_server.c
+++ b/http/http_server.c
@@ -4,12 +4,12 @@
#include "http_response.h"
#include "http_status.h"
#include
-#include
-#include
#include
+#include
#include
#include
#include
+#include
#include
HttpServerRunStatus http_server_setup(HttpServer *s) {
@@ -49,19 +49,9 @@ HttpServerRunStatus http_server_run(HttpServer *s) {
accept(s->server_fd, (struct sockaddr *)s->address, &addrlen)) < 0)
return HTTP_SRS_ACCEPT_FAILED;
- pid_t pid = fork();
- if (pid < 0) {
- close(client_fd);
- return HTTP_SRS_FORK_FAILED;
- }
- if (pid > 0) {
- close(client_fd);
- return HTTP_SRS_WONT_HANDLE;
- }
-
char request[BUFSIZ] = {0};
- if ((valread = read(client_fd, request, 1024 - 1)) < 0)
+ if ((valread = recv(client_fd, request, 1024 - 1, MSG_PEEK)) < 0)
return HTTP_SRS_READ_FAILED;
HttpRequest *req = handle_request(request);
@@ -72,6 +62,8 @@ HttpServerRunStatus http_server_run(HttpServer *s) {
if (!strcmp(req->path, "/")) {
res = from_file("./" DEFAULT_HTML);
+ } else if (!strncmp(req->path, "/cgi/", strlen("/cgi/"))) {
+ return cgi(req->path, client_fd);
} else {
char path[] = ".";
strcat(path, req->path);
@@ -80,12 +72,18 @@ HttpServerRunStatus http_server_run(HttpServer *s) {
// print_request(req);
// free_request(req);
if (res == NULL) {
+ char *body = malloc(sizeof(char) * 128);
+ body = "404 Not "
+ "Found
";
HttpResponse __res = {
.status_code = HTTP_NOT_FOUND,
- .body = "",
- .content_type = HTTP_CT_PLAIN_TEXT,
- .content_length = 1,
- .body_in_heap = false,
+ .content_length = strlen(body),
+ .content_type = HTTP_CT_HTML,
+ .body = body,
+ .body_in_heap = false, // Lorsqu'on essaie de libérer le body
+ // sur cette instance, le server crash.
+ // Alors, on ne le libère pas et ça cause
+ // des memory leaks.
};
res = malloc(sizeof(__res));
*res = __res;
@@ -94,7 +92,6 @@ HttpServerRunStatus http_server_run(HttpServer *s) {
http_respond(res, client_fd);
free_response(res);
close(client_fd);
-
return HTTP_SRS_RUNNING;
}
diff --git a/http/http_server.h b/http/http_server.h
index 1db3274..629a9d8 100644
--- a/http/http_server.h
+++ b/http/http_server.h
@@ -1,7 +1,8 @@
#ifndef HTTP_SERVER_H
#define HTTP_SERVER_H
-#include
+// #include
+#include
#include
#ifndef DEFAULT_HTML
diff --git a/main.c b/main.c
index e6f8b6e..8eb9237 100644
--- a/main.c
+++ b/main.c
@@ -1,9 +1,6 @@
#include "http/http_server.h"
-#include
#include
#include
-#include
-#include
int main() {
HttpServer server = {.port = 8080, .workers = 3};
@@ -14,7 +11,6 @@ int main() {
while ((status = http_server_run(&server)) == HTTP_SRS_RUNNING)
;
-
printf("Status: %d\n", status);
http_server_stop(&server);