I don't think that this is actually documented anywhere, so here's a crack at
it. Not authoritative. This doesn't document the routes.py-based rewriting,
just the "normal" handling of incoming URLs.
main.wsgibase:
web2py expects its incoming URL to be in environ['PATH_INFO'] and
environ['QUERY_STRING']. If PATH_INFO is not set, we try to set it and
QUERY_STRING from REQUEST_URI.
Likewise, if HTTP_HOST is not set, we try to set it from SERVER_NAME and
SERVER_PORT.
We then call rewrite.url_in to do all the work (regardless of whether routes.py
exists).
rewrite.url_in:
If routes.py exists and contains a parametric router ('routers', a dict), we
invoke rewrite.map_url_in to do the work; otherwise rewrite.regex_url_in does
the work (including when routes.py does not exist).
rewrite.regex_url_in:
rewrite.regex_select determines the application. This is needed in case we're
using app-specific routing.
If routes.py exists, call rewrite.regex_filter_in to rewrite the URL.
For each item in environ, create a copy with the key in lower case, with dots
(in the key) replaced with underscores.
In request.path_info, convert backslashes to slashes.
Use regex_static to detect URLs of static files; return static files at this
point, with spaces converted to underscores, where by 'spaces' we mean any
white space, '+', or '%20'.
Otherwise, replace '%20' with ' ' (space).
Test path against regex_url; if it doesn't match, raise an invalid-request
exception.
Set request.application, controller, function from the first three elements of
the path, converting spaces (and +) to underscores. Use /init/default/index as
the defaults, unless overridden in routes.py.
Set request.raw_extension to the extension, if any.
Set request.extension to the extension, or 'html' if None.
Set request.raw_args to the remainder of the path.
If the app is in routes_apps_raw, set request.args = None.
Otherwise replace spaces (but not +) with underscore and validate against
regex_args, raising a 400 exception if no match, and split the result (on /)
into the List request.args.