Skip to content
SALAH-NAMEPublic

About

A simple HTTP/1.1 server written in C++.

Resources

Stars

1 star

Watchers

1 watching

Forks

Latest commit

 

History

346 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WebServ

A HTTP/1.1 server written from scratch in C++98, built as a team Ed, Edd, Eddy.

No external HTTP libraries, sockets, request parsing, routing, CGI, and the event loop are all hand-rolled and driven by a single non-blocking epoll()-style loop.

Glitch test suite main page

(Screenshot of our internal test suite.)

Features

  • HTTP/1.1 parsing (headers, chunked transfer-encoding, keep-alive)
  • GET, POST, DELETE methods
  • File upload / download and static file serving
  • Per-route allowed methods
  • Internal (301) and external (302) redirections
  • Autoindex (directory listing) on/off
  • Custom and default index pages
  • Custom and default error pages
  • Multiple servers / multiple ports via a single config file
  • Non-blocking I/O, single event loop, never hangs on a slow client
  • CGI support (Python, Bash, PHP)
  • Cookies & session management (login, visit counter, private notes)
  • Multiple CGI interpreters configurable per location

Config file

Server behavior is driven by an NGINX-style config file (see conf/*.conf), parsed by a hand-written tokenizer/parser (src/config).

server {
    listen 8080;
    host 127.0.0.1;
    server_name example.local;

    root www/webServPages;
    index index.html;

    location / {
        allowed_methods GET POST;
        autoindex off;
    }

    location /upload {
        allowed_methods POST DELETE;
        client_max_body_size 10M;
    }

    location /cgi-bin {
        cgi_pass /usr/bin/python3;
        allowed_methods GET POST;
    }

    error_page 404 www/ErrorPages/Non-Found.html;
}
Full config grammar (EBNF)
(* Top level structure *)
Config = [WhiteSpace], [GlobalDirectives], {ServerBlock}+, [WhiteSpace];

(* Global directives *)
GlobalDirectives = {Directive};

(* Server block *)
ServerBlock = [WhiteSpace], "server", WhiteSpace, "{", [WhiteSpace],
              {Directive | LocationBlock},
              [WhiteSpace], "}", [WhiteSpace];

(* Location block *)
LocationBlock = [WhiteSpace], "location", WhiteSpace,
                (LocationPath | LocationRegexPath), WhiteSpace,
                "{", [WhiteSpace],
                {Directive},
                [WhiteSpace], "}", [WhiteSpace];

(* Location paths *)
LocationPath = Value;
LocationRegexPath = "~", {WhiteSpace}+, Value;

(* Directive structure *)
Directive = [WhiteSpace], DirectiveName, {(WhiteSpace, Value)}+, [WhiteSpace], ";", [WhiteSpace];

(* Directive names *)
DirectiveName = "listen" | "host" | "server_name" | "error_page" | "client_max_body_size" |
                "root" | "index" | "allowed_methods" | "autoindex" | "return" | "cgi_pass" |
                "cgi_timeout" | "connection_timeout" | "error_log" | "access_log";

(* Value types *)
Value = Number | Size | String;

(* Numeric value *)
Number = Digit, {Digit};
Digit = "0" | "1" | ... | "9";

(* Size value with suffix *)
Size = Number, Suffix;
Suffix = "K" | "k" | "M" | "m" | "G" | "g";

(* String value *)
String = (Letter | Digit | SpecialChar), {Letter | Digit | SpecialChar};
Letter = "a" | "b" | ... | "z" | "A" | "B" | ... | "Z";
SpecialChar = "_" | "-" | "." | "/";

(* Comment *)
Comment = "#", {AnyChar - EOL}, EOL;
AnyChar = ? any character ?;
EOL = {? end of line character ? | "\n"};

(* Whitespace handling *)
WhiteSpace = {" " | "\t" | "\n" | "\r" | Comment};

Getting started

make                      # build (debug mode by default)
./webserv [config_file]   # defaults to conf/default.conf if omitted

Other build modes:

make release      # optimized build
make sanitize     # build with ASan/UBSan
make valgrind     # build for valgrind debugging
make tests        # build & run unit tests
make run          # build + run, ARGS_MAKE="conf/bonus.conf" to pass a config
make help         # full list of targets

Stress testing

We built a themed "test suite" site (www/glitch) that doubles as a stress-testing playground:

Stress test page

siege -c 255 -t 30S http://127.0.0.1:8080/empty.html

Team

Role Member
Config Randomizer Ed
CGI Master Mohamed Idbellaali
Multiplex Architect Abdelkarim Laktari

About

A simple HTTP/1.1 server written in C++.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages