Better docstrings
This commit is contained in:
parent
42a5b6b65b
commit
c7f0e1e4fb
26
CHANGELOG.md
26
CHANGELOG.md
|
@ -5,30 +5,30 @@
|
||||||
#### Features
|
#### Features
|
||||||
|
|
||||||
- Added support for python 3.8.
|
- Added support for python 3.8.
|
||||||
- Added a new server diagnostics tool ``jetforce-diagnostics``.
|
- Added a new server diagnostics tool, ``jetforce-diagnostics``.
|
||||||
- Added ability to binding to IPv6 addresses (if supported by your OS):
|
- Added ability to binding to IPv6 addresses (if supported by your OS):
|
||||||
- For IPv4 : --host "0.0.0.0"
|
- For IPv4 : ``--host "0.0.0.0"``
|
||||||
- For IPv6 : --host "::"
|
- For IPv6 : ``--host "::"``
|
||||||
- For IPv4 + IPv6 : --host ""
|
- For IPv4 + IPv6 : ``--host ""``
|
||||||
- Various improvements have been made to the project documentation.
|
- Various improvements have been made to the project documentation.
|
||||||
|
|
||||||
#### Bugfixes
|
#### Bugfixes
|
||||||
|
|
||||||
- A URL missing a scheme will now be interpreted as "gemini://".
|
- A URL missing a scheme will now be interpreted as "gemini://".
|
||||||
- A request to the root URL without a trailing slash will now return a 31
|
- A request to the root URL without a trailing slash will now return a
|
||||||
permanent redirect.
|
``31 PERMANENT REDIRECT``.
|
||||||
- Requests containing an invalid or unparsable URL format will now return a
|
- Requests containing an invalid or unparsable URL format will now return a
|
||||||
status of 59 Bad Request instead of 50 Permanent Failure.
|
status of ``59 BAD REQUEST`` instead of ``50 PERMANENT FAILURE``.
|
||||||
- Files starting with ``~`` will now be included in directory listings.
|
- Files starting with ``~`` will now be included in directory listings.
|
||||||
- Requests containing an incorrect scheme, hostname, or port will now return a
|
- Requests containing an incorrect scheme, hostname, or port will now return a
|
||||||
53 Proxy Refused instead of a 50 Permanent Failure.
|
``53 PROXY REFUSED`` instead of a ``50 PERMANENT FAILURE``.
|
||||||
- The port number in the URL (if provided) is now validated against the
|
- The port number in the URL (if provided) is now validated against the
|
||||||
server's port number.
|
server's port number.
|
||||||
- OS errors when attempting to read a file will return a 51 NOT FOUND status
|
- OS errors when attempting to read a file will return a ``51 NOT FOUND``
|
||||||
instead of a 42 CGI Error. This is a precaution to prevent leaking sensitive
|
status instead of a ``42 CGI Error``. This is a precaution to prevent leaking
|
||||||
information about the server's filesystem.
|
sensitive information about the server's filesystem.
|
||||||
- For security, unhandled exceptions now display a generic error message
|
- For security, unhandled exceptions will now display a generic error message
|
||||||
instead of the specific exception string.
|
instead of the plain exception string.
|
||||||
|
|
||||||
### v0.1.0 (2019-09-22)
|
### v0.1.0 (2019-09-22)
|
||||||
|
|
||||||
|
|
61
jetforce.py
61
jetforce.py
|
@ -1,4 +1,37 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Jetforce, an experimental Gemini server.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
GeminiServer:
|
||||||
|
An asynchronous TCP server built on top of python's asyncio stream
|
||||||
|
abstraction. This is a lightweight class that accepts incoming requests,
|
||||||
|
logs them, and sends them to a configurable request handler to be processed.
|
||||||
|
|
||||||
|
GeminiRequestHandler:
|
||||||
|
The request handler manages the life of a single gemini request. It exposes
|
||||||
|
a simplified interface to read the request URL and write the gemini response
|
||||||
|
status line and body to the socket. The request URL and other server
|
||||||
|
information is stuffed into an ``environ`` dictionary that encapsulates the
|
||||||
|
request at a low level. This dictionary, along with a callback to write the
|
||||||
|
response data, and passed to a configurable "application" function or class.
|
||||||
|
|
||||||
|
JetforceApplication:
|
||||||
|
This is a base class for writing jetforce server applications. It doesn't
|
||||||
|
anything on its own, but it does provide a convenient interface to define
|
||||||
|
custom server endpoints using route decorators. If you want to utilize
|
||||||
|
jetforce as a library and write your own server in python, this is the class
|
||||||
|
that you want to extend. The examples/ directory contains some examples of
|
||||||
|
how to accomplish this.
|
||||||
|
|
||||||
|
StaticDirectoryApplication:
|
||||||
|
This is a pre-built application that serves files from a static directory.
|
||||||
|
It provides an "out-of-the-box" gemini server without needing to write any
|
||||||
|
lines of code. This is what is invoked when you launch jetforce from the
|
||||||
|
command line.
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
@ -150,6 +183,13 @@ class RoutePattern:
|
||||||
class JetforceApplication:
|
class JetforceApplication:
|
||||||
"""
|
"""
|
||||||
Base Jetforce application class with primitive URL routing.
|
Base Jetforce application class with primitive URL routing.
|
||||||
|
|
||||||
|
This is a base class for writing jetforce server applications. It doesn't
|
||||||
|
anything on its own, but it does provide a convenient interface to define
|
||||||
|
custom server endpoints using route decorators. If you want to utilize
|
||||||
|
jetforce as a library and write your own server in python, this is the class
|
||||||
|
that you want to extend. The examples/ directory contains some examples of
|
||||||
|
how to accomplish this.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -216,7 +256,12 @@ class JetforceApplication:
|
||||||
|
|
||||||
class StaticDirectoryApplication(JetforceApplication):
|
class StaticDirectoryApplication(JetforceApplication):
|
||||||
"""
|
"""
|
||||||
Serve a static directory over Gemini.
|
Application for serving static files & CGI over gemini.
|
||||||
|
|
||||||
|
This is a pre-built application that serves files from a static directory.
|
||||||
|
It provides an "out-of-the-box" gemini server without needing to write any
|
||||||
|
lines of code. This is what is invoked when you launch jetforce from the
|
||||||
|
command line.
|
||||||
|
|
||||||
If a directory contains a file with the name "index.gmi", that file will
|
If a directory contains a file with the name "index.gmi", that file will
|
||||||
be returned when the directory path is requested. Otherwise, a directory
|
be returned when the directory path is requested. Otherwise, a directory
|
||||||
|
@ -388,11 +433,18 @@ class GeminiRequestHandler:
|
||||||
"""
|
"""
|
||||||
Handle a single Gemini Protocol TCP request.
|
Handle a single Gemini Protocol TCP request.
|
||||||
|
|
||||||
|
The request handler manages the life of a single gemini request. It exposes
|
||||||
|
a simplified interface to read the request URL and write the gemini response
|
||||||
|
status line and body to the socket. The request URL and other server
|
||||||
|
information is stuffed into an ``environ`` dictionary that encapsulates the
|
||||||
|
request at a low level. This dictionary, along with a callback to write the
|
||||||
|
response data, and passed to a configurable "application" function or class.
|
||||||
|
|
||||||
This design borrows heavily from the standard library's HTTP request
|
This design borrows heavily from the standard library's HTTP request
|
||||||
handler (http.server.BaseHTTPRequestHandler). However, I did not make any
|
handler (http.server.BaseHTTPRequestHandler). However, I did not make any
|
||||||
attempts to directly emulate the existing conventions, because Gemini is an
|
attempts to directly emulate the existing conventions, because Gemini is an
|
||||||
inherently simpler protocol than HTTP and much of the boilerplate could be
|
inherently simpler protocol than HTTP and much of the boilerplate could be
|
||||||
removed or slimmed-down.
|
removed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TIMESTAMP_FORMAT = "%d/%b/%Y:%H:%M:%S %z"
|
TIMESTAMP_FORMAT = "%d/%b/%Y:%H:%M:%S %z"
|
||||||
|
@ -551,7 +603,10 @@ class GeminiRequestHandler:
|
||||||
|
|
||||||
class GeminiServer:
|
class GeminiServer:
|
||||||
"""
|
"""
|
||||||
An asynchronous TCP server that understands the Gemini Protocol.
|
An asynchronous TCP server that uses the asyncio stream abstraction.
|
||||||
|
|
||||||
|
This is a lightweight class that accepts incoming requests, logs them, and
|
||||||
|
sends them to a configurable request handler to be processed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
request_handler_class = GeminiRequestHandler
|
request_handler_class = GeminiRequestHandler
|
||||||
|
|
Loading…
Reference in New Issue