{"id":46152387,"url":"https://github.com/sctg-development/tokeisrv","last_synced_at":"2026-03-02T09:02:43.754Z","repository":{"id":324908642,"uuid":"1099030984","full_name":"sctg-development/tokeisrv","owner":"sctg-development","description":"Get your Github badge counting your code, quickly.","archived":false,"fork":false,"pushed_at":"2026-01-10T15:34:59.000Z","size":356,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-11T02:41:08.181Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sctg-development.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-18T13:17:18.000Z","updated_at":"2026-01-10T15:33:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sctg-development/tokeisrv","commit_stats":null,"previous_names":["sctg-development/tokeisrv"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/sctg-development/tokeisrv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Ftokeisrv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Ftokeisrv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Ftokeisrv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Ftokeisrv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sctg-development","download_url":"https://codeload.github.com/sctg-development/tokeisrv/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sctg-development%2Ftokeisrv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29996278,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-02T01:47:34.672Z","status":"online","status_checked_at":"2026-03-02T02:00:07.342Z","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":[],"created_at":"2026-03-02T09:02:42.127Z","updated_at":"2026-03-02T09:02:43.729Z","avatar_url":"https://github.com/sctg-development.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://tokeisrv.sctg.eu.org/b1/github/sctg-development/tokeisrv?type=rust\u0026category=code)\n![](https://tokeisrv.sctg.eu.org/b1/github/sctg-development/tokeisrv?type=rust\u0026category=comments)\n[![codecov](https://codecov.io/github/sctg-development/tokeisrv/branch/main/graph/badge.svg)](https://codecov.io/github/sctg-development/tokeisrv)\n[![CI](https://github.com/sctg-development/tokeisrv/actions/workflows/ci.yaml/badge.svg)](https://github.com/sctg-development/tokeisrv/actions/workflows/ci.yaml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n# tokeisrv — Tokei HTTP Badge Service\n\nA small HTTP service exposing Tokei statistics (lines of code, comments, blanks, etc.) as SVG badges. The service uses `tokei` to compute language statistics, `actix-web` to expose endpoints, and `rsbadges` to generate SVG badge images.\n\nThis project is an adaptation of XAMPPRocky's tokei web badge server; modifications and maintenance are by Ronan Le Meillat (SCTG Development). Code is licensed under the MIT license — see source headers.\n\nTL;DR — Quick deployment\n------------------------\nuse MarkDown code like\n```text\n![](https://tokeisrv.example.com/b1/github/sctg-development/tokeisrv?type=rust\u0026category=code)\n![](https://tokeisrv.example.com/b1/github/sctg-development/tokeisrv?type=rust\u0026category=comments)\n```\nWant to deploy your own instance quickly? See the short step-by-step guide: [Deploy your own service using Docker Compose](./deploy-your-own-service.md).\nIt covers creating a free `.pp.ua` domain, configuring Cloudflare and Cloudflare Tunnel (cloudflared), generating credentials, running `docker compose`, and example badge usage.\n\n---\n\n## Features ✅\n\n- Serves SVG badges for repository language statistics (lines, code, files, comments, blanks)\n- Badge customization: color, style, label, logo, and language ranking\n- Cache remote repository stats for faster responses (`cached` crate) with configurable TTL and size (`--cache-ttl`, `--cache-size`)\n- CLI args and environment variables for server configuration\n- Verbose logs by default, quiet mode via `-q`/`--quiet`\n- Optional user whitelist to limit which repository owners can be cloned (`--user-whitelist`)\n- Optional git server whitelist to restrict allowed domain hosts for repo cloning (`--gitserver-whitelist`)\n- Admin-protected flush-cache action (`--admin-password` / `TOKEI_ADMIN_PASSWORD`) — accepts only SHA-256/512 crypt hashes (openssl `-5`/`-6`)\n - Optional ignore-filetypes to skip scanning files by extension, e.g. `png`, `jpg`, `gz` (`--ignore-filetype`, `TOKEI_IGNORE_FILETYPE`) \n- No git dependencies at runtime\n\n---\n\n## Getting started — build \u0026 run 🚀\n\nPrerequisites:\n- Rust toolchain (stable)\n\nBuild:\n\n```bash\ncargo build --release\n```\n\nRun with default settings (bind 0.0.0.0:8000):\n\n```bash\ncargo run --release --\n```\n\nRun with custom bind/port and quiet flag (CLI has precedence over env vars):\n\n```bash\ncargo run --release -- --bind 127.0.0.1 --port 8080 -q\n```\n\nTo control the maximum number of cached entries, provide `--cache-size`. Default is 1000 entries:\n\n```bash\ncargo run --release -- --cache-size 2048\n```\n\nYou can also ignore specific file extensions using `--ignore-filetype` (comma-separated, no leading dot) or the environment variable `TOKEI_IGNORE_FILETYPE`:\n\n```bash\ncargo run --release -- --ignore-filetype \"png,jpg,gz\" --bind 0.0.0.0 --port 8000\n```\n```\n\nYou can also use environment variables instead of CLI options:\n\n```bash\nexport TOKEI_BIND=127.0.0.1\nexport TOKEI_PORT=8080\ncargo run --release --\n```\n\nNotes:\n- CLI options take precedence over environment variables.\n- Default behavior: verbose logs (RUST_LOG defaults to `info` when unset). Use `-q` or `--quiet` to silence logs.\n\n---\n\n## API endpoints and usage 🛠️\n\nMain endpoint (badge generator):\n\n- GET /b1/{domain}/{user}/{repo}\n\nExamples:\n\n```bash\n# Default: show badge for lines\ncurl \"http://127.0.0.1:8000/b1/github.com/XAMPPRocky/tokei\"\n\n# Show code lines as a badge\ncurl \"http://127.0.0.1:8000/b1/github.com/XAMPPRocky/tokei?category=code\"\n\n# Show top language ranking\ncurl \"http://127.0.0.1:8000/b1/github.com/XAMPPRocky/tokei?show_language=true\"\n\n# Use branch override\ncurl \"http://127.0.0.1:8000/b1/github.com/XAMPPRocky/tokei?branch=main\"\n\n# Generate JSON instead of SVG\ncurl -H \"Accept: application/json\" \"http://127.0.0.1:8000/b1/github.com/XAMPPRocky/tokei\"\n```\n\nQuery parameters details:\n- `category`: `lines` (default), `code`, `blanks`, `comments`, `files`\n- `label`: custom left-side label\n- `style`: `plastic`, `flat`, `flat-square`, `for-the-badge`, `social`\n- `color`: custom hex color for the message side of the badge\n- `logo`: badge logo name (if supported by `rsbadges`)\n- `type`: filter which language types are considered (comma-separated)\n- `show_language`: Boolean (`true`/`false`) to display top language name on the badge\n- `language_rank`: choose index for ranking language\n- `branch`: choose repository branch to analyze\n\n---\n\n## Caching behavior 🧠\n\nThis service uses an in-memory LRU cache to store repository statistics for faster responses. Each cached entry stores:\n\n- Timestamp when the stats were added to the cache\n- Full commit SHA (40 hex characters)\n- SHA256 hash of the requested URL (useful for deduplication)\n- JSON summary of top-level counts (Lines, Code, Comments, Blanks)\n- The full tokei `Language` vector used to render badges\n\nDefault behavior:\n\n- Number of cached entries (TimedSizedCache size): 1000 entries (default)\n- TTL for cached entries: 1 day (24 hours) (default)\n- You can change the maximum number of cached entries with the CLI flag `--cache-size` or the environment variable `TOKEI_CACHE_SIZE`.\n- Cache TTL can be overridden with CLI flag `--cache-ttl` (seconds) or the environment variable `TOKEI_CACHE_TTL`. CLI takes precedence.\n - You can restrict which git servers can be queried using `--gitserver-whitelist` or environment variable `TOKEI_GITSERVER_WHITELIST`. If this list is empty, all servers are permitted. The service normalizes whitelist entries and the requested server host to lowercase for comparison; the server \u003cuser\u003e part of the repository remains case-sensitive.\n- The cache follows an LRU (least recently used) policy when space is needed and evicts oldest entries first.\n\nNotes:\n\n- If the git SHA hasn't changed, the repository is not recloned and the badge is generated from the cached result.\n- If the cache is full, the least recently used entry is evicted to make room.\n\nEtag headers and `If-None-Match` are supported by the service; cached responses will return 304 Not Modified when appropriate.\n\nNote: updating `cached` from 0.55 to 0.56 requires a Duration type for TTL — the repo uses `std::time::Duration::from_secs(DAY_IN_SECONDS)`.\n\n---\n\n## Logging\n\n- Default: logs are verbose (RUST_LOG defaults to `info` when not set)\n- To reduce log output: pass `-q` / `--quiet` to the binary\n- You can still use `RUST_LOG` to control specific logging levels if `-q` is not used\n\nExample:\n\n```bash\n# Use an environment variable for detailed filtering\nRUST_LOG=actix_web=info,target=debug cargo run --release --\n```\n\n---\n\n## Security \u0026 limitations ⚠️\n\n- The service clones remote repositories to a temporary directory — ensure you trust the sources you allow or limit access.\n\nAdmin password \u0026 administrative actions (optional)\n-------------------------------------------------\nThis service exposes a lightweight administrative action to flush cached statistics for a given repository. The flush action is protected by an administrative password mechanism to avoid accidental or malicious cache invalidation.\n\nHow it works:\n- Provide one or more **hashed** admin passwords compatible with `openssl passwd` (SHA-based crypt hashes). These are configured either via the CLI option `--admin-password` (can be specified multiple times) or the environment variable `TOKEI_ADMIN_PASSWORD` (comma-separated list of hashes).\n- Each stored value must be the hashed result produced by `openssl passwd` using **SHA-256** or **SHA-512** crypt formats (i.e., `-5` or `-6`). Example generation:\n\n```bash\n# SHA-512\nopenssl passwd -6 -salt testsalt supersecret\n# SHA-256\nopenssl passwd -5 -salt testsalt supersecret\n```\n\n- When invoking the admin action over HTTP, the client provides the password in clear text as the `admin-password` query parameter; the server computes the compatible hash and compares it against the stored hashes.\n\nImportant security note and allowed algorithms\n---------------------------------------------\n- For security and portability the server **only accepts SHA-based crypt hashes** produced by `openssl passwd -5` (SHA-256) or `openssl passwd -6` (SHA-512).\n- If an administrator attempts to configure a hashed password using another crypt algorithm (for example, MD5/`-1`), the server will **reject the request** when that hash is used and return an HTTP 403 response with the body:\n\n```\n403 - password algorithm not allowed\n```\n\nThe flush-cache admin action\n---------------------------\n- Endpoint: `GET /b1/{domain}/{user}/{repo}?action=flush-cache\u0026admin-password=\u003cpassword\u003e`\n- Behavior: if authentication succeeds, the service removes any cached entries for the specified repository (both branch and HEAD entries when applicable) and returns a success badge; otherwise it returns a forbidden badge (or the explicit 403 message above when a disallowed algorithm is detected).\n\nNotes and future direction:\n- To generate hashes portable across platforms, use `openssl passwd -5` or `-6` as shown above.\n- We plan to eventually replace the current reliance on the `openssl` CLI with a pure-Rust verifier to simplify CI/containers and remove the runtime dependency.\n\n\nUser whitelist (optional, recommended for security)\n-----------------------------------------------\nYou can optionally restrict which repository owners the service is permitted to analyze. This prevents the server from cloning arbitrary repositories and reduces attack surface.\n\nHow it works:\n- Provide a comma-separated list of allowed usernames (e.g., `alice,bob`). If the list is empty (default), all requests are permitted.\n- Whitelist can be set using the CLI flag `--user-whitelist` or the environment variable `TOKEI_USER_WHITELIST`.\n- When a request targets a repository whose owner is not listed, the server returns a red `forbidden` SVG badge (HTTP 403) instead of cloning the repo.\n\nNotes on formatting and behavior:\n- The whitelist expects a comma-separated list of usernames with no surrounding spaces (whitespace is trimmed). Empty entries are not allowed.\n- Username matching is exact and case-sensitive. If you want case-insensitive matching, normalize usernames to lowercase before passing them in.\n- The server logs a warning for requests blocked by the whitelist for monitoring/auditing purposes.\n\nExample usage\n-------------\nUsing the CLI:\n```bash\n./tokei_rs --user-whitelist alice,bob --bind 0.0.0.0 --port 8000\n```\n\nUsing environment variables:\n```bash\nexport TOKEI_USER_WHITELIST=\"alice,bob\"\n./tokei_rs\n```\n\nUsing Docker (passing env to container):\n```bash\ndocker run -e TOKEI_USER_WHITELIST=\"alice,bob\" -p 8000:8000 sctg/tokeisrv:latest\n```\n\nUsing Helm (chart value):\n```bash\nhelm install tokeisrv helm/tokeisrv --set userWhitelist='alice,bob'\n# Example: set admin passwords (comma-separated hashed values, use openssl -5/-6 to generate)\nhelm install tokeisrv helm/tokeisrv --set adminPassword='$6$testsalt$ABCD...,$6$othersalt$EFGH...'\n```\n\nThis feature should be used when you want to operate the service in a managed environment or expose it publicly — it helps ensure only repositories from trusted owners are processed.\n\nGit server whitelist (optional, recommended for security)\n------------------------------------------------------\nYou can optionally restrict which git servers (remote domains) the service is permitted to contact. This prevents the service from being used as a proxy to reach arbitrary hosts and reduces attack surface.\n\nHow it works:\n- Provide a comma-separated list of allowed domain names (e.g., `github.com,gitlab.com`). If the list is empty (default), all servers are permitted.\n- Whitelist can be set using the CLI flag `--gitserver-whitelist` or the environment variable `TOKEI_GITSERVER_WHITELIST`.\n- When a request targets a repository whose git server domain is not listed, the server returns a red `forbidden` SVG badge (HTTP 403) instead of making the request.\n\nNotes on formatting and behavior:\n- The whitelist expects a comma-separated list of hostnames with no surrounding spaces (whitespace is trimmed). Empty entries are not allowed.\n- Domain matching is exact and case-sensitive. For best results, provide fully-qualified domain names (e.g., `github.com`) and normalize to lowercase if you want to avoid mismatches.\n\nExample usage\n-------------\nUsing the CLI:\n```bash\n./tokei_rs --gitserver-whitelist github.com,gitlab.com --bind 0.0.0.0 --port 8000\n```\n\nUsing environment variables:\n```bash\nexport TOKEI_GITSERVER_WHITELIST=\"github.com,gitlab.com\"\n./tokei_rs\n```\n\nUsing Docker (passing env to container):\n```bash\ndocker run -e TOKEI_GITSERVER_WHITELIST=\"github.com,gitlab.com\" -p 8000:8000 sctg/tokeisrv:latest\n```\n\nUsing Helm (chart value):\n```bash\nhelm install tokeisrv helm/tokeisrv --set gitServerWhitelist='github.com,gitlab.com'\n```\n\nUsing Helm to configure ignored file extensions (chart value):\n```bash\nhelm install tokeisrv helm/tokeisrv --set ignoreFiletypes='png,jpg,gz'\n```\n\nThis should be used when you want to tightly control which remote git servers are accessed by the service, such as in corporate environments.\n\nIgnore file types (optional, recommended)\n------------------------------------------------------\nYou can optionally configure the service to ignore certain file extensions when scanning repositories (for example, large binaries, images, or archives). This reduces CPU usage and scan time, and is especially useful on hosted builds where you want to avoid scanning generated binaries.\n\nHow it works:\n- Provide a comma-separated list of file extensions (no dot) via the CLI flag `--ignore-filetype` or the environment variable `TOKEI_IGNORE_FILETYPE`.\n- The service converts entries such as `png` into a pattern `**/*.png` and passes them as exclude patterns to the `tokei` analyzer.\n\nNotes on formatting and behavior:\n- Case-insensitive: entries are normalized to lowercase.\n- Example default list used by the service: `gfs,xsd,csv,dxf,wkt,dgn,rsc,png,a,so,pc,ai,jpg,gif,gz,bz2,xz,gzip,bzip2,pdf`.\n- To ignore a specific extension, include it without a leading dot: `png` not `.png`.\n\nExample usage\n-------------\nUsing the CLI:\n```bash\n./tokei_rs --ignore-filetype png,jpg,gz --bind 0.0.0.0 --port 8000\n```\n\nUsing environment variables:\n```bash\nexport TOKEI_IGNORE_FILETYPE=\"png,jpg,gz\"\n./tokei_rs\n```\n\nUsing Docker (passing env to container):\n```bash\ndocker run -e TOKEI_IGNORE_FILETYPE=\"png,jpg,gz\" -p 8000:8000 sctg/tokeisrv:latest\n```\n\nUsing Helm (chart value):\n```bash\nhelm install tokeisrv helm/tokeisrv --set ignoreFiletypes='png,jpg,gz'\n```\n\n---\n## Supported Languages\n\nThose language are supported\n```\nAbap\nActionScript\nAda\nAgda\nAlex\nAlloy\nAPL\nAsn1\nAsp\nAspNet\nAssembly\nAssemblyGAS\nATS\nAutoconf\nAutoHotKey\nAutomake\nAWK\nBash\nBatch\nBazel\nBean\nBicep\nBitbake\nBQN\nBrightScript\nC\nCabal\nCassius\nCeylon\nCHeader\nCil\nClojure\nClojureC\nClojureScript\nCMake\nCobol\nCoffeeScript\nCogent\nColdFusion\nColdFusionScript\nCoq\nCpp\nCppHeader\nCrystal\nCSharp\nCShell\nCss\nCuda\nCUE\nCython\nD\nD2\nDAML\nDart\nDeviceTree\nDhall\nDockerfile\nDotNetResource\nDreamMaker\nDust\nEbuild\nEdgeDB\nEdn\nElisp\nElixir\nElm\nElvish\nEmacsDevEnv\nEmojicode\nErlang\nFactor\nFEN\nFish\nFlatBuffers\nForgeConfig\nForth\nFortranLegacy\nFortranModern\nFreeMarker\nFSharp\nFstar\nGDB\nGdScript\nGdShader\nGherkin\nGleam\nGlsl\nGo\nGraphql\nGroovy\nGwion\nHamlet\nHandlebars\nHappy\nHare\nHaskell\nHaxe\nHcl\nHex\nHex0\nHex1\nHex2\nHiCAD\nhledger\nHlsl\nHolyC\nHtml\nHy\nIdris\nIni\nIntelHex\nIsabelle\nJai\nJanet\nJava\nJavaScript\nJq\nJson\nJsx\nJulia\nJulius\nJust\nKakouneScript\nKaemFile\nKotlin\nLean\nLess\nLingua Franca\nLinkerScript\nLiquid\nLisp\nLLVM\nLogtalk\nLua\nLucius\nM1Assembly\nMadlang\nMax\nMakefile\nMarkdown\nMdx\nMeson\nMint\nMlatu\nModuleDef\nMonkeyC\nMoonScript\nMsBuild\nMustache\nNim\nNix\nNotQuitePerl\nNuGetConfig\nNushell\nObjectiveC\nObjectiveCpp\nOCaml\nOdin\nOpenSCAD\nOpenQASM\nOrg\nOz\nPascal\nPerl\nPerl6\nPest\nPhix\nPhp\nPo\nPoke\nPolly\nPony\nPostCss\nPowerShell\nProcessing\nProlog\nProtobuf\nPRQL\nPSL\nPureScript\nPyret\nPython\nQcl\nQml\nR\nRacket\nRakefile\nRazor\nRenpy\nReStructuredText\nRON\nRPMSpecfile\nRuby\nRubyHtml\nRust\nSass\nScala\nScheme\nScons\nSh\nShaderLab\nSlang\nSml\nSolidity\nSpecmanE\nSpice\nSql\nSRecode\nStata\nStratego\nSvelte\nSvg\nSwift\nSwig\nSystemVerilog\nSlint\nTact\nTcl\nTempl\nTex\nText\nThrift\nToml\nTsx\nTwig\nTypeScript\nUMPL\nUnrealDeveloperMarkdown\nUnrealPlugin\nUnrealProject\nUnrealScript\nUnrealShader\nUnrealShaderHeader\nUrWeb\nUrWebProject\nVala\nVB6\nVBScript\nVelocity\nVerilog\nVerilogArgsFile\nVhdl\nVimScript\nVisualBasic\nVisualStudioProject\nVisualStudioSolution\nVue\nWebAssembly\nWolfram\nXaml\nXcodeConfig\nXml\nXSL\nXtend\nYaml\nZenCode\nZig\nZoKrates\nZsh\n```\n## Contributing 👩‍💻👨‍💻\n\nPlease open issues or pull requests. If you're planning larger changes, create an issue first so we can coordinate design.\n\n---\n\n## License\n\nThis software is provided under the MIT license. See comments in source files for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsctg-development%2Ftokeisrv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsctg-development%2Ftokeisrv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsctg-development%2Ftokeisrv/lists"}