2022-07-13 14:22:26 +02:00
2022-07-13 14:22:26 +02:00
2022-07-07 20:13:14 +02:00
2022-07-07 20:13:14 +02:00
2022-07-13 14:22:26 +02:00
2022-07-07 20:13:14 +02:00
2022-07-13 14:22:26 +02:00
2022-07-07 20:13:14 +02:00
2022-07-07 20:13:14 +02:00

for correction

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 : 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 : 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
  • Your program has to take a configuration file as argument, or use a default path.
  • You cant 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 dont 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 wouldnt 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.
  • We will consider that NGINX is HTTP 1.1 compliant and may be used to compare headers and answer behaviors.
  • Your HTTP response status codes must be accurate.
  • You server must have default error pages if none are provided.
  • You cant use fork for something else than CGI (like PHP, or Python, and so forth).
  • You must be able to serve a fully static website.
  • Clients must be able to upload files.
  • You need at least GET, POST, and DELETE methods.
  • Stress tests your server. It must stay available at all cost.
  • Your server must be able to listen to multiple ports (see Configuration file)
  • Your server should never die.
  • 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
  • You must provide some configuration files and default basic files to test and demonstrate every feature works during evaluation.

In the configuration file, you should be able to:

  • 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 dont 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.
      • Do you wonder what a CGI is?
      • Because you wont 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).

ressources

Description
No description provided
Readme 15 MiB
Languages
C++ 55.9%
HTML 26.2%
Shell 6.8%
CSS 5.9%
PHP 2.8%
Other 2.4%