From 46a5e55e6dfb60116e2c071dc7ab550ccfc8332e Mon Sep 17 00:00:00 2001 From: hugogogo Date: Fri, 22 Jul 2022 22:17:12 +0200 Subject: [PATCH] baked hugo version of webserv --- Makefile | 38 +----- srcs/{Webserv.cpp => bak__Webserv.cpp} | 2 +- srcs/{Webserv.hpp => bak__Webserv.hpp} | 0 srcs/main_1.cpp | 163 ------------------------- webserv | Bin 201224 -> 201248 bytes 5 files changed, 7 insertions(+), 196 deletions(-) rename srcs/{Webserv.cpp => bak__Webserv.cpp} (99%) rename srcs/{Webserv.hpp => bak__Webserv.hpp} (100%) delete mode 100644 srcs/main_1.cpp diff --git a/Makefile b/Makefile index 9018e0d..edf516a 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,4 @@ -## VARIABLES -#NAME = my_program -#VPATH = srcs -#CXX = c++ -#CXXFLAGS = -I ./srcs -#OBJS = $(SRCS:%.cpp=%.o) -# -#MAIN = main.cpp -#SRCS = $(MAIN) Webserv.cpp -# -## RULES -#all: $(NAME) -# -#hugo: MAIN = main_hugo.cpp -#hugo: re -# -#$(NAME) : $(OBJS) -# $(CXX) $(OBJS) -o $(NAME) -#clean: -# rm -f $(OBJS) -#fclean: clean -# rm -f $(NAME) -#re: fclean all -#.PHONY : all clean fclean re - - NAME = webserv CXX = c++ @@ -40,14 +14,16 @@ VPATH = $(DIR_SRCS) DIR_SRCS = srcs HEADERS_D = ./srcs -HEADERS = Webserv.hpp +HEADERS = bak__Webserv.hpp DEPENDENCIES = $(HEADERS:%=$(HEADERS_D)/%) -SRCS = $(MAIN) Webserv.cpp -MAIN = main.cpp +#SRCS = $(MAIN) Webserv.cpp +SRCS = $(MAIN) bak__Webserv.cpp + +#MAIN = main.cpp #MAIN = main_luke.cpp -#MAIN = main_hugo.cpp +MAIN = main_hugo.cpp #MAIN = main_poll.cpp #MAIN = main_select.cpp @@ -59,8 +35,6 @@ OBJS = $(SRCS:%.cpp=$(DIR_OBJS)/%.o) # -------------------- all: $(NAME) -luke: Webserv.cpp main_luke.cpp -luke: re $(DIR_OBJS)/%.o: %.cpp | $(DIR_OBJS) $(CXX) $(CXXFLAGS) -c $< -o $@ diff --git a/srcs/Webserv.cpp b/srcs/bak__Webserv.cpp similarity index 99% rename from srcs/Webserv.cpp rename to srcs/bak__Webserv.cpp index a918509..3a82531 100644 --- a/srcs/Webserv.cpp +++ b/srcs/bak__Webserv.cpp @@ -1,5 +1,5 @@ -#include "Webserv.hpp" +#include "bak__Webserv.hpp" Webserv::Webserv() { diff --git a/srcs/Webserv.hpp b/srcs/bak__Webserv.hpp similarity index 100% rename from srcs/Webserv.hpp rename to srcs/bak__Webserv.hpp diff --git a/srcs/main_1.cpp b/srcs/main_1.cpp deleted file mode 100644 index ec98b84..0000000 --- a/srcs/main_1.cpp +++ /dev/null @@ -1,163 +0,0 @@ - -# include // close -# include // exit -# 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 -# include // fcntl - -# define INVALID -1 -# define BACKLOG 20 -// test with curl http://localhost:PORT (replace PORT by the port number you choose below) -# define PORT 4040 -# define BUFSIZE 8192 -# define MSG_TEST "Le Webserv / 20 =D\n" -# define MSG_BOUNCE "bounced properly ;)\n" - -int main() -{ - struct sockaddr_in my_addr, their_addr; - int sckt_fd, axpt_fd, lstn, ret; - socklen_t addr_len; - struct pollfd poll_s; - char buf[BUFSIZE]; - - - // --------------------------------------------------------------------------- // - // 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 // - // // - // --------------------------------------------------------------------------- // - 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(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: - // - // int yes=1; - // - // // lose the pesky "Address already in use" error message - // if (setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof yes) == -1) { - // perror("setsockopt"); - // exit(1); - // } - - - // --------------------------------------------------------------------------- // - // LISTEN // - // mark the socket as passive, to receive incoming connection requests // - // --------------------------------------------------------------------------- // - lstn = listen(sckt_fd, BACKLOG); - if (lstn == INVALID) - { - perror("err listen()"); - return 0; - } - std::cout << "server listening\n"; - - while (1) - { - - // ----------------------------------------------------------------------- // - // ACCEPT // - // extract first connection request in the queue of the listening socket // - // and creates a new socket that is connected, and returns it // - // ----------------------------------------------------------------------- // - 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"; - - - ///////////////////// - // luke version - ///////////////////// - - - // ----------------------------------------------------------------------- // - // FCNTL // - // manipulate the new socket fd to mark it as non-blocking // - // ----------------------------------------------------------------------- // - fcntl(axpt_fd, F_SETFL, O_NONBLOCK); - - - // ----------------------------------------------------------------------- // - // POLL // - // waits for an event on the axpt_fd : there is data to read // - // ----------------------------------------------------------------------- // - poll_s.fd = axpt_fd; - poll_s.events = POLLIN; // We need a way to valid POLLOUT and POLLIN at the same time (both, not one of them) - poll(&poll_s, 1, -1); - std::cout << "poll()\n"; - - - // ----------------------------------------------------------------------- // - // RECV // - // act as read, read the data of the socket created by accept() // - // ----------------------------------------------------------------------- // - ret = recv(axpt_fd, buf, BUFSIZE, 0); - if (ret == -1) - { - perror("err recv()"); - if (send(axpt_fd, MSG_BOUNCE, sizeof MSG_BOUNCE - 1, 0) == -1) - perror("err send()"); - close(axpt_fd); - continue; - } - std::cout << "recv()\n"; - buf[ret] = '\0'; - - - // ----------------------------------------------------------------------- // - // SEND // - // act as write, write data in the socket created by accept() // - // ----------------------------------------------------------------------- // - std::cout << "send()\n"; - if (send(axpt_fd, buf, ret, 0) == -1) // echo the read - perror("err send()"); - if (send(axpt_fd, MSG_TEST, sizeof MSG_TEST - 1, 0) == -1) - perror("err send()"); - - // ----------------------------------------------------------------------- // - // CLOSE // - // close the file descriptor of the connected socket // - // ----------------------------------------------------------------------- // - close(axpt_fd); - } - - return 0; -} - diff --git a/webserv b/webserv index 0c070e500f2f525baced64401c6d55f30b0c3e6e..208505c9ecf3992f47a4962e47e8bfe44c1e844f 100755 GIT binary patch delta 9492 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
nsBKOO6R_ZaJ9fW8VliL
zDLyJ#^~eb~SE=8JxLDvTke0>1qMhUn!9l!U;PtS8z<<}P%+=BtxL)81$UA|rY6Ci*
zRLArQ;8Plo)%OwS@e;_1fL)eBsou*goFf8BD2}4#DMWEL1)c#|l%LUs2R=0(X5UW%pVn}lKINQN
z=*j5<_r1rIF49@)48J-q225eRUb=2(H`45ixn4vM!>%&%Ts^V#jPhkV42N_B#
z=0s3}9s@-L=IDLu>z(?Ra{$}^1O?&71tFU&gnugt!rxn;au4gB9pXB`biwFC6f#4&
z3hoNJ7eLqZZ{>)3=<`LA2xn)VEY7{Q;|zg!fGkzurC@WOp1J}Z;&OpcY3T$QRGt|Y
zv+vE-fL+ESPV{sod=?ZNgW_xK=O65Q1R5liWd4cTQqxTZ*nhgfHv!B1=XGT)(6Bcb
z1GWu9^)bzp$LocE4G5ynO;?UD8r9Vc9E9bIx?CJ2@~qbDz0GtKa914u5vq;qlNoNn
zI8Tgc3?~An1+{~YT6~;8lg1yjZ0lBQbGL4A#lL`F^RXtoPkqBQ&n3QyAw9qmzScDS
a%Q^?0N6}F|SvP*&*P28{eAd_6;eP>Dnssgf

delta 9470
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
WkD1f_(uzOwv$n