{"id":47897667,"url":"https://github.com/gamemann/cweb","last_synced_at":"2026-04-04T03:53:27.018Z","repository":{"id":303859203,"uuid":"1015064295","full_name":"gamemann/cweb","owner":"gamemann","description":"A low-level web server written in C I'm using to learn more about web servers. This is a work-in-progress and not ready for production.. yet.","archived":false,"fork":false,"pushed_at":"2025-07-19T20:36:11.000Z","size":2461,"stargazers_count":20,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-04T03:53:23.614Z","etag":null,"topics":["c","html","linux","low-level","multi-threading","multithreaded","multithreading","server","socket","tcp","web-app","web-development","web-server","webserver"],"latest_commit_sha":null,"homepage":"https://cdeacon.net/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gamemann.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-07T00:18:14.000Z","updated_at":"2025-10-28T03:00:48.000Z","dependencies_parsed_at":"2025-07-10T04:52:22.856Z","dependency_job_id":"ac1d1376-d678-46e4-b7e7-0cc31667820e","html_url":"https://github.com/gamemann/cweb","commit_stats":null,"previous_names":["gamemann/cweb"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gamemann/cweb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2Fcweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2Fcweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2Fcweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2Fcweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gamemann","download_url":"https://codeload.github.com/gamemann/cweb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gamemann%2Fcweb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31387024,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T01:22:39.193Z","status":"online","status_checked_at":"2026-04-04T02:00:07.569Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","html","linux","low-level","multi-threading","multithreaded","multithreading","server","socket","tcp","web-app","web-development","web-server","webserver"],"created_at":"2026-04-04T03:53:26.370Z","updated_at":"2026-04-04T03:53:27.012Z","avatar_url":"https://github.com/gamemann.png","language":"C","readme":"[![CWeb Build Workflow](https://github.com/gamemann/cweb/actions/workflows/build.yml/badge.svg)](https://github.com/gamemann/cweb/actions/workflows/build.yml) [![CWeb Run Workflow](https://github.com/gamemann/cweb/actions/workflows/run.yml/badge.svg)](https://github.com/gamemann/cweb/actions/workflows/run.yml)\n\n\nThis is a **low-level**, **multithreaded** web server written in C. This project is a work-in-progress and I'm using it to learn more about web servers in general. There is also a basic HTTP **stress tool** (`cweb-stress`) included in this repository that sends HTTP requests to a host from **one or more threads** (multithreaded)!  \n\nWhile the web server is in a runnable state, it is **not ready for production use**. I'm not entirely sure if I'll make this ready for production in the future. It will take a lot of time, but hey, maybe some day!\n\n![CWeb Preview](./images/cweb-preview.gif)\n\n## HTML File System\nAt this time, the web server implements a basic HTML file system. The URI paths from a HTTP request is mapped to the file system in [`public/`](./public/), but can be changed with the `public_dir` configuration setting detailed later on in this README. For example, say you're using the domain `test123.com`.\n\n* `test123.com` =\u003e [`./public/index.html`](./public/index.html)\n* `test123.com/test` =\u003e [`./public/test/index.html`](./public/test/index.html)\n* `test123.com/test2` =\u003e [`./public/test2.html`](./public/test2.html)\n* `test123.com/definitely/not/found` =\u003e [`./public/404.html`](./public/404.html)\n\n## Building\nIf you're cloning this project, make sure to clone all of its submodule(s) which includes [JSON-C](https://github.com/json-c/json-c) (required).\n\nYou can do this by passing the `--recursive` flag when cloning the repository like below.\n\n```bash\ngit clone --recursive https://github.com/gamemann/cweb.git\n```\n\nIf you've already cloned the repository, you can execute the following command inside of the cloned repository to download the submodules.\n\n```bash\ngit submodule update --init\n```\n\n### Building \u0026 Installing JSON-C\nThe [JSON-C](https://github.com/json-c/json-c) library is required to read the config file.\n\nI've made some chains in the Makefile that makes it easier to build and install JSON-C.\n\nTo build JSON-C, use the following command.\n\n```bash\nmake json-c\n```\n\nTo install JSON-C to the system, use the following command as root (or via `sudo`).\n\n```bash\nmake json-c-install\n```\n\n### Building \u0026 Installing Main Program\nTo build the main project, simply use the command below.\n\n```bash\nmake\n```\n\nTo install the project to the system (`cweb` executable), use the following command as root (or via `sudo`).\n\n```bash\nmake install\n```\n\n## Command Line Usage\n### CWeb\nThe following command line arguments are supported for `cweb`.\n\n| Argument | Default | Description |\n| -------- | ------- | ----------- |\n| `-c --cfg \u003cval\u003e` | `./conf.json` | The path to the runtime config file. |\n| `-t --time \u003cval\u003e` | - | If set, runs the web server for this long in seconds before exiting. |\n| `-l --list` | - | Prints the contents of the runtime config and exits. |\n| `-h --help` | - | Prints the help menu and exits. |\n| `-r --log-lvl \u003cval\u003e` | - | Overrides the log level runtime config value. |\n| `-f --log-file \u003cval\u003e` | - | Overrides the log file runtime config value. |\n| `-b --bind-addr \u003cval\u003e` | - | Overrides the bind address runtime config value. |\n| `-p --bind-port \u003cval\u003e` | - | Overrides the bind port runtime config value. |\n\n### CWeb Stress\nThe following command line arguments are supported for `cweb-stress`.\n\n| Argument | Default | Description |\n| -------- | ------- | ----------- |\n| `--details -z` | - | If set, prints to `stdout` whenever an HTTP request is sent (will hurt performance, but useful for debugging). |\n| `--host -i \u003cval\u003e` | - | The host to send HTTP requests to (supports host names and IPs). |\n| `--port -p \u003cval\u003e` | - | The port to send HTTP requests to. |\n| `--domain -d \u003cval\u003e` | `localhost` | The domain to use (what the HTTP `Host` header is set to). |\n| `--method -m \u003cval\u003e` | `GET` | The HTTP method to use. |\n| `--path -r \u003cval\u003e` | `/` | The HTTP path to use. |\n| `--http-version -v \u003cval\u003e` | `HTTP/1.1` | The HTTP version to use. |\n| `--ua -u \u003cval\u003e` | - | The user agent to set (if unset, will not pass the `User-Agent` HTTP header). |\n| `--body -b \u003cval\u003e` | - | The HTTP body to send. |\n| `--threads -t \u003cval\u003e` | - | The amount of threads to create (if unset, will use amount of CPUs the host has). |\n| `--send-delay -s \u003cval\u003e` | `0` | The amount of time in microseconds to wait between sending HTTP requests on each thread. Leaving this at 0 will result in the best performance, but if you don't want to send as many requests at once, raising this value is the solution. |\n| `-l --list` | - | Prints the current CLI values. |\n| `-h --help` | - | Prints the help menu and exits. |\n\n## Configuration\nA config file is loaded from the file system that is parsed using JSON. The default config file location is `./conf.json`. I recommend copying or renaming the [`conf.ex.json`](./conf.ex.json) file to `conf.json`.\n\nModifying runtime config values only requires a restart in the tool for new values to take effect.\n\nThe following runtime config options are available.\n\n| Name | Type | Default | Description |\n| ---- | ---- | ------- | ----------- |\n| `log_lvl` | int | `7` | The log level (1 = fatal, 2 = error, 3 = warn, 4 = notice, 5 = info, 6 = debug, and 7 = trace). |\n| `log_file` | string | `/var/log/cweb.log` | The path to the log file. |\n| `bind_addr` | string | `0.0.0.0` | The address to bind the web server to. |\n| `bind_port` | int | `8` | The port to bind the web server to. |\n| `server_name` | string | `CWeb` | The name of the web server (set as the \"Server\" response header). |\n| `public_dir` | string | `./public` | The path to the HTML file system. |\n| `threads` | int | `0` | The amount of threads to set up to process web requests (0 = automatic). |\n| `thread_type` | int | `0` | The thread type to use (0 = setup one global socket and poll socket on each thread, 1 = setup a separate socket per thread and poll it) |\n| `allowed_hosts` | string/string array | `[]` | An array or single allowed hosts/domains. |\n| `allowed_user_agents` | string/string array | `[]` | An array or single allowed user agents. |\n\n## Images\n![CWeb Preview01](./images/cweb-preview01.png)\n\n![CWeb Preview02](./images/cweb-preview02.png)\n\n![CWeb Preview03](./images/cweb-preview03.png)\n\n## Credits\n* [Christian Deacon](https://github.com/gamemann)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgamemann%2Fcweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgamemann%2Fcweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgamemann%2Fcweb/lists"}