• Stars
    star
    113
  • Rank 310,115 (Top 7 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created over 7 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Web Push library for Rust

Rust Web Push

Cargo tests crates.io docs.rs

This crate implements the server half of the web push API, in Rust!

For more background on the web push framework itself, please reference this excellent document.

Requirements

Clients require an async executor. System Openssl is needed for compilation.

Migration notes

This library is still in active development, and will have breaking changes in accordance with semver. Please view the GitHub release notes for detailed notes.

Example

use web_push::*;
use web_push::clients::isahc_client::IsahcWebPushClient;
use std::fs::File;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
    let endpoint = "https://updates.push.services.mozilla.com/wpush/v1/...";
    let p256dh = "key_from_browser_as_base64";
    let auth = "auth_from_browser_as_base64";

    //You would likely get this by deserializing a browser `pushSubscription` object via serde.  
    let subscription_info = SubscriptionInfo::new(
        endpoint,
        p256dh,
        auth
    );

    //Read signing material for payload.
    let file = File::open("private.pem").unwrap();
    let mut sig_builder = VapidSignatureBuilder::from_pem(file, &subscription_info)?.build()?;

    //Now add payload and encrypt.
    let mut builder = WebPushMessageBuilder::new(&subscription_info);
    let content = "Encrypted payload to be sent in the notification".as_bytes();
    builder.set_payload(ContentEncoding::Aes128Gcm, content);
    builder.set_vapid_signature(sig_builder);

    let client = IsahcWebPushClient::new()?;

    //Finally, send the notification!
    client.send(builder.build()?).await?;
    Ok(())
}

VAPID

VAPID authentication prevents unknown sources sending notifications to the client and is required by all current browsers when sending a payload.

The private key to be used by the server can be generated with OpenSSL:

openssl ecparam -genkey -name prime256v1 -out private_key.pem

To derive a public key from the just-generated private key, to be used in the JavaScript client:

openssl ec -in private_key.pem -pubout -outform DER|tail -c 65|base64|tr '/+' '_-'|tr -d '\n'

The signature is created with VapidSignatureBuilder. It automatically adds the required claims aud and exp. Adding these claims to the builder manually will override the default values.

Using the example program

To send a web push from command line, first subscribe to receive push notifications with your browser and store the subscription info into a json file. It should have the following content:

{
  "endpoint": "https://updates.push.services.mozilla.com/wpush/v1/TOKEN",
  "keys": {
    "auth": "####secret####",
    "p256dh": "####public_key####"
  }
}

Google has good instructions for building a frontend to receive notifications.

Store the subscription info to examples/test.json and send a notification with cargo run --example simple_send -- -f examples/test.json -p "It works!".

Overview

Currently, the crate implements RFC8188 content encryption for notification payloads. This is done by delegating encryption to mozilla's ece crate. Our security is thus tied to theirs. The default client is built on isahc, but can be swapped out with a hyper based client using the hyper-client feature. Custom clients can be made using the request_builder module.

Library tested with Google's and Mozilla's push notification services. Also verified to work on Edge.

Openssl is needed to build. Install openssl-dev or equivalent on *nix, or openssl using vcpkg on Windows. A nix script is also available.

If installing on Windows, this is the exact command:

vcpkg integrate install
vcpkg install openssl:x64-windows-static-md

Debugging

If you get an error or the push notification doesn't work you can try to debug using the following instructions:

Add the following to your Cargo.toml:

log = "0.4"
pretty_env_logger = "0.3"

Add the following to your main.rs:

extern crate pretty_env_logger;

// ...
fn main() {
    pretty_env_logger::init();
    // ...
}

Or use any other logging library compatible with https://docs.rs/log/

Then run your program with the following environment variables:

RUST_LOG="web_push::client=trace" cargo run

This should print some more information about the requests to the push service which may aid you or somebody else in finding the error.

More Repositories

1

nixos

NixOS Configuration
Nix
100
star
2

emacs-prisma-mode

A quick and dirty emacs major mode for Prisma schemas
Emacs Lisp
52
star
3

c2dm_on_rails

A Rails API for sending Google Android push notifications
Ruby
50
star
4

nix-prisma-example

An example Prisma project using nix
Nix
32
star
5

nixos-prisma

Nix derivations of common Prisma tools
Nix
10
star
6

AppsProto

Quick Ruby on Rails hack
Ruby
3
star
7

dotvim

Vim plugins and configuration
Vim Script
3
star
8

ado-jdbc

Rust/wasm
Rust
2
star
9

writing

Writings for Prisma and Other Contexts
Shell
2
star
10

tikplay

Tikplay kotiserverin omistaville
2
star
11

soundcloud_favorites_rss

Ruby
1
star
12

Blog-from-Berlin

Blog using Octopress
JavaScript
1
star
13

dotemacs

Emacs configuration
Emacs Lisp
1
star
14

GraphiteTest

A small sinatra + jquery + flot application for parsing graphite json
JavaScript
1
star
15

my-fauna-blog

A test app with Hyper/Rust/FaunaDB
Rust
1
star
16

napi-test

Rust
1
star
17

tokio_quiz

Rust Quiz 3
Rust
1
star
18

capper

capper is a collection of opinionated Capistrano recipes
Ruby
1
star
19

neon-db-test

Testing neon event handler
Rust
1
star
20

async-query

A tracer bullet on abscracting async psql/sqlite/mysql
Rust
1
star
21

MySimpleUploader

Multipart uploads with progress using Node.js
JavaScript
1
star
22

lambda-cpus

A tool to display the number of physical and logical cpus in AWS Lambda
Rust
1
star
23

pgbouncer-reproduction

A demonstration how Prisma breaks with pgbouncer
Shell
1
star
24

blocking_test

SPEED TEST
Rust
1
star
25

biletappi

biletappi on
Tcl
1
star
26

diskotappi

My Bot Project (tm)
Ruby
1
star
27

herrbot

IRC bot written with Haskell. A learning experiement. Base code from http://www.haskell.org/haskellwiki/Roll_your_own_IRC_bot
Haskell
1
star
28

napi-events

A test how to push logs from Rust to JavaScript
Rust
1
star
29

haskell_mux

A spike to produce a Haskell version of message multiplexer with ØMQ and Haskell
Haskell
1
star