Please find the project's documentation here.
./webserv configuration_file
The format of our configuration files are directly inspired from NGINX.
There is two types of data:
- directives
- block
Directives are mades as follow:
keyword: value;
Blocks are used to provide contextual data within a scope. The scope is surrounded by curly brackets. There are two kinds of blocks:
- Server block
- Location block
Location blocks are used to differentiate the behavior of your server based on the address and port requested by the client.
server {
listen 8080; # listening port [REQUIRED]
server_names 42.fr www.42.fr; # Will match HTTP Header-field `Host`
location / { ... } # zero or more location blocks
}
Location blocks are used to differentiate the behavior of your server based on the path requested by the client (URI path in the HTTP start-line). They inherit the directives from the parent block (server or location). Each of these scopes defines a route.
listen
: unsigned int - represents the port on which the virtual server is listeningserver_names
: one or more URI separated by space(s) - matches with the HTTP Header-field Host
allowed_methods
: zero or more flags (GET
|POST
|DELETE
) separated by space(s) - HTTP request methods allowed for the routeclient_max_body_size
: unsigned int - maximum request body size (in bytes) allowed for the routeredirect
: URI - request made on this route will be answered by a Moved Permanently (308) response pointing to this URIroot
: path - path which the server will use to serve files requested by the clientindex
: filename - filename used to resolve a request pointing to a directory pathautoindex
: (on
|off
) - ifon
, a request pointing to a directory path will be answered by an HTML representation of the files contained in the directory
cgi_setupt
: file-extention and path-to-the-binary, separated by a space - if a request is pointing to a file that ends with the file-extention, it will be answerd by the STDOUT of this file given as an argument to the path-to-the-binary executableerror_file
: status-code and path-to-error-file, separated by a space - if an error occured with the same statuts-code as the one set, the server will respond by sending the file at path-to-error-file
This configuration sets up a server that listens on port 8080 and responds to requests on the /
route.
server {
listen 8080;
server_names 42.fr www.42.fr;
root /var/www/html;
index index.html;
autoindex on;
location / {
allowed_methods GET POST;
client_max_body_size 1024;
}
}
This configuration redirects requests to the root route to a new URL.
server {
listen 8080;
server_names 42.fr
location / {
redirect /new-location;
}
location /new-location {
root /var/www/new-location;
index index.html;
}
}
This configuration sets up a CGI script to handle requests for .py
files.
server {
listen 8080;
server_names 42.fr;
location / {
root /var/www/html;
index index.html;
cgi_setup .py /usr/bin/python3;
}
}
Note that these are just examples, and you will need to adjust them to match the specific needs of your application.
Load-testing using Vegeta
Run with Vegeta on a Dell OptiPlex 7400 AIO Series (RAM: 15GiB, CPU: 12th Gen Intel(R) Core(TM) i7-12700)
getting a index.html
file containing the following content:
<!DOCTYPE html>
<html>
<head>
<title>Hello World HTML</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
> echo "GET http://localhost:8080/index.html" | vegeta attack -duration=120s -rate 0 -max-workers 72 | tee results.bin | vegeta report
Requests [total, rate, throughput] 4633030, 38608.59, 38532.05
Duration [total, attack, wait] 2m0s, 2m0s, 207.308ms
Latencies [min, mean, 50, 90, 95, 99, max] 12.356µs, 1.845ms, 1.571ms, 2.004ms, 2.285ms, 2.916ms, 813.214ms
Bytes In [total, mean] 528028962, 113.97
Bytes Out [total, mean] 0, 0.00
Success [ratio] 99.97%
Status Codes [code:count] 0:1197 200:4631833