A torture test for gemini servers.
Python 3.7 or newer.
Tests that inspect TLS certificates additionally require that the pyca/cryptography library be installed.
This script originated from an idea on the gemini mailing list that it would be nice to have a gemini "torture test" to uncover bugs and unhandled edge cases in new server implementations. It was originally called jetforce-diagnostics and was bundled with the jetforce server. Now it has been moved to its own repository and operates as a separate project.
usage: gemini-diagnostics [host] [port] [--help]
A diagnostic tool for gemini servers.
This program will barrage your server with a series of requests in
an attempt to uncover unexpected behavior. Not all of these checks
adhere strictly to the gemini specification. Some of them are
general best practices, and some trigger undefined behavior. Results
should be taken with a grain of salt and analyzed on their own merit.
positional arguments:
host server hostname (default: localhost)
port server port (default: 1965)
optional arguments:
-h, --help show this help message and exit
--checks CHECKS comma separated list of checks to apply
--show-checks display the complete list of checks and exit
--delay DELAY seconds to sleep between checks (default: 2)
- [IPv4Address]
- Establish a connection over an IPv4 address.
- [IPv6Address]
- Establish a connection over an IPv6 address.
- [TLSVersion]
- Server must negotiate at least TLS v1.2, ideally TLS v1.3.
- [TLSClaims]
- Certificate claims must be valid.
- [TLSVerified]
- Certificate should be self-signed or have a trusted issuer.
- [TLSCloseNotify]
- Server should send a close_notify alert before closing the connection.
- [TLSRequired]
- Non-TLS requests should be refused.
- [ConcurrentConnections]
- Server should support concurrent connections.
- [ResponseFormat]
- Validate the response header and body for the root URL.
- [HomepageNoRedirect]
- The root URL should return the same resource with or without the trailing slash..
- [PageNotFound]
- Request a gemini URL that does not exist.
- [RequestMissingCR]
- A request without a should timeout.
- [URLIncludePort]
- Send the URL with the port explicitly defined.
- [URLSchemeMissing]
- A URL without a scheme should result in a 59 Bad Request.
- [URLByIPAddress]
- Send the URL using the IPv4 address.
- [URLInvalidUTF8Byte]
- Send a URL containing a non-UTF8 byte sequence.
- [URLMaxSize]
- Send a 1024 byte URL, the maximum allowed size.
- [URLAboveMaxSize]
- Send a 1025 byte URL, above the maximum allowed size.
- [URLWrongPort]
- A URL with an incorrect port number should be rejected.
- [URLWrongHost]
- A URL with a foreign hostname should be rejected.
- [URLSchemeHTTP]
- Send a URL with an HTTP scheme.
- [URLSchemeHTTPS]
- Send a URL with an HTTPS scheme.
- [URLSchemeGopher]
- Send a URL with a Gopher scheme.
- [URLEmpty]
- Empty URLs should not be accepted by the server.
- [URLRelative]
- Relative URLs should not be accepted by the server.
- [URLInvalid]
- Random text should not be accepted by the server.
- [URLDotEscape]
- A URL should not be able to escape the root using dot notation.
Contributions are welcome!