CHA-CGI(5)
π Local CGI support in Chawan π
okay bestie, welcome to CHA-CGI(5) from the File Formats Manual β the local CGI support page for Chawan. This is the βdrop a script in a folder and let Chawan run itβ situation, and itβs honestly kind of iconic. Letβs keep every detail, no skips, fr fr. π«Ά
Chawan supports the invocation of CGI scripts placed in a directory specified in the external.cgi-dir configuration option. By default, this is set to $CHA_DIR/cgi-bin (i.e. ~/.chawan/cgi-bin or ~/.config/chawan/cgi-bin, depending on config.tomlβs location) and /usr/local/libexec/chawan/cgi-bin.
A CGI script in one of these directories can be executed by visiting the URL cgi-bin:script-name. $PATH_INFO and $QUERY_STRING are set as normal, i.e. cgi-bin:script-name/abcd?defgh=ijkl will set $PATH_INFO to /abcd, and $QUERY_STRING to defgh=ijkl.
Further notes on processing CGI paths:
- The URL must be opaque, so you must not add a double slash after the scheme. e.g.
cgi-bin://script-namewill NOT work, onlycgi-bin:script-name. - Paths beginning with
/cgi-bin/or/$LIB/are stripped of this segment automatically. So e.g.cgi-bin:/cgi-bin/script-namebecomescgi-bin:script-name. - Absolute paths are accepted as e.g.
cgi-bin:/path/to/cgi/dir/script-name. Note however, that this only works if/path/to/cgi/dirhas already been specified as a CGI directory inexternal.cgi-dir.
π Headers π
Local CGI scripts may send some headers that Chawan will interpret specially (and thus will not pass forward to e.g. the fetch API, etc):
Statusβ interpreted as the HTTP status code.Cha-Controlβ special header, see below.
These headers must be sent before any regular headers. Headers received after a regular header or a Cha-Control: ControlDone header will be treated as regular headers.
The Cha-Control headerβs value is parsed as follows:
Cha-Control-Value = Command *Parameter
Command = ALPHA *ALPHA
Parameter = SPACE *CHAR
In other words, it is Command [Param1] [Param2] ....
Currently available commands are:
Connectedβ Takes no parameters. Must be the first reported header; it means that connection to the server has been successfully established, but no data has been received yet. When any other header is sent first, Chawan will act as if aCha-Control: Connectedheader had been implicitly sent before that.ConnectionErrorβ Must be the first reported header. Parameter 1 is the error code, see below. If any following parameters are given, they are concatenated to form a custom error message.
Note: short but descriptive error messages are preferred, messages that do not fit on the screen are currently truncated.
ControlDoneβ Signals that no more special headers will be sent; this means thatCha-ControlandStatusheaders sent after this must be interpreted as regular headers (and thus e.g. will be available for JS code calling the script using thefetchAPI).
WARNING: this header must be sent before any non-hardcoded headers that take external input. For example, an HTTP client would have to send Cha-Control: ControlDone before returning the retrieved headers.
Following is a list of error codes and their string counterparts. CGI scripts may use either (but not both) in a ConnectionError header.
1 InternalErrorβ An internal error prevented the script from retrieving the requested resource. CGI scripts can also use this to signal that they have no information on what went wrong.2 InvalidMethodβ The client requested data using a method not supported by this protocol.3 InvalidURLβ The request URL could not be interpreted as a valid URL for this format.4 FileNotFoundβ No file was found at the requested address, so the request is meaningless. Note: this should only be used by protocols that do not rely on a client-server architecture, e.g. local file access, local databases, or peer-to-peer file retrieval mechanisms. A server responding with βno file foundβ is NOT a connection error, and is better represented as a response with a 404 status code.5 ConnectionRefusedβ The server refused to establish a connection.6 ProxyRefusedToConnectβ The proxy refused to establish a connection.7 FailedToResolveHostβ The hostname could not be resolved.8 FailedToResolveProxyβ The proxy could not be resolved.9 ProxyAuthFailβ The proxy refused the provided username/password.10 InvalidResponseβ The serverβs response deviates from the specification so badly that it cannot be meaningfully processed.11 ProxyInvalidResponseβ The proxyβs response deviates from the specification so badly that it cannot be meaningfully processed.12 DisallowedSubnetβ Attempting to access a private subnet from a public one. Used for blocking malicious cross-origin HTTP requests to the local network.
πΈ Environment variables πΈ
Chawan sets the following environment variables:
SERVER_SOFTWARE="Chawan"SERVER_PROTOCOL="HTTP/1.0"SERVER_NAME="localhost"SERVER_PORT="80"REMOTE_HOST="localhost"REMOTE_ADDR="127.0.0.1"GATEWAY_INTERFACE="CGI/1.1"SCRIPT_NAME="/cgi-bin/script-name"if called with a relative path, and"/path/to/script/script-name"if called with an absolute path.SCRIPT_FILENAME="/path/to/script/script-name"QUERY_STRING=β the query string (i.e.URL.search). This variable is percent-encoded.PATH_INFO=β everything after the scriptβs path name, e.g. forcgi-bin:script-name/abcd/efgh"/abcd/efgh". This variable is NOT percent-encoded.REQUEST_URI="$SCRIPT_NAME/$PATH_INFO?$QUERY_STRINGβ this is the exact assignment as written in the original, closing-quote situation and all.REQUEST_METHOD=β HTTP method used for making the request, e.g.GETorPOSTREQUEST_HEADERS=β A newline-separated list of all headers for this request.CHA_LIBEXEC_DIR=β The libexec directory Chawan was configured to use at compile time. See the tools section below for details on why this is useful.CONTENT_TYPE=β for POST requests, the Content-Type header. Not set for other request types (e.g. GET).CONTENT_LENGTH=β the content length, if$CONTENT_TYPEhas been set.ALL_PROXY=β if a proxy has been set, the proxy URL. WARNING: for security reasons, this must be respected when making external connections. If a CGI script does not support proxies, it must never make any external connections when theALL_PROXYvariable is set, but rather return an error message.HTTP_COOKIE=β if set, the Cookie header.HTTP_REFERER=β if set, the Referer header.HTTP_AUTHORIZATION=β if set, the Authorization header.REMOTE_USER=β if Authorization uses βBasicβ auth, its user part.CHA_TMP_DIR=β directory used for storing temporary files.CHA_DIR=β location of the config file.
Requests originating from the cha-urimethodmap(5) feature also set a set of environment variables starting with MAPPED_URI_. However, this feature is deprecated in favor of passing parameters from browsecap, as described in cha-mailcap(5).
π¦ Request body π¦
If the request body is not empty, it is streamed into the program through the standard input.
Note that this may be both an application/x-www-form-urlencoded or a multipart/form-data request; CONTENT_TYPE stores information about the request type, and in case of a multipart request, the boundary as well.
π§ Tools π§
Chawan provides certain helper binaries that may be useful for CGI scripts. These can be portably accessed by executing "$CHA_LIBEXEC_DIR"/[program].
Currently, the following tools are available:
urldecβ percent-decode strings passed on standard input.urlencβ percent-encode strings passed on standard input, taking a percent-encode set as the first parameter.
π Troubleshooting π
Note that standard error is redirected to the browser console (by default, M-cM-c). This makes it easy to debug a misbehaving CGI script, but may also slow down the browser in case of excessive logging. If this is not the desired behavior, wrap your script into a shell script that redirects stderr to /dev/null.
π My script is returning a βFailed to execute scriptβ error message.
This means the execl call to the script failed. Make sure that your CGI scriptβs executable bit is set, i.e. run chmod +x /path/to/cgi/script.
π My script is returning an βinvalid CGI pathβ error message.
Make sure that you did not include leading slashes. Reminder: cgi-bin://script-name does not work, use cgi-bin:script-name.
π My script is returning a βCGI file not foundβ error message.
Double check that your CGI script is in the correct location. Also, make sure that you are not accidentally calling the script with an absolute path via cgi-bin:/script-name (instead of the correct cgi-bin:script-name).
It is also possible that external.cgi-dir is not really set to the directory your script is in. Note that by default, this depends on the binaryβs path, so e.g. if your binary is in ~/src/chawan/target/release/bin/cha, but you put your CGI script to /usr/local/libexec/chawan/cgi-bin, then it will not work.
π My script is returning a βfailed to set up CGI scriptβ error message.
This means that either pipe or fork failed. Maybe you are running out of memory?
π See also π
π Thatβs the whole CHA-CGI(5) page, bestie β footer says CHA-CGI(5), and the original has no separate source/version/date line, so consider this your cute sign-off. Stay slay, keep your scripts executable, and may your stderr always be readable. π
β¨
π¦ where this page comes from
- arch rolling: chawan 0.5.0-1 Β· Unlicense
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms