htaccess/escape-literal-dots
Severity: warning · Status: enforced · Applies to: ids/**/.htaccess
What
A . in a RewriteRule pattern matches any single character. To match a literal dot — in a filename, a version number, or a media type — escape it as \..
Why
^vocab.ttl$ looks like it matches vocab.ttl, and it does. It also matches vocabXttl, vocab-ttl, vocab1ttl, and every other single character in that position.
That is rarely what you want, and it produces redirects for URLs you never intended to serve — which then fail at the destination, giving the user a 404 from your server instead of a clean 404 from w3id.org. In a versioned scheme it can silently route one version's requests to another.
The same applies inside RewriteCond patterns, where media types are the usual victim: application/ld+json is a regular expression in which + means "one or more of the preceding character".
Wrong
RewriteRule ^vocab.ttl$ https://example.org/vocab.ttl [R=303,L]
RewriteRule ^(1.0.0)$ https://example.org/$1/vocab.ttl [R=303,L]
RewriteCond %{HTTP_ACCEPT} application/ld+jsonRight
RewriteRule ^vocab\.ttl$ https://example.org/vocab.ttl [R=303,L]
RewriteRule ^(1\.0\.0)$ https://example.org/$1/vocab.ttl [R=303,L]
RewriteCond %{HTTP_ACCEPT} application/ld\+jsonA version pattern in general:
RewriteRule ^([0-9]+(\.[0-9]+)*)$ https://example.org/$1/vocab.ttl [R=303,L]Dots in the substitution are literal and need no escaping — only the pattern is a regular expression.
How to fix
Escape every . in the pattern that is meant to be a literal dot.
A dot that is a deliberate wildcard is not reported: (.*), (.+) and .? are all doing their job, and so is a dot inside a character class. The check looks only for a dot followed by something shaped like a file extension, which is where the mistake actually lives.
How to check
Run w3id-check with --rule htaccess/escape-literal-dots to check this rule on its own; without it the tool runs every rule, as the pull request checks do.
node tools/check/bin/w3id-check.js --rule htaccess/escape-literal-dots ids/my-projectTesting your changes covers installing the tool, and what else is worth checking by hand.