mirror of
https://github.com/KeyZox71/webserv.git
synced 2025-05-10 23:48:46 +02:00
「✨」 feat(main loop): added a main loop so the server serve
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ obj/
|
|||||||
.direnv/
|
.direnv/
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
.cache
|
.cache
|
||||||
|
*.log
|
||||||
|
18
Dockerfile
18
Dockerfile
@ -1,11 +1,13 @@
|
|||||||
FROM alpine:3.21
|
FROM alpine:3.21
|
||||||
|
|
||||||
COPY ./ /build
|
COPY ./ /build
|
||||||
|
|
||||||
RUN apk add --no-cache clang make \
|
RUN apk add --no-cache clang make \
|
||||||
&& cd /build \
|
&& cd /build \
|
||||||
&& make \
|
&& make \
|
||||||
&& chmod +x webserv \
|
&& chmod +x webserv \
|
||||||
&& cp webserv /bin/webserv
|
&& cp webserv /bin/webserv
|
||||||
|
|
||||||
RUN [ "/bin/webserv", "$WEBSERV-CONF"]
|
STOPSIGNAL SIGINT
|
||||||
|
|
||||||
|
RUN [ "/bin/webserv", "$WEBSERV-CONF"]
|
||||||
|
5
Makefile
5
Makefile
@ -6,8 +6,7 @@
|
|||||||
# By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ #
|
# By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/10/25 16:09:27 by adjoly #+# #+# #
|
# Created: 2024/10/25 16:09:27 by adjoly #+# #+# #
|
||||||
# Updated: 2025/04/10 11:52:13 by mmoussou ### ########.fr #
|
# Updated: 2025/04/22 14:32:50 by adjoly ### ########.fr #
|
||||||
# Updated: 2025/03/25 18:13:53 by adjoly ### ########.fr #
|
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ SHELL = bash
|
|||||||
|
|
||||||
NAME = webserv
|
NAME = webserv
|
||||||
|
|
||||||
CC = c++
|
CC = clang++
|
||||||
|
|
||||||
OBJSDIR = obj/
|
OBJSDIR = obj/
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ log_file = "test.log"
|
|||||||
|
|
||||||
[server]
|
[server]
|
||||||
server_names = { "localhost", "2B5.local" }
|
server_names = { "localhost", "2B5.local" }
|
||||||
host = "localhost"
|
host = "0.0.0.0"
|
||||||
port = 8080
|
port = 8080
|
||||||
|
|
||||||
[server.error_pages]
|
[server.error_pages]
|
||||||
|
@ -6,13 +6,14 @@
|
|||||||
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/24 14:17:34 by adjoly #+# #+# */
|
/* Created: 2025/03/24 14:17:34 by adjoly #+# #+# */
|
||||||
/* Updated: 2025/03/24 14:20:00 by adjoly ### ########.fr */
|
/* Updated: 2025/04/22 11:51:33 by mmoussou ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
class cgi {
|
class cgi {
|
||||||
public:
|
public:
|
||||||
cgi();
|
cgi();
|
||||||
|
35
includes/config/Config.hpp
Normal file
35
includes/config/Config.hpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* Config.hpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/04/14 12:20:06 by adjoly #+# #+# */
|
||||||
|
/* Updated: 2025/04/22 15:25:39 by adjoly ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <config/Server.hpp>
|
||||||
|
|
||||||
|
namespace webserv {
|
||||||
|
namespace config {
|
||||||
|
|
||||||
|
class Config {
|
||||||
|
public:
|
||||||
|
Config(std::string &);
|
||||||
|
~Config();
|
||||||
|
|
||||||
|
Logger *getLogger(void) { return _log; }
|
||||||
|
|
||||||
|
std::vector<Server *> getServers(void) { return _servers; }
|
||||||
|
Server *getServer(const std::string &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Server *> _servers;
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace config
|
||||||
|
}; // namespace webserv
|
@ -6,15 +6,15 @@
|
|||||||
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */
|
/* Created: 2025/03/19 14:59:41 by adjoly #+# #+# */
|
||||||
/* Updated: 2025/03/26 08:31:41 by adjoly ### ########.fr */
|
/* Updated: 2025/04/22 12:34:00 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "cppeleven.hpp"
|
#include <cppeleven.hpp>
|
||||||
#include "log.hpp"
|
#include <log.hpp>
|
||||||
#include "node/default.hpp"
|
#include <node/default.hpp>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -26,9 +26,22 @@ namespace config {
|
|||||||
|
|
||||||
class Route {
|
class Route {
|
||||||
public:
|
public:
|
||||||
Route(toml::ANode *, Logger *);
|
Route(toml::ANode *);
|
||||||
~Route(void);
|
~Route(void);
|
||||||
|
|
||||||
|
bool getDirList(void) { return _dirlist; }
|
||||||
|
bool getCookies(void) { return _cookies; }
|
||||||
|
bool getRedirect(void) { return _redirect; }
|
||||||
|
|
||||||
|
int32_t getMaxBody(void) { return _max_body; }
|
||||||
|
|
||||||
|
std::string getRootDir(void) { return _root; }
|
||||||
|
std::string getUpRoot(void) { return _up_root; }
|
||||||
|
std::string getIndex(void) { return _index; }
|
||||||
|
std::map<std::string, std::string> *getCgi(void) { return _cgi; }
|
||||||
|
|
||||||
|
bool *getMethods(void) { return _methods; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
bool _dirlist;
|
bool _dirlist;
|
||||||
@ -42,8 +55,6 @@ class Route {
|
|||||||
std::string _index;
|
std::string _index;
|
||||||
std::map<std::string, std::string> *_cgi;
|
std::map<std::string, std::string> *_cgi;
|
||||||
|
|
||||||
Logger *_log;
|
|
||||||
|
|
||||||
bool _methods[3]; ///> A methods boolean array which correspond to - 0: GET,
|
bool _methods[3]; ///> A methods boolean array which correspond to - 0: GET,
|
||||||
///1: POST, 2: DELETE
|
///1: POST, 2: DELETE
|
||||||
toml::ANode *_table;
|
toml::ANode *_table;
|
||||||
|
@ -6,22 +6,25 @@
|
|||||||
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/19 14:11:28 by adjoly #+# #+# */
|
/* Created: 2025/03/19 14:11:28 by adjoly #+# #+# */
|
||||||
/* Updated: 2025/03/25 17:56:34 by adjoly ### ########.fr */
|
/* Updated: 2025/04/22 15:25:58 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "config/default.hpp"
|
#include <webserv.hpp>
|
||||||
#include "cppeleven.hpp"
|
#include <config/Route.hpp>
|
||||||
#include "node/ANode.hpp"
|
#include <cppeleven.hpp>
|
||||||
|
#include <node/ANode.hpp>
|
||||||
|
#include <webserv.hpp>
|
||||||
|
#include <config/URL.hpp>
|
||||||
|
|
||||||
namespace webserv {
|
namespace webserv {
|
||||||
namespace config {
|
namespace config {
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
public:
|
public:
|
||||||
Server(std::string);
|
Server(toml::ANode *);
|
||||||
~Server();
|
~Server();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,11 +51,6 @@ class Server {
|
|||||||
return not_nullptr;
|
return not_nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Can be used to get the Logger pointer
|
|
||||||
*/
|
|
||||||
Logger *getLogger(void) { return _log; }
|
|
||||||
|
|
||||||
// @brief Can be used to get a server name
|
// @brief Can be used to get a server name
|
||||||
std::vector<std::string> *getServerNames(void) { return _server_names; }
|
std::vector<std::string> *getServerNames(void) { return _server_names; }
|
||||||
// @brief Can be used to get the host specified in the config file
|
// @brief Can be used to get the host specified in the config file
|
||||||
@ -60,9 +58,14 @@ class Server {
|
|||||||
// @brief Can be used to get the port specified in the config file
|
// @brief Can be used to get the port specified in the config file
|
||||||
int getPort(void) { return _port; }
|
int getPort(void) { return _port; }
|
||||||
|
|
||||||
|
// @brief Can be used to check if a servername is present in this config
|
||||||
|
bool isServerName(const std::string &);
|
||||||
|
|
||||||
|
Route *whatRoute(const URL &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
std::map<std::string, Route *>
|
std::map<URL, Route *>
|
||||||
*_routes; ///> A map of all the route present in the config file
|
*_routes; ///> A map of all the route present in the config file
|
||||||
std::map<int, std::string> *_err_pages; ///> An error pages map to map error
|
std::map<int, std::string> *_err_pages; ///> An error pages map to map error
|
||||||
/// specified in the config file
|
/// specified in the config file
|
||||||
@ -75,17 +78,11 @@ class Server {
|
|||||||
|
|
||||||
toml::ANode *_table; ///> The table used for the parsing (is deleted at the
|
toml::ANode *_table; ///> The table used for the parsing (is deleted at the
|
||||||
/// end of the constructor)
|
/// end of the constructor)
|
||||||
Logger *_log; ///> A pointer to the logger class
|
|
||||||
|
|
||||||
std::map<int, std::string> *
|
std::map<int, std::string> *
|
||||||
_parseErrPages(std::map<std::string, toml::ANode *> *table);
|
_parseErrPages(std::map<std::string, toml::ANode *> *table);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Can be used to get the [server] table in _table
|
|
||||||
*
|
|
||||||
* @return A pointer to the [server] table as an ANode
|
|
||||||
*/
|
|
||||||
toml::ANode *_getServerTable(void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace config
|
} // namespace config
|
||||||
|
75
includes/config/URL.hpp
Normal file
75
includes/config/URL.hpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* URL.hpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/04/22 12:17:48 by adjoly #+# #+# */
|
||||||
|
/* Updated: 2025/04/22 12:42:21 by adjoly ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <webserv.hpp>
|
||||||
|
|
||||||
|
class URL {
|
||||||
|
public:
|
||||||
|
URL(const std::string &url) : _full_url(url) { parse(); }
|
||||||
|
|
||||||
|
bool operator==(const URL &other) const {
|
||||||
|
return comparePathSegments(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const URL &other) const { return _full_url < other._full_url; }
|
||||||
|
|
||||||
|
std::vector<std::string> getSegments(void) { return _path_segments; }
|
||||||
|
std::string getFullUrl(void) { return _full_url; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void parse() {
|
||||||
|
size_t scheme_pos = _full_url.find("://");
|
||||||
|
size_t path_start = 0;
|
||||||
|
|
||||||
|
if (scheme_pos != std::string::npos) {
|
||||||
|
path_start = _full_url.find('/', scheme_pos + 3);
|
||||||
|
} else {
|
||||||
|
path_start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path_start != std::string::npos) {
|
||||||
|
std::string path = _full_url.substr(path_start);
|
||||||
|
splitPath(path, _path_segments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void splitPath(const std::string &path,
|
||||||
|
std::vector<std::string> &segments) const {
|
||||||
|
std::stringstream ss(path);
|
||||||
|
std::string segment;
|
||||||
|
while (std::getline(ss, segment, '/')) {
|
||||||
|
if (!segment.empty()) {
|
||||||
|
segments.push_back(segment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool comparePathSegments(const URL &other) const {
|
||||||
|
size_t min_size =
|
||||||
|
std::min(_path_segments.size(), other._path_segments.size());
|
||||||
|
for (size_t i = 0; i < min_size; ++i) {
|
||||||
|
if (_path_segments[i] != other._path_segments[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string _full_url;
|
||||||
|
std::vector<std::string> _path_segments;
|
||||||
|
};
|
@ -6,17 +6,18 @@
|
|||||||
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/19 14:15:51 by adjoly #+# #+# */
|
/* Created: 2025/03/19 14:15:51 by adjoly #+# #+# */
|
||||||
/* Updated: 2025/03/26 08:39:08 by adjoly ### ########.fr */
|
/* Updated: 2025/04/22 15:28:31 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Route.hpp"
|
#include <config/Config.hpp>
|
||||||
#include "Server.hpp"
|
#include <config/Route.hpp>
|
||||||
#include "cppeleven.hpp"
|
#include <config/Server.hpp>
|
||||||
#include "node/Table.hpp"
|
#include <cppeleven.hpp>
|
||||||
#include "node/default.hpp"
|
#include <node/Table.hpp>
|
||||||
|
#include <node/default.hpp>
|
||||||
#include <tomlpp.hpp>
|
#include <tomlpp.hpp>
|
||||||
|
|
||||||
namespace webserv {
|
namespace webserv {
|
||||||
@ -34,13 +35,13 @@ namespace config {
|
|||||||
* @return The value got or not_nullptr
|
* @return The value got or not_nullptr
|
||||||
*/
|
*/
|
||||||
static inline void *accessValue(const std::string &name, toml::nodeType type,
|
static inline void *accessValue(const std::string &name, toml::nodeType type,
|
||||||
toml::ANode *table, Logger *log) {
|
toml::ANode *table, Logger *log) {
|
||||||
void *val;
|
void *val;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
if (table == not_nullptr)
|
if (table == not_nullptr)
|
||||||
return not_nullptr;
|
return not_nullptr;
|
||||||
val = dynamic_cast<toml::Table *>(table)->access(name, type, found);
|
val = dynamic_cast<toml::ANode *>(table)->access(name, type, found);
|
||||||
if (found == true && val != not_nullptr) {
|
if (found == true && val != not_nullptr) {
|
||||||
return val;
|
return val;
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/04/10 13:43:54 by adjoly #+# #+# */
|
/* Created: 2025/04/10 13:43:54 by adjoly #+# #+# */
|
||||||
/* Updated: 2025/04/10 13:58:52 by adjoly ### ########.fr */
|
/* Updated: 2025/04/11 11:36:22 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -14,3 +14,5 @@
|
|||||||
|
|
||||||
#define SAMPLE_CONF_PATH "./sample.conf"
|
#define SAMPLE_CONF_PATH "./sample.conf"
|
||||||
#define WEBSRV_VERSION "v0.1"
|
#define WEBSRV_VERSION "v0.1"
|
||||||
|
|
||||||
|
bool help(int, char **);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/20 09:28:27 by adjoly #+# #+# */
|
/* Created: 2025/03/20 09:28:27 by adjoly #+# #+# */
|
||||||
/* Updated: 2025/04/10 14:21:46 by adjoly ### ########.fr */
|
/* Updated: 2025/04/22 16:14:25 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -19,22 +19,41 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace webserv {
|
namespace webserv {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Used to log debug message
|
||||||
|
*
|
||||||
|
* @note Only work if VERBOSE mode is active
|
||||||
|
*/
|
||||||
|
static inline void log(std::string emoji, std::string who, std::string str) {
|
||||||
|
#ifdef VERBOSE
|
||||||
|
if (who.empty())
|
||||||
|
std::cout << "「" << emoji << "」debug: " << str << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "「" << emoji << "」debug(" << who << "): " << str
|
||||||
|
<< std::endl;
|
||||||
|
#else
|
||||||
|
(void)emoji, (void)who, (void)str;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
class Logger {
|
class Logger {
|
||||||
public:
|
public:
|
||||||
|
Logger(void) : _ttyOnly(true) {
|
||||||
|
log("➕", "Logger", "default constructor called");
|
||||||
|
}
|
||||||
Logger(const std::string &fileName) : _fileName(fileName) {
|
Logger(const std::string &fileName) : _fileName(fileName) {
|
||||||
if (fileName.empty())
|
log("➕", "Logger", "filename constructor called");
|
||||||
_ttyOnly = true;
|
_file.open(fileName.c_str(), std::ios::app);
|
||||||
else {
|
|
||||||
_file.open(fileName.c_str(), std::ios::app);
|
|
||||||
_ttyOnly = false;
|
|
||||||
}
|
|
||||||
if (!_file.is_open() && !_ttyOnly) {
|
if (!_file.is_open() && !_ttyOnly) {
|
||||||
_ttyOnly = true;
|
_ttyOnly = true;
|
||||||
warn("could not open log file, going tty only");
|
warn("could not open log file, going tty only");
|
||||||
}
|
} else
|
||||||
|
_ttyOnly = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger(const Logger &other) : _ttyOnly(other._ttyOnly) {
|
Logger(const Logger &other) : _ttyOnly(other._ttyOnly) {
|
||||||
|
log("➕", "Logger", "copy constructor called");
|
||||||
if (!other._ttyOnly) {
|
if (!other._ttyOnly) {
|
||||||
_file.open(other._fileName.c_str(), std::ios::app);
|
_file.open(other._fileName.c_str(), std::ios::app);
|
||||||
if (!_file.is_open()) {
|
if (!_file.is_open()) {
|
||||||
@ -46,6 +65,7 @@ class Logger {
|
|||||||
|
|
||||||
// Copy assignment operator
|
// Copy assignment operator
|
||||||
Logger &operator=(const Logger &other) {
|
Logger &operator=(const Logger &other) {
|
||||||
|
log("➕", "Logger", "copy assignment constructor called");
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
if (_file.is_open()) {
|
if (_file.is_open()) {
|
||||||
_file.close();
|
_file.close();
|
||||||
@ -62,6 +82,7 @@ class Logger {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
~Logger(void) {
|
~Logger(void) {
|
||||||
|
log("➖", "Logger", "destructor called");
|
||||||
if (_file.is_open())
|
if (_file.is_open())
|
||||||
_file.close();
|
_file.close();
|
||||||
}
|
}
|
||||||
@ -88,12 +109,23 @@ class Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void debug(const std::string &msg) {
|
||||||
|
#ifdef VERBOSE
|
||||||
|
std::string ss = printPogitMsg("🏗️", "webserv", "debug", msg);
|
||||||
|
std::cerr << ss << std::endl;
|
||||||
|
if (!_ttyOnly) {
|
||||||
|
_file << ss << std::endl;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void)msg;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
std::string printPogitMsg(const std::string &emoji,
|
std::string printPogitMsg(const std::string &emoji, const std::string &type,
|
||||||
const std::string &type,
|
const std::string &what, const std::string &msg) {
|
||||||
const std::string &what,
|
|
||||||
const std::string &msg) {
|
|
||||||
std::stringstream os;
|
std::stringstream os;
|
||||||
#ifdef TTY
|
#ifdef TTY
|
||||||
(void)emoji;
|
(void)emoji;
|
||||||
@ -103,9 +135,9 @@ class Logger {
|
|||||||
os << type << "(" << what << "):" << msg;
|
os << type << "(" << what << "):" << msg;
|
||||||
#else
|
#else
|
||||||
if (what.empty())
|
if (what.empty())
|
||||||
os << "「" << emoji << "」" << type << ":" << msg;
|
os << "「" << emoji << "」" << type << ": " << msg;
|
||||||
else
|
else
|
||||||
os << "「" << emoji << "」" << type << "(" << what << "):" << msg;
|
os << "「" << emoji << "」" << type << "(" << what << "): " << msg;
|
||||||
#endif
|
#endif
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
@ -115,4 +147,6 @@ class Logger {
|
|||||||
std::ofstream _file;
|
std::ofstream _file;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern Logger *_log;
|
||||||
|
|
||||||
}; // namespace webserv
|
}; // namespace webserv
|
||||||
|
@ -6,13 +6,11 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/16 17:51:46 by mmoussou #+# #+# */
|
/* Created: 2025/03/16 17:51:46 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/03/24 15:05:53 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/22 11:52:00 by mmoussou ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __WEBSERV_REQUESTS_ERRORS_HPP__
|
|
||||||
# define __WEBSERV_REQUESTS_ERRORS_HPP__
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -22,16 +20,10 @@
|
|||||||
namespace webserv {
|
namespace webserv {
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
/*
|
|
||||||
* DOES NOT WORK
|
|
||||||
* still need to do uh things but base is done at least :D
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Errors {
|
class Errors {
|
||||||
public:
|
public:
|
||||||
//static http::Response &getRequest(int error_code);
|
|
||||||
static std::string getResponseBody(int error_code);
|
static std::string getResponseBody(int error_code);
|
||||||
static void setEntry(const std::string &key, int value);
|
static void setEntries(const std::map<int, std::string>);
|
||||||
|
|
||||||
static std::map<int, std::string> message;
|
static std::map<int, std::string> message;
|
||||||
private:
|
private:
|
||||||
@ -43,5 +35,3 @@ private:
|
|||||||
|
|
||||||
} // -namespace http
|
} // -namespace http
|
||||||
} // -namespace webserv
|
} // -namespace webserv
|
||||||
|
|
||||||
#endif // __WEBSERV_REQUESTS_ERRORS_HPP__
|
|
||||||
|
@ -6,13 +6,11 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/11 22:13:38 by mmoussou #+# #+# */
|
/* Created: 2025/02/11 22:13:38 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/04/02 01:47:24 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/23 14:38:55 by mmoussou ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __WEBSERV_REQUESTS_HTTP_IMESSAGE_HPP__
|
|
||||||
# define __WEBSERV_REQUESTS_HTTP_IMESSAGE_HPP__
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -25,6 +23,8 @@ public:
|
|||||||
virtual std::map<std::string, std::string> getHeaders(void) const;
|
virtual std::map<std::string, std::string> getHeaders(void) const;
|
||||||
virtual std::string getBody(void) const;
|
virtual std::string getBody(void) const;
|
||||||
|
|
||||||
|
virtual ~IMessage() {}
|
||||||
|
|
||||||
virtual void setHeaders(std::map<std::string, std::string> const headers);
|
virtual void setHeaders(std::map<std::string, std::string> const headers);
|
||||||
virtual void setBody(std::string const body);
|
virtual void setBody(std::string const body);
|
||||||
|
|
||||||
@ -43,5 +43,3 @@ protected:
|
|||||||
|
|
||||||
} // -namespace http
|
} // -namespace http
|
||||||
} // -namespace webserv
|
} // -namespace webserv
|
||||||
|
|
||||||
#endif // __WEBSERV_REQUESTS_HTTP_IMESSAGE_HPP__
|
|
||||||
|
@ -6,13 +6,11 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/03 17:23:00 by mmoussou #+# #+# */
|
/* Created: 2025/02/03 17:23:00 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/02/14 15:43:32 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/22 15:07:02 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __WEBSERV_REQUESTS_HTTP_REQUEST_HPP__
|
|
||||||
# define __WEBSERV_REQUESTS_HTTP_REQUEST_HPP__
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -22,11 +20,15 @@
|
|||||||
#include <requests/HttpIMessage.hpp>
|
#include <requests/HttpIMessage.hpp>
|
||||||
#include <requests/HttpResponse.hpp>
|
#include <requests/HttpResponse.hpp>
|
||||||
|
|
||||||
|
#include <config/default.hpp>
|
||||||
|
|
||||||
namespace webserv {
|
namespace webserv {
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
class IRequest: public http::IMessage {
|
class IRequest: public http::IMessage {
|
||||||
public:
|
public:
|
||||||
|
virtual ~IRequest(void);
|
||||||
|
|
||||||
virtual void parse(std::string const &data) = 0;
|
virtual void parse(std::string const &data) = 0;
|
||||||
virtual http::Response execute(void) = 0;
|
virtual http::Response execute(void) = 0;
|
||||||
|
|
||||||
@ -35,21 +37,25 @@ public:
|
|||||||
std::string getMethod(void) const;
|
std::string getMethod(void) const;
|
||||||
std::string getTarget(void) const;
|
std::string getTarget(void) const;
|
||||||
std::string getProtocol(void) const;
|
std::string getProtocol(void) const;
|
||||||
|
config::Server *getConfig(void) const;
|
||||||
|
|
||||||
void setMethod(std::string const method);
|
void setMethod(std::string const method);
|
||||||
void setTarget(std::string const target);
|
void setTarget(std::string const target);
|
||||||
void setProtocol(std::string const protocol);
|
void setProtocol(std::string const protocol);
|
||||||
|
void setServer(std::string const protocol);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string _method;
|
std::string _method;
|
||||||
std::string _target;
|
std::string _target;
|
||||||
std::string _protocol;
|
std::string _protocol;
|
||||||
|
config::Server *_conf;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Get: public http::IRequest {
|
class Get: public http::IRequest {
|
||||||
public:
|
public:
|
||||||
Get(void);
|
Get(void);
|
||||||
|
~Get(void);
|
||||||
Get(std::string &data);
|
Get(std::string &data);
|
||||||
|
|
||||||
void parse(std::string const &data);
|
void parse(std::string const &data);
|
||||||
@ -61,6 +67,7 @@ public:
|
|||||||
class Post: public http::IRequest {
|
class Post: public http::IRequest {
|
||||||
public:
|
public:
|
||||||
Post(void);
|
Post(void);
|
||||||
|
~Post(void);
|
||||||
Post(std::string &data);
|
Post(std::string &data);
|
||||||
|
|
||||||
void parse(std::string const &data);
|
void parse(std::string const &data);
|
||||||
@ -72,6 +79,7 @@ public:
|
|||||||
class Delete: public http::IRequest {
|
class Delete: public http::IRequest {
|
||||||
public:
|
public:
|
||||||
Delete(void);
|
Delete(void);
|
||||||
|
~Delete(void);
|
||||||
Delete(std::string &data);
|
Delete(std::string &data);
|
||||||
|
|
||||||
void parse(std::string const &data);
|
void parse(std::string const &data);
|
||||||
@ -82,5 +90,3 @@ public:
|
|||||||
|
|
||||||
} // -namespace http
|
} // -namespace http
|
||||||
} // -namespace webserv
|
} // -namespace webserv
|
||||||
|
|
||||||
#endif // __WEBSERV_REQUESTS_HTTP_REQUEST_HPP__
|
|
||||||
|
@ -6,13 +6,11 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/03 17:21:20 by mmoussou #+# #+# */
|
/* Created: 2025/02/03 17:21:20 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/03/24 15:16:39 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/23 14:36:47 by mmoussou ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __WEBSERV_REQUESTS_HTTP_RESPONSE_HPP__
|
|
||||||
# define __WEBSERV_REQUESTS_HTTP_RESPONSE_HPP__
|
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -26,6 +24,7 @@ namespace http {
|
|||||||
class Response: public http::IMessage {
|
class Response: public http::IMessage {
|
||||||
public:
|
public:
|
||||||
Response(void);
|
Response(void);
|
||||||
|
~Response(void);
|
||||||
|
|
||||||
std::string getProtocol(void) const;
|
std::string getProtocol(void) const;
|
||||||
uint getStatusCode(void) const;
|
uint getStatusCode(void) const;
|
||||||
@ -45,5 +44,3 @@ private:
|
|||||||
|
|
||||||
} // -namespace http
|
} // -namespace http
|
||||||
} // -namespace webserv
|
} // -namespace webserv
|
||||||
|
|
||||||
#endif // __WEBSERV_REQUESTS_HTTP_RESPONSE_HPP__
|
|
||||||
|
@ -6,18 +6,14 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/03 15:48:22 by mmoussou #+# #+# */
|
/* Created: 2025/02/03 15:48:22 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/03/17 14:08:50 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/22 11:51:54 by mmoussou ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __WEBSERV_REQUESTS_DEFAULT_HPP__
|
|
||||||
# define __WEBSERV_REQUESTS_DEFAULT_HPP__
|
|
||||||
|
|
||||||
#include <requests/Errors.hpp>
|
#include <requests/Errors.hpp>
|
||||||
#include <requests/HttpRequest.hpp>
|
#include <requests/HttpRequest.hpp>
|
||||||
#include <requests/HttpResponse.hpp>
|
#include <requests/HttpResponse.hpp>
|
||||||
|
|
||||||
using namespace webserv;
|
using namespace webserv;
|
||||||
|
|
||||||
#endif // __WEBSERV_REQUESTS_DEFAULT_HPP__
|
|
||||||
|
42
includes/server/Client.hpp
Normal file
42
includes/server/Client.hpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* Client.hpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/04/14 14:14:39 by adjoly #+# #+# */
|
||||||
|
/* Updated: 2025/04/23 14:39:16 by mmoussou ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <config/default.hpp>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <requests/default.hpp>
|
||||||
|
#include <server/default.hpp>
|
||||||
|
#include <webserv.hpp>
|
||||||
|
|
||||||
|
namespace webserv {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class Client {
|
||||||
|
public:
|
||||||
|
Client(int, sockaddr_in, config::Config *);
|
||||||
|
virtual ~Client(void);
|
||||||
|
|
||||||
|
void answer(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _getRequest(std::string);
|
||||||
|
|
||||||
|
int _fd;
|
||||||
|
struct sockaddr_in _client_addr;
|
||||||
|
http::IRequest *_request;
|
||||||
|
//http::Response *_response;
|
||||||
|
config::Server *_conf;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace webserv
|
92
includes/server/Server.hpp
Normal file
92
includes/server/Server.hpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* Server.hpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/04/11 17:45:43 by adjoly #+# #+# */
|
||||||
|
/* Updated: 2025/04/22 11:51:27 by mmoussou ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <log.hpp>
|
||||||
|
#include <config/default.hpp>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace webserv {
|
||||||
|
|
||||||
|
struct client_data {
|
||||||
|
sockaddr_in sock_data;
|
||||||
|
pollfd poll_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Server {
|
||||||
|
public:
|
||||||
|
Server(config::Config *);
|
||||||
|
~Server(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Used to setup the webserver (primarly socket)
|
||||||
|
*/
|
||||||
|
void _setup(void);
|
||||||
|
/**
|
||||||
|
* @brief Used to run the webserver
|
||||||
|
*/
|
||||||
|
void _run(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Used to handle client request
|
||||||
|
*
|
||||||
|
* @param The fd of the client
|
||||||
|
*/
|
||||||
|
bool _handle_client(struct pollfd &, sockaddr_in *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Can be used to fill the vector passed as parameters with all the
|
||||||
|
* port and host in the config
|
||||||
|
* @param The vector of host
|
||||||
|
* @param The vector of port
|
||||||
|
*/
|
||||||
|
int _fillHostsPorts(std::vector<std::string> &, std::vector<int> &);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Can be used to open a socket with a specific port and host
|
||||||
|
* @param The host
|
||||||
|
* @param The port
|
||||||
|
*/
|
||||||
|
int _createSocket(std::string, int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Can be used to check if an fd is one of the socket or not
|
||||||
|
*
|
||||||
|
* @param the fd to check
|
||||||
|
*/
|
||||||
|
bool _isServerSocket(int fd) {
|
||||||
|
for (std::vector<int>::iterator it = _fds_server.begin();
|
||||||
|
it != _fds_server.end(); it++) {
|
||||||
|
if (fd == *it) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config::Config
|
||||||
|
*_conf; // Pointer to the configuration class (with all config in)
|
||||||
|
Logger *_log; // Pointer to the log class
|
||||||
|
std::vector<int> _fds_server; // The fds of the sockets
|
||||||
|
std::vector<struct pollfd> _client_fds; // A vector of all the poll fd
|
||||||
|
std::vector<sockaddr_in *>
|
||||||
|
_client_data; // vector of all the client sockaddr_in
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace webserv
|
@ -6,20 +6,19 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/11 13:29:05 by mmoussou #+# #+# */
|
/* Created: 2025/02/11 13:29:05 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/02/12 00:14:11 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/22 12:04:53 by mmoussou ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __WEBSERV_SERVER_DEFAULT_HPP__
|
|
||||||
# define __WEBSERV_SERVER_DEFAULT_HPP__
|
#include <server/Server.hpp>
|
||||||
|
#include <server/Client.hpp>
|
||||||
|
|
||||||
namespace webserv {
|
namespace webserv {
|
||||||
namespace server {
|
|
||||||
|
|
||||||
} // -namespace server
|
|
||||||
|
|
||||||
} // -namespace webserv
|
} // -namespace webserv
|
||||||
|
|
||||||
using namespace webserv;
|
using namespace webserv;
|
||||||
|
|
||||||
#endif // __WEBSERV_SERVER_DEFAULT_HPP__
|
|
||||||
|
@ -6,26 +6,40 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/11 13:29:21 by mmoussou #+# #+# */
|
/* Created: 2025/02/11 13:29:21 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/04/10 13:58:56 by adjoly ### ########.fr */
|
/* Updated: 2025/04/22 14:27:31 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __WEBSERV_WEBSERV_HPP__
|
|
||||||
# define __WEBSERV_WEBSERV_HPP__
|
|
||||||
|
|
||||||
#include <string>
|
#define auto __auto_type
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
#include <sys/types.h>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
#define range(x) \
|
||||||
|
x.begin(); \
|
||||||
|
it != x.end(); \
|
||||||
|
it++
|
||||||
|
#define prange(x) \
|
||||||
|
x->begin(); \
|
||||||
|
it != x->end(); \
|
||||||
|
it++
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 4096
|
||||||
|
|
||||||
namespace webserv {
|
namespace webserv {
|
||||||
|
|
||||||
} //-namespace webserv
|
} // namespace webserv
|
||||||
|
|
||||||
#endif // __WEBSERV_WEBSERV_HPP__
|
|
||||||
|
9
sample.conf
Normal file
9
sample.conf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[server]
|
||||||
|
host = "localhost"
|
||||||
|
port = 8080
|
||||||
|
|
||||||
|
[server.location./]
|
||||||
|
methods = { "GET" }
|
||||||
|
root = "/var/www/html"
|
||||||
|
dirlist = true
|
||||||
|
client_max_body_size = "10M"
|
60
src/config/Config.cpp
Normal file
60
src/config/Config.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* Config.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/04/14 12:53:54 by adjoly #+# #+# */
|
||||||
|
/* Updated: 2025/04/22 15:35:52 by adjoly ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "node/default.hpp"
|
||||||
|
#include "webserv.hpp"
|
||||||
|
#include "cppeleven.hpp"
|
||||||
|
#include "node/ANode.hpp"
|
||||||
|
#include <config/default.hpp>
|
||||||
|
|
||||||
|
using namespace webserv::config;
|
||||||
|
|
||||||
|
Config::Config(std::string &filename) {
|
||||||
|
toml::Toml *file = new toml::Toml(filename);
|
||||||
|
|
||||||
|
file->parse();
|
||||||
|
toml::ANode *table = file->getParsedFile();
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
void *logFile = table->access("log_file", toml::STRING, found);
|
||||||
|
if (found == true && logFile != not_nullptr) {
|
||||||
|
_log = new Logger(*static_cast<std::string *>(logFile));
|
||||||
|
} else {
|
||||||
|
_log = new Logger();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, toml::ANode *> *node = table->getTable();
|
||||||
|
for (auto it = prange(node)) {
|
||||||
|
if (it->second->type() == toml::TABLE) {
|
||||||
|
_log->info("taking server from table : " + it->first);
|
||||||
|
Server *srv = new Server(it->second);
|
||||||
|
_servers.push_back(srv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete table;
|
||||||
|
delete file;
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::~Config(void) {
|
||||||
|
for (auto it = range(_servers)) {
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Server *Config::getServer(const std::string &server_name) {
|
||||||
|
for (auto it = range(_servers)) {
|
||||||
|
if ((*it)->isServerName(server_name)) {
|
||||||
|
return (*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (not_nullptr);
|
||||||
|
}
|
@ -9,12 +9,13 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "cppeleven.hpp"
|
#include "cppeleven.hpp"
|
||||||
#include "log.hpp"
|
#include <log.hpp>
|
||||||
#include "node/default.hpp"
|
#include "node/default.hpp"
|
||||||
#include <config/default.hpp>
|
#include <config/default.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
using namespace webserv::config;
|
using namespace webserv::config;
|
||||||
|
|
||||||
std::map<std::string, std::string> *Route::_parseCGI(toml::ANode *table) {
|
std::map<std::string, std::string> *Route::_parseCGI(toml::ANode *table) {
|
||||||
@ -57,12 +58,11 @@ void Route::_parseMethods(std::vector<toml::ANode *> *table) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Route::Route(toml::ANode *table, Logger *logger)
|
Route::Route(toml::ANode *table)
|
||||||
: _max_body(10485760), _log(logger) {
|
: _max_body(10485760) {
|
||||||
void *val;
|
void *val;
|
||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
_log = logger;
|
|
||||||
_table = table;
|
_table = table;
|
||||||
if (_table->type() != toml::TABLE) {
|
if (_table->type() != toml::TABLE) {
|
||||||
_log->warn("location need to be a table and not a :" +
|
_log->warn("location need to be a table and not a :" +
|
||||||
|
@ -6,71 +6,37 @@
|
|||||||
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/03/24 15:10:07 by adjoly #+# #+# */
|
/* Created: 2025/03/24 15:10:07 by adjoly #+# #+# */
|
||||||
/* Updated: 2025/03/26 08:47:50 by adjoly ### ########.fr */
|
/* Updated: 2025/04/22 15:36:30 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "config/Server.hpp"
|
|
||||||
#include "config/Route.hpp"
|
|
||||||
#include "cppeleven.hpp"
|
#include "cppeleven.hpp"
|
||||||
#include "log.hpp"
|
|
||||||
#include "node/ANode.hpp"
|
|
||||||
#include "node/Table.hpp"
|
|
||||||
#include "node/default.hpp"
|
|
||||||
#include "tomlpp.hpp"
|
|
||||||
#include <config/default.hpp>
|
#include <config/default.hpp>
|
||||||
#include <stdexcept>
|
#include <webserv.hpp>
|
||||||
#include <string>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
using namespace webserv::config;
|
using namespace webserv::config;
|
||||||
|
|
||||||
toml::ANode *Server::_getServerTable(void) {
|
Server::Server(toml::ANode *node) : _table(node) {
|
||||||
toml::ANode *serverT;
|
|
||||||
|
|
||||||
std::map<std::string, toml::ANode *>::iterator table =
|
|
||||||
_table->getTable()->find("server");
|
|
||||||
if (table == _table->getTable()->end())
|
|
||||||
throw std::runtime_error(
|
|
||||||
"could not find any [server] table in config file :(");
|
|
||||||
else
|
|
||||||
serverT = table->second;
|
|
||||||
return serverT;
|
|
||||||
}
|
|
||||||
|
|
||||||
Server::Server(std::string file_name) {
|
|
||||||
toml::Toml *tomlFile = new toml::Toml(file_name);
|
|
||||||
|
|
||||||
try {
|
|
||||||
tomlFile->parse();
|
|
||||||
} catch (std::runtime_error &e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
std::map<std::string, toml::ANode *> *map;
|
if (_table == not_nullptr)
|
||||||
_table = tomlFile->getParsedFile();
|
return;
|
||||||
|
|
||||||
void *val = _table->access("log_file", toml::STRING, found);
|
// host parsing
|
||||||
std::string log_file = "";
|
|
||||||
if (found == true && val != not_nullptr) {
|
|
||||||
std::string log_file = *static_cast<std::string *>(val);
|
|
||||||
}
|
|
||||||
_log = new Logger(log_file);
|
|
||||||
_table = _getServerTable();
|
|
||||||
|
|
||||||
// host and port parsing
|
|
||||||
void *host = accessValue("host", toml::STRING, _table, _log);
|
void *host = accessValue("host", toml::STRING, _table, _log);
|
||||||
if (host != not_nullptr) {
|
if (host != not_nullptr) {
|
||||||
_host = *static_cast<std::string *>(host);
|
_host = *static_cast<std::string *>(host);
|
||||||
} else {
|
} else {
|
||||||
|
delete _table;
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"no host specified - please specify one in server.host");
|
"no host specified - please specify one in server.host");
|
||||||
}
|
}
|
||||||
|
// port parsing
|
||||||
void *port = accessValue("port", toml::INT, _table, _log);
|
void *port = accessValue("port", toml::INT, _table, _log);
|
||||||
if (host != not_nullptr) {
|
if (port != not_nullptr) {
|
||||||
_port = *static_cast<unsigned short *>(port);
|
_port = *static_cast<unsigned short *>(port);
|
||||||
} else {
|
} else {
|
||||||
|
delete _table;
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"no port specified - please specify one in server.port");
|
"no port specified - please specify one in server.port");
|
||||||
}
|
}
|
||||||
@ -86,13 +52,16 @@ Server::Server(std::string file_name) {
|
|||||||
std::string str = *static_cast<std::string *>((*vecIt)->getValue());
|
std::string str = *static_cast<std::string *>((*vecIt)->getValue());
|
||||||
_server_names->push_back(str);
|
_server_names->push_back(str);
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
_log->warn(
|
_log->warn(
|
||||||
"no server_names all request will be accepted from any hostname");
|
"no server_names all request will be accepted from any hostname");
|
||||||
|
_server_names = not_nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// error_pages parsing
|
// error_pages parsing
|
||||||
map = static_cast<std::map<std::string, toml::ANode *> *>(
|
std::map<std::string, toml::ANode *> *map =
|
||||||
accessValue("error_pages", toml::TABLE, _table, _log));
|
static_cast<std::map<std::string, toml::ANode *> *>(
|
||||||
|
accessValue("error_pages", toml::TABLE, _table, _log));
|
||||||
if (map != not_nullptr) {
|
if (map != not_nullptr) {
|
||||||
_err_pages = _parseErrPages(map);
|
_err_pages = _parseErrPages(map);
|
||||||
} else
|
} else
|
||||||
@ -101,27 +70,26 @@ Server::Server(std::string file_name) {
|
|||||||
// location parsing
|
// location parsing
|
||||||
it = _table->accessIt("location", toml::TABLE, found);
|
it = _table->accessIt("location", toml::TABLE, found);
|
||||||
if (found == true && it != _table->getTable()->end()) {
|
if (found == true && it != _table->getTable()->end()) {
|
||||||
_routes = new std::map<std::string, Route *>;
|
_routes = new std::map<URL, Route *>;
|
||||||
std::map<std::string, toml::ANode *> *location_table = it->second->getTable();
|
std::map<std::string, toml::ANode *> *location_table =
|
||||||
|
it->second->getTable();
|
||||||
for (it = location_table->begin(); it != location_table->end(); it++) {
|
for (it = location_table->begin(); it != location_table->end(); it++) {
|
||||||
if (_routes->find(it->first) != _routes->end())
|
if (_routes->find(URL(it->first)) != _routes->end())
|
||||||
continue;
|
continue;
|
||||||
(*_routes)[it->first] = new Route(it->second, _log);
|
(*_routes)[URL(it->first)] = new Route(it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete tomlFile->getParsedFile();
|
//delete _table;
|
||||||
delete tomlFile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server(void) {
|
Server::~Server(void) {
|
||||||
std::map<std::string, Route *>::iterator it = _routes->begin();
|
for (auto it = prange(_routes)) {
|
||||||
for (; it != _routes->end(); it++) {
|
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
delete _routes;
|
delete _routes;
|
||||||
delete _err_pages;
|
delete _err_pages;
|
||||||
delete _server_names;
|
if (_server_names != not_nullptr)
|
||||||
delete _log; // to see if nessecary
|
delete _server_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, std::string> *
|
std::map<int, std::string> *
|
||||||
@ -143,3 +111,21 @@ Server::_parseErrPages(std::map<std::string, toml::ANode *> *table) {
|
|||||||
}
|
}
|
||||||
return errPages;
|
return errPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Server::isServerName(const std::string &server_name) {
|
||||||
|
for (auto it = prange(_server_names)) {
|
||||||
|
if (*it == server_name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Route *Server::whatRoute(const URL &url) {
|
||||||
|
for (auto it = prange(_routes)) {
|
||||||
|
if (it->first == url) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return not_nullptr;
|
||||||
|
}
|
||||||
|
24
src/help.cpp
24
src/help.cpp
@ -6,11 +6,11 @@
|
|||||||
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/04/10 13:08:36 by adjoly #+# #+# */
|
/* Created: 2025/04/10 13:08:36 by adjoly #+# #+# */
|
||||||
/* Updated: 2025/04/10 14:20:36 by adjoly ### ########.fr */
|
/* Updated: 2025/04/22 11:47:39 by mmoussou ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "log.hpp"
|
#include <log.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <help.hpp>
|
#include <help.hpp>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -37,7 +37,7 @@ void _generateConf(void) {
|
|||||||
file << "[server]\nhost = \"localhost\"\nport = "
|
file << "[server]\nhost = \"localhost\"\nport = "
|
||||||
"8080\n\n[server.location./]\nmethods = { \"GET\" }\nroot "
|
"8080\n\n[server.location./]\nmethods = { \"GET\" }\nroot "
|
||||||
"= \"/var/www/html\"\ndirlist = true\nclient_max_body_size "
|
"= \"/var/www/html\"\ndirlist = true\nclient_max_body_size "
|
||||||
"= \"10M\"";
|
"= \"10M\"\n";
|
||||||
file.close();
|
file.close();
|
||||||
_log.info("config file successfully generated");
|
_log.info("config file successfully generated");
|
||||||
} else {
|
} else {
|
||||||
@ -50,16 +50,24 @@ void _printVersion(void) {
|
|||||||
std::cout << "You are running : Webserv " << WEBSRV_VERSION << std::endl;
|
std::cout << "You are running : Webserv " << WEBSRV_VERSION << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void help(int ac, char **av) {
|
bool help(int ac, char **av) {
|
||||||
if (ac < 2) {
|
if (ac < 2) {
|
||||||
_printHelp();
|
_printHelp();
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
std::string option = av[1];
|
std::string option = av[1];
|
||||||
if (option == "--help" || option == "-v")
|
if (option == "--help" || option == "-v") {
|
||||||
_printHelp();
|
_printHelp();
|
||||||
else if (option == "--generate" || option == "-g")
|
return true;
|
||||||
|
}
|
||||||
|
else if (option == "--generate" || option == "-g") {
|
||||||
_generateConf();
|
_generateConf();
|
||||||
else if (option == "--version" || option == "-v")
|
return true;
|
||||||
|
}
|
||||||
|
else if (option == "--version" || option == "-v") {
|
||||||
_printVersion();
|
_printVersion();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
165
src/main.cpp
165
src/main.cpp
@ -6,134 +6,65 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/03 15:45:07 by mmoussou #+# #+# */
|
/* Created: 2025/02/03 15:45:07 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/04/10 12:18:39 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/22 15:43:21 by adjoly ### ########.fr */
|
||||||
/* Updated: 2025/03/25 17:10:29 by adjoly ### ########.fr */
|
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include <config/Server.hpp>
|
#include <config/default.hpp>
|
||||||
#include <tomlpp.hpp>
|
#include <csignal>
|
||||||
#include <webserv.hpp>
|
#include <server/default.hpp>
|
||||||
|
#include <config/Config.hpp>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <exception>
|
||||||
|
#include <help.hpp>
|
||||||
#include <requests/default.hpp>
|
#include <requests/default.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
#include <tomlpp.hpp>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <log.hpp>
|
||||||
|
#include <webserv.hpp>
|
||||||
|
|
||||||
#define PORT 8080
|
namespace webserv {
|
||||||
#define BUFFER_SIZE 4096
|
Logger *_log = not_nullptr;
|
||||||
|
|
||||||
int server_socket;
|
|
||||||
int client_socket;
|
|
||||||
|
|
||||||
void close_socket(int signal)
|
|
||||||
{
|
|
||||||
std::cerr << std::endl << "closing..." << std::endl;
|
|
||||||
close(client_socket);
|
|
||||||
close(server_socket);
|
|
||||||
exit(signal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getMethod(std::string &data)
|
int _sig = 0;
|
||||||
{
|
|
||||||
return (data.substr(0, data.substr(0, 4).find_last_not_of(" ") + 1));
|
void ft_sig(int sig) {
|
||||||
|
_sig = sig;
|
||||||
|
std::stringstream str;
|
||||||
|
str << "sig hitted = ";
|
||||||
|
str << sig;
|
||||||
|
_log->info(str.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main(int ac, char **av) {
|
||||||
{
|
if (help(ac, av)) {
|
||||||
// handle ctrl-C to close server socket
|
return EXIT_SUCCESS;
|
||||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR || signal(SIGINT, close_socket) == SIG_ERR || signal(SIGQUIT, close_socket) == SIG_ERR)
|
}
|
||||||
{
|
std::cout << "Starting server..." << std::endl;
|
||||||
std::cerr << "Error registering signal handlers!" << std::endl;
|
if (access(av[1], F_OK) < 0) {
|
||||||
return 1;
|
std::cout << "File : " << av[1] << " could not be opened" << std::endl;
|
||||||
}
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
// create a socket
|
|
||||||
server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if (server_socket == -1)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to create socket" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare the server address
|
config::Config *conf;
|
||||||
sockaddr_in server_address;
|
try {
|
||||||
std::memset(&server_address, 0, sizeof(server_address));
|
std::string str = av[1];
|
||||||
server_address.sin_family = AF_INET;
|
conf = new config::Config(str);
|
||||||
server_address.sin_addr.s_addr = INADDR_ANY;
|
} catch (std::exception &e) {
|
||||||
server_address.sin_port = htons(PORT);
|
std::cout << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (signal(SIGINT, &ft_sig) == SIG_ERR) {
|
||||||
|
conf->getLogger()->error("could not bind sigint :(");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (bind(server_socket, (sockaddr*)&server_address, sizeof(server_address)) == -1)
|
webserv::Server *serv = new webserv::Server(conf);
|
||||||
{
|
|
||||||
std::cerr << "Failed to bind socket" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (listen(server_socket, 5) == -1)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to listen on socket" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Server is listening on port " << PORT << std::endl;
|
delete serv;
|
||||||
|
delete _log;
|
||||||
while (true)
|
delete conf;
|
||||||
{
|
|
||||||
// accept an incoming connection
|
|
||||||
sockaddr_in client_address;
|
|
||||||
socklen_t client_address_len = sizeof(client_address);
|
|
||||||
//int client_socket = accept(server_socket, (sockaddr*)&client_address, &client_address_len);
|
|
||||||
client_socket = accept(server_socket, (sockaddr*)&client_address, &client_address_len);
|
|
||||||
if (client_socket == -1) {
|
|
||||||
std::cerr << "Failed to accept connection" << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// receive the HTTP request
|
|
||||||
std::string received_data;
|
|
||||||
char buffer[BUFFER_SIZE];
|
|
||||||
ssize_t bytes_received;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
std::memset(buffer, 0, BUFFER_SIZE);
|
|
||||||
bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0);
|
|
||||||
if (bytes_received == -1)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to receive request" << std::endl;
|
|
||||||
close(client_socket);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
received_data += std::string(buffer, bytes_received);
|
|
||||||
}
|
|
||||||
while (buffer[bytes_received]);
|
|
||||||
|
|
||||||
// parse the request
|
|
||||||
|
|
||||||
// handle the request
|
|
||||||
std::string response;
|
|
||||||
|
|
||||||
//std::cout << received_data << std::endl;
|
|
||||||
std::cout << getMethod(received_data) << std::endl;
|
|
||||||
|
|
||||||
if (getMethod(received_data) == "GET")
|
|
||||||
{
|
|
||||||
std::cout << "------------ GET REQUEST ------------" << std::endl;
|
|
||||||
http::Get request(received_data);
|
|
||||||
|
|
||||||
response = request.execute().str();
|
|
||||||
}
|
|
||||||
else if (getMethod(received_data) == "POST")
|
|
||||||
{
|
|
||||||
std::cout << "------------ POST REQUEST ------------" << std::endl;
|
|
||||||
http::Post request(received_data);
|
|
||||||
|
|
||||||
response = request.execute().str();
|
|
||||||
//std::cout << "worked" << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response = "HTTP/1.1 501 Not Implemented\r\nContent-Type: text/html\r\n\r\n<html><body><h1>501 Not Implemented</h1></body></html>";
|
|
||||||
}
|
|
||||||
|
|
||||||
send(client_socket, response.c_str(), response.length(), 0);
|
|
||||||
//close(client_socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(server_socket);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/03 16:07:01 by mmoussou #+# #+# */
|
/* Created: 2025/02/03 16:07:01 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/04/10 11:50:48 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/22 15:03:46 by adjoly ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -20,6 +20,10 @@
|
|||||||
|
|
||||||
using namespace webserv;
|
using namespace webserv;
|
||||||
|
|
||||||
|
http::IRequest::~IRequest(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::string http::IRequest::str(void) const
|
std::string http::IRequest::str(void) const
|
||||||
{
|
{
|
||||||
std::ostringstream response;
|
std::ostringstream response;
|
||||||
@ -75,6 +79,10 @@ http::Get::Get(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http::Get::~Get(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
http::Get::Get(std::string &data)
|
http::Get::Get(std::string &data)
|
||||||
{
|
{
|
||||||
this->parse(data);
|
this->parse(data);
|
||||||
@ -218,6 +226,10 @@ http::Delete::Delete(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http::Delete::~Delete(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
http::Delete::Delete(std::string &data)
|
http::Delete::Delete(std::string &data)
|
||||||
{
|
{
|
||||||
this->parse(data);
|
this->parse(data);
|
||||||
@ -297,6 +309,10 @@ http::Post::Post(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http::Post::~Post(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
http::Post::Post(std::string &data)
|
http::Post::Post(std::string &data)
|
||||||
{
|
{
|
||||||
this->parse(data);
|
this->parse(data);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/02/03 17:28:31 by mmoussou #+# #+# */
|
/* Created: 2025/02/03 17:28:31 by mmoussou #+# #+# */
|
||||||
/* Updated: 2025/04/08 01:11:40 by mmoussou ### ########.fr */
|
/* Updated: 2025/04/23 14:30:28 by mmoussou ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -27,6 +27,10 @@ http::Response::Response(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
http::Response::~Response(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
std::string http::Response::str(void) const
|
std::string http::Response::str(void) const
|
||||||
{
|
{
|
||||||
std::ostringstream response;
|
std::ostringstream response;
|
||||||
|
76
src/server/Client.cpp
Normal file
76
src/server/Client.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* Client.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: mmoussou <mmoussou@student.42angouleme.fr +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/04/17 11:12:41 by mmoussou #+# #+# */
|
||||||
|
/* Updated: 2025/04/23 14:40:06 by mmoussou ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include <log.hpp>
|
||||||
|
#include <server/Client.hpp>
|
||||||
|
|
||||||
|
using namespace server;
|
||||||
|
|
||||||
|
Client::Client(int fd, sockaddr_in socket, config::Config *conf)
|
||||||
|
: _fd(fd), _client_addr(socket) {
|
||||||
|
std::string received_data;
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
ssize_t bytes_received;
|
||||||
|
do {
|
||||||
|
std::memset(buffer, 0, BUFFER_SIZE);
|
||||||
|
bytes_received = recv(fd, buffer, BUFFER_SIZE - 1, 0);
|
||||||
|
if (bytes_received == -1) {
|
||||||
|
_log->error("failed to receive request");
|
||||||
|
throw std::runtime_error("failed to receive request");
|
||||||
|
}
|
||||||
|
received_data += std::string(buffer, bytes_received);
|
||||||
|
} while (buffer[bytes_received]);
|
||||||
|
|
||||||
|
this->_getRequest(received_data);
|
||||||
|
|
||||||
|
this->_conf = conf->getServer(this->_request->getHeaders()["Host"]);
|
||||||
|
|
||||||
|
// if (received_data.length > (get max_body_size from Route corresponding) )
|
||||||
|
// throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::_getRequest(std::string request_str) {
|
||||||
|
std::string method = request_str.substr(
|
||||||
|
0, request_str.substr(0, 4).find_last_not_of(" ") + 1);
|
||||||
|
|
||||||
|
if (method == "GET") {
|
||||||
|
_log->info("get request received");
|
||||||
|
this->_request = new http::Get(request_str);
|
||||||
|
} else if (method == "DELETE") {
|
||||||
|
_log->info("delete request received");
|
||||||
|
this->_request = new http::Delete(request_str);
|
||||||
|
} else if (method == "POST") {
|
||||||
|
_log->info("post request received");
|
||||||
|
this->_request = new http::Post(request_str);
|
||||||
|
} else {
|
||||||
|
_log->info("unsupported request received");
|
||||||
|
this->_request = new http::Get();
|
||||||
|
this->_request->setMethod("501");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::answer(void) {
|
||||||
|
(void) _client_addr;
|
||||||
|
std::string response;
|
||||||
|
|
||||||
|
if (this->_request->getMethod() == "GET" ||
|
||||||
|
this->_request->getMethod() == "DELETE" ||
|
||||||
|
this->_request->getMethod() == "POST")
|
||||||
|
response = this->_request->execute().str();
|
||||||
|
else
|
||||||
|
response = "HTTP/1.1 501 Not Implemented\r\nContent-Type: text/html\r\n\r\n<html><body><h1>501 Not Implemented</h1></body></html>";
|
||||||
|
send(this->_fd, response.c_str(), response.length(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Client::~Client(void) {
|
||||||
|
delete (http::Get *)(this->_request);
|
||||||
|
}
|
166
src/server/Server.cpp
Normal file
166
src/server/Server.cpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* Server.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/04/11 16:11:40 by adjoly #+# #+# */
|
||||||
|
/* Updated: 2025/04/23 16:22:22 by adjoly ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
|
#include <exception>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <iterator>
|
||||||
|
#include <log.hpp>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <requests/default.hpp>
|
||||||
|
#include <server/default.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <webserv.hpp>
|
||||||
|
|
||||||
|
using namespace webserv;
|
||||||
|
|
||||||
|
extern int _sig;
|
||||||
|
|
||||||
|
std::string convertIPToString(const struct in_addr *addr) {
|
||||||
|
unsigned int ip = ntohl(addr->s_addr);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << ((ip >> 24) & 0xFF) << "." << ((ip >> 16) & 0xFF) << "."
|
||||||
|
<< ((ip >> 8) & 0xFF) << "." << (ip & 0xFF);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string convertPortToString(const struct sockaddr_in *sa) {
|
||||||
|
int port = ntohs(sa->sin_port);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << port;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getMethod(std::string &data) {
|
||||||
|
return (data.substr(0, data.substr(0, 4).find_last_not_of(" ") + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
int Server::_fillHostsPorts(std::vector<std::string> &hosts,
|
||||||
|
std::vector<int> &ports) {
|
||||||
|
std::vector<config::Server *> config = _conf->getServers();
|
||||||
|
|
||||||
|
for (auto it = range(config)) {
|
||||||
|
hosts.push_back((*it)->getHost());
|
||||||
|
ports.push_back((*it)->getPort());
|
||||||
|
}
|
||||||
|
return config.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::_setup(void) {
|
||||||
|
std::vector<std::string> hosts;
|
||||||
|
std::vector<int> ports;
|
||||||
|
|
||||||
|
int size = _fillHostsPorts(hosts, ports);
|
||||||
|
if (size < 1)
|
||||||
|
throw std::runtime_error("no server present in the config file");
|
||||||
|
|
||||||
|
auto itH = hosts.begin();
|
||||||
|
for (auto it = range(ports), itH++) {
|
||||||
|
int fd = _createSocket(*itH, *it);
|
||||||
|
_fds_server.push_back(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
short sigHandling(void) {
|
||||||
|
if (_sig == SIGINT) {
|
||||||
|
return 727;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::_run(void) {
|
||||||
|
struct pollfd fd;
|
||||||
|
|
||||||
|
for (std::vector<int>::iterator it = _fds_server.begin();
|
||||||
|
it != _fds_server.end(); it++) {
|
||||||
|
fd.fd = *it;
|
||||||
|
fd.events = POLLIN;
|
||||||
|
_client_fds.push_back(fd);
|
||||||
|
_client_data.push_back(NULL);
|
||||||
|
_log->debug("new socket in poll");
|
||||||
|
}
|
||||||
|
|
||||||
|
// to add signal instead of 727
|
||||||
|
while (727 - sigHandling()) {
|
||||||
|
if (poll(_client_fds.data(), _client_fds.size(), -1) < 0) {
|
||||||
|
std::stringstream str;
|
||||||
|
str << "poll failed : ";
|
||||||
|
str << strerror(errno);
|
||||||
|
_log->error(str.str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = range(_fds_server)) {
|
||||||
|
struct sockaddr_in client_addr;
|
||||||
|
socklen_t addrlen = sizeof(client_addr);
|
||||||
|
int client_fd =
|
||||||
|
accept((*it), (struct sockaddr *)&client_addr, &addrlen);
|
||||||
|
|
||||||
|
if (client_fd < 0) {
|
||||||
|
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||||
|
continue;
|
||||||
|
std::stringstream str;
|
||||||
|
str << "Accept failed: ";
|
||||||
|
str << strerror(errno);
|
||||||
|
_log->error(str.str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pollfd pfd;
|
||||||
|
pfd.fd = client_fd;
|
||||||
|
pfd.events = POLLIN | POLLOUT;
|
||||||
|
pfd.revents = 0;
|
||||||
|
_client_fds.push_back(pfd);
|
||||||
|
struct sockaddr_in *new_client_sock = new sockaddr_in();
|
||||||
|
std::memmove(new_client_sock, &client_addr,
|
||||||
|
sizeof(struct sockaddr_in));
|
||||||
|
_client_data.push_back(new_client_sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = _fds_server.size(); i < _client_fds.size(); ++i) {
|
||||||
|
if (_client_fds[i].revents & POLLIN) {
|
||||||
|
if (_handle_client(_client_fds[i], _client_data[i])) {
|
||||||
|
close(_client_fds[i].fd);
|
||||||
|
_client_fds.erase(_client_fds.begin() + i);
|
||||||
|
delete _client_data[i];
|
||||||
|
_client_data.erase(_client_data.begin() + i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Server::Server(config::Config *conf) : _conf(conf) {
|
||||||
|
log("➕", "Server::Server", "config constructor called");
|
||||||
|
_log = conf->getLogger();
|
||||||
|
try {
|
||||||
|
_setup();
|
||||||
|
_run();
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
_log->error(e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Server::~Server(void) {
|
||||||
|
log("➖", "Server::Server", "destructor called");
|
||||||
|
for (std::vector<struct pollfd>::iterator it = _client_fds.begin();
|
||||||
|
it != _client_fds.end(); it++)
|
||||||
|
close(it->fd);
|
||||||
|
}
|
93
src/server/ServerUtils.cpp
Normal file
93
src/server/ServerUtils.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* ServerUtils.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: adjoly <adjoly@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2025/04/17 11:58:42 by adjoly #+# #+# */
|
||||||
|
/* Updated: 2025/04/23 16:00:14 by adjoly ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include <server/Client.hpp>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <server/default.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
using namespace webserv::server;
|
||||||
|
|
||||||
|
bool convertStringToIP(const char *ip_str, struct in_addr *addr) {
|
||||||
|
// Split the IP string into four octets
|
||||||
|
unsigned int a, b, c, d;
|
||||||
|
if (sscanf(ip_str, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if each octet is within the valid range
|
||||||
|
if (a > 255 || b > 255 || c > 255 || d > 255) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine the octets into a single 32-bit address
|
||||||
|
addr->s_addr = htonl((a << 24) | (b << 16) | (c << 8) | d);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Server::_createSocket(std::string host, int port) {
|
||||||
|
int fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||||
|
if (fd == -1) {
|
||||||
|
std::ostringstream str;
|
||||||
|
str << port;
|
||||||
|
throw std::runtime_error("socket binding failed for : " + host + ":" +
|
||||||
|
str.str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int opt = 1;
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
|
||||||
|
close(fd);
|
||||||
|
throw std::runtime_error("setsockopt failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
if (!convertStringToIP(host.c_str(), &addr.sin_addr)) {
|
||||||
|
throw std::runtime_error("ip is not of the valid format : " + host);
|
||||||
|
}
|
||||||
|
std::stringstream str;
|
||||||
|
str << port;
|
||||||
|
_log->debug("port : " + str.str());
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
|
close(fd);
|
||||||
|
std::ostringstream str;
|
||||||
|
str << port;
|
||||||
|
throw std::runtime_error("bind failed for : " + host + ":" + str.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(fd, SOMAXCONN) < 0) {
|
||||||
|
close(fd);
|
||||||
|
std::ostringstream str;
|
||||||
|
str << port;
|
||||||
|
throw std::runtime_error("listen failed for : " + host + ":" + str.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Server::_handle_client(struct pollfd &pollfd, sockaddr_in *sock_data) {
|
||||||
|
try {
|
||||||
|
Client client(pollfd.fd, *sock_data, _conf);
|
||||||
|
client.answer();
|
||||||
|
} catch (std::runtime_error &e) {
|
||||||
|
_log->error(e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
90
upload.html
90
upload.html
@ -1,90 +0,0 @@
|
|||||||
<meta charset="utf-8">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>upload</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- j'ai pas volé le code (c'est faux) -->
|
|
||||||
<!-- putain les pubs spotify c'est chiant -->
|
|
||||||
<!-- je m'en fous de leur bière -->
|
|
||||||
<form id="upload_form" enctype="multipart/form-data" method="post">
|
|
||||||
<input type="file" name="file1" id="file1" onchange="uploadFile()"><br>
|
|
||||||
<progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
|
|
||||||
<h3 id="status"></h3>
|
|
||||||
<p id="loaded_n_total"></p>
|
|
||||||
</form>
|
|
||||||
<button id="abort" hidden>annuler le tranfert</button>
|
|
||||||
<script>
|
|
||||||
function _(el) {
|
|
||||||
return document.getElementById(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
function uploadFile() {
|
|
||||||
bouton = document.getElementById("abort")
|
|
||||||
var file = _("file1").files[0];
|
|
||||||
|
|
||||||
// alert(file.name+" | "+file.size+" | "+file.type);
|
|
||||||
var formdata = new FormData();
|
|
||||||
formdata.append("file1", file);
|
|
||||||
var ajax = new XMLHttpRequest();
|
|
||||||
bouton.onclick = function(){
|
|
||||||
ajax.abort()
|
|
||||||
}
|
|
||||||
bouton.removeAttribute("hidden")
|
|
||||||
ajax.upload.addEventListener("progress", progressHandler, false);
|
|
||||||
ajax.addEventListener("load", completeHandler, false);
|
|
||||||
ajax.addEventListener("error", errorHandler, false);
|
|
||||||
ajax.addEventListener("abort", abortHandler, false);
|
|
||||||
ajax.open("POST", "/upload.html");
|
|
||||||
ajax.send(formdata);
|
|
||||||
startmillis = Date.now()
|
|
||||||
}
|
|
||||||
|
|
||||||
function copy(){
|
|
||||||
window.getSelection().removeAllRanges()
|
|
||||||
range = document.createRange()
|
|
||||||
range.selectNodeContents(_("addr"))
|
|
||||||
window.getSelection().addRange(range)
|
|
||||||
document.execCommand('copy')
|
|
||||||
window.getSelection().removeAllRanges()
|
|
||||||
temp = _("addr").innerHTML
|
|
||||||
_("addr").innerHTML = "copié !"
|
|
||||||
setTimeout(()=>{_("addr").innerHTML = temp},500)
|
|
||||||
}
|
|
||||||
|
|
||||||
function progressHandler(event) {
|
|
||||||
// console.log(Math.round((event.loaded/1024/1024)*100)/100)
|
|
||||||
// console.log((Date.now()-startmillis)/1000+'s')
|
|
||||||
//console.log((event.loaded/1024/1024) /((Date.now()-startmillis)*1000)+"Mo/s")
|
|
||||||
// console.log((event.loaded/1024/1024))
|
|
||||||
|
|
||||||
console.log(`${(event.loaded/1024/1024)} / ${(Date.now()-startmillis)} / 1000`)
|
|
||||||
console.log((event.loaded/1024/1024)/((Date.now()-startmillis)/1000))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_("loaded_n_total").innerHTML = Math.round((event.loaded/1024/1024)*100)/100 + "Mo / " + Math.round((event.total/1024/1024)*100)/100+"Mo envoyé<br/>"+Math.round((event.loaded/1024/1024)/((Date.now()-startmillis)/1000)*100)/100+"Mo/s en moyenne";
|
|
||||||
var percent = (event.loaded / event.total) * 100;
|
|
||||||
_("progressBar").value = Math.round(percent);
|
|
||||||
_("status").innerHTML = Math.round(percent * 100) / 100 + "% envoyé... veuillez patienter";
|
|
||||||
}
|
|
||||||
|
|
||||||
function completeHandler(event) {
|
|
||||||
_("status").innerHTML = event.target.responseText;
|
|
||||||
_("progressBar").value = 0; //wil clear progress bar after successful upload
|
|
||||||
console.log("fin de l'envoi")
|
|
||||||
_("abort").setAttribute("hidden",true)
|
|
||||||
}
|
|
||||||
|
|
||||||
function errorHandler(event) {
|
|
||||||
_("status").innerHTML = "Upload Failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
function abortHandler(event) {
|
|
||||||
_("status").innerHTML = "envoi annulé";
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
Reference in New Issue
Block a user