From d1f114b8878cfcb47392ab6304f0af1e51f67a24 Mon Sep 17 00:00:00 2001
From: nicolas-arnaud
Date: Thu, 10 Nov 2022 21:15:45 +0100
Subject: [PATCH] cgi
---
default.json | 4 ++-
includes/Route.hpp | 7 ++--
includes/webserv.hpp | 2 ++
public/testsite/basique.html | 1 +
public/testsite/index.php | 8 +++++
srcs/load/Route.cpp | 6 ++++
srcs/load/Socket.cpp | 62 ++++++++++++++++++++++++++----------
srcs/tools.cpp | 10 ++++--
8 files changed, 78 insertions(+), 22 deletions(-)
create mode 100644 public/testsite/index.php
diff --git a/default.json b/default.json
index 3674d70..f623e18 100644
--- a/default.json
+++ b/default.json
@@ -13,7 +13,9 @@
"listens": ["192.168.62.61:8080", "localhost", "555"],
"root": "public/testsite",
"indexs": ["basique.html"],
- "cgi": "cgi.sh",
+ "cgi": {
+ ".php": "/usr/bin/php-cgi"
+ },
"locations":
{
"docs/":
diff --git a/includes/Route.hpp b/includes/Route.hpp
index ed39f74..195863f 100644
--- a/includes/Route.hpp
+++ b/includes/Route.hpp
@@ -7,11 +7,13 @@ class Route {
string _location;
string _root;
string _ret;
- std::vector _indexs;
- std::vector _headers;
bool _autoindex;
public:
+ std::vector _indexs;
+ std::vector _headers;
+ std::map _cgi;
+
Route(Server *server, string location, JSONNode *datas);
~Route(void);
string getLocation(void);
@@ -22,4 +24,5 @@ class Route {
Server *getServer(void);
string getIndex(string uri, string path);
string correctUri(string uri);
+ friend class Socket;
};
diff --git a/includes/webserv.hpp b/includes/webserv.hpp
index 833fd32..6f032ce 100644
--- a/includes/webserv.hpp
+++ b/includes/webserv.hpp
@@ -8,6 +8,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -50,6 +51,7 @@ bool isInt(string str);
std::vector split(string str, char delim);
listen_t get_listen_t(string listen);
string getMime(string path);
+string get_extension(string str);
string read_file(string path);
#include "Nodes.hpp"
diff --git a/public/testsite/basique.html b/public/testsite/basique.html
index 9336073..01c7c94 100644
--- a/public/testsite/basique.html
+++ b/public/testsite/basique.html
@@ -26,6 +26,7 @@
'; ?>
+
+
diff --git a/srcs/load/Route.cpp b/srcs/load/Route.cpp
index 0134fa7..db983bb 100644
--- a/srcs/load/Route.cpp
+++ b/srcs/load/Route.cpp
@@ -23,6 +23,12 @@ Route::Route(Server *server, string location, JSONNode *datas)
_headers.push_back((*it)->str());
}
}
+ if ((tmp = object["cgi"])) {
+ JSONObject cgis = tmp->obj();
+ for (JSONObject::iterator it = cgis.begin(); it != cgis.end(); it++) {
+ _cgi[(*it).first] = (*it).second->str();
+ }
+ }
}
Route::~Route(void) {}
diff --git a/srcs/load/Socket.cpp b/srcs/load/Socket.cpp
index 3d17ba7..5fc94da 100644
--- a/srcs/load/Socket.cpp
+++ b/srcs/load/Socket.cpp
@@ -216,29 +216,57 @@ int Socket::answer(Env *env) {
string method = _request["Method:"].at(0);
std::vector allowed;
if (method != "GET" && method != "POST" && method != "DELETE")
- send_answer(
- "HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
- else if ((allowed = route->getHeadersLst()).size() > 0) {
+ send_answer("HTTP/1.1 405 Method Not Allowed\r\n\r\n");
+ else if ((allowed = route->_headers).size() > 0) {
if (std::find(allowed.begin(), allowed.end(), method) == allowed.end())
- send_answer(
- "HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
- } else if ((allowed = server->getHeadersLst()).size() > 0) {
+ send_answer("HTTP/1.1 405 Method Not Allowed\r\n\r\n");
+ } else if ((allowed = server->_headers).size() > 0) {
if (std::find(allowed.begin(), allowed.end(), method) == allowed.end())
- send_answer(
- "HTTP/1.1 405 Method Not Allowed\r\nContent-length: 0\r\n\r\n");
+ send_answer("HTTP/1.1 405 Method Not Allowed\r\n\r\n");
}
string path = route->correctUri(_request["Method:"].at(1));
cout << "Path: " << path << "\n";
- ret = route->getIndex(_request["Method:"].at(1), path);
- if (ret == "") {
- cout << "No index: lf file\n";
- ret = read_file(path);
- }
- answer << (ret == "" ? " 404 Not Found\r\nContent-length: 0\r\n\r\n"
- : " 200 OK\r\n")
- << ret;
- cout << "|===|Answer|===|\n" << answer.str() << "|===|End of answer|===|\n";
+ string cgi;
+ if (route->_cgi.size())
+ cgi = route->_cgi[get_extension(path)];
+ cout << "Cgi:" << cgi << "\n";
+ if (cgi != "") {
+ int status;
+ int fd[2];
+ pipe(fd);
+ int pid = fork();
+ if (pid == 0) {
+ const char **args = new const char *[cgi.length() + path.length() + 2];
+ args[0] = cgi.c_str();
+ args[1] = path.c_str();
+ args[2] = NULL;
+ dup2(fd[1], STDOUT_FILENO);
+ close(fd[1]);
+ close(fd[0]);
+ execve(cgi.c_str(), (char **)args, NULL);
+ }
+ close(fd[1]);
+ waitpid(pid, &status, 0);
+ cout << "Cgi finished\n";
+ char buffer[10000];
+ size_t len = read(fd[0], buffer, 10000);
+ buffer[len] = 0;
+ ret = string(buffer);
+ len = ret.length() - ret.find("\r\n\r\n") - 4;
+ answer << " 200 OK\r\nContent-length: " << len << "\r\n";
+ answer << ret;
+ } else {
+ ret = route->getIndex(_request["Method:"].at(1), path);
+ if (ret == "") {
+ cout << "No index: lf file\n";
+ ret = read_file(path);
+ }
+ answer << (ret == "" ? " 404 Not Found\r\nContent-length: 0\r\n\r\n"
+ : " 200 OK\r\n")
+ << ret;
+ }
+ cout << "|===|Answer|===|\n" << answer.str() << "|===|End of answer|===|\n";
send_answer(answer.str());
_content = "";
_header = "";
diff --git a/srcs/tools.cpp b/srcs/tools.cpp
index 210a72d..687ec54 100644
--- a/srcs/tools.cpp
+++ b/srcs/tools.cpp
@@ -22,9 +22,8 @@ std::vector split(string str, char delim) {
std::vector tokens;
std::string token;
std::stringstream ss(str);
- while (getline(ss, token, delim)) {
+ while (getline(ss, token, delim))
tokens.push_back(token);
- }
return tokens;
}
@@ -210,6 +209,13 @@ string getMime(string path) {
return ("text/plain");
}
+string get_extension(string str) {
+ int dot_pos = str.rfind('.');
+ string ret = str.substr(dot_pos);
+ cout << ret << "\n";
+ return ret;
+}
+
string read_file(string path) {
string str;
string content;