Warmcat homepage andy@warmcat.com
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"en-US,en;q\u003d0.5", "gen_ut":1718896901, "reponame":"gitohashi", "desc":"Git web frontend with clientside rendering", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://warmcat.com/repo/gitohashi", "f":3, "items": [ { "schema":"libjg2-1", "oid":{ "oid": "9961e6fef5f0f2458efc1c2a40d63f7cc50ebfce", "alias": [ "refs/heads/main","refs/heads/master"]},"tree": [ { "name": "assets","mode": "16384", "size":0}, { "name": "cmake","mode": "16384", "size":0}, { "name": "doc","mode": "16384", "size":0}, { "name": "etc-gitohashi","mode": "16384", "size":0}, { "name": "example-cert","mode": "16384", "size":0}, { "name": "examples","mode": "16384", "size":0}, { "name": "include","mode": "16384", "size":0}, { "name": "lib","mode": "16384", "size":0}, { "name": "src","mode": "16384", "size":0}, { "name": "system","mode": "16384", "size":0}, { "name": "templates","mode": "16384", "size":0}, { "name": "xss","mode": "16384", "size":0}, { "name": ".gitignore","mode": "33188", "size":35}, { "name": ".sai.json","mode": "33188", "size":763}, { "name": "CMakeLists.txt","mode": "33188", "size":9610}, { "name": "LICENSE","mode": "33188", "size":27131}, { "name": "README.md","mode": "33188", "size":18087}, { "name": "lgtm.yml","mode": "33188", "size":615}],"s":{"c":1718896901,"u": 934}} ,{"schema":"libjg2-1", "cid":"01c9b98db69cd57cb76354aef43fa936", "oid":{ "oid": "9961e6fef5f0f2458efc1c2a40d63f7cc50ebfce", "alias": [ "refs/heads/main","refs/heads/master"]},"blobname": "README.md", "blob": "[![CI status](https://warmcat.com/sai/status/gitohashi)](https://warmcat.com/sai/gitohashi) [![coverity](https://scan.coverity.com/projects/16562/badge.svg?flat\u003d1)](https://scan.coverity.com/projects/gitohashi) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b16f6d786a4846648a10c0265f2a2887)](https://www.codacy.com/app/lws-team/gitohashi?utm_source\u003dgithub.com\u0026amp;utm_medium\u003dreferral\u0026amp;utm_content\u003dwarmcat/gitohashi\u0026amp;utm_campaign\u003dBadge_Grade) [![Total alerts](https://img.shields.io/lgtm/alerts/g/warmcat/gitohashi.svg?logo\u003dlgtm\u0026logoWidth\u003d18)](https://lgtm.com/projects/g/warmcat/gitohashi/alerts/) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/warmcat/gitohashi.svg?logo\u003dlgtm\u0026logoWidth\u003d18)](https://lgtm.com/projects/g/warmcat/gitohashi/context:cpp) [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/warmcat/gitohashi.svg?logo\u003dlgtm\u0026logoWidth\u003d18)](https://lgtm.com/projects/g/warmcat/gitohashi/context:javascript)\n\n\ngitohashi Gitweb daemon\n-----------------------\n\nLightweight C Daemon that provides HTTP network transport and HTML presentation\nvia a JSON representation of bare git repositories discovered via gitolite and\naccessed via libgit2.\n\nSupports http/1, http/2 and unix socket (proxiable by, eg, apache, lighttpd or\nlibwebsocket's own lwsws) serving, avatar proxy caching and many other features.\n\nYou can find real deployments at, eg, https://libwebsockets.org/git and\nhttps://warmcat.com/git .\n\n![gitohashi-overview](./doc/doc-assets/gitohashi-overview.svg)\n\n## Features\n\n - Follows github type web display of repository state, default view is to show\n rendered README.md. Markdown can include references to files from the\n repo revision directly.\n\n - No per-page forking... no cgi... no subprocesses... persistant daemon\n architecture\n\n - Can optionally serve http[s] directly over http/1.1 and http/2, and / or\n serve locally on per-vhost unix socket for integration with existing Apache /\n lighttpd etc server + mod_proxy\n \n - Only needs configuration per-vhost in JSON, the repo configuration and\n access control is taken from gitolite config.\n\n - Clientside JS, CSS and HTML are provided, along with Markdown parsing\n and syntax highlighting JS to present the JSON + HTML in a modern and\n responsive way. SVG icons provided. Customizing the css and HTML\n template encouraged.\n\n - Transparent caching at JSON block level, keyed using global repository ref\n state... cache invalidated when any ref updated. ETAG browser cache\n validation supported as well. Ref hash based cache invalidation, not time-\n based, so no cached view more than a few seconds out of date.\n \n - Multiple vhosts natively supported; each can have their own template html /\n css and gitolite ACL \u0022user\u0022 name for automatic repo permissions\n\n - Safe gravatar proxy cache, served locally, no referrer leaks\n\n - Very modest on memory, Valgrind-clean, Coverity-clean, works great on a\n Raspberry Pi 3\n \n - I18N (Internationalization) supported keyed off the browser ACCEPT-\n LANGUAGE header, Japanese, Traditional and Simplified Chinese provided on top\n of the default English UI\n \n - Strict Content-Security-Policy out of the box, default-deny, 'self' and\n whitelisted img sources only (travis status etc). \n\n - Dynamically linked - binds to distro system libs to stay up to date\n\n# Getting Started\n\n## Build\n\ngitohashi is a small cmake project with only two dependencies, [libgit2](https://libgit2.org/)\nand [libwebsockets](https://libwebsockets.org/git/libwebsockets), also easy to build cmake projects.\n\nFull build details: [README-build.md](./doc/README-build.md)\n\n### Config\n\nYou can get started by copying ./etc-gitohashi to /etc/gitohashi\n\n```\n $ sudo cp -rp ./etc-gitohashi /etc/gitohashi\n```\n\nThis contains JSON configuration files for two example gitohashi vhosts, one\ndirectly serving on :443 over https and the other serving on a unix domain\nsocket for integration with another server.\n\nYou'll need to amend, eg, the path to the gitolite repository base dir.\n\nIf you are setting that up too, don't forget to create a bare test repo **and\npush content to it so gitohashi has something to display**.\n\nYou'll need to ensure the gitohashi daemon runs with permissions that allow it\nat least read access to the directories and files in the gitolite repository.\n\nFor example if the repository is owned by a user 'git', you can choose to run\ngitohashi under the same user. If that makes problems due to, eg, selinux,\nanother more complex way is run gitohashi as apache, and set the repositor\nbase dir and underneath to be git:apache and set the \u0022sticky bit\u0022 so the\ngroup is inherited. This also requires `git config` to be set up to have\n`sharedRepository \u003d group`, gitolite config is able to force this in the\nbare repo config it manages using `config core.sharedRepository \u003d group`\n\n### Startup\n\nThe gitohashi `make install` adds a systemd service file, so you can manage it\nthe same as other services.\n\nHowever you will need to move it into place if you are installing to, eg,\n`/usr/local/...` as it does by default.\n\n```\n $ sudo cp /usr/local/lib/systemd/system/gitohashi.service /usr/lib/systemd/system/\n```\n\nAfterwards you can use gitohashi normally with systemd:\n\n```\n $ systemctl start gitohashi\n```\n\n### Direct serving\n\ngitohashi can serve on http and https, using http/1.1 and / or http/2 directly.\nThe default example configuration defines two vhosts, one serving on\nhttp://localhost:443/git and the other serving on a unix domain socket intended\nto be proxied by Apache or another frontend server.\n\n### Apache integration\n\ngitohashi can serve over unix sockets, as shown in the `unixskt` example\nvhost. The unix socket should live in `/var/run/`, the example one is at\n`/var/run/gitohashi-unixskt`. Multiple vhosts can each expose their own\nunix socket.\n\ngitohashi will take care of unlinking and creating the unix sockets at startup,\nas well as changing their owner:group to the owner:group that gitohashi runs\nunder.\n\nHowever selinux must be informed that it's OK for the named unix sockets to be\nconnected to by Apache. You can do this by allowing apache to connect to\nlocal unix sockets generally with\n\n```\n$ sudo semodule -X 300 -i /usr/local/share/gitohashi/gitohashi-selinux.pp\n```\n\nAfterwards, for each vhost you want to use gitohashi on Apache, you need to\nadd\n\n```\nSSLProxyEngine on\nProxyPass /git unix:///var/run/gitohashi-unixskt|http://localhost/git\n```\n\nFor multiple vhosts, `unix:///var/run/gitohashi-unixskt` becomes the per-vhost\nunix socket you created in gitohashi's vhost config.\n\n### Serving gitohashi Assets\n\ngitohashi installs its `./assets` directory into\n`/usr/local/share/gitohashi` by default.\n\nasset|function\n---|---\ninconsolata.ttf|Web font for nice monospaced content\njg2.js|The clientside part that turns the JSON into HTML\njg2.css|Helper CSS for formatting jg2.js output\nlogo.css|CSS SVG Image included by the example template HTML\ngitohashi-custom.css|CSS overrides related to the custom HTML template (normally served from wherever the HTML template is served from)\nhighlight.pack.js|Highlight.js script to perform clientside file markup\ngithub.css|Highlight.js CSS (NB they provide many alternatives...)\nshowdown.min.js|Showdown script to perform clientside markdown to HTML\nshowdown.min.js.map|Additional information about minified showdown\n\nGitohashi also installs an example html template from its `./templates` dir,\n`gitohashi-example.html` into `/usr/local/share/gitohashi/templates`. This\nis not designed to be directly served, instead the gitohashi vhost is pointed\nto a customized copy of it adapted with a suitable logo, content and css /\nfonts.\n\nAssuming you want \u0022sandwiched\u0022 JSON-in-HTML mode, two places need to know the\npath:\n\n - you need to inform the library the filepath to the HTML template file in\n the vhost config struct\n\n - you must serve that dir somehow over HTTP so the client browser can get at\n the rest of the assets mentioned in the HTML. (The HTML is provided\n directly by gitohashi in sandwich mode, but the other assets are collected\n by the client browser over HTTP). The provided HTTP template\n assumes it's served from the same server at the virtual path\n `/git/_gitohashi`, but you can change that as needed.\n\nCaching policy in your HTTP server for the assets can be relaxed, since they\nwill normally only change when gitohashi it updated.\n\n### Integration with gitolite v3\n\nGitohashi tries to require as little configuration as possible. One big help\nwith that is it can use parse gitolite ACLs from the same repo base directory.\nThat allows you to use gitolite config to control which repos gitohashi can\naccess and set information about them.\n\nFull details: [README-gitolite.md](./doc/README-gitolite.md) \n\n## Caching in gitohashi\n\nTo minimize the cost of generated, external and static page assets, gitohashi\nuses several different types of cache. \n\n### Avatar cache\n\ngitohashi makes a lot of use of avatars to make it easy to recognize commit\nauthors and who has contributed.\n\n - Repeated avatar references on the client side are coalesced to one fetch by\nthe browser, but on pages with many commits by different people, that can still\nadd up to a lot of fetches. The caching policy is controlled by the server the\navatar was fetched from, even though avatars very seldom change.\n\n - With a third-party avatar provider, there's also a problem your browser is\ninforming them of every URL you visit via `referrer`, and which avatars are\nthere. This may be \u0022too much information\u0022.\n\n - Gravatar is also listed by mozilla as a service that needs protecting against\nfor privacy; you will lose your green padlock on pages that reference gravatar\ndirectly.\n\nFor these reasons gitohashi includes a smart server-side avatar cache.\n\nIt's not a generic proxy cache, gitohashi knows when it specifically generates\nJSON mentioning an identity, and the avatar cache fetches the related avatar if\nit's not already in the cache. The avatar cache is exposed in a mount serving\nstatic files with a user-controllable cache policy (which you can set to days\nor weeks to control the related client traffic). In this way it's secure\nagainst abuse.\n\nNo referrer information is sent, and since the JSON tells the browser to pick\nup the avatar images from your server, the client finds no references to\nthe third-party avatar provider and so no privacy issues.\n\n### Transparent JSON Cache\n\nGitohashi has a sophisticated transparent JSON cache.\n\nCache entries are invalidated when the related repo's refs\nchange; gitohashi maintains a hash of all refs in a repo for this purpose.\n\nIt means that deprecated repos nobody pushes to will keep their caches\nunless the size limit is reached and the cache content is reaped according to\nLRU, while active repos will always have fresh content reflecting their\ncurrent status with only a few seconds delay, and the cached versions of that\ncontent will exist until the next push, maximizing their usefulness.\n\nGitohashi checks the `user-agent` header of the client for \u0022bot\u0022 or \u0022Bot\u0022, and\nif present disables cache generation for the request, so that random bot\nspidering doesn't flush meaningful user accesses that may be useful for other\nusers in the cache.\n\n## Client-side HTTP cache\n\nAssets that may have a safe client-side cache policy (CSS, JS, fonts etc) are\nseparated out to their own URL base that may have the relaxed caching policy\napplied to it. The generated HTML + JSON is never cached and always produced\nlive. \n\n## ETAG client-side HTTP cache\n\nWhen the client-side cache time expires, the client can still avoid reloading\nby using ETAGs (all modern browsers do this automatically). Gitohashi\nunderstands ETAGs and will reply with a HTTP response code indicating the\ncached object is unchanged, renewing the clientside cache copy without having\nto resend any content.\n\n## Notes on developing with gitohashi\n\n1. You can run gitohashi from the commandline with sudo, but you must\n override HOME. libgit2 will try to use any .gitrc in your original user's\n HOME and fail on opening the repos. Use this kind of thing:\n \n```\n$ sudo HOME\u003d/tmp valgrind --leak-check\u003dfull --show-leak-kinds\u003dall /usr/local/bin/gitohashi\n```\n\n2. You can either attach gdb to the gitohashi process even if run by systemd\n using `gdb -p \u003cpid\u003e`, or run it under gdb with, eg\n \n```\n$ sudo HOME\u003d/tmp valgrind gdb --ex r --args /usr/local/bin/gitohashi\n```\n\n## Serving git protocol over https\n\nGitohashi only does gitweb, which is unrelated to git's optional read-only\nhttps protocol access. Git's own `git-http-backend` should be used as a\nCGI to serve git https protocol.\n\n## XSS mitigation\n\n### Making the most of Content-Security-Policy\n\nModern browsers understand XSS and allow the server to specify a kind of\n\u0022selinux on your web page\u0022 at the time the pages are served. This is\nindependent of what is on the original page or what may be inserted into the\nDOM.\n\nGitohashi's example HTML template and the example `/etc/gitohashi` conf are\nalready set for default-deny `Content-Security-Policy` for all types of content,\nwith specific overrides to allow scripts, CSS and fonts from the same server\nthat sent the original page, and images additionally from travis / appveyor and\ncoverity ONLY.\n\nThat means inline (injected) scripts and style are specifically disallowed by\nthe default security policy told to the browser by gitohashi when it serves the\npage. The default CSP is enough to get A+ at https://observatory.mozilla.org .\n\n### Showdown\n\nGeneric markdown is unfortunately sucecptible to XSS attacks, made a lot worse\nby wanting to allow the input to fall back to raw html.\n\nHowever we don't need that for README.md type applications, so we perform\nthe following changes to the markdown input before processing\n\ncharacter|change\n---|---\nAmpersand|\u0026 a m p ;\nLess than|\u0026 l t ; \u0026 # 8 2 0 3;\nGreater than|\u0026 g t ;\nPercent|\u0026 # 3 7 ;\n\nThe additional zero-width space after the less-than is to defeat Showdown's\nsuicidal desire to interpret the HTML escape sequence \u0026 l t ; as a valid, active\nless-than character for opening html tags.\n\nWith this the xss test page at ./xss/README.md with several dozen xss variations\ndoes not render to anything active scriptwise.\n\nSee https://warmcat.com/git/gitohashi/tree/xss\n\n### Highlight.js\n\nAt least for C highlight, providing the same large set of XSS attacks in a .c is\nunable to do anything on the client, again by globally preprocessing the\ncharacters critical to the attack variants into escaped forms first.\n\nSee https://warmcat.com/git/gitohashi/tree/xss/xss.c\n\n## Upstreams and licenses\n\n### libwebsockets\n\nLGPL2.1+SLE\n\nhttps://libwebsockets.org/git/libwebsockets\n\n### highlightjs\n\nhttps://highlightjs.org/\n\nincluded in gitohashi:\n\n - assets/highlight.pack.js\n - assets/github.css\n\n```\nCopyright (c) 2006, Ivan Sagalaev\nAll rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n * Neither the name of highlight.js nor the names of its contributors \n may be used to endorse or promote products derived from this software \n without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n```\n\n### showdown\n\nhttps://github.com/showdownjs/showdown\n\nincluded in gitohashi:\n\n - assets/showdown.min.js\n\n```\nShowdown Copyright (c) 2007, John Fraser\nhttp://www.attacklab.net\nAll rights reserved.\n\nOriginal Markdown copyright (c) 2004, John Gruber\nhttp://daringfireball.net\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above copyright notice,\n this list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n\n* Neither the name \u0022Markdown\u0022 nor the names of its contributors may\n be used to endorse or promote products derived from this software\n without specific prior written permission.\n\nThis software is provided by the copyright holders and contributors \u0022as\nis\u0022 and any express or implied warranties, including, but not limited\nto, the implied warranties of merchantability and fitness for a\nparticular purpose are disclaimed. In no event shall the copyright owner\nor contributors be liable for any direct, indirect, incidental, special,\nexemplary, or consequential damages (including, but not limited to,\nprocurement of substitute goods or services; loss of use, data, or\nprofits; or business interruption) however caused and on any theory of\nliability, whether in contract, strict liability, or tort (including\nnegligence or otherwise) arising in any way out of the use of this\nsoftware, even if advised of the possibility of such damage.\n```\n","s":{"c":1718896901,"u": 466}} ],"g": 3884,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 1, "si": 0, "db":0, "di":1, "sat":0, "lfc": "0000"}