diff --git a/README.md b/README.md index 6bf5390..be6550c 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,24 @@ - in client.cpp i fill the port, is there a default one in case it's not in the request ? - timeout server but still works ? - path contains double "//" from `Webserv::_get()` in response.cpp -- how do we deal with cgi config default folder path or anything ? +- cgi path ? defined in config ? and root path ? : + - `Client.cpp : fill_script_path()` + - `cgi.cpp : is_cgi()` + - `cgi.cpp : set_env()` +- what if the uri contains a php file, and the config said php must be handled by cgi, but the path to this php in the uri is wrong ? + - is it ok ? `http://my_site.com/cgi-bin/php-cgi` (real path) + - is it ok ? `http://my_site.com/php-cgi` (reconstruct path ?) + - is it ok ? `http://my_site.com/something/php-cgi` (what about 'something' ?) + - is it ok ? `http://my_site.com/something/cgi-bin/php-cgi` (real path with 'something' before ? ) #### notifications - i changed the Client getters in two categories : - getters for requests infos : `get_rq_` - getters for client sides infos : `get_cl_` (such as ip of client) - i changed the variables in request struct in Client : - - `path` become `uri`....>(ex. `/path/to/file?var=val`) - - add `abs_path`............>(ex. `/path/to/file `) - - add `query`................>(ex. ` var=val`) + - `path` become `uri` (ex. `/path/to/file?var=val`) + - add `abs_path` (ex. `/path/to/file` ) + - add `query` (ex. `var=val`) - the header fields names, as key in map, are stored in lowercase, and getters are case-insensitives diff --git a/srcs/Client.cpp b/srcs/Client.cpp index 321df1e..010cf2c 100644 --- a/srcs/Client.cpp +++ b/srcs/Client.cpp @@ -43,7 +43,7 @@ Client::Client( Client const & src ) { raw_request = src.raw_request; response = src.response; -// buf = strdup(src.buf); +// buf = strdup(src.buf); // TODO: this doesn't work body_size = src.body_size; status = src.status; return; @@ -75,14 +75,9 @@ void Client::parse_request() size_t pos; // DEBUG -std::cout << "\n" - << "request:\n" << raw_request - << "START _______________________\n\n" +std::cout << "\nREQUEST _____________________\n" << raw_request - << "\nSCRIPT PATH _________________\n" - << "\npath:" << _request.script.path - << "\npath_info:" << _request.script.info - << "\n END _______________________\n"; + << "\n\n"; pos = (raw_request).find(CRLF CRLF); sub = (raw_request).substr(0, pos); @@ -92,7 +87,7 @@ std::cout << "\n" _parse_request_headers(list); _parse_request_body(pos + 4); _parse_port_hostname(this->get_rq_headers("Host")); - // add "raw_request.clear()" after parsing ? for little less memory usage ? + raw_request.clear(); } bool Client::fill_script_path(std::string script) @@ -103,10 +98,10 @@ bool Client::fill_script_path(std::string script) std::string tmp; pos = path.find(script); - if (pos != std::string::npos) + if (pos == 0) { tmp = path.substr(0, pos + len); - _request.script.path = "./srcs/cgi-bin" + tmp; // TODO: deal with cgi path + _request.script.path = "./srcs" + tmp; // TODO: root path ? _request.script.info = path.substr(pos + len); return true; } diff --git a/srcs/Client.hpp b/srcs/Client.hpp index 9d57934..539a29b 100644 --- a/srcs/Client.hpp +++ b/srcs/Client.hpp @@ -74,9 +74,9 @@ class Client bool fill_script_path(std::string script); private: - int _fd; - std::string _port; - std::string _ip; + const int _fd; + const std::string _port; + const std::string _ip; listen_socket * _lsocket; struct Request _request; diff --git a/srcs/webserv/cgi_script.cpp b/srcs/webserv/cgi_script.cpp index 662094d..cc4d836 100644 --- a/srcs/webserv/cgi_script.cpp +++ b/srcs/webserv/cgi_script.cpp @@ -4,9 +4,9 @@ bool Webserv::_is_cgi(Client *client) { // TODO see how it works with config - if (client->fill_script_path("php-cgi")) + if (client->fill_script_path("/cgi-bin/php-cgi")) return true; - if (client->fill_script_path("cgi_cpp.cgi")) + if (client->fill_script_path("/cgi-bin/cgi_cpp.cgi")) return true; return false; } @@ -18,6 +18,10 @@ void Webserv::_exec_cgi(Client *client) env = _set_env(client); _exec_script(client, env); // _construct_response(client); + + for (size_t i = 0; env[i]; i++) + delete[] env[i]; + delete[] env; } char* Webserv::_dup_env(std::string var, std::string val = "") @@ -54,8 +58,7 @@ char** Webserv::_set_env(Client *client) env[9] = _dup_env("REMOTE_IDENT"); // authentification not supported env[10] = _dup_env("REMOTE_USER"); // authentification not supported env[11] = _dup_env("REQUEST_METHOD" , client->get_rq_method_str()); - env[12] = _dup_env("SCRIPT_NAME"); // TODO: define (https://www.rfc-editor.org/rfc/rfc3875#section-4.1.13 - // ,https://www.rfc-editor.org/rfc/rfc3875#section-8.2) + env[12] = _dup_env("SCRIPT_NAME" , client->get_rq_script_path()); env[13] = _dup_env("SERVER_NAME" , client->get_rq_hostname()); env[14] = _dup_env("SERVER_PORT" , client->get_rq_port()); env[15] = _dup_env("SERVER_PROTOCOL" , client->get_rq_version()); @@ -70,45 +73,82 @@ void Webserv::_exec_script(Client *client, char **env) { #define RD 0 #define WR 1 - #define BUF_SIZE 10 + #define CGI_BUF_SIZE 10 - char buf[BUF_SIZE]; - int fd_in[2]; - int fd_out[2]; - char * const * nll = NULL; - std::string response; - std::string body = client->get_rq_body(); +/*1*/ #define FD_WR_TO_CHLD fd_in[WR] +/* */ #define FD_WR_TO_PRNT fd_out[WR] +/* */ #define FD_RD_FR_CHLD fd_out[RD] +/* */ #define FD_RD_FR_PRNT fd_in[RD] +/*2*/// #define FD_WR_TO_CHLD fdIn +/* */// #define FD_WR_TO_PRNT fdOut +/* */// #define FD_RD_FR_CHLD fdOut +/* */// #define FD_RD_FR_PRNT fdIn - pipe(fd_in); - pipe(fd_out); - if (fork() == 0) + pid_t pid; + char buf[CGI_BUF_SIZE]; // WIP define buffer + char * const * nll = NULL; + std::string response; + std::string body = client->get_rq_body(); + +/*1*/ int fd_in[2]; +/* */ int fd_out[2]; +/*2*/// FILE *fIn; +/* */// FILE *fOut; +/* */// long fdIn; +/* */// long fdOut; + +/*1*/ pipe(fd_in); +/* */ pipe(fd_out); +/*2*/// fIn = tmpfile(); +/* */// fOut = tmpfile(); +/* */// fdIn = fileno(fIn); +/* */// fdOut = fileno(fOut); + + pid = fork(); + if (pid == -1) + std::cerr << "fork crashed" << std::endl; + else if (pid == 0) { - close(fd_in[WR]); - close(fd_out[RD]); - dup2(fd_in[RD], STDIN_FILENO); - dup2(fd_out[WR], STDOUT_FILENO); + +/*1*/ close(FD_WR_TO_CHLD); +/* */ close(FD_RD_FR_CHLD); +/*2*/ + + dup2(FD_RD_FR_PRNT, STDIN_FILENO); + dup2(FD_WR_TO_PRNT, STDOUT_FILENO); execve(client->get_rq_script_path().c_str(), nll, env); - std::cerr << "execve crashed\n"; + std::cerr << "execve crashed.\n"; } else { - close(fd_in[RD]); - close(fd_out[WR]); - // write to stdin of child programm - write(fd_in[WR], body.c_str(), body.size()); - close(fd_in[WR]); - waitpid(-1, NULL, 0); +/*1*/ close(FD_RD_FR_PRNT); +/* */ close(FD_WR_TO_PRNT); +/*2*/ - // read stdout of child programm - memset(buf, '\0', BUF_SIZE); - while (read(fd_out[RD], buf, BUF_SIZE) > 0) + write(FD_WR_TO_CHLD, body.c_str(), body.size()); + close(FD_WR_TO_CHLD); + waitpid(-1, NULL, 0); +/*1*/ +/*2*/// lseek(fdOut, 0, SEEK_SET); + + memset(buf, '\0', CGI_BUF_SIZE); + while (read(FD_RD_FR_CHLD, buf, CGI_BUF_SIZE - 1) > 0) { response += buf; - memset(buf, '\0', BUF_SIZE); + memset(buf, '\0', CGI_BUF_SIZE); } } if (response.empty()) - response += "Status: 500\r\n\r\n"; + response = "Status: 500\r\n\r\n"; + +/*1*/ +/*2*/// fclose(fIn); +/* */// fclose(fOut); +/* */// close(fdIn); +/* */// close(fdOut); + +// DEBUG +std::cout << "\n______response________\n" << response << "\n________________________\n"; // TODO: see how this must be handled client->response += response; } diff --git a/srcs/webserv/response.cpp b/srcs/webserv/response.cpp index 151eb59..261b959 100644 --- a/srcs/webserv/response.cpp +++ b/srcs/webserv/response.cpp @@ -147,6 +147,12 @@ void Webserv::_get(Client *client, ServerConfig &server, LocationConfig &locatio // if (_is_cgi(client)) { +// DEBUG +std::cout << "\nSCRIPT PATH _________________" + << "\npath:" << client->get_rq_script_path() + << "\npath_info:" << client->get_rq_script_info() + << "\n\n"; + _exec_cgi(client); return; }