controller_websub
HTTP hub and subscriber callback controller for mod_websub.
Endpoints
| Dispatch | Method | Purpose |
|---|---|---|
websub (/.zotonic/websub) | POST, form encoded | Request subscription or unsubscription at this site's hub. |
websub_callback (/.zotonic/websub/:token) | GET | Confirm pending subscriber intent or receive a denial. |
websub_callback | POST, JSON | Receive a signed resource-export delivery from a remote hub. |
Subscription forms use the standard hub.mode, hub.topic, hub.callback,
optional hub.secret, and optional hub.lease_seconds fields. The topic must
match a local resource's advertised JSON topic URL. Lease seconds are ignored
for unsubscription. Accepted requests receive 202 after durable queue admission;
overload receives 503. Verification and authorization run independently in
task_verify/7, so accepting a request does not activate the subscription.
The hub checks that the resource is visible to the subscriber and authoritative, then verifies the callback by GET with a random challenge. It activates or removes the subscription only after a successful response with the exact challenge body. Private subscriptions require explicit HTTP authorization; browser cookies alone are insufficient. The worker retains the authentication's effective group limits.
Subscriber callbacks match the capability token, discovered topic, pending action,
and verification deadline. Valid intent returns the challenge as plain text with
nosniff; unexpected intent returns 404. A denial stops the matching subscription.
Delivery accepts resource-export JSON, verifies the configured HMAC signature in
m_websub:handle_push_notification/4, and queues import work. Invalid signatures
are ignored locally while the callback can still acknowledge receipt with 2xx.
Outbound callback requests use z_websub_http and z_fetch, with destination
checks and automatic redirects disabled. Callback verification and delivery do
not use the initiating user's OAuth2 credentials. Request admission is deduplicated
and bounded per site; inbound delivery bodies are limited to 1 MiB.
See mod_websub for the complete two-site flow, resource identity versus topic,
OAuth2 integration, and the open DNS connection-pinning TODO.