script path is found and fill
This commit is contained in:
38
README.md
38
README.md
@@ -2,6 +2,9 @@
|
|||||||
## work together
|
## work together
|
||||||
#### questions
|
#### questions
|
||||||
- in client.cpp i fill the port, is there a default one in case it's not in the request ?
|
- 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 ?
|
||||||
|
|
||||||
#### notifications
|
#### notifications
|
||||||
- i changed the Client getters in two categories :
|
- i changed the Client getters in two categories :
|
||||||
@@ -13,24 +16,6 @@
|
|||||||
- add `query` (ex. var=val)
|
- add `query` (ex. var=val)
|
||||||
- the header fields names, as key in map, are stored in lowercase, and getters are case-insensitives
|
- the header fields names, as key in map, are stored in lowercase, and getters are case-insensitives
|
||||||
|
|
||||||
#### share knowledge
|
|
||||||
##### cgi
|
|
||||||
- the cgi-script will send back at least one header field followed by an empty line
|
|
||||||
- this header field will be one of three :
|
|
||||||
- "Content-Type"
|
|
||||||
- "Location"
|
|
||||||
- "Status"
|
|
||||||
- the cgi-script may send back more header fields
|
|
||||||
- the server must check and modify few things :
|
|
||||||
- there is no duplicate in headers fields (if there is, resolve conflict)
|
|
||||||
- there is no space between the field name and the ":"
|
|
||||||
- the newlines are of form "\r\n", and not "\n" only
|
|
||||||
- if the location field is not present, then if the status field is not present either, then the status code is 200
|
|
||||||
- the cgi-script can return a location field, of two types :
|
|
||||||
- local redirection : start with a "/", the server must answer as if this was the request uri
|
|
||||||
- client redirection : start with <name-of-cheme>":", the server must send back a status 302 with this uri to the client
|
|
||||||
- to pass the body-message to the cgi-script, we write it into the temporary fd on which the script read it's standard input
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
## man
|
## man
|
||||||
@@ -110,6 +95,23 @@
|
|||||||
## cgi rfc
|
## cgi rfc
|
||||||
[rfc 3875](https://www.rfc-editor.org/rfc/rfc3875)
|
[rfc 3875](https://www.rfc-editor.org/rfc/rfc3875)
|
||||||
|
|
||||||
|
#### summary :
|
||||||
|
- the cgi-script will send back at least one header field followed by an empty line
|
||||||
|
- this header field will be one of three :
|
||||||
|
- "Content-Type"
|
||||||
|
- "Location"
|
||||||
|
- "Status"
|
||||||
|
- the cgi-script may send back more header fields
|
||||||
|
- the server must check and modify few things :
|
||||||
|
- there is no duplicate in headers fields (if there is, resolve conflict)
|
||||||
|
- there is no space between the field name and the ":"
|
||||||
|
- the newlines are of form "\r\n", and not "\n" only
|
||||||
|
- if the location field is not present, then if the status field is not present either, then the status code is 200
|
||||||
|
- the cgi-script can return a location field, of two types :
|
||||||
|
- local redirection : start with a "/", the server must answer as if this was the request uri
|
||||||
|
- client redirection : start with <name-of-cheme>":", the server must send back a status 302 with this uri to the client
|
||||||
|
- to pass the body-message to the cgi-script, we write it into the temporary fd on which the script read it's standard input
|
||||||
|
|
||||||
[3.1: server responsabilities](https://www.rfc-editor.org/rfc/rfc3875#section-3.1)
|
[3.1: server responsabilities](https://www.rfc-editor.org/rfc/rfc3875#section-3.1)
|
||||||
|
|
||||||
- The server [...] receives the request from the client
|
- The server [...] receives the request from the client
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ std::cout << "\n"
|
|||||||
<< "request:\n" << raw_request
|
<< "request:\n" << raw_request
|
||||||
<< "START _______________________\n\n"
|
<< "START _______________________\n\n"
|
||||||
<< raw_request
|
<< raw_request
|
||||||
|
<< "\nSCRIPT PATH _________________\n"
|
||||||
|
<< "\npath:" << _request.script.path
|
||||||
|
<< "\npath_info:" << _request.script.info
|
||||||
<< "\n END _______________________\n";
|
<< "\n END _______________________\n";
|
||||||
|
|
||||||
pos = (raw_request).find(CRLF CRLF);
|
pos = (raw_request).find(CRLF CRLF);
|
||||||
@@ -92,6 +95,24 @@ std::cout << "\n"
|
|||||||
// add "raw_request.clear()" after parsing ? for little less memory usage ?
|
// add "raw_request.clear()" after parsing ? for little less memory usage ?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::fill_script_path(std::string script)
|
||||||
|
{
|
||||||
|
size_t pos;
|
||||||
|
int len = script.size();
|
||||||
|
std::string path = this->get_rq_abs_path();
|
||||||
|
std::string tmp;
|
||||||
|
|
||||||
|
pos = path.find(script);
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
tmp = path.substr(0, pos + len);
|
||||||
|
_request.script.path = "./srcs/cgi-bin" + tmp; // TODO: deal with cgi path
|
||||||
|
_request.script.info = path.substr(pos + len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Client::clear()
|
void Client::clear()
|
||||||
{
|
{
|
||||||
clear_request();
|
clear_request();
|
||||||
@@ -103,6 +124,7 @@ void Client::clear()
|
|||||||
|
|
||||||
void Client::clear_request()
|
void Client::clear_request()
|
||||||
{
|
{
|
||||||
|
clear_script();
|
||||||
_request.method = UNKNOWN;
|
_request.method = UNKNOWN;
|
||||||
_request.uri.clear();
|
_request.uri.clear();
|
||||||
_request.version.clear();
|
_request.version.clear();
|
||||||
@@ -114,6 +136,12 @@ void Client::clear_request()
|
|||||||
_request.hostname.clear();
|
_request.hostname.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::clear_script()
|
||||||
|
{
|
||||||
|
_request.script.path.clear();
|
||||||
|
_request.script.info.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
* GETTERS
|
* GETTERS
|
||||||
@@ -136,8 +164,17 @@ std::string Client::get_rq_version() const { return _request.version; }
|
|||||||
std::string Client::get_rq_body() const { return _request.body; }
|
std::string Client::get_rq_body() const { return _request.body; }
|
||||||
std::string Client::get_rq_port() const { return _request.port; }
|
std::string Client::get_rq_port() const { return _request.port; }
|
||||||
std::string Client::get_rq_hostname() const { return _request.hostname; }
|
std::string Client::get_rq_hostname() const { return _request.hostname; }
|
||||||
|
std::string Client::get_rq_script_path()const { return _request.script.path; }
|
||||||
|
std::string Client::get_rq_script_info()const { return _request.script.info; }
|
||||||
std::string Client::get_rq_headers(const std::string & key) const
|
std::string Client::get_rq_headers(const std::string & key) const
|
||||||
{ return _request.headers.find(::str_tolower(key))->second; }
|
{
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
|
||||||
|
it = _request.headers.find(::str_tolower(key));
|
||||||
|
if (it == _request.headers.end())
|
||||||
|
return "";
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
@@ -159,9 +196,7 @@ void Client::_parse_request_line( std::string rline )
|
|||||||
tmp = ::trim(sline[0], ' ');
|
tmp = ::trim(sline[0], ' ');
|
||||||
tmp = ::trim(tmp, '\r');
|
tmp = ::trim(tmp, '\r');
|
||||||
_request.method = str_to_http_method(tmp);
|
_request.method = str_to_http_method(tmp);
|
||||||
// TODO uri in request_line
|
// uri
|
||||||
// https://www.rfc-editor.org/rfc/rfc7230#section-5.3
|
|
||||||
// https://stackoverflow.com/questions/40311306/when-is-absoluteuri-used-from-the-http-request-specs
|
|
||||||
tmp = ::trim(sline[1], ' ');
|
tmp = ::trim(sline[1], ' ');
|
||||||
tmp = ::trim(tmp, '\r');
|
tmp = ::trim(tmp, '\r');
|
||||||
_request.uri = tmp;
|
_request.uri = tmp;
|
||||||
|
|||||||
@@ -11,6 +11,12 @@
|
|||||||
# include <netinet/in.h> // sockaddr_in, struct in_addr
|
# include <netinet/in.h> // sockaddr_in, struct in_addr
|
||||||
# include <arpa/inet.h> // htonl, htons, ntohl, ntohs, inet_addr, inet_ntoa
|
# include <arpa/inet.h> // htonl, htons, ntohl, ntohs, inet_addr, inet_ntoa
|
||||||
|
|
||||||
|
struct Script
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
std::string info;
|
||||||
|
};
|
||||||
|
|
||||||
struct Request
|
struct Request
|
||||||
{
|
{
|
||||||
http_method method;
|
http_method method;
|
||||||
@@ -22,6 +28,7 @@ struct Request
|
|||||||
std::string body;
|
std::string body;
|
||||||
std::string port;
|
std::string port;
|
||||||
std::string hostname;
|
std::string hostname;
|
||||||
|
struct Script script;
|
||||||
};
|
};
|
||||||
|
|
||||||
# define MAX_FILESIZE 1000000 // (1Mo)
|
# define MAX_FILESIZE 1000000 // (1Mo)
|
||||||
@@ -56,11 +63,15 @@ class Client
|
|||||||
std::string get_rq_body() const;
|
std::string get_rq_body() const;
|
||||||
std::string get_rq_port() const;
|
std::string get_rq_port() const;
|
||||||
std::string get_rq_hostname() const;
|
std::string get_rq_hostname() const;
|
||||||
|
std::string get_rq_script_path() const;
|
||||||
|
std::string get_rq_script_info() const;
|
||||||
std::string get_rq_headers(const std::string & key) const;
|
std::string get_rq_headers(const std::string & key) const;
|
||||||
|
|
||||||
void parse_request();
|
void parse_request();
|
||||||
void clear();
|
void clear();
|
||||||
void clear_request();
|
void clear_request();
|
||||||
|
void clear_script();
|
||||||
|
bool fill_script_path(std::string script);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _fd;
|
int _fd;
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ class Webserv
|
|||||||
void _construct_client(Client *client);
|
void _construct_client(Client *client);
|
||||||
char** _set_env(Client *client);
|
char** _set_env(Client *client);
|
||||||
char* _dup_env(std::string var, std::string val);
|
char* _dup_env(std::string var, std::string val);
|
||||||
|
char* _dup_env(std::string var, int i);
|
||||||
void _exec_script(Client *client, char **env);
|
void _exec_script(Client *client, char **env);
|
||||||
// epoll_update.cpp
|
// epoll_update.cpp
|
||||||
int _epoll_update(int fd, uint32_t events, int op);
|
int _epoll_update(int fd, uint32_t events, int op);
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
|
|
||||||
bool Webserv::_is_cgi(Client *client)
|
bool Webserv::_is_cgi(Client *client)
|
||||||
{
|
{
|
||||||
// TMP
|
// TODO see how it works with config
|
||||||
if (client->get_rq_abs_path().find("/cgi-bin") != std::string::npos)
|
if (client->fill_script_path("php-cgi"))
|
||||||
|
return true;
|
||||||
|
if (client->fill_script_path("cgi_cpp.cgi"))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -26,16 +28,26 @@ char* Webserv::_dup_env(std::string var, std::string val = "")
|
|||||||
return ( strdup(str.c_str()) );
|
return ( strdup(str.c_str()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* Webserv::_dup_env(std::string var, int i)
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
std::string val;
|
||||||
|
|
||||||
|
val = ::itos(i);
|
||||||
|
str = var + "=" + val;
|
||||||
|
return ( strdup(str.c_str()) );
|
||||||
|
}
|
||||||
|
|
||||||
char** Webserv::_set_env(Client *client)
|
char** Webserv::_set_env(Client *client)
|
||||||
{
|
{
|
||||||
char** env = new char*[19];
|
char** env = new char*[19];
|
||||||
|
|
||||||
env[0] = _dup_env("AUTH_TYPE");
|
env[0] = _dup_env("AUTH_TYPE"); // authentification not supported
|
||||||
env[1] = _dup_env("CONTENT_LENGTH" , "665");
|
env[1] = _dup_env("CONTENT_LENGTH" , client->get_rq_body().size());
|
||||||
env[2] = _dup_env("CONTENT_TYPE");
|
env[2] = _dup_env("CONTENT_TYPE" , client->get_rq_headers("Content-Type"));
|
||||||
env[3] = _dup_env("GATEWAY_INTERFACE");
|
env[3] = _dup_env("GATEWAY_INTERFACE" , "CGI/1.0");
|
||||||
env[4] = _dup_env("PATH_INFO");
|
env[4] = _dup_env("PATH_INFO" , client->get_rq_script_info());
|
||||||
env[5] = _dup_env("PATH_TRANSLATED");
|
env[5] = _dup_env("PATH_TRANSLATED"); // not supported
|
||||||
env[6] = _dup_env("QUERY_STRING" , client->get_rq_query());
|
env[6] = _dup_env("QUERY_STRING" , client->get_rq_query());
|
||||||
env[7] = _dup_env("REMOTE_ADDR" , client->get_cl_ip());
|
env[7] = _dup_env("REMOTE_ADDR" , client->get_cl_ip());
|
||||||
env[8] = _dup_env("REMOTE_HOST" , client->get_rq_headers("Host")); // just test
|
env[8] = _dup_env("REMOTE_HOST" , client->get_rq_headers("Host")); // just test
|
||||||
@@ -65,8 +77,7 @@ void Webserv::_exec_script(Client *client, char **env)
|
|||||||
if (fork() == 0)
|
if (fork() == 0)
|
||||||
{
|
{
|
||||||
dup2(client->get_cl_fd(), STDOUT_FILENO);
|
dup2(client->get_cl_fd(), STDOUT_FILENO);
|
||||||
// execve("./srcs/cgi-bin/cgi_cpp.cgi", nll, client->env);
|
execve(client->get_rq_script_path().c_str(), nll, env);
|
||||||
execve("./srcs/cgi-bin/php-cgi", nll, env);
|
|
||||||
}
|
}
|
||||||
// inside parent process
|
// inside parent process
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user