https://github.com/cozis/blogtech Skip to content Navigation Menu Toggle navigation Sign in * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + GitHub Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code Explore + All features + Documentation + GitHub Skills + Blog * Solutions By size + Enterprise + Teams + Startups By industry + Healthcare + Financial services + Manufacturing By use case + CI/CD & Automation + DevOps + DevSecOps * Resources Topics + AI + DevOps + Security + Software Development + View all Explore + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Enterprise + Enterprise platform AI-powered developer platform Available add-ons + Advanced Security Enterprise-grade security features + GitHub Copilot Enterprise-grade AI features + Premium Support Enterprise-grade 24/7 support * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up Reseting focus You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} cozis / blogtech Public * Notifications You must be signed in to change notification settings * Fork 7 * Star 246 Custom web server for my blog playin.coz.is/index.html License Unlicense license 246 stars 7 forks Branches Tags Activity Star Notifications You must be signed in to change notification settings * Code * Issues 1 * Pull requests 0 * Actions * Projects 0 * Security * Insights Additional navigation options * Code * Issues * Pull requests * Actions * Projects * Security * Insights cozis/blogtech This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. main BranchesTags Go to file Code Folders and files Name Name Last commit message Last commit date Latest commit History 73 Commits docroot docroot tests tests .gitignore .gitignore Makefile Makefile README.md README.md UNLICENSE UNLICENSE attempts.txt attempts.txt serve.c serve.c View all files Repository files navigation * README * Unlicense license My Blog Technology This is a minimal web server designed to host my blog. It's built from scratch to be robust enough to face the public internet. No reverse proxies required! You can see it in action at http:// playin.coz.is/index.html. I asked Reddit to hack me, which resulted in gigabytes of hilarious and malicious request logs. I saved some in attempts.txt, and may dig out a few more for fun someday :^) But.. Why? I enjoy making my own tools and I'm a bit tired of hearing that everything needs to be "battle-tested." So what it will crash? Bugs can be fixed :^) Specs * Linux only * Implements HTTP/1.1, pipelining, and keep-alive connections * HTTPS support (up to TLS 1.2 using BearSSL) * Minimal dependencies (libc and BearSSL when using HTTPS) * Configurable timeouts * Access logs, crash logs, log rotation, disk usage limits * No Transfer-Encoding: Chunked (responds with 411 Length Required, prompting the client to resend with Content-Length) * Single core (This will probably change when I get a better VPS) * No static file caching (yet) Benchmarks The focus of the project is robustness, but it's definitely not slow. Here's a quick comparison agains nginx (static endpoint, both single-threaded, 1K connection limit) (blogtech) $ wrk -c 500 -d 5s http://127.0.0.1:80/hello Running 5s test @ http://127.0.0.1:80/hello 2 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 6.66ms 3.71ms 48.87ms 92.30% Req/Sec 39.59k 6.43k 50.60k 67.35% 385975 requests in 5.01s, 30.55MB read Requests/sec: 76974.24 Transfer/sec: 6.09MB (nginx) $ wrk -c 500 -d 5s http://127.0.0.1:8080/hello Running 5s test @ http://127.0.0.1:8080/hello 2 threads and 500 connections Thread Stats Avg Stdev Max +/- Stdev Latency 149.11ms 243.02ms 934.12ms 81.80% Req/Sec 24.97k 16.87k 57.73k 61.11% 224790 requests in 5.08s, 42.01MB read Requests/sec: 44227.78 Transfer/sec: 8.27MB Nginx uses this configuration: worker_processes 1; events { worker_connections 1024; } http { server { listen 8080; location /hello { add_header Content-Type text/plain; return 200 "Hello, world!"; } } } Build & Run By default the server build is HTTP-only: $ make this generates the executables: serve (release build), serve_cov (coverage build), and serve_debug (debug build). Release builds listen on port 80; debug builds on port 8080. To enable HTTPS, you'll need to clone BearSSL and build it. You can do so by running these commands from the root folder of this repository: $ mkdir 3p $ cd 3p $ git clone https://www.bearssl.org/git/BearSSL $ cd BearSSL $ make -j $ cd ../../ $ make -B HTTPS=1 The same executables will be generated, but with secure connections on port 443 (release) or 8081 (debug). Place your cert.pem and key.pem files in the same directory as the executable. You can customiza names and locations by changing: #define HTTPS_KEY_FILE "key.pem" #define HTTPS_CERT_FILE "cert.pem" For testing locally with HTTPS, generate a self-signed certificate (and private key): openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048 openssl req -new -x509 -key key.pem -out cert.pem -days 365 Usage The server serves static content from the docroot/ folder. You can change this by modifying the respond function: typedef struct { Method method; string path; int major; int minor; int nheaders; Header headers[MAX_HEADERS]; string content; } Request; void respond(Request request, ResponseBuilder *b) { if (request.major != 1 || request.minor > 1) { status_line(b, 505); // HTTP Version Not Supported return; } if (request.method != M_GET) { status_line(b, 405); // Method Not Allowed return; } if (string_match_case_insensitive(request.path, LIT("/hello"))) { status_line(b, 200); append_content_s(b, LIT("Hello, world!")); return; } if (serve_file_or_dir(b, LIT("/"), LIT("docroot/"), request.path, NULLSTR, false)) return; status_line(b, 404); append_content_s(b, LIT("Nothing here :|")); } you can add your endpoints here by switching on the request.path field. Note that the path is just a slice into the request buffer. URIs are not parsed. Testing I routinely run the server under valgrind and 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. I also use it to host my website and post it here and there to keep it under stress.Turns out, all of those bots scanning he internet for vulnerable websites make great fuzzers! Known Issues * Server replies to HTTP/1.0 clients as HTTP/1.1 Contributing I usually work on the DEV branch and merge into MAIN once in a while. If you open a pull requests remember to target DEV. It will make things easier! About Custom web server for my blog playin.coz.is/index.html Resources Readme License Unlicense license Activity Stars 246 stars Watchers 3 watching Forks 7 forks Report repository Releases 2 0.2.0 Latest Sep 24, 2024 + 1 release Packages 0 No packages published Contributors 2 * @cozis cozis Francesco Cozzuto * @geon geon Victor Widell Languages * C 80.2% * HTML 13.4% * Python 5.6% * Makefile 0.8% Footer (c) 2024 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact * Manage cookies * Do not share my personal information You can't perform that action at this time.