1#!/usr/bin/env bash 2# Checks a running Worker's host handling with curl (src/host.rs): what 3# `lmjtfy.fun` does with a repository's path, and the routes of 4# `code.lmjtfy.fun`, in each mode of the GIT_REDIRECT switch. Costs nothing: 5# no request here reaches Jev or Workers AI. 6# 7# check-hosts home on http://127.0.0.1:8795 a dev server as lmjtfy.fun, redirect on 8# check-hosts home off http://127.0.0.1:8796 ... redirect off: the apex serves the code 9# check-hosts code on http://127.0.0.1:8797 a dev server as code.lmjtfy.fun, redirect on 10# check-hosts code off http://127.0.0.1:8798 11# 12# The mode named here must be the one the server was started with: a server 13# in the other mode fails the checks. 14# 15# `wrangler dev` sends the Worker its first route's host whatever the client 16# says, so each host and mode is its own dev server, given the host it should 17# be and the var (the toml's default is "off"): 18# wrangler dev --local --host lmjtfy.fun --port 8795 --var GIT_REDIRECT:on 19# wrangler dev --local --host lmjtfy.fun --port 8796 --var GIT_REDIRECT:off 20# wrangler dev --local --host code.lmjtfy.fun --port 8797 --var GIT_REDIRECT:on 21# wrangler dev --local --host code.lmjtfy.fun --port 8798 --var GIT_REDIRECT:off 22# (a Host header on the request is overwritten, measured 2026-10-05). A 23# fifth (8799), with the var set to something else (`--var GIT_REDIRECT:ON`), is 24# checked as `bad`: it must behave as off. 25# 26# What it cannot check: a clone, a pull, or any page that reads GitHub need 27# the secret LMJTFY_GITHUB_TOKEN, which a local server lacks; it answers 503 28# (git) or 502 (a page), and that is what is asserted. 29set -uo pipefail 30 31which=${1:?home or code} 32mode=${2:?on, off or bad} 33base=${3:?the dev server, e.g. http://127.0.0.1:8795} 34# `bad` is a switch the Worker refuses: it must act as off. 35[[ $mode == bad ]] && mode=off 36[[ $mode == on || $mode == off ]] || { echo "on, off or bad"; exit 2; } 37failed=0 38 39# For a redirect, curl was not told to follow, so its target is the Location. 40location() { 41 curl -s -o /dev/null --max-time 60 -D - "$base$1" | tr -d '\r' | sed -n 's/^[Ll]ocation: //p' 42} 43expect() { # description, wanted status, method, path [, wanted location] 44 local status 45 status=$(curl -s -o /dev/null --max-time 60 -X "$3" -w '%{http_code}' "$base$4") 46 if [[ $status != "$2" ]]; then echo "FAIL $1: $3 $4 -> $status, wanted $2"; failed=1; return; fi 47 if [[ -n ${5:-} ]]; then 48 local at 49 at=$(location "$4") 50 if [[ $at != "$5" ]]; then echo "FAIL $1: $3 $4 -> Location $at, wanted $5"; failed=1; return; fi 51 fi 52 echo "ok $1: $3 $4 -> $status${5:+ $5}" 53} 54 55repos=(lmjtfy jevcrates postjevsql jevsnes jevhooks jevstrudel) 56refs='/info/refs?service=git-upload-pack' 57 58case $which in 59 home) 60 if [[ $mode == on ]]; then 61 for repo in "${repos[@]}"; do 62 expect "$repo, git's first request" 308 GET "/$repo.git$refs" "https://code.lmjtfy.fun/$repo.git$refs" 63 expect "$repo, a page and its query" 308 GET "/$repo.git/apps/x/y.rs?raw&a=b" "https://code.lmjtfy.fun/$repo.git/apps/x/y.rs?raw&a=b" 64 expect "$repo, its front page" 308 GET "/$repo.git" "https://code.lmjtfy.fun/$repo.git" 65 expect "$repo, a POST is told, not sent on" 405 POST "/$repo.git/git-upload-pack" 66 done 67 expect "an unserved repository is not sent on" 404 GET "/whiskers.git$refs" 68 else 69 # Off: the apex serves the code itself, exactly as before the code host. 70 for repo in "${repos[@]}"; do 71 expect "$repo, a clone is served here (no token: 503)" 503 GET "/$repo.git$refs" 72 expect "$repo, its front page is served here" 200 GET "/$repo.git" 73 expect "$repo, a push is not served" 403 GET "/$repo.git/info/refs?service=git-receive-pack" 74 done 75 expect "an unserved repository" 404 GET "/whiskers.git$refs" 76 fi 77 expect "the site" 200 GET "/rules" 78 expect "the home page" 200 GET "/" 79 # The home page's clone command and link follow the switch, so it never 80 # names an address that is not live. 81 page=$(curl -s --max-time 60 "$base/") 82 if [[ $mode == on ]]; then 83 want='https://code.lmjtfy.fun/lmjtfy.git' 84 grep -qF "git clone --recurse-submodules $want" <<<"$page" && grep -qF "href=\"$want\"" <<<"$page" \ 85 && echo "ok the home page offers the code host" || { echo "FAIL the home page does not offer $want"; failed=1; } 86 else 87 want='https://lmjtfy.fun/lmjtfy.git' 88 if grep -qF "git clone --recurse-submodules $want" <<<"$page" && grep -qF "href=\"$want\"" <<<"$page" && ! grep -qF 'code.lmjtfy.fun' <<<"$page"; then 89 echo "ok the home page offers the apex and does not name the code host" 90 else 91 echo "FAIL the home page should offer $want and not name code.lmjtfy.fun"; failed=1 92 fi 93 fi 94 ;; 95 code) 96 expect "the front page" 200 GET "/" 97 for repo in "${repos[@]}"; do 98 expect "$repo, its front page" 200 GET "/$repo.git" 99 expect "$repo, a clone without the token" 503 GET "/$repo.git$refs" 100 expect "$repo, a push is not served" 403 GET "/$repo.git/info/refs?service=git-receive-pack" 101 done 102 expect "an unserved repository" 404 GET "/whiskers.git$refs" 103 expect "the code's picture" 200 GET "/card.png?code=main&repo=lmjtfy.git" 104 expect "a question's picture is the archive's" 404 GET "/card.png?q=x" 105 expect "an icon" 200 GET "/icons/file-rust.png" 106 for path in /ask /gate /rate /seen /feed /live /rules /rules.svg /datastar.js /live.js; do 107 expect "no $path here" 404 GET "$path" 108 done 109 expect "no asking here" 405 POST "/ask" 110 ;; 111 *) echo "home or code"; exit 2 ;; 112esac 113 114if ((failed)); then echo "FAILED"; exit 1; fi 115echo "all ok"