diff --git a/Makefile b/Makefile index f09c8cc..17f51b6 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ - NAME = webserv CXX = c++ @@ -6,19 +5,19 @@ CXX = c++ CXXFLAGS = -Wall -Wextra -Werror CXXFLAGS += -std=c++98 CXXFLAGS += -I$(HEADERS_D) -#CXXFLAGS += -g +CXXFLAGS += -g #CXXFLAGS += -O3 -SHELL = /bin/zsh +#SHELL = /bin/zsh VPATH = $(DIR_SRCS) -DIR_SRCS = tests +DIR_SRCS = srcs -HEADERS_D = ./templates -HEADERS = +HEADERS_D = ./srcs +HEADERS = Webserv.hpp DEPENDENCIES = $(HEADERS:%=$(HEADERS_D)/%) -SRCS = main.cpp +SRCS = main.cpp Webserv.cpp DIR_OBJS = builds OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o) @@ -29,7 +28,7 @@ OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o) all: $(NAME) -$(DIR_OBJS)/%.o: $(SRCS) | $(DIR_OBJS) +$(DIR_OBJS)/%.o: %.cpp | $(DIR_OBJS) $(CXX) $(CXXFLAGS) -c $< -o $@ $(DIR_OBJS): @@ -38,7 +37,7 @@ $(DIR_OBJS): $(OBJS): $(DEPENDENCIES) #$(OBJS): $(DEPENDENCIES) Makefile -$(NAME) : +$(NAME) : $(OBJS) $(CXX) $(OBJS) -o $(NAME) clean: diff --git a/srcs/Webserv.cpp b/srcs/Webserv.cpp index 884218a..a284a13 100644 --- a/srcs/Webserv.cpp +++ b/srcs/Webserv.cpp @@ -8,24 +8,20 @@ Webserv::Webserv() if (_socket_fd == -1) { ::perror("err socket(): "); - throw std::runtime_error("Socket init"); +// throw std::runtime_error("Socket init"); + throw WebservError(); } } -/* Webserv::Webserv(Webserv const &src) -{ - -} */ - Webserv::~Webserv() { std::cout << "Server destroyed\n"; } -/* Webserv & Webserv::operator=(Webserv const &rhs) -{ - -} */ +const char * Webserv::WebservError::what() const throw() { + return ("error"); +} + /////////////// // Functions // @@ -43,7 +39,7 @@ void Webserv::bind(in_port_t port) if (::bind(_socket_fd, (const sockaddr*)&addr, sizeof addr) == -1) { ::perror("err bind(): "); - throw std::runtime_error("Socket bind"); +// throw std::runtime_error("Socket bind"); } } @@ -52,7 +48,7 @@ void Webserv::listen(unsigned int max_connections) if (::listen(_socket_fd, max_connections) == -1) { ::perror("err listen(): "); - throw std::runtime_error("Socket listen"); +// throw std::runtime_error("Socket listen"); } } @@ -67,55 +63,56 @@ void Webserv::start() int accepted_fd; // poll (or equivalent) - struct pollfd poll_s; - poll_s.fd = _socket_fd; - poll_s.events = POLLIN; +// struct pollfd poll_s; +// poll_s.fd = _socket_fd; +// poll_s.events = POLLIN; - char buf[BUFSIZE]; // WIP buffer. need to try with std::vector or std::string. - int ret; +// char buf[BUFSIZE]; // WIP buffer. need to try with std::vector or std::string. +// int ret; std::cout << "Server started\n"; while (1) { - std::cout << "----------\n"; - std::cout << "poll()\n"; // poll (or equivalent) - ::poll(&poll_s, 1, -1); +// std::cout << "----------\n"; +// std::cout << "poll()\n"; // poll (or equivalent) +// ::poll(&poll_s, 1, -1); - std::cout << "accept()\n"; addr_len = sizeof addr; accepted_fd = ::accept(_socket_fd, (sockaddr*)&addr, &addr_len); if (accepted_fd == -1) { ::perror("err accept(): "); + //throw WebservError(); continue; } + std::cout << "accept()\n"; - // "Your server must never block and the client can be bounced properly if necessary". - // NO-Block OK, but how to handle it ? Miss the bouncing part. - ::fcntl(accepted_fd, F_SETFL, O_NONBLOCK); - - std::cout << "recv()\n"; - ret = ::recv(accepted_fd, buf, BUFSIZE, 0); - if (ret == -1) - { - ::perror("err recv(): "); - if (::send(accepted_fd, MSG_BOUNCE, sizeof MSG_BOUNCE - 1, 0) == -1) - ::perror("err send(): "); - ::close(accepted_fd); - continue; - } - /* - if (ret == BUFSIZE) - // send error like "request too long" to client - */ - buf[ret] = '\0'; - - std::cout << "send()\n"; - if (::send(accepted_fd, buf, ret, 0) == -1) // echo the read - ::perror("err send(): "); - if (::send(accepted_fd, MSG_TEST, sizeof MSG_TEST - 1, 0) == -1) - ::perror("err send(): "); - - ::close(accepted_fd); +// // "Your server must never block and the client can be bounced properly if necessary". +// // NO-Block OK, but how to handle it ? Miss the bouncing part. +// ::fcntl(accepted_fd, F_SETFL, O_NONBLOCK); +// +// std::cout << "recv()\n"; +// ret = ::recv(accepted_fd, buf, BUFSIZE, 0); +// if (ret == -1) +// { +// ::perror("err recv(): "); +// if (::send(accepted_fd, MSG_BOUNCE, sizeof MSG_BOUNCE - 1, 0) == -1) +// ::perror("err send(): "); +// ::close(accepted_fd); +// continue; +// } +// /* +// if (ret == BUFSIZE) +// // send error like "request too long" to client +// */ +// buf[ret] = '\0'; +// +// std::cout << "send()\n"; +// if (::send(accepted_fd, buf, ret, 0) == -1) // echo the read +// ::perror("err send(): "); +// if (::send(accepted_fd, MSG_TEST, sizeof MSG_TEST - 1, 0) == -1) +// ::perror("err send(): "); +// +// ::close(accepted_fd); } } diff --git a/srcs/Webserv.hpp b/srcs/Webserv.hpp index 01f87f1..d57511c 100644 --- a/srcs/Webserv.hpp +++ b/srcs/Webserv.hpp @@ -36,6 +36,11 @@ class Webserv std::map _request; std::map _response; + class WebservError : public std::exception { + const char * what() const throw(); + }; + }; #endif + diff --git a/srcs/main.cpp b/srcs/main.cpp index eecfa30..ae76e10 100644 --- a/srcs/main.cpp +++ b/srcs/main.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include "Webserv.hpp" int main(void) { @@ -28,47 +28,56 @@ int main(void) /* wip hugo version + # include + # include + # include + # include // close + # include // fcntl -# include +# include // cout, cin # include // errno # include // perror +# include // memset # include // socket, accept, listen, send, recv, bind, connect, setsockopt, getsockname # include // sockaddr_in +# include // inet_ntoa, inet_addr, htonl, htons, ntohl, ntohs +# include // poll -# define INVALID_SCKT -1 -# define INVALID_BIND -1 -# define INVALID_LSTN -1 -# define INVALID_AXPT -1 +# define INVALID -1 # define PORT 80 -# define NB_CONX 20 +# define BACKLOG 20 int main() { struct sockaddr_in my_addr; struct sockaddr_in their_addr; - int socket_fd; - int new_fd; + int sckt_fd; + int axpt_fd; int lstn; + socklen_t addr_len; - socket_fd = socket(AF_INET, SOCK_STREAM, 0); - if (socket_fd == INVALID_SCKT) + // INIT SOCKET + sckt_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + if (sckt_fd == INVALID) { perror("err socket(): "); return 0; } + std::cout << "server init\n"; + // BIND IT memset(&my_addr, 0, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(PORT); my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // my_addr.sin_addr.s_addr = inet_addr("10.12.110.57"); - - bind(socket_fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); - if (socket_fd == INVALID_BIND) + bind(sckt_fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + if (sckt_fd == INVALID) { perror("err bind(): "); return 0; } + std::cout << "socket bind to port: " << PORT << "\n"; // https://beej.us/guide/bgnet/html/index-wide.html#cb29 : // // Sometimes, you might notice, you try to rerun a server and bind() fails, claiming “Address already in use.” What does that mean? Well, a little bit of a socket that was connected is still hanging around in the kernel, and it’s hogging the port. You can either wait for it to clear (a minute or so), or add code to your program allowing it to reuse the port, like this: @@ -81,20 +90,31 @@ int main() // exit(1); // } - lstn = listen(socket_fd, NB_CONX); - if (lstn == INVALID_LSTN) + // LISTEN ON IT + lstn = listen(sckt_fd, BACKLOG); + if (lstn == INVALID) { perror("err listen(): "); return 0; } + std::cout << "server listening\n"; - new_fd = accept(socket_fd, &their_addr, sizeof(their_addr)); - if (new_fd == INVALID_AXPT) + // ACCEPT INCOMING CONNECT + while (1) { - perror("err accept(): "); - return 0; - } + addr_len = sizeof(their_addr); + axpt_fd = accept(sckt_fd, (sockaddr*)&their_addr, &addr_len); + if (axpt_fd == INVALID) + { + perror("err accept(): "); + continue; + } + std::cout << "server accepted a socket from: " + << inet_ntoa(their_addr.sin_addr) + << "\n"; + break; + } return 0; } diff --git a/webserv b/webserv new file mode 100755 index 0000000..7d8cc3e Binary files /dev/null and b/webserv differ