>It’s inefficient to read the list of swear words every time swearfilter is called (and similarly for checkban and checkAdminIP)
Agreed, its not efficient.
>The way it is implemented, you’ll also have quite a few false positives
Yes. The filter is only for a handful of swearwords, I wouldn't bother making it larger since people can easily circumvent it with various characters.
>Also, is it common idiom in Go to both defer f.Close() and manually call f.Close()? Seems noisy to me (and would, in many other systems, give an error when the deferred code tries to close an already closed file)
Honestly, I don't know. This was just based on some file io tutorials I referenced. Might be able to not have that defer statement at all. I haven't tried.
>Other issue: from glancing at the code, the 403 page doesn’t seem to return a 403 status code.
Good catch.