{"id":18162293,"url":"https://github.com/raphiara/tiny_http","last_synced_at":"2025-05-07T15:03:41.255Z","repository":{"id":259010874,"uuid":"863528401","full_name":"RaphiaRa/tiny_http","owner":"RaphiaRa","description":"lightweight, easy-to-use, and embeddable HTTP server library in C","archived":false,"fork":false,"pushed_at":"2025-02-16T21:14:43.000Z","size":418,"stargazers_count":25,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T11:11:48.537Z","etag":null,"topics":["arm","c","embeddable","http","http-server","lightweight","linux","macos","single-source","web","web-development"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RaphiaRa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-09-26T13:00:16.000Z","updated_at":"2025-02-16T21:14:33.000Z","dependencies_parsed_at":"2025-02-16T22:18:50.795Z","dependency_job_id":"ffdad7ff-f8bb-4838-87c5-b2827cd10c9e","html_url":"https://github.com/RaphiaRa/tiny_http","commit_stats":null,"previous_names":["raphiara/tiny_http"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RaphiaRa%2Ftiny_http","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RaphiaRa%2Ftiny_http/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RaphiaRa%2Ftiny_http/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RaphiaRa%2Ftiny_http/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RaphiaRa","download_url":"https://codeload.github.com/RaphiaRa/tiny_http/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246578278,"owners_count":20799784,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["arm","c","embeddable","http","http-server","lightweight","linux","macos","single-source","web","web-development"],"created_at":"2024-11-02T09:04:40.118Z","updated_at":"2025-04-01T03:32:01.389Z","avatar_url":"https://github.com/RaphiaRa.png","language":"C","readme":"# tiny_http - Work in Progress...\n\u003cdiv align=\"center\"\u003e\n\n[![Linux](https://github.com/RaphiaRa/tiny_http/actions/workflows/linux.yml/badge.svg?branch=main)](https://github.com/RaphiaRa/tiny_http/actions/workflows/linux.yml)\n[![MacOS](https://github.com/RaphiaRa/tiny_http/actions/workflows/macos.yml/badge.svg?branch=main)](https://github.com/RaphiaRa/tiny_http/actions/workflows/macos.yml)\n\n\u003c/div\u003e\ntiny_http is my attempt at creating a lightweight, easy-to-use, and embeddable HTTP server library in C99.\n\n##### Hello, World! Example:\n```c\n#include \"th.h\"\n\nstatic th_err\nhandler(void* userp, const th_request* req, th_response* resp)\n{\n    th_set_body(resp, \"Hello, World!\");\n    th_add_header(resp, \"Content-Type\", \"text/plain\");\n    return TH_ERR_OK;\n}\n\nint main()\n{\n    th_server* server;\n    th_server_create(\u0026server, NULL);\n    th_bind(server, \"0.0.0.0\", \"8080\", NULL);\n    th_route(server, TH_METHOD_GET, \"/\", handler, NULL);\n    while (1) {\n        th_poll(server, 1000);\n    }\n    return 0;\n}\n```\nSimply copy the code above to a file (e.g. `hello.c`) where you have the `th.h` and `th.c` files, and compile it with:\n```sh\n$ gcc -o hello hello.c th.c\n```\nThen run the server with:\n```sh\n$ ./hello\n```\n\nI wrote this library because I wanted a simple drop-in solution for the legacy C and C++ codebases I work with, hence the lack of dependencies and new language features. It is not designed to be a full-fledged web server, but rather a simple tool to build small web applications or to serve static files. No threading or forking is used.\n\n## Features\n\n- Simple integration (just copy the `th.h` and `th.c` files to your project)\n- HTTPS support (via OpenSSL) (Works, but still needs to be optimized as it's quite slow)\n- Path capturing (e.g. `/user/{id}`)\n- Supports Linux and MacOS (Windows support is planned)\n- Fully customizable memory allocation and logging\n- File Uploads (Multipart form data)\n\n## Planned features\n\n- Websockets\n\n## Dependencies\n\n- The C standard library\n- OpenSSL (optional, for HTTPS support)\n- gperf (optinal, for binary builds and amalgamation)\n- python3 (optional, for running the amalgamation script)\n\n## Enabling HTTPS\n\nTo enable HTTPS support, you need to link against OpenSSL and set `TH_WITH_SSL=1` when compiling the library.\n```sh\n$ gcc -o myserver myserver.c th.c -lssl -lcrypto -DTH_WITH_SSL=1\n```\nPass the certificate and private key file paths to `th_bind`:\n```c\nth_bind_opt opt = {\n    .cert_file = \"cert.pem\", \n    .key_file = \"key.pem\",\n};\nth_bind(server, \"0.0.0.0\", \"433\", \u0026opt);\n```\n\n## Logging\n\nLogging can be configured via the `TH_LOG_LEVEL` macro.\n```c\n$ gcc -o myserver myserver.c th.c -DTH_LOG_LEVEL=TH_LOG_LEVEL_TRACE\n```\nPossible values are:\n```c\nTH_LOG_LEVEL_NONE\nTH_LOG_LEVEL_ERROR\nTH_LOG_LEVEL_WARN\nTH_LOG_LEVEL_INFO\nTH_LOG_LEVEL_DEBUG\nTH_LOG_LEVEL_TRACE\n```\nBy default, tiny_http logs to `stderr`,\nbut users can provide their own logging function (See [examples/custom_logger.c](examples/custom_logger.c)).\n\n## Building binaries, examples, and tests\n\nLibrary builds, examples, and tests can be built using CMake (This requires gperf to be installed).\n```sh\n$ mkdir build; cd build\n$ cmake ..\n$ make\n```\n\n## More examples\n\nExample - Path capturing:\n```c\n#include \"th.h\"\n\nstatic th_err\nhandler(void* userp, const th_request* req, th_response* resp)\n{\n    const char* msg = th_find_pathvar(req, \"msg\");\n    th_printf_body(resp, \"Hello, %s!\", msg);\n    th_add_header(resp, \"Content-Type\", \"text/plain\");\n    return TH_ERR_OK;\n}\n\nint main(void)\n{\n    th_server* server;\n    th_server_create(\u0026server, NULL);\n    th_bind(server, \"0.0.0.0\", \"8080\", NULL);\n    th_route(server, TH_METHOD_GET, \"/{msg}\", handler, NULL);\n    while (1) {\n        th_poll(server, 1000);\n    }\n    return 0;\n}\n```\nIt's possible to specify a capture type by adding a colon before the parameter name: `{string:param}` (Default if nothing is specified), `{int:param}`, `{path:param}`.\n\nExample - File serving:\n```c\n#include \"th.h\"\n\nstatic th_err\nhandle_path(void* userp, const th_request* req, th_response* resp)\n{\n    const char* path = th_find_pathvar(req, \"path\");\n    th_set_body_from_file(resp, \"root\", path);\n    return TH_ERR_OK;\n}\n\nstatic th_err\nhandle_index(void* userp, const th_request* req, th_response* resp)\n{\n    th_set_body_from_file(resp, \"root\", \"index.html\");\n    return TH_ERR_OK;\n}\n\nint main(void)\n{\n    th_server* server;\n    th_server_create(\u0026server, NULL);\n    th_bind(server, \"0.0.0.0\", \"8080\", NULL);\n    th_add_dir(server, \"root\", \"/path/to/your/files\");\n    th_route(server, TH_METHOD_GET, \"/{path:path}\", handle_path, NULL);\n    th_route(server, TH_METHOD_GET, \"/\", handle_index, NULL);\n    while (1) {\n        th_poll(server, 1000);\n    }\n    return 0;\n}\n```\n\nMore detailed examples can be found in the `examples` directory.\n\n## Performance\n\nAlthough tiny_http is not designed to be high-performance, it's still quite fast.\nHere is a comparison with [Drogon](https://github.com/drogonframework/drogon) (One of my favorite C++ web frameworks) on my cloud server (2 dedicated AMD Epyc vCPUs).\n[![Benchmark](benchmark/result.png)](benchmark/benchmark.md)\n\nNotes:\n- Drogon will, of course scale much better with more threads. This is just to give a rough idea of tiny_http's performance.\n- The slower static file test is probably because of tiny_http not using `sendfile` on Linux yet.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphiara%2Ftiny_http","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraphiara%2Ftiny_http","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphiara%2Ftiny_http/lists"}