Updating docs
This commit is contained in:
		
							parent
							
								
									8abb027288
								
							
						
					
					
						commit
						97e6a5bfb5
					
				
							
								
								
									
										91
									
								
								README.md
								
								
								
								
							
							
						
						
									
										91
									
								
								README.md
								
								
								
								
							| 
						 | 
				
			
			@ -39,9 +39,10 @@ Use the ``--help`` flag to view command-line options:
 | 
			
		|||
 | 
			
		||||
```bash
 | 
			
		||||
$ jetforce --help
 | 
			
		||||
usage: jetforce [-h] [--host HOST] [--port PORT] [--tls-certfile FILE]
 | 
			
		||||
                [--tls-keyfile FILE] [--hostname HOSTNAME] [--dir DIR]
 | 
			
		||||
                [--cgi-dir DIR] [--index-file FILE]
 | 
			
		||||
usage: jetforce [-h] [--host HOST] [--port PORT] [--hostname HOSTNAME]
 | 
			
		||||
                [--tls-certfile FILE] [--tls-keyfile FILE] [--tls-cafile FILE]
 | 
			
		||||
                [--tls-capath DIR] [--dir DIR] [--cgi-dir DIR]
 | 
			
		||||
                [--index-file FILE]
 | 
			
		||||
 | 
			
		||||
An Experimental Gemini Protocol Server
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -49,63 +50,68 @@ optional arguments:
 | 
			
		|||
  -h, --help           show this help message and exit
 | 
			
		||||
  --host HOST          Server address to bind to (default: 127.0.0.1)
 | 
			
		||||
  --port PORT          Server port to bind to (default: 1965)
 | 
			
		||||
  --hostname HOSTNAME  Server hostname (default: localhost)
 | 
			
		||||
  --tls-certfile FILE  Server TLS certificate file (default: None)
 | 
			
		||||
  --tls-keyfile FILE   Server TLS private key file (default: None)
 | 
			
		||||
  --hostname HOSTNAME  Server hostname (default: localhost)
 | 
			
		||||
  --dir DIR            Local directory to serve (default: /var/gemini)
 | 
			
		||||
  --tls-cafile FILE    A CA file to use for validating clients (default: None)
 | 
			
		||||
  --tls-capath DIR     A directory containing CA files for validating clients
 | 
			
		||||
                       (default: None)
 | 
			
		||||
  --dir DIR            Root directory on the filesystem to serve (default:
 | 
			
		||||
                       /var/gemini)
 | 
			
		||||
  --cgi-dir DIR        CGI script directory, relative to the server's root
 | 
			
		||||
                       directory (default: cgi-bin)
 | 
			
		||||
  --index-file FILE    If a directory contains a file with this name, that
 | 
			
		||||
                       file will be served instead of auto-generating an index
 | 
			
		||||
                       page (default: index.gmi)
 | 
			
		||||
 | 
			
		||||
If the TLS cert/keyfile is not provided, a self-signed certificate will
 | 
			
		||||
automatically be generated and saved to your temporary directory.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Hostname
 | 
			
		||||
 | 
			
		||||
Because the gemini protocol sends the whole URL in the request, it's necessary
 | 
			
		||||
to declare the hostname that your server is expecting to receive traffic under.
 | 
			
		||||
Jetforce will reject any request that doesn't match your hostname with a status
 | 
			
		||||
of ``Proxy Request Refused``.
 | 
			
		||||
 | 
			
		||||
### TLS Certificates
 | 
			
		||||
 | 
			
		||||
The gemini specification *requires* that all connections be sent over TLS.
 | 
			
		||||
Before you deploy jetforce, you should either generate your own self-signed
 | 
			
		||||
certificate, or obtain one from a Certificate Authority like
 | 
			
		||||
[Let's Encrypt](https://letsencrypt.org).
 | 
			
		||||
 | 
			
		||||
In order to make local development easier, if you do not specify the certificate
 | 
			
		||||
arguments, jetforce will automatically generate a temporary ad-hoc TLS certificate
 | 
			
		||||
to use. Here's the OpenSSL command that jetforce uses internally:
 | 
			
		||||
If you do not provide a TLS certificate file using the ``--tls-certfile`` flag,
 | 
			
		||||
jetforce will automatically generate a temporary cert for you to use. This is
 | 
			
		||||
great for making development easier, but before you expose your server to the
 | 
			
		||||
public internet you should configure something more permanent. You can generate
 | 
			
		||||
your own self-signed server certificate, or obtain one from a Certificate
 | 
			
		||||
Authority like [Let's Encrypt](https://letsencrypt.org).
 | 
			
		||||
 | 
			
		||||
Here's the OpenSSL command that jetforce uses to generate a self-signed cert:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ openssl req -newkey rsa:2048 -nodes -keyout {hostname}.key \
 | 
			
		||||
    -nodes -x509 -out {hostname}.crt -subj "/CN={hostname}"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
There are currently no plans to support transient self-signed client certificates.
 | 
			
		||||
This is due to a technical limitation of the python standard library's ``ssl``
 | 
			
		||||
module, which is described in detail 
 | 
			
		||||
Jetforce also supports verified client TLS certificates. You can specify your
 | 
			
		||||
client CA with the ``--tls-cafile`` or ``--tls-capath`` flags. Verified
 | 
			
		||||
connections will have the ``REMOTE_USER`` variable added to their environment,
 | 
			
		||||
which contains the client certificate's CN attribute. Instructions on how to
 | 
			
		||||
generate TLS client certificates are outside of the scope of this readme, but
 | 
			
		||||
you can find many helpful tutorials
 | 
			
		||||
[online](https://portal.mozz.us/?url=gemini%3A%2F%2Fmozz.us%2Fjournal%2F2019-08-21.txt).
 | 
			
		||||
 | 
			
		||||
There are currently no plans to support unverified (transient) client
 | 
			
		||||
certificates. This is due to a technical limitation of the python standard
 | 
			
		||||
library's ``ssl`` module, which is described in detail 
 | 
			
		||||
[here](https://portal.mozz.us/?url=gemini%3A%2F%2Fmozz.us%2Fjournal%2F2019-08-21.txt).
 | 
			
		||||
 | 
			
		||||
Support for verified client certificates will be added in a future version.
 | 
			
		||||
### Static Files
 | 
			
		||||
 | 
			
		||||
### Hostname
 | 
			
		||||
Jetforce will serve static files in the ``/var/gemini/`` directory:
 | 
			
		||||
 | 
			
		||||
Because the gemini protocol sends the *whole* URL in the request, it's required
 | 
			
		||||
that you declare the hostname that your server is expecting to receive traffic
 | 
			
		||||
under. Jetforce will reject any request that doesn't match your hostname with a
 | 
			
		||||
status of ``Proxy Request Refused``.
 | 
			
		||||
 | 
			
		||||
Using python, you can modify this behavior to do fancy things like building a
 | 
			
		||||
proxy server for HTTP requests. See [http_proxy.py](examples/http_proxy.py) for
 | 
			
		||||
an example of how this is done.
 | 
			
		||||
 | 
			
		||||
### Serving Files
 | 
			
		||||
 | 
			
		||||
Jetforce serves files from the ``/var/gemini/`` directory by default:
 | 
			
		||||
 | 
			
		||||
- Files with the **.gmi** extension will be interpreted as *text/gemini*.
 | 
			
		||||
- Other files will have their *mimetype* guessed based on their file extension.
 | 
			
		||||
- Directories will look for a file with the name **index.gmi**.
 | 
			
		||||
- If an index file does not exist, a directory listing will be generated.
 | 
			
		||||
- Files ending with **.gmi** will be interpreted as the *text/gemini* type
 | 
			
		||||
- If a directory is requested, jetforce will look for a file in that directory
 | 
			
		||||
  with the name of **index.gmi**
 | 
			
		||||
  - If it exists, the index file will be returned
 | 
			
		||||
  - Otherwise, jetforce will generate a directory listing
 | 
			
		||||
 | 
			
		||||
### CGI Scripts
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -113,14 +119,17 @@ Jetforce implements a slightly modified version of the official CGI
 | 
			
		|||
specification. Because Gemini is a less complex than HTTP, the CGI interface is
 | 
			
		||||
also inherently easier and more straightforward to use.
 | 
			
		||||
 | 
			
		||||
The main difference in this implementation is that the CGI script is expected
 | 
			
		||||
to write the entire gemini response *verbatim* to stdout:
 | 
			
		||||
The main difference in jetforce's implementation is that the CGI script is
 | 
			
		||||
expected to write the entire gemini response *verbatim* to stdout:
 | 
			
		||||
 | 
			
		||||
1. The status code and meta on the first line
 | 
			
		||||
2. Any additional response body on subsequent lines
 | 
			
		||||
2. The optional response body on subsequent lines
 | 
			
		||||
 | 
			
		||||
Unlike HTTP's CGI, there are no request/response headers or other special
 | 
			
		||||
fields to perform actions like redirects.
 | 
			
		||||
Unlike CGI v1.1, there are no headers or other special values that the script
 | 
			
		||||
can respond with.
 | 
			
		||||
 | 
			
		||||
Some of the HTTP-specific environment variables like ``REQUEST_METHOD`` are not
 | 
			
		||||
used, because they don't make sense in the context of a Gemini request.
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,11 +39,6 @@ An Experimental Gemini Server, v{__version__}
 | 
			
		|||
https://github.com/michael-lazar/jetforce
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
EPILOG = """
 | 
			
		||||
If the TLS cert/keyfile is not provided, a self-signed certificate will
 | 
			
		||||
automatically be generated and saved to your temporary directory.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Status:
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			@ -616,7 +611,6 @@ def command_line_parser() -> argparse.ArgumentParser:
 | 
			
		|||
    parser = argparse.ArgumentParser(
 | 
			
		||||
        prog="jetforce",
 | 
			
		||||
        description="An Experimental Gemini Protocol Server",
 | 
			
		||||
        epilog=EPILOG,
 | 
			
		||||
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument("--host", help="Server address to bind to", default="127.0.0.1")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue