{"id":16164249,"url":"https://github.com/troglobit/merecat","last_synced_at":"2025-04-04T13:08:27.079Z","repository":{"id":11722616,"uuid":"62570366","full_name":"troglobit/merecat","owner":"troglobit","description":"Small and made-easy HTTP/HTTPS server based on Jef Poskanzer's thttpd","archived":false,"fork":false,"pushed_at":"2024-11-02T13:36:28.000Z","size":1416,"stargazers_count":159,"open_issues_count":9,"forks_count":21,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-28T12:04:05.502Z","etag":null,"topics":["acme","cgi","embedded","gzip-compression","http-redirect","http-server","httpd","https","letsencrypt","php","php-cgi","ssi","ssl","thttpd","tls","virtual-hosts","webserver","zlib"],"latest_commit_sha":null,"homepage":"https://troglobit.com/projects/merecat/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/troglobit.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-04T15:02:39.000Z","updated_at":"2025-03-27T08:09:05.000Z","dependencies_parsed_at":"2024-11-09T18:00:59.935Z","dependency_job_id":"192a0960-f490-4895-a7d0-3ed063621ad4","html_url":"https://github.com/troglobit/merecat","commit_stats":{"total_commits":990,"total_committers":17,"mean_commits":58.23529411764706,"dds":0.06464646464646462,"last_synced_commit":"4c6e3e401b8ec2fc6b106097c70d8032b0700e96"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troglobit%2Fmerecat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troglobit%2Fmerecat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troglobit%2Fmerecat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troglobit%2Fmerecat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/troglobit","download_url":"https://codeload.github.com/troglobit/merecat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247177422,"owners_count":20896648,"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":["acme","cgi","embedded","gzip-compression","http-redirect","http-server","httpd","https","letsencrypt","php","php-cgi","ssi","ssl","thttpd","tls","virtual-hosts","webserver","zlib"],"created_at":"2024-10-10T02:45:54.915Z","updated_at":"2025-04-04T13:08:27.062Z","avatar_url":"https://github.com/troglobit.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"Merecat httpd ∴ Embedded Web Server\n===================================\n[![License Badge][]][License] [![GitHub Status][]][GitHub] [![Coverity Status]][Coverity Scan]\n\n\u003cimg align=\"right\" width=\"500\" src=\"www/img/merecat.jpg\" alt=\"http://imgur.com/user/SunShot\"\u003e\n\n[Merecat][] started out as a pun at [Mongoose][], but is now useful for\nactual web serving purposes.  It is however not a real [Meerkat][],\nmerely yet another copycat, forked from the great [thttpd][] created by\nJef\u0026nbsp;Poskanzer.\n\nMerecat httpd expands on the features originally offered by thttpd, but\nstill has a limited feature set:\n\n - Virtual hosts\n - Basic `.htpassd` and `.htaccess` support\n - URL-traffic-based throttling\n - CGI/1.1\n - HTTP/1.1 Keep-alive\n - Built-in gzip deflate using zlib\n - HTTPS support using OpenSSL/LibreSSL, works with [Let's Encrypt][]!\n - Dual server support, both HTTP/HTTPS from one process\n - HTTP redirect, to gently redirect from HTTP server to HTTPS\n - Native PHP support, using `php-cgi` if enabled in `merecat.conf`\n\nThe resulting footprint (~140 kiB) makes it quick and suitable for small\nand embedded systems!\n\nMerecat is available as free/open source software under the simplified\n2-clause [BSD license][license].  For more information, see the manual\npage `merecat(8)`, or the [FAQ][].\n\nThe rest of this README covers some basic functions and recommendations.\nFor more in-depth use-case examples, see the following HowTos:\n\n - https://troglobit.com/howtos/merecat-basic-cig-in-c/\n - https://troglobit.com/howtos/merecat-and-lets-encrypt/\n - https://troglobit.com/howtos/merecat-and-ikiwiki/\n - https://troglobit.com/howtos/merecat-and-cgit/\n\n\nDocker\n------\n\nTry out [Docker Merecat](https://hub.docker.com/r/troglobit/merecat/)\nsafely isolated from the rest of the system, with easy deployment.\n\n\nAuthentication\n--------------\n\nTo protect a directory in your `~USERNAME/public_html/`, create the file\n`.htpasswd` using the included `htpasswd` tool:\n\n```shell\nuser@example:~/\u003e cd public_html/Downloads\nuser@example:~/public_html/Downloads/\u003e htpasswd -c .htpasswd friend\nChanging password for user friend\nNew password: *****\nRe-type new password: *****\n```\n\nEnable this feature, and user home directories, with the `configure`\nscript.  See more on this in the [Features](#features) section below.\n\n\nVirtual Hosts\n-------------\n\nSetting up virtual hosts on a server can be a bit of a hassle with other\nweb servers.  With Merecat you simply create directories for each host\nin the web server root:\n\n```\n/var/www/\n  |-- icons/\n  |-- cgi-bin/\n  |-- errors/\n  |    `-- err404.html\n  |-- ftp.example.com/\n   `- www.example.com/\n```\n\nEdit `/etc/merecat.conf`:\n\n```conf\nvirtual-host = true\ncgi \"/cgi-bin/*|**.cgi\" {\n    enabled = true\n}\n```\n\nNow the web server root, `/var/www/`, no longer serves files, only\nvirtual host directories do, execpt for the shared files in `icons/`,\n`cgi-bin/`, and `errors/`.\n\nOn Linux bind mounts can be used to set up FTP and web access to the\nsame files. Example `/etc/fstab`:\n\n```\n/srv/ftp  /var/www/ftp.example.com  none  defaults,bind  0  0\n```\n\n\nOptimizing Performance\n----------------------\n\nThere are many tricks to optimizing the performance of your web server.\nOne of the most important ones is browser caching.  Merecat supports\nboth `ETag:` and `Cache-Control:`, however to enable the latter you need\nto define the `max-age` setting in `/etc/merecat.conf`:\n\n```conf\nmax-age = 3600        # One hour\n```\n\nThe value is completely site dependent.  For an embedded system you\nmight want to set it to the maximum value, whereas for other scenarios\nyou will likely want something else.  By default this is disabled (0).\n\nAnother trick is to employ `gzip` compression.  Merecat has built-in\nsupport for serving HTML, CSS, and other `text/*` files if there is a\n`.gz` version of the same file.  Here is an example of how to compress\nrelevant files:\n\n```shell\nroot@example:~/\u003e cd /var/www/\nroot@example:/var/www/\u003e for file in `find . -name '*.html' -o -name '*.css'`; do \\\n      gzip -c $file \u003e $file.gz; done\n```\n\nThis approach is more CPU friendly than letting Merecat \"deflate\" files\non the fly, which it otherwise does.\n\n\nHTTPS Support\n-------------\n\nIf `configure` finds OpenSSL installed, HTTPS support is enabled, this\ncan be disabled using `--without-ssl`.  However, to gain access to the\nSSL/TLS settings you also need support for `merecat.conf`, so you must\ninstall [libConfuse][].  See below for all Build Requirements.\n\nThe HTTPS support has SSLv2, SSLv3, and TLSv1 disabled (hard coded) by\ndefault.  Only TLSv2 and later will be enabled and negotiated on a per\nclient basis.\n\nTo set up Merecat for HTTPS the following `/etc/merecat.conf` settings\nmust be enabled:\n\n```conf\nserver secure {\n    port = 443\n    ssl {\n        certfile = /etc/letsencrypt/live/example.com/fullchain.pem\n        keyfile  = /etc/letsencrypt/live/example.com/privkey.pem\n        dhfile   = /etc/letsencrypt/live/example.com/dhparam.pem\n    }\n}\n```\n\n### Let's Encrypt\n\nMerecat fully supports [Let's Encrypt][] certificates, including HTTP-01\nrenewals.  Use the server location directive:\n\n```conf\nserver default {\n        port = 80\n        location \"/.well-known/acme-challenge/**\" {\n                 path = \"letsencrypt/.well-known/acme-challenge/\"\n        }\n        redirect \"/**\" {\n                 code = 301\n                 location = \"https://$host$request_uri$args\"\n        }\n}\n```\n\nThe `path` must be relative to the server root directory.  Use bind\nmounts to get `/var/lib/letsencrypt` into your server root.  This way\nwe can ensure `certbot` only writes to its own directory and cannot\nwrite to any file in the server root.\n\nThen run `certbot` with the following arguments and then add all virtual\nhosts you want to support from Merecat:\n\n```shell\nroot@example:/var/www/\u003e certbot certonly --webroot --webroot-path /var/lib/letsencrypt\n```\n\nFor a HowTo see:\n\n- https://troglobit.com/howtos/merecat-and-lets-encrypt/\n\n### Self-signed Certificate\n\nTo create a self signed certificate and enable perfect forward secrecy,\nPFS, i.e. Diffie-Helman paramters (optional), use the `openssl` tool as\nshown below.  Notice the use of a sub-shell with `openssl.cnf` where\nmost of the certificate settings are, and more importantly notice the\nuse of `subjectAltName`, or SAN.  The latter is required by most\nbrowsers today.\n\n```shell\nroot@example:/var/www/\u003e mkdir private certs\nroot@example:/var/www/\u003e openssl req -x509 -newkey rsa:4096 -nodes    \\\n            -keyout private/server.key -new -out certs/server.pem    \\\n            -subj /CN=www.acme.com -reqexts SAN -extensions SAN      \\\n            -sha256 -days 3650 -config \u003c(cat /etc/ssl/openssl.cnf    \\\n             \u003c(printf '[SAN]\\nsubjectAltName=DNS:www.acme.com'))\nroot@example:/var/www/\u003e openssl dhparam -out certs/dhparm.pem 4096\n```\n\nHTTP Redirect\n-------------\n\nFor a setup with two servers, the following example can be used to run\nHTTPS on port 4443, HTTP on port 8080 and redirect to the HTTPS server\non any access:\n\n```conf\nserver secure {\n    port     = 4443\n    ssl {\n        certfile = certs/server.pem\n        keyfile  = private/server.key\n        dhfile   = certs/dhparm.pem\n    }\n}\n\nserver default {\n    port = 8080\n    redirect \"/**\" {\n        code = 303\n        location = \"https://$host:4443$request_uri$args\"\n    }\n}\n```\n\nSupported HTTP redirect codes are: 301, 302, 303, and 307.\n\nThe location setting supports three nginx style variables as shown\nin the example.  Please note the quotes around the pattern, or the\n.conf parser will think the pattern is a C-style comment.\n\n\nBuild Requirements\n------------------\n\nMerecat depends on a few external libraries, if enabled, e.g. OpenSSL,\nzlib, and [libConfuse][].  On Debian/Ubuntu systems you can install the\ndependencies with:\n\n```shell\nuser@example:~/\u003e sudo apt install pkg-config libconfuse-dev libssl-dev zlib1g-dev\n```\n\nIf you build the deps. from source, they may default to use an install\nprefix of `/usr/local`.  Non Debian/Ubuntu systems rarely support this\nGNU standard, so here is how you reference it for the Merecat\n`configure` script:\n\n```shell\nuser@example:~/merecat/\u003e PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure\n```\n\nTo build Merecat without support for `/etc/merecat.conf`:\n\n```shell\nuser@example:~/merecat/\u003e ./configure --without-config\n```\n\nIf you build from GIT sources and not a released tarball, then remember:\n\n```shell\nuser@example:~/merecat/\u003e ./autogen.sh\n```\n\nTo install `httpd` into `/usr/sbin/`, default index and icons into\n`/var/www`, and config file to `/etc/merecat.conf`:\n\n```shell\nuser@example:~/merecat/\u003e ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc\nuser@example:~/merecat/\u003e make\nuser@example:~/merecat/\u003e sudo make install\n```\n\nCross compiling Merecat for an another target is possible by setting the\n`--host` flag to the configure script.  This is well documented in the\n[GNU Documentation][configure].  Note: usually the `--build` system is\nautomatically detected.\n\n\u003e Merecat builds are silent by default.  For detailed compiler output,\n\u003e disable silent mode with `configure --disable-silent-rules`, or build\n\u003e with `make V=1`.\n\n\nFeatures\n--------\n\nMerecat consists of a front-end, `merecat.c`, and a standalone HTTP\nlibrary, `libhttpd.c`, which can be tweaked in various ways and used\nfor embedding a web server in another application if needed.\n\nThe most common options are available from the `merecat` command line\nand the `merecat.conf` configuration file.  Other, less common options,\ncan be enabled using the `configure` script:\n\n```\n--enable-builtin-icons  Enable built-in icons for dir listings\n--enable-htaccess       Enable .htaccess files for access control\n--enable-htpasswd       Enable .htpasswd files for authentication\n--enable-public-html    Enable $HOME/public_html as ~USERNAME/\n--enable-msie-padding   Add padding to error messages for Internet Explorer\n--disable-dirlisting    Disable directory listings when no index file is found\n--without-config        Disable /etc/merecat.conf support using libConfuse\n--without-ssl           Disable HTTPS support, default: enabled\n--without-symlinks      Disable httpd and in.httpd symlinks to merecat\n--without-zlib          Disable mod_deflate (gzip) using zlib\n```\n\nThe source file `merecat.h` has even more features that can be tweaked,\nsome of those are mentioned in the man page, but the header file has\nvery useful comments as well.\n\n\nOrigin \u0026 References\n-------------------\n\nMerecat is a stiched up fork of [sthttpd][] with lots of lost patches\nfound lying around the web.  The sthttpd project in turn is a fork from\nthe original [thttpd][] -- the tiny/turbo/throttling HTTP server.\n\n* [thttpd][] was created by Jef Poskanzer \u003cmailto:jef@mail.acme.com\u003e\n* [sthttpd][] was spawned by Anthony G. Basile \u003cmailto:blueness@gentoo.org\u003e\n* [Merecat][] is maintained by Joachim Wiberg \u003cmailto:troglobit@gmail.com\u003e\n\n[Merecat]:          https://merecat.troglobit.com\n[Meerkat]:          https://en.wikipedia.org/wiki/Meerkat\n[license]:          https://github.com/troglobit/merecat/blob/master/LICENSE\n[Mongoose]:         https://github.com/cesanta/mongoose\n[Let's Encrypt]:    https://letsencrypt.org/\n[libConfuse]:       https://github.com/martinh/libconfuse/\n[configure]:        https://www.gnu.org/software/automake/manual/html_node/Cross_002dCompilation.html\n[FAQ]:              http://halplant.com:2001/server/thttpd_FAQ.html\n[thttpd]:           http://www.acme.com/software/thttpd/\n[sthttpd]:          https://github.com/blueness/sthttpd/\n[License]:          https://en.wikipedia.org/wiki/BSD_licenses\n[License Badge]:    https://img.shields.io/badge/License-BSD%202--Clause-orange.svg\n[GitHub]:           https://github.com/troglobit/merecat/actions/workflows/build.yml/\n[GitHub Status]:    https://github.com/troglobit/merecat/actions/workflows/build.yml/badge.svg\n[Coverity Scan]:    https://scan.coverity.com/projects/18686\n[Coverity Status]:  https://scan.coverity.com/projects/18686/badge.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroglobit%2Fmerecat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftroglobit%2Fmerecat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroglobit%2Fmerecat/lists"}