wip with both my and luke code

This commit is contained in:
hugogogo
2022-07-13 17:31:18 +02:00
parent 461c10b6a2
commit 6b1fd5a15b
5 changed files with 99 additions and 78 deletions

View File

@@ -1,4 +1,3 @@
NAME = webserv NAME = webserv
CXX = c++ CXX = c++
@@ -6,19 +5,19 @@ CXX = c++
CXXFLAGS = -Wall -Wextra -Werror CXXFLAGS = -Wall -Wextra -Werror
CXXFLAGS += -std=c++98 CXXFLAGS += -std=c++98
CXXFLAGS += -I$(HEADERS_D) CXXFLAGS += -I$(HEADERS_D)
#CXXFLAGS += -g CXXFLAGS += -g
#CXXFLAGS += -O3 #CXXFLAGS += -O3
SHELL = /bin/zsh #SHELL = /bin/zsh
VPATH = $(DIR_SRCS) VPATH = $(DIR_SRCS)
DIR_SRCS = tests DIR_SRCS = srcs
HEADERS_D = ./templates HEADERS_D = ./srcs
HEADERS = HEADERS = Webserv.hpp
DEPENDENCIES = $(HEADERS:%=$(HEADERS_D)/%) DEPENDENCIES = $(HEADERS:%=$(HEADERS_D)/%)
SRCS = main.cpp SRCS = main.cpp Webserv.cpp
DIR_OBJS = builds DIR_OBJS = builds
OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o) OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o)
@@ -29,7 +28,7 @@ OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o)
all: $(NAME) all: $(NAME)
$(DIR_OBJS)/%.o: $(SRCS) | $(DIR_OBJS) $(DIR_OBJS)/%.o: %.cpp | $(DIR_OBJS)
$(CXX) $(CXXFLAGS) -c $< -o $@ $(CXX) $(CXXFLAGS) -c $< -o $@
$(DIR_OBJS): $(DIR_OBJS):
@@ -38,7 +37,7 @@ $(DIR_OBJS):
$(OBJS): $(DEPENDENCIES) $(OBJS): $(DEPENDENCIES)
#$(OBJS): $(DEPENDENCIES) Makefile #$(OBJS): $(DEPENDENCIES) Makefile
$(NAME) : $(NAME) : $(OBJS)
$(CXX) $(OBJS) -o $(NAME) $(CXX) $(OBJS) -o $(NAME)
clean: clean:

View File

@@ -8,24 +8,20 @@ Webserv::Webserv()
if (_socket_fd == -1) if (_socket_fd == -1)
{ {
::perror("err socket(): "); ::perror("err socket(): ");
throw std::runtime_error("Socket init"); // throw std::runtime_error("Socket init");
throw WebservError();
} }
} }
/* Webserv::Webserv(Webserv const &src)
{
} */
Webserv::~Webserv() Webserv::~Webserv()
{ {
std::cout << "Server destroyed\n"; std::cout << "Server destroyed\n";
} }
/* Webserv & Webserv::operator=(Webserv const &rhs) const char * Webserv::WebservError::what() const throw() {
{ return ("error");
}
} */
/////////////// ///////////////
// Functions // // Functions //
@@ -43,7 +39,7 @@ void Webserv::bind(in_port_t port)
if (::bind(_socket_fd, (const sockaddr*)&addr, sizeof addr) == -1) if (::bind(_socket_fd, (const sockaddr*)&addr, sizeof addr) == -1)
{ {
::perror("err bind(): "); ::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) if (::listen(_socket_fd, max_connections) == -1)
{ {
::perror("err listen(): "); ::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; int accepted_fd;
// poll (or equivalent) // poll (or equivalent)
struct pollfd poll_s; // struct pollfd poll_s;
poll_s.fd = _socket_fd; // poll_s.fd = _socket_fd;
poll_s.events = POLLIN; // poll_s.events = POLLIN;
char buf[BUFSIZE]; // WIP buffer. need to try with std::vector or std::string. // char buf[BUFSIZE]; // WIP buffer. need to try with std::vector or std::string.
int ret; // int ret;
std::cout << "Server started\n"; std::cout << "Server started\n";
while (1) while (1)
{ {
std::cout << "----------\n"; // std::cout << "----------\n";
std::cout << "poll()\n"; // poll (or equivalent) // std::cout << "poll()\n"; // poll (or equivalent)
::poll(&poll_s, 1, -1); // ::poll(&poll_s, 1, -1);
std::cout << "accept()\n";
addr_len = sizeof addr; addr_len = sizeof addr;
accepted_fd = ::accept(_socket_fd, (sockaddr*)&addr, &addr_len); accepted_fd = ::accept(_socket_fd, (sockaddr*)&addr, &addr_len);
if (accepted_fd == -1) if (accepted_fd == -1)
{ {
::perror("err accept(): "); ::perror("err accept(): ");
//throw WebservError();
continue; continue;
} }
std::cout << "accept()\n";
// "Your server must never block and the client can be bounced properly if necessary". // // "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. // // NO-Block OK, but how to handle it ? Miss the bouncing part.
::fcntl(accepted_fd, F_SETFL, O_NONBLOCK); // ::fcntl(accepted_fd, F_SETFL, O_NONBLOCK);
//
std::cout << "recv()\n"; // std::cout << "recv()\n";
ret = ::recv(accepted_fd, buf, BUFSIZE, 0); // ret = ::recv(accepted_fd, buf, BUFSIZE, 0);
if (ret == -1) // if (ret == -1)
{ // {
::perror("err recv(): "); // ::perror("err recv(): ");
if (::send(accepted_fd, MSG_BOUNCE, sizeof MSG_BOUNCE - 1, 0) == -1) // if (::send(accepted_fd, MSG_BOUNCE, sizeof MSG_BOUNCE - 1, 0) == -1)
::perror("err send(): "); // ::perror("err send(): ");
::close(accepted_fd); // ::close(accepted_fd);
continue; // continue;
} // }
/* // /*
if (ret == BUFSIZE) // if (ret == BUFSIZE)
// send error like "request too long" to client // // send error like "request too long" to client
*/ // */
buf[ret] = '\0'; // buf[ret] = '\0';
//
std::cout << "send()\n"; // std::cout << "send()\n";
if (::send(accepted_fd, buf, ret, 0) == -1) // echo the read // if (::send(accepted_fd, buf, ret, 0) == -1) // echo the read
::perror("err send(): "); // ::perror("err send(): ");
if (::send(accepted_fd, MSG_TEST, sizeof MSG_TEST - 1, 0) == -1) // if (::send(accepted_fd, MSG_TEST, sizeof MSG_TEST - 1, 0) == -1)
::perror("err send(): "); // ::perror("err send(): ");
//
::close(accepted_fd); // ::close(accepted_fd);
} }
} }

View File

@@ -36,6 +36,11 @@ class Webserv
std::map<std::string, std::string> _request; std::map<std::string, std::string> _request;
std::map<std::string, std::string> _response; std::map<std::string, std::string> _response;
class WebservError : public std::exception {
const char * what() const throw();
};
}; };
#endif #endif

View File

@@ -6,7 +6,7 @@
#include <iostream> #include <iostream>
#include <exception> #include <exception>
#include <stdexcept> #include <stdexcept>
#include <Webserv.hpp> #include "Webserv.hpp"
int main(void) int main(void)
{ {
@@ -28,47 +28,56 @@ int main(void)
/* /*
wip hugo version wip hugo version
# include <map>
# include <exception>
# include <stdexcept>
# include <unistd.h> // close
# include <fcntl.h> // fcntl
# include <iostream> # include <iostream> // cout, cin
# include <cerrno> // errno # include <cerrno> // errno
# include <cstdio> // perror # include <cstdio> // perror
# include <string.h> // memset
# include <sys/socket.h> // socket, accept, listen, send, recv, bind, connect, setsockopt, getsockname # include <sys/socket.h> // socket, accept, listen, send, recv, bind, connect, setsockopt, getsockname
# include <netinet/in.h> // sockaddr_in # include <netinet/in.h> // sockaddr_in
# include <arpa/inet.h> // inet_ntoa, inet_addr, htonl, htons, ntohl, ntohs
# include <poll.h> // poll
# define INVALID_SCKT -1 # define INVALID -1
# define INVALID_BIND -1
# define INVALID_LSTN -1
# define INVALID_AXPT -1
# define PORT 80 # define PORT 80
# define NB_CONX 20 # define BACKLOG 20
int main() int main()
{ {
struct sockaddr_in my_addr; struct sockaddr_in my_addr;
struct sockaddr_in their_addr; struct sockaddr_in their_addr;
int socket_fd; int sckt_fd;
int new_fd; int axpt_fd;
int lstn; int lstn;
socklen_t addr_len;
socket_fd = socket(AF_INET, SOCK_STREAM, 0); // INIT SOCKET
if (socket_fd == INVALID_SCKT) sckt_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if (sckt_fd == INVALID)
{ {
perror("err socket(): "); perror("err socket(): ");
return 0; return 0;
} }
std::cout << "server init\n";
// BIND IT
memset(&my_addr, 0, sizeof(my_addr)); memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET; my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT); my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// my_addr.sin_addr.s_addr = inet_addr("10.12.110.57"); // my_addr.sin_addr.s_addr = inet_addr("10.12.110.57");
bind(sckt_fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
bind(socket_fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); if (sckt_fd == INVALID)
if (socket_fd == INVALID_BIND)
{ {
perror("err bind(): "); perror("err bind(): ");
return 0; return 0;
} }
std::cout << "socket bind to port: " << PORT << "\n";
// https://beej.us/guide/bgnet/html/index-wide.html#cb29 : // 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 its 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: // 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 its 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); // exit(1);
// } // }
lstn = listen(socket_fd, NB_CONX); // LISTEN ON IT
if (lstn == INVALID_LSTN) lstn = listen(sckt_fd, BACKLOG);
if (lstn == INVALID)
{ {
perror("err listen(): "); perror("err listen(): ");
return 0; return 0;
} }
std::cout << "server listening\n";
new_fd = accept(socket_fd, &their_addr, sizeof(their_addr)); // ACCEPT INCOMING CONNECT
if (new_fd == INVALID_AXPT) while (1)
{
addr_len = sizeof(their_addr);
axpt_fd = accept(sckt_fd, (sockaddr*)&their_addr, &addr_len);
if (axpt_fd == INVALID)
{ {
perror("err accept(): "); perror("err accept(): ");
return 0; continue;
}
std::cout << "server accepted a socket from: "
<< inet_ntoa(their_addr.sin_addr)
<< "\n";
break;
} }
return 0; return 0;
} }

BIN
webserv Executable file

Binary file not shown.