Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
*.o
*.pem
serve
serve_*
serve.gcno
*.gcno
*.gcda
logs/log_*.txt
*.info
logs
report
blacklist.txt
3p
backtrace.txt
21 changes: 16 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
.PHONY: all report cppcheck gcc-analyzer clang-tidy

HTTPS ?= 0

COMMON_FLAGS = -Wall -Wextra -DHTTPS=$(HTTPS) -ggdb -rdynamic
DEBUG_FLAGS = -O0 -ggdb #-fsanitize=address,undefined
COVERAGE_FLAGS = -fprofile-arcs -ftest-coverage -lgcov
RELEASE_FLAGS = -ggdb -O2 -DNDEBUG -DRELEASE

ifneq ($(HTTPS),0)
COMMON_FLAGS += -l:libbearssl.a -I3p/BearSSL/inc -L3p/BearSSL/build
endif

all: serve_debug serve_cov serve

serve_debug: serve.c
gcc serve.c -o serve_debug -Wall -Wextra -O0 -ggdb
serve: serve.c
gcc $< -o $@ $(COMMON_FLAGS) $(RELEASE_FLAGS)

serve_cov: serve.c
gcc serve.c -o serve_cov -Wall -Wextra -O2 -fprofile-arcs -ftest-coverage -lgcov
gcc $< -o $@ $(COMMON_FLAGS) $(COVERAGE_FLAGS)

serve: serve.c
gcc serve.c -o serve -Wall -Wextra -O2 -DNDEBUG -DRELEASE
serve_debug: serve.c
gcc $< -o $@ $(COMMON_FLAGS) $(DEBUG_FLAGS)

report:
lcov --capture --directory . --output-file coverage.info
Expand Down
30 changes: 21 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,36 @@ This is a minimal web server designed to serve my blog. I'm writing it to be rob
# Specs
- Only runs on Linux
- HTTP/1.1 support with pipelining and keep-alive
* HTTPS (TLS 1.2 using BearSSL)
- Uses request and connection timeouts
- IP blacklist
- Access log, log file rotation, hard disk usage limits
- No `Transfer-Encoding: Chunked` (when receiving a chunked request the server responds with `411 Length Required`, prompting the client to try again with the `Content-Length` header)
- Static file serving utilities
- Single core (This will probably change when I get a better VPS)

# Testing
I routinely run the server under valgrind or sanitizers (address, undefined) and target it using `wrk`. I'm also adding automatized tests to `tests/test.py` to check compliance with the HTTP/1.1 spec.
# Building
By default the server is built without HTTPS and you can do so by doing:
```
$ make
```
this will generate `serve`, `serve_cov`, and `serve_debug`. These are respectively release, coverage, and debug build. Unless you're modifying the source you need to use `serve`.

# Blocking IPs
To block any number of IP addresses you need to create a `blacklist.txt` file and insert the IPs. You can also add comments:
If you want to enable HTTPS, you'll need to create a `3p` directory (in the same folder as this README) and clone BearSSL in it. Then you'll need to build it.
```
# I'm a comment
10.0.0.1
127.0.0.1 # I'm a comment too
$ mkdir 3p
$ cd 3p
$ git clone https://www.bearssl.org/git/BearSSL
$ cd BearSSL
$ make -j
$ cd ../../
$ make -B HTTPS=1
```
Blocked addresses will be rejected after being accepted. This is just a best effort solution as you should block connections using iptables or nftables.
which will produce the same executables but with HTTPS enabled. Your private key `key.pem` and certificate `cert.pem` will need to be stored in the same folder as the executable.

NOTE: If you already built the files and want to build them again with a different HTTPS setting, you'll need to force the build with the `-B` option

# Testing
I routinely run the server under valgrind or sanitizers (address, undefined) and target it using `wrk`. I'm also adding automatized tests to `tests/test.py` to check compliance with the HTTP/1.1 spec.

# Known Issues
- Server replies to HTTP/1.0 clients as HTTP/1.1
Loading