Megaphone is an internal Mozilla system providing global broadcasts for Firefox.
Traditionally Firefox has polled multiple services at different frequencies (e.g. every 24 hours) to check for updates. Megaphone serves as an alternative, notifying user agents of new updates in near real time (within 5 minutes) over the WebPush WebSocket protocol.
This enables Firefox to:
- Revoke HTTPS Certificates or malicious extensions immediately after security incidents occur
- Update quicker (Firefox itself, tracking protection lists, or general settings)
- Provide faster turn-around/feedback loops for studies/experiments (Shield)
All via one unified, simpler client-side service that doesn't require polling.
This repository provides a Rust based Megaphone endpoint (API). Broadcasts are sent to the Megaphone endpoint. The autopush-rs service polls the endpoint as the source of truth for current broadcasts, ultimately delivering them to clients.
Also see the API doc.
-
Rust nightly as specified in the
rust-toolchain
file (recognized by cargo) in the root of the project (recognized by cargo). -
MySQL 5.7 (or compatible)
-
libmysqlclient (brew install mysql on macOS, apt-get install libmysqlclient-dev on Ubuntu)
-
*For running the docker image locally: docker-compose v1.21.0 or later
-
Create a
megaphone
user/database -
Run:
$ export ROCKET_DATABASE_URL=mysql://scott:tiger@mydatabase/megaphone $ cargo run
-
From a dedicated screen (or tmux window)
$ docker-compose up
This will create two intertwined docker images:
db_1 - the database image. This image is a local test image. The database can be accessed via mysql -umegaphone -ptest -h localhost --port 4306 megaphone
.
app_1 - the megaphone application. This is accessible via port 8000.
Megaphone is normally called via a HTTP interface using Authorized calls. Responses are generally JSON objects with appropriate HTTP status codes to indicate success/failure.
All calls to Megaphone (minus the Dockerflow Status Checks) require authorization. Authorization is specified by the Authorization
header via Bearer tokens specified in the application's configuration.
e.g.
export ROCKET_BROADCASTER_AUTH={test=["foobar"]}
export ROCKET_READER_AUTH={autopush=["quux"]}
The test broadcaster would specify:
Authorization: Bearer foobar
The autopush reader would specify:
Authorization: Bearer quux
Broadcast a new version.
The body of the PUT request becomes the new version value.
A special version value of "NOP" (the string "NOP" prefixed and suffixed by four underscores) signals a "No Operation" to clients: that no action should take place, effectively overwriting and cancelling any pending version update.
The return value is a JSON structure including the HTTP status of the result: successful results either being a 201
code for newly created broadcasts or 200
for an update to an existing broadcast.
{
"code": 200
}
Read the current broadcasts.
The return value is a JSON structure including the HTTP status of the result and a broadcasts
object consisting of broadcastIDs and their current versions.
{
"code": 200,
"broadcasts": {
"test/broadcast1": "v3",
"test/broadcast2": "v0"
}
}
Return the status of the server.
This call is only used for server status checks.
Return a light weight status check (200 OK).
This call is only used for the Load Balancer's check.
Return a JSON response of the version information of the server.