SSI Variables Available in Nginx and Apache

SSI is an old, unpopular, unsexy, and still very useful web server technology. Documentation was never great, and these days when people ask or answer questions about it they don't usually bother to specify which server. The behaviours of Nginx and Apache SSIs are quite different, and I'd assume that SSIs on other servers are different again. I may get into those behavioural differences later. But today I'm going to give as comprehensive a list as I can of SSI built-in variables across the two servers that interest me.

I've included several variable names that don't work on either server. This is because I've found them in documentation online. Perhaps they used to work, or maybe the source(s) was wrong. Either way, I hope this helps dispel some misinformation.

Variable Apache v2.4.x Nginx v1.1x Notes
ARGS (none) varname=setting Same as QUERY_STRING?
AUTH_TYPE (none) (none) I've only ever seen '(none)' but I believe this would work under AUTH
BINARY_REMOTE_ADDR (none) Nginx shows entirely blank ...
BODY_BYTES_SENT (none) 0 Nginx only, always reports '0'?
BYTES_SENT (none) 0 Nginx only, always reports '0'?
CONNECTION (none) 74 No idea what this is
CONNECTION_REQUESTS (none) 1 No idea
CONTENT_LENGTH (none) (none) Old or wrong
CONTENT_TYPE (none) (none) Old or wrong
DATE_GMT Wednesday, 10-Jul-2019 18:49:56 UTC Wednesday, 10-Jul-2019 18:49:56 UTC Works on both
DATE_LOCAL Wednesday, 10-Jul-2019 14:49:56 EDT Wednesday, 10-Jul-2019 14:49:56 EDT Works on both
DOCUMENT_NAME index.html (none) Just the local filename, no path or query string
DOCUMENT_URI /test/index.html /test/index.html (same as the Nginx-specific "URI"?): webserver path to file, no machine name, no query string
DOCUMENT_ROOT /home/gorr/public_html /home/gorr/public_html the local file system path to the root of the web server doc tree
GATEWAY_INTERFACE CGI/1.1 (none)
HOST (none) localhost Nginx: the host name you visited the server by, only host NOT port
HOSTNAME (none) go-macbook.local NOT the same as SERVER_NAME: initially thought it was but on Mac I got 'go-mbp.local' which doesn't match SERVER_NAME or nginx.conf 'server_name' value ... this is what the visiting host thinks its hostname is? Matches Bash's $HOSTNAME on the Mac
HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Appears identical on both servers: there are probably times when it's not.
HTTP_ACCEPT_ENCODING gzip, deflate gzip, deflate
HTTP_HOST localhost:8080 localhost:8080 shows hostname that the client visited, plus port if it's not 80
HTTP_USER_AGENT Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0
HTTP_REFERER http://localhost:8088/ssi-test/ http://localhost:8088/ssi-test/ empty if you visit direct, otherwise includes FULL referring URI (protocol://machine[:port]/path)
IS_ARGS (none) ? Nginx shows literally a '?' No idea.
LAST_MODIFIED Wednesday, 10-Jul-2019 18:08:24 EDT (none) I really wish Nginx had this
LIMIT_RATE (none) 0 No idea
MSEC (none) 1562796780.435 appears to be seconds since the millennia, in the form NNNNNNNNNN.XXX, three decimals
NGINX_VERSION (none) 1.17.1 not something I'd publicly announce, but could be used to test before using local version-specific features
PATH /home/gorr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin (none) (Apache was running as the user, so we see user-specific PATH elements ...)
PID (none) 19678 PID of the worker proccess (not the master)
PIPE (none) . I've only seen Nginx show '.', not sure what good this is
PROXY_PROTOCOL_ADDR (none) Nginx returns not the more common "(none)" but nothing at all
PROXY_PROTOCOL_PORT (none) Nginx returns not "(none)" but nothing at all
QUERY_STRING varname=setting varname=setting Exactly what it says on the tin
QUERY_STRING_UNESCAPED (none) varname=setting appears to backslash-escape special characters in the query string (kind of the reverse of what I expected)
REALPATH_ROOT (none) /home/gorr/public_html same as DOCUMENT_ROOT but Nginx specific?
REMOTE_ADDR 127.0.0.1 127.0.0.1 visitor address, only tested on localhost so far, have seen '::1'
REMOTE_ADDRIP (none) (none)
REMOTE_HOST (none) (none)
REMOTE_PORT 60694 60694 works, but what use?
REQUEST (none) GET /test/index.html?varname=setting HTTP/1.1 full specification of the request
REQUEST_METHOD GET GET works (GET, POST, etc.)
REQUEST_FILENAME (none) /home/gorr/public_html/test/index.html the real filesystem path and filename to the requested file (equivalent to Apache SCRIPT_FILENAME)
REQUEST_ID (none) 05868c375d6910f1b03e5b3d2abef395
REQUEST_LENGTH (none) 497 reports something, not request string length, not the byte size of the file (got smaller when file grew ...)
REQUEST_TIME 0.00 (none) It's only ever reported '0.00', even with complex multi-include SSI pages
REQUEST_URI /test/index.html?test=querystring /test/index.html?test=querystring web filepath, filename, and query string - no host or port
SCHEME (none) http presumably would report 'https' if appropriate, untested
SCRIPT_FILENAME /home/gorr/public_html/test/index.html (none) real filesystem path to the requested file (equivalent to Nginx REQUEST_FILENAME)
SCRIPT_NAME /test/index.html (none) full web path to requested file
SCRIPT_URI (none) (none)
SCRIPT_URL (none) (none)
SERVER_ADDR 127.0.0.1 127.0.0.1 IP address of the server
SERVER_ADMIN you@example.com (none) The email address defined by 'ServerAdmin' in the Apache configuration file
SERVER_NAME localhost localhost Reflects nginx.conf's 'server_name' setting, Apache the same?
SERVER_PORT 8080 8080 or 80, or 443 ...
SERVER_PROTOCOL HTTP/1.1 HTTP/1.1
SERVER_SIGNATURE (none) Actually [empty] for Apache, am I missing something?
SERVER_SOFTWARE Apache/2.4.39 (Fedora) (none) Apache-specific
STATUS (none) 200 HTTP status code, Nginx only
TIME_ISO8601 (none) 2019-07-11T09:11:27-04:00
TIME_LOCAL (none) 11/Jul/2019:09:11:27 -0400
URI /ssi-201907/builtins.html (none) similar to REQUEST_URI (no host, just the URI), but in this case it does NOT include the query string