PyWeb 0.4.3
A review release: bug fixes, security hardening and speed-ups. No API
removals; one new setting (PYWEB_TRUST_PROXY).
Fixed
- Pages showed stale data when a module-level value (
ITEMS = []) was
changed by an@serverfunction: the compiler copied its starting
value into browser code, and the page re-rendered with it. Values
that code changes now come from the server on each request. db.transaction(): a statement error that your code caught rolled
back the transaction's earlier writes while later ones still
committed. Errors inside a transaction now leave it to
transaction()(all or nothing).db.stream()inside a transaction waited for a second connection
(a 10 second hang with SQLite in memory); it now uses the
transaction's.pyweb servesent SVG, images, fonts, JSON and WebAssembly as
application/octet-stream(browsers don't show an SVG sent that way).- Your own files in
static/(such asapp.css) were cached by
browsers for a year, so deploys didn't show up for returning
visitors. They're now revalidated with an ETag (a304when
unchanged); content-hashed files,?v=URLs and npm packages are
still cached for a year. - Client-side navigation could show a page prefetched before a server
call changed its data. async defserver functions ignoredrpc_timeout.- The ASGI adapter kept only the last of repeated request headers, so
HTTP/2 clients sending each cookie separately lost all but one. pyweb dts: type aliases were never written, members on one line
({ a: string; b?: number }) produced invalid Python, and optional
fields before required ones made the stub fail to import.- Very long upload filenames are shortened (keeping the extension)
instead of failing to save.
Security
- RPC rate limits used the
X-Forwarded-Forheader, which any client
can set (so the limit was easy to get around), and put every visitor
without a session cookie in one shared bucket. They now use the
connection's address; behind a reverse proxy setPYWEB_TRUST_PROXY=1
(or the number of proxies) to use the address your proxy saw. auth.require_sessionandauth.login_responseonly redirect to
paths on your site (//evil.examplebecomes/); the new
auth.safe_next()does the same for your own?next=handling.- Magic-link tokens are signed separately from session cookies, so one
can't be used as the other. Links issued before the upgrade stop
working (they last 15 minutes).
Performance
- HTML, JavaScript, CSS, JSON and SVG are gzipped for browsers that
accept it (the shared runtime goes from 46 KB to 15 KB); static files
are compressed once and kept. - Memory no longer grows without bound in long-running servers: the
rate limiter forgets idle callers, the realtime bus forgets channels
quiet for an hour, the in-memory cache drops expired entries, and
the job queue forgets jobs an hour after they finish. - The job queue runs jobs on a pool of 8 threads instead of one thread
per job, andwait()returns as soon as the job finishes. pyweb devno longer re-scans virtualenvs in the project folder
every 0.4 s, and reloads whenpyweb.lockchanges (after
pyweb add).