#!/bin/sh guess_content_type() { ext="${ref%"~"}" case "${ext##*.}" in appcache|manifest) content_type=text/cache-manifest ;; atom ) content_type=application/atom+xml ;; bat ) content_type=application/x-msdownload ;; coffee ) content_type=text/coffeescript ;; css ) content_type=text/css ;; csv ) content_type=text/csv ;; eot ) content_type=application/vnd.ms-fontobject ;; geojson ) content_type=application/vnd.geo+json ;; hbs|handlebars ) content_type=text/x-handlebars-template ;; htc ) content_type=text/x-component ;; htm|html ) content_type=text/html ;; ics ) content_type=text/calendar ;; jscad ) content_type=application/javascript ;; json ) content_type=application/json ;; jsonld ) content_type=application/ld+json ;; kml ) content_type=application/vnd.google-earth.kml+xml ;; # md|markdown ) content_type=text/markdown ;; mjs|js ) content_type=application/javascript ;; mhtml ) content_type=multipart/related ;; n3 ) content_type=text/n3 ;; nt ) content_type=application/n-triples ;; otf ) content_type=font/otf ;; owl|rdf ) content_type=application/rdf+xml ;; pdf ) content_type=application/pdf ;; rss ) content_type=application/rss+xml ;; shex|shexc ) content_type=text/shex ;; svg ) content_type=image/svg+xml ;; swf ) content_type=application/x-shockwave-flash ;; stl ) content_type=model/stl ;; tt[cf] ) content_type=application/x-font-ttf ;; ttl ) content_type=text/turtle ;; vcard ) content_type=text/vcard ;; vcf ) content_type=text/x-vcard ;; vtt ) content_type=text/vtt ;; woff ) content_type=application/font-woff ;; woff2 ) content_type=application/font-woff2 ;; xht|xhtml ) content_type=application/xhtml+xml ;; xml ) content_type=text/xml ;; txt ) content_type=text/plain ;; xsl|xsd ) content_type=application/xml ;; xslt ) content_type=application/xslt+xml ;; yaml|yml ) content_type=text/yaml ;; wasm ) content_type=application/wasm ;; rpm|[ds]rpm ) content_type=application/x-redhat-package-manager ;; * ) content_type=text/plain ;; esac case "${ext##*.}" in bat|eot|htc|kml|nt|otf|pdf|svg|swf|ttc|ttf|woff|woff2|wasm|rpm|[ds]rpm) ;; * ) content_type="$content_type; charset=utf-8" ;; esac } cd /var/cache/nginx/ra.ws.co.ls.cgi || exit tmpf="$(mktemp -t 'ra.ws.co.ls-XXXXXXXX')" trap 'rm -f "$tmpf"' EXIT INT dir="${DOCUMENT_URI%/blob/*}" if ! [ -d ".$dir.git" ]; then { mkdir -p ".$dir.git" && git clone --depth 1 --filter=blob:none --bare "https://git.sr.ht$dir" ".$dir.git"; } > "$tmpf" 2>&1 || { printf '%s\n' 'Status: 500 Internal Server Error' 'Content-Type: text/plain; charset=utf-8' '' cat "$tmpf" exit } fi cd ".$dir.git" || exit if [ $(( $(date -r .ls-remote +%s 2>/dev/null) + 600 )) -lt $(date +%s) ]; then git ls-remote --symref > new.ls-remote cmp -s .ls-remote new.ls-remote 2>/dev/null; cmpfail=$? mv new.ls-remote .ls-remote if [ $cmpfail -ne 0 ]; then while IFS=' ' read -r val ref; do { [ "$ref" = HEAD ] && [ "${val#"ref:"}" != "$val" ]; } && echo "$val" > HEAD { [ "${ref%"^{}"}" = "$ref" ] && [ "$ref" != HEAD ]; } && echo "$ref:$ref" done < .ls-remote | git fetch --stdin --no-write-fetch-head origin >&2 fi fi echo "${DOCUMENT_URI#*/blob/}" | gawk '{ slashes=$0 gsub(/[^/]*/, "", slashes) for(i = 1; i <= length(slashes); ++i) print gensub(/\//, ":", i, $0) }' | { while read -r ref; do git show "$ref" > "$tmpf" && { guess_content_type printf '%s\n' 'Status: 200 OK' \ "Content-Type: $content_type" \ 'Cache-Control: max-age=86400, public' \ "ETag: \"$(git rev-parse "$ref" 2>/dev/null || echo "$ref"):${ref#*:}\"" \ '' exec cat "$tmpf" } done printf '%s\n' 'Status: 400 Bad Request' 'Content-Type: text/plain; charset=utf-8' '' exec cat "$tmpf" }