diff --git a/42_testers/cgi_tester b/42_testers/cgi_tester new file mode 100755 index 0000000..72def28 Binary files /dev/null and b/42_testers/cgi_tester differ diff --git a/42_testers/tester b/42_testers/tester new file mode 100755 index 0000000..34c9ab1 Binary files /dev/null and b/42_testers/tester differ diff --git a/Makefile b/Makefile index 82cf35a..a775cd8 100644 --- a/Makefile +++ b/Makefile @@ -3,25 +3,15 @@ NAME = webserv CXX = c++ CXXFLAGS = -Wall -Wextra #-Werror -CXXFLAGS += $(HEADERS_I) +CXXFLAGS += $(HEADERS_D:%=-I%) CXXFLAGS += -std=c++98 CXXFLAGS += -g CXXFLAGS += -MMD -MP #header dependencie #CXXFLAGS += -O3 -#SHELL = /bin/zsh VPATH = $(SRCS_D) -HEADERS_I = $(HEADERS_D:%=-I%) -HEADERS_D = srcs \ - headers -HEADERS = Webserv.hpp \ - ConfigParser.hpp \ - ServerConfig.hpp \ - LocationConfig.hpp \ - Client.hpp \ - MethodType.hpp \ - utils.hpp \ +HEADERS_D = srcs SRCS_D = srcs \ srcs/webserv @@ -33,6 +23,8 @@ SRCS = main.cpp \ ConfigParserUtils.cpp \ ConfigParserPost.cpp \ utils.cpp \ + cgi_script.cpp \ + Client.cpp \ OBJS_D = builds OBJS = $(SRCS:%.cpp=$(OBJS_D)/%.o) diff --git a/README.md b/README.md new file mode 100644 index 0000000..20c8b93 --- /dev/null +++ b/README.md @@ -0,0 +1,136 @@ + +--- +## questions +- mettre les fonctions specifiques a la requete, dans la class client ? +- où est-ce que j'inclus le cgi ? +- est-ce que le cgi est appellé par `/cgi-bin` ? + - non +- g rajouté `char ** env` dans client.cpp + - non +- ajouter un champ "message body" dans client ? + - non +- comment organiser la creation du message reponse (cgi ou pas) et des headers ? +- comment je gere le path `/cgi-bin/` avec la suite ? +- qu'est-ce que le cgi renvoit comme headers ? comment c'est géré ? + - https://www.rfc-editor.org/rfc/rfc3875 + +--- +## man + +- **htons, htonl, ntohs, ntohl :** converts the unsigned short or integer argument between host byte order and network byte order +- **poll :** waits for one of a set of file descriptors to become ready to perform I/O + - alternatives : select, epoll (epoll_create, epoll_ctl, epoll_wait), kqueue (kqueue, kevent) +- **socket :** creates an endpoint for communication and returns a file descriptor that refers to that endpoint +- **listen :** marks a socket as a passive socket, that is, as a socket that will be used to accept incoming connection requests using accept() +- **accept :** used with connection-based socket types. It extracts the first connection request on the queue of pending connections for the listening socket, creates a new connected socket, and returns a new file descriptor referring to that socket. The newly created socket is not in the listening state. The original socket is unaffected by this call +- **send :** (~write) used to transmit a message to another socket. May be used only when the socket is in a connected state (so that the intended recipient is known). The only difference between send() and write() is the presence of flags. With a zero flags argument, send() is equivalent to write() +- **recv :** (~read) used to receive messages from a socket. May be used to receive data on both connectionless and connection-oriented sockets. The only difference between recv() and read() is the presence of flags. With a zero flags argument, recv() is generally equivalent to read() +- **bind :** associate a socket fd to a local address. When a socket is created with socket(), it exists in a name space (address family) but has no address assigned to it. It is normally necessary to assign a local address using bind() before a socket may receive connections (see accept()) +- **connect :** connects a socket fd to a remote address +- **inet_addr :** converts the Internet host address cp from IPv4 numbers-and-dots notation into binary data in network byte order. Use of this function is problematic because in case of error it returns -1, wich is a valid address (255.255.255.255). Avoid its use in favor of inet_aton(), inet_pton(), or getaddrinfo() +- **setsockopt :** manipulate options for a socket fd. Options may exist at multiple protocol levels; they are always present at the uppermost socket level +- **getsockname :** returns the current address to which a socket fd is bound +- **fcntl :** manipulate an open fd, by performing some actions, like duplicate it or changing its flags + +--- +## todo + +- [ ] read the RFC and do some tests with telnet and NGINX +#### parsing config +- [ ] Your program has to take a configuration file as argument, or use a default path. +- [ ] Choose the port and host of each ’server’. +- [ ] Setup the server_names or not. +- [ ] The first server for a host:port will be the default for this host:port (that means it will answer to all the requests that don’t belong to an other server). +- [ ] Setup default error pages. +- [ ] Limit client body size. +- [ ] Setup routes with one or multiple of the following rules/configuration (routes wont be using regexp): + - [ ] Define a list of accepted HTTP methods for the route. + - [ ] Define a HTTP redirection. + - [ ] Define a directory or a file from where the file should be searched (for example, if url /kapouet is rooted to /tmp/www, url /kapouet/pouic/toto/pouet is /tmp/www/pouic/toto/pouet). + - [ ] Turn on or off directory listing. + - [ ] Set a default file to answer if the request is a directory. + - [ ] Execute CGI based on certain file extension (for example .php). + - [ ] Make the route able to accept uploaded files and configure where they should be saved. +#### connection basic +- [ ] You can’t execve another web server. +- [ ] Your server must never block and the client can be bounced properly if necessary. +- [ ] It must be non-blocking and use only 1 poll() (or equivalent) for all the I/O operations between the client and the server (listen included). +- [ ] poll() (or equivalent) must check read and write at the same time. +- [ ] You must never do a read or a write operation without going through poll() (or equivalent). +- [ ] Checking the value of errno is strictly forbidden after a read or a write operation. +- [ ] You don’t need to use poll() (or equivalent) before reading your configuration file. Because you have to use non-blocking file descriptors, it is possible to use read/recv or write/send functions with no poll() (or equivalent), and your server wouldn’t be blocking. But it would consume more system resources. Thus, if you try to read/recv or write/send in any file descriptor without using poll() (or equivalent), your grade will be 0. +- [ ] You can use every macro and define like FD_SET, FD_CLR, FD_ISSET, FD_ZERO (understanding what and how they do it is very useful). +- [ ] A request to your server should never hang forever. +- [ ] Your server must be compatible with the web browser of your choice. +#### parsing request HTTP (fields, ...) +- [ ] We will consider that NGINX is HTTP 1.1 compliant and may be used to compare headers and answer behaviors. +#### response HTTP (fields, ...) +- [ ] Your HTTP response status codes must be accurate. +- [ ] You server must have default error pages if none are provided. +- [ ] You can’t use fork for something else than CGI (like PHP, or Python, and so forth). +- [ ] You must be able to serve a fully static website. +#### upload files +- [ ] Clients must be able to upload files. +#### CGI +- [ ] You need at least GET, POST, and DELETE methods. +- [ ] Do you wonder what a CGI is? +- [ ] Because you won’t call the CGI directly, use the full path as PATH_INFO. +- [ ] Just remember that, for chunked request, your server needs to unchunked it and the CGI will expect EOF as end of the body. +- [ ] Same things for the output of the CGI. If no content_length is returned from the CGI, EOF will mark the end of the returned data. +- [ ] Your program should call the CGI with the file requested as first argument. +- [ ] The CGI should be run in the correct directory for relative path file access. +- [ ] Your server should work with one CGI (php-CGI, Python, and so forth). +#### write tests +- [ ] Stress tests your server. It must stay available at all cost. +- [ ] Do not test with only one program. +- [ ] Write your tests with a more convenient language such as Python or Golang, and so forth. Even in C or C++ if you want to +#### persistent connexion +- [ ] Your server must be able to listen to multiple ports (see Configuration file) +- [ ] Your server should never die. + + +--- +## cgi env variables +[cgi env variables](http://www.faqs.org/rfcs/rfc3875.html) +[wikipedia variables environnements cgi](https://fr.wikipedia.org/wiki/Variables_d%27environnement_CGI) +[cgi server variables on adobe](https://helpx.adobe.com/coldfusion/cfml-reference/reserved-words-and-variables/cgi-environment-cgi-scope-variables/cgi-server-variables.html) +``` +AUTH_TYPE : if the srcipt is protected, the authentification method used to validate the user +CONTENT_LENGTH : length of the request content +CONTENT_TYPE : if there is attached information, as with method POST or PUT, this is the content type of the data (e.g. "text/plain", it is set by the attribute "enctype" in html