Browse Source

save22-11-17-1

master
nicolas-arnaud 2 years ago
parent
commit
8b22bc9b5e
  1. 18
      default.json
  2. 5
      includes/Client.hpp
  3. 2
      includes/Env.hpp
  4. 2
      includes/webserv.hpp
  5. 10
      public/testsite/LICENSE
  6. 46
      public/testsite/basique.html
  7. 21
      public/testsite/index.py
  8. 10
      srcs/debug.cpp
  9. 18
      srcs/load/Env.cpp
  10. 8
      srcs/load/Route.cpp
  11. 64
      srcs/sock/Client.cpp

18
default.json

@ -1,27 +1,21 @@
{
"root_folder": "./www",
"allowed_methods": ["GET", "POST", "PUT", "DELETE"],
"servers": [
{
"server_name": "localhost",
"listens": [
"localhost:8080"
],
"listens": ["localhost:8080"],
"root": "public/",
"return": "301 https://$host$uri"
},
{
"server_name": "localhost",
"listens": [
"192.168.62.61:8080",
"localhost",
"555"
],
"listens": ["192.168.62.61:8080", "localhost", "555"],
"root": "public/testsite",
"indexs": [
"basique.html"
],
"indexs": ["basique.html"],
"cgi": {
".php": "/usr/bin/php-cgi"
".php": "/usr/bin/php",
".py": "/usr/bin/python"
},
"client_max_body_size": 10000,
"locations": {

5
includes/Client.hpp

@ -8,8 +8,9 @@ class Client {
ip_port_t _ip_port;
Master *_parent;
Server *_server;
Env *_env;
Route *_route;
string _method, _uri, _host, _header, _body;
string _method, _uri, _query, _host, _header, _body;
int _len;
bool _last_chunk;
request_t _request;
@ -25,6 +26,8 @@ class Client {
void send_error(int error_code);
void send_answer(string msg);
void print_header(void);
public:
Client(int fd, ip_port_t ip_port, Master *parent);
~Client(void);

2
includes/Env.hpp

@ -5,6 +5,8 @@ class Env {
public:
std::vector< Server * > _servers;
std::vector< Master * > _masters;
vec_string _allowed_methods;
Env(JSONNode *conf);
void cycle(void);

2
includes/webserv.hpp

@ -1,6 +1,6 @@
#pragma once
#define DEBUG 0
#define DEBUG 1
#include <arpa/inet.h>
#include <dirent.h>

10
public/testsite/LICENSE

@ -0,0 +1,10 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

46
public/testsite/basique.html

@ -12,22 +12,28 @@
<button class="first"
style="height: 50px; font-size: 20px; background-color: rgb(0, 255, 85); color: white;">CLIQUEZ ICI POUR VOIR
VOTRE CADEAU</button>
<script>
const button1 = document.querySelector('button.first');
button1.addEventListener('click', function () {
alert('PRANK hahaha, cliquez sur le bouton en bas de la page pour voir le vrai cadeau');
document.querySelector('body').innerHTML = '<button class ="second" style="position: fixed; bottom: 0; left: 0; width: 100%; height: 50px; font-size: 20px; background-color: red; color: white;">CLIQUEZ ICI POUR VOIR VOTRE VRAI CADEAU</button>';
const button2 = document.querySelector('button.second');
button2.addEventListener('click', function () {
document.querySelector('body').innerHTML = '<img src="./monkey.gif" style="width: 100%; height: 100%;">';
});
});
</script>
<ul>
<li><a href="/docs/">Documentss</a></li>
<li><a href="/img/">Images</a></li>
<li><a href="/index.php">php-cgi test</a></li>
</ul>
<h1> Query and python cgi test </h1>
<form action = "/index.py" method = "get">
First Name: <input type = "text" name = "first_name"> <br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>
<h1> File Creation test: </h1>
<form action="/" method="post" enctype="text/plain">
Filename: <input type="text" id="changeAction" />
Content: <input name="content" type="text">
<button type="submit">Create file</button>
</form>
<h1> Forms tests: </h1>
<form action="/" method="post" enctype="multipart/form-data">
<input type="text" name="description" value="form-data" />
<input type="file" name="myFile" />
@ -37,6 +43,24 @@
<input type="text" name="description" value="UrlEncode" />
<button type="submit">Submit</button>
</form>
<script>
const button1 = document.querySelector('button.first');
button1.addEventListener('click', function () {
alert('PRANK hahaha, cliquez sur le bouton en bas de la page pour voir le vrai cadeau');
document.querySelector('body').innerHTML = '<button class ="second" style="position: fixed; bottom: 0; left: 0; width: 100%; height: 50px; font-size: 20px; background-color: red; color: white;">CLIQUEZ ICI POUR VOIR VOTRE VRAI CADEAU</button>';
const button2 = document.querySelector('button.second');
button2.addEventListener('click', function () {
document.querySelector('body').innerHTML = '<img src="./monkey.gif" style="width: 100%; height: 100%;">';
});
});
const actionUpdater = document.querySelector("#changeAction");
actionUpdater.addEventListener("change", () => {
const parent = actionUpdater.parentElement;
parent.action = actionUpdater.value;
});
</script>
</body>
</html>

21
public/testsite/index.py

@ -0,0 +1,21 @@
#!/usr/bin/python
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
first_name = form.getvalue('first_name')
last_name = form.getvalue('last_name')
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Hello - Second CGI Program</title>"
print "</head>"
print "<body>"
print "<h2>Hello %s %s</h2>" % (first_name, last_name)
print "</body>"
print "</html>"

10
srcs/debug.cpp

@ -1,9 +1,19 @@
#include "webserv.hpp"
void print_block(string name, string content) {
if (!DEBUG)
return ;
string separator = "|==================================================="
"===========================|\n";
cout << name << separator.substr(name.length(), string::npos) << content
<< "\n"
<< separator;
}
void Client::print_header(void) {
cout << "Method: " << _method << "\n";
cout << "Uri: " << _uri << "\n";
cout << "Query: " << _query << "\n";
cout << "Host: " << _host << "\n";
cout << "Location: " << _route->getRoot() << "\n";
}

18
srcs/load/Env.cpp

@ -25,14 +25,26 @@ Env::~Env() {
*/
Env::Env(JSONNode *conf) {
try {
JSONList servers = conf->obj()["servers"]->lst();
for (std::vector< JSONNode * >::iterator it = servers.begin();
it < servers.end(); it++) {
JSONNode *node;
JSONList lst;
if ((node = conf->obj()["servers"]))
{
lst = conf->obj()["servers"]->lst();
for (std::vector< JSONNode * >::iterator it = lst.begin();
it < lst.end(); it++) {
Server *server = new Server(*it);
_servers.push_back(server);
std::vector< Master * > tmp_s = server->get_sockets(*it);
_masters.insert(_masters.end(), tmp_s.begin(), tmp_s.end());
}
}
if ((node = conf->obj()["allowed_methods"])) {
JSONList lst = node->lst();
for (JSONList::iterator it = lst.begin(); it < lst.end();
it++) {
_allowed_methods.push_back((*it)->str());
}
}
} catch (std::exception &e) {
std::cerr << e.what() << "\n";
}

8
srcs/load/Route.cpp

@ -14,6 +14,8 @@ Route::Route(Server *server, string location, JSONNode *datas)
: _server(server), _location(location) {
JSONObject object = datas->obj();
JSONNode *tmp;
_autoindex = false;
_client_max_body_size = -1;
if ((tmp = object["root"]))
_root = tmp->str();
if ((tmp = object["return"]))
@ -70,7 +72,8 @@ string Route::getIndex(string uri, string path) {
if ((dir = opendir(path.c_str())) == NULL) {
return "";
} else {
// cout << "get index(): path=" << path << "\n";
if (DEBUG)
cout << "get index(): path=" << path << "\n";
body << "<h3 style=\"text-align: center;\">" << path
<< " files :</h3>\n<ul>\n";
while ((entry = readdir(dir)) != NULL) {
@ -91,7 +94,8 @@ string Route::getIndex(string uri, string path) {
}
if (!_autoindex)
return "";
// cout << "Getting autoindex\n";
if (DEBUG)
cout << "Getting autoindex\n";
ret << "Content-type: text/html \r\n";
ret << "Content-length: " << body.str().length() << "\r\n";
ret << "\r\n" << body.str();

64
srcs/sock/Client.cpp

@ -27,6 +27,7 @@ void Client::clean(void) {
bool Client::getHeader(Env *env, string paquet) {
if (paquet.length() < 1)
send_error(403);
print_block("Paquet: ", paquet);
if (header_pick("Method:", 0) != "")
return getBody(paquet);
vec_string lines = split(paquet, "\r\n");
@ -40,7 +41,7 @@ bool Client::getHeader(Env *env, string paquet) {
if (_header.find("\r\n\r\n") != string::npos)
return !this->parseHeader(env)
? false
: (paquet.length() > 0 ? getBody(paquet) : true);
: (_len != 0 ? getBody(paquet) : true);
}
return false;
}
@ -50,6 +51,8 @@ bool Client::getBody(string paquet) {
vec_string::iterator it;
for (it = lines.begin(); it < lines.end(); it++) {
if (DEBUG)
cout << "Remaining length: " << _len << "\n";
if ((*it).length() && _len <= 0 &&
header_pick("Transfer-Encoding:", 0) == "chunked") {
_len = std::strtol((*it).c_str(), 0, 16) + 2;
@ -68,6 +71,8 @@ bool Client::getBody(string paquet) {
bool Client::parseHeader(Env *env) {
vec_string lines, method, line;
if (DEBUG)
cout << "Parsing header...\n";
lines = split(_header, "\r\n");
method = split(lines.at(0), " ");
_request["Method:"] = method;
@ -78,38 +83,44 @@ bool Client::parseHeader(Env *env) {
_request[line.at(0)] = vec_string(line.begin() + 1, line.end());
}
}
if ((method.at(0) == "POST" || method.at(0) == "PUT") &&
header_pick("Content-Length:", 0) == "" &&
header_pick("Transfer-Encoding:", 0) != "chunked") {
send_error(400);
return false;
}
_method = header_pick("Method:", 0);
_uri = header_pick("Method:", 1);
if ((_method == "POST" || _method == "PUT") &&
header_pick("Content-Length:", 0) == "" &&
header_pick("Transfer-Encoding:", 0) != "chunked")
return (send_error(400), false);
vec_string uri_split = split(header_pick("Method:", 1), "?");
_uri = uri_split.at(0);
if (uri_split.size() > 1)
_query = uri_split.at(1);
_host = header_pick("Host:", 0);
_env = env;
_server = _parent->choose_server(env, _host);
_route = _server->choose_route(_uri);
if (DEBUG)
print_header();
string len = header_pick("Content-Length:", 0).c_str();
if (len != "") {
_len = std::atoi(len.c_str());
_last_chunk = true;
if (_len > _route->_client_max_body_size)
int max_len = _route->_client_max_body_size >= 0 ? _route->_client_max_body_size : _server->_client_max_body_size >= 0 ? _server->_client_max_body_size : INT_MAX;
if (_len > max_len)
return (send_error(413), false);
}
} else
_len = 0;
return true;
}
bool Client::check_method(void) {
vec_string allowed;
if ((allowed = _route->_allowed_methods).size() > 0 ||
(allowed = _server->_allowed_methods).size() > 0)
if ((_route && (allowed = _route->_allowed_methods).size() > 0) ||
(_server && (allowed = _server->_allowed_methods).size() > 0) ||
((allowed = _env->_allowed_methods).size() > 0))
return std::find(allowed.begin(), allowed.end(), _method) <
allowed.end()
? true
: false;
else if (_method == "GET" || _method == "POST" || _method != "DELETE" ||
_method != "PUT")
else if (_method == "GET" || _method == "POST" || _method == "DELETE" ||
_method == "PUT")
return (true);
return (false);
}
@ -126,20 +137,25 @@ void Client::answer(void) {
string cgi = _route->_cgi.size() ? _route->_cgi[get_extension(path)]
: _server->_cgi.size() ? _server->_cgi[get_extension(path)]
: "";
if (DEBUG)
cout << "Path: " << path << "\n";
if (_method == "PUT")
create_file(path);
if (cgi != "")
send_cgi(cgi, path);
else if (!check_method())
if (!check_method())
send_error(405);
else {
if ((ret = _route->getIndex(_uri, path)) == "")
ret = read_file(path);
if (ret == "404")
if (ret == "404") {
if (_method == "POST" || _method == "PUT")
create_file(path);
else
send_error(404);
}
else if (ret == "403")
send_error(403);
else if (_method == "DELETE")
std::remove(path.c_str());
else if (cgi != "")
send_cgi(cgi, path);
else
send_answer("HTTP/1.1 200 OK\r\n" + ret);
}
@ -171,9 +187,11 @@ void Client::send_cgi(string cgi, string path) {
args[1] = path.c_str();
args[2] = NULL;
string path_info = "PATH_INFO=" + _route->getRoot();
const char **env = new const char *[path_info.length() + 1];
string query = "QUERY_STRING=" + _query;
const char **env = new const char *[path_info.length() + query.length() + 2];
env[0] = path_info.c_str();
env[1] = NULL;
env[1] = query.c_str();
env[2] = NULL;
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
close(fd[0]);

Loading…
Cancel
Save