webpush

package
v0.0.0-...-5ef73ad Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2016 License: Apache-2.0 Imports: 29 Imported by: 1

Documentation

Overview

Package webpush provides helper functions for sending encrpyted payloads using the Web Push protocol.

Sending a message:

import (
  "strings"
  "github.com/googlechrome/push-encryption-go/webpush"
)

func main() {
  // The values that make up the Subscription struct come from the browser
  sub := &webpush.Subscription{endpoint, key, auth}
  webpush.Send(nil, sub, "Yay! Web Push!", nil)
}

You can turn a JSON string representation of a PushSubscription object you collected from the browser into a Subscription struct with a helper function.

var exampleJSON = []byte(`{"endpoint": "...", "keys": {"p256dh": "...", "auth": "..."}}`)
sub, err := SubscriptionFromJSON(exampleJSON)

If the push service requires an authentication header (notably Google Cloud Messaging, used by Chrome) then you can add that as a fourth parameter:

if strings.Contains(sub.Endpoint, "https://android.googleapis.com/gcm/send/") {
  webpush.Send(nil, sub, "A message for Chrome", myGCMKey)
}

Package webpush is a generated protocol buffer package.

It is generated from these files:

webpush.proto

It has these top-level messages:

SubscribeRequest
SubscribeResponse
PushRequest
PushResponse
MonitorRequest
Message
AckRequest
AckResponse
ReceiptRequest
Receipt

Index

Constants

This section is empty.

Variables

View Source
var ReceiveBaseUrl = "https://localhost:9443"
View Source
var SendBaseUrl = "https://localhost:8443"

Functions

func Decrypt

func Decrypt(sub *Subscription, crypt *EncryptionResult, subPrivate []byte) (plain []byte, err error)

Decrypt an encrypted messages.

func InitServer

func InitServer(port string) (err error)

func NewPushRequest

func NewPushRequest(sub *Subscription, message string, token string) (*http.Request, error)

NewPushRequest creates a valid Web Push HTTP request for sending a message to a subscriber. If the push service requires an authentication header (notably Google Cloud Messaging, used by Chrome) then you can add that as the token parameter. Deprecated - token auth is not part of the spec.

func NewRequest

func NewRequest(to *Subscription, message string, ttlSec int, vapid *Vapid) (*http.Request, error)

NewVapidRequest creates a valid Web Push HTTP request for sending a message to a subscriber, using Vapid authentication. You can add more headers to configure collapsing, TTL.

func Poll

func Poll(res http.ResponseWriter, req *http.Request)

Poll provides a backward compatible mechanism for fetching messages using streaming json. The format is similar with BrowserChannel, for easier parsing.

func RegisterWebpushServer

func RegisterWebpushServer(s *grpc.Server, srv WebpushServer)

func Send

func Send(client *http.Client, sub *Subscription, message, token string) (*http.Response, error)

Send a message using the Web Push protocol to the recipient identified by the given subscription object. If the client is nil then the default HTTP client will be used. If the push service requires an authentication header (notably Google Cloud Messaging, used by Chrome) then you can add that as the token parameter.

func SendHandler

func SendHandler(res http.ResponseWriter, req *http.Request)

Webpush send will look for a connection and send the message.

func SubscribeHandler

func SubscribeHandler(res http.ResponseWriter, req *http.Request)

Subscribe creates a subscription. Initial version is just a random - some interface will be added later, to allow sets.

Types

type AckRequest

type AckRequest struct {
	MessageId string `protobuf:"bytes,1,opt,name=message_id" json:"message_id,omitempty"`
}

func (*AckRequest) Descriptor

func (*AckRequest) Descriptor() ([]byte, []int)

func (*AckRequest) ProtoMessage

func (*AckRequest) ProtoMessage()

func (*AckRequest) Reset

func (m *AckRequest) Reset()

func (*AckRequest) String

func (m *AckRequest) String() string

type AckResponse

type AckResponse struct {
}

func (*AckResponse) Descriptor

func (*AckResponse) Descriptor() ([]byte, []int)

func (*AckResponse) ProtoMessage

func (*AckResponse) ProtoMessage()

func (*AckResponse) Reset

func (m *AckResponse) Reset()

func (*AckResponse) String

func (m *AckResponse) String() string

type Channel

type Channel struct {
}

Channel represents an active connection to a UA

func (*Channel) Close

func (*Channel) Close()

func (*Channel) Run

func (*Channel) Run()

func (*Channel) Send

func (*Channel) Send(*Message)

type EncryptionResult

type EncryptionResult struct {
	Ciphertext      []byte
	Salt            []byte
	ServerPublicKey []byte
}

EncryptionResult stores the result of encrypting a message. The ciphertext is the actual encrypted message, while the salt and server public key are required to be sent to the client so that the message can be decrypted.

func Encrypt

func Encrypt(sub *Subscription, message string) (*EncryptionResult, error)

Encrypt a message such that it can be sent using the Web Push protocol. You can find out more about the various pieces:

func EncryptWithTempKey

func EncryptWithTempKey(sub *Subscription, plaintext []byte,
	serverPrivateKey, serverPublicKey []byte) (*EncryptionResult, error)

Encrypt a message using Web Push protocol, reusing the temp key. A new salt will be used. This is ~20% faster.

type Message

type Message struct {
	MessageId string `protobuf:"bytes,1,opt,name=message_id" json:"message_id,omitempty"`
	// Maps to the SubscribeResponse push parameter, returned as Link rel="urn:ietf:params:push"
	// in the push promise.
	Push            string `protobuf:"bytes,2,opt,name=push" json:"push,omitempty"`
	Data            []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
	SenderVapid     string `protobuf:"bytes,4,opt,name=sender_vapid" json:"sender_vapid,omitempty"`
	ContentEncoding string `protobuf:"bytes,7,opt,name=content_encoding" json:"content_encoding,omitempty"`
	Salt            string `protobuf:"bytes,8,opt,name=salt" json:"salt,omitempty"`
	Dh              string `protobuf:"bytes,9,opt,name=dh" json:"dh,omitempty"`
}

Message is returned as PUSH PROMISE frames in the spec. The gRPC interface defines it as a stream, returned in normal DATA frames.

func (*Message) Descriptor

func (*Message) Descriptor() ([]byte, []int)

func (*Message) ProtoMessage

func (*Message) ProtoMessage()

func (*Message) Reset

func (m *Message) Reset()

func (*Message) String

func (m *Message) String() string

type MonitorRequest

type MonitorRequest struct {
	// This is the push or push_set in the subscribe response.
	PushSet string `protobuf:"bytes,1,opt,name=push_set" json:"push_set,omitempty"`
	// JWT token, signed with key
	Authorization string `protobuf:"bytes,2,opt,name=authorization" json:"authorization,omitempty"`
	// Public key used for signing, identifies sender/receiver
	Key string `protobuf:"bytes,3,opt,name=key" json:"key,omitempty"`
}

func (*MonitorRequest) Descriptor

func (*MonitorRequest) Descriptor() ([]byte, []int)

func (*MonitorRequest) ProtoMessage

func (*MonitorRequest) ProtoMessage()

func (*MonitorRequest) Reset

func (m *MonitorRequest) Reset()

func (*MonitorRequest) String

func (m *MonitorRequest) String() string

type PushRequest

type PushRequest struct {
	// The value returned in the SubscribeResponse push, without the hostname.
	Push    string `protobuf:"bytes,1,opt,name=push" json:"push,omitempty"`
	Ttl     int32  `protobuf:"varint,2,opt,name=ttl" json:"ttl,omitempty"`
	Data    []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
	Urgency string `protobuf:"bytes,4,opt,name=urgency" json:"urgency,omitempty"`
	// Prefer header indicating delivery receipt request.
	RespondAsync    bool   `protobuf:"varint,5,opt,name=respond_async" json:"respond_async,omitempty"`
	Topic           string `protobuf:"bytes,6,opt,name=topic" json:"topic,omitempty"`
	ContentEncoding string `protobuf:"bytes,7,opt,name=content_encoding" json:"content_encoding,omitempty"`
	Salt            string `protobuf:"bytes,8,opt,name=salt" json:"salt,omitempty"`
	Dh              string `protobuf:"bytes,9,opt,name=dh" json:"dh,omitempty"`
}

func (*PushRequest) Descriptor

func (*PushRequest) Descriptor() ([]byte, []int)

func (*PushRequest) ProtoMessage

func (*PushRequest) ProtoMessage()

func (*PushRequest) Reset

func (m *PushRequest) Reset()

func (*PushRequest) String

func (m *PushRequest) String() string

type PushResponse

type PushResponse struct {
	MessageId string `protobuf:"bytes,1,opt,name=message_id" json:"message_id,omitempty"`
	// If request includes the respond_async parameter.
	//
	PushReceipt string `protobuf:"bytes,2,opt,name=push_receipt" json:"push_receipt,omitempty"`
}

func (*PushResponse) Descriptor

func (*PushResponse) Descriptor() ([]byte, []int)

func (*PushResponse) ProtoMessage

func (*PushResponse) ProtoMessage()

func (*PushResponse) Reset

func (m *PushResponse) Reset()

func (*PushResponse) String

func (m *PushResponse) String() string

type Receipt

type Receipt struct {
	MessageId string `protobuf:"bytes,1,opt,name=message_id" json:"message_id,omitempty"`
}

func (*Receipt) Descriptor

func (*Receipt) Descriptor() ([]byte, []int)

func (*Receipt) ProtoMessage

func (*Receipt) ProtoMessage()

func (*Receipt) Reset

func (m *Receipt) Reset()

func (*Receipt) String

func (m *Receipt) String() string

type ReceiptRequest

type ReceiptRequest struct {
	ReceiptSubscription string `protobuf:"bytes,1,opt,name=receipt_subscription" json:"receipt_subscription,omitempty"`
}

func (*ReceiptRequest) Descriptor

func (*ReceiptRequest) Descriptor() ([]byte, []int)

func (*ReceiptRequest) ProtoMessage

func (*ReceiptRequest) ProtoMessage()

func (*ReceiptRequest) Reset

func (m *ReceiptRequest) Reset()

func (*ReceiptRequest) String

func (m *ReceiptRequest) String() string

type SubscribeRequest

type SubscribeRequest struct {
	// A UA should group subscriptions in a set. First request from a
	// UA will not include a set - it is typically a subscription associated with
	// the UA itself.
	PushSet string `protobuf:"bytes,1,opt,name=push_set" json:"push_set,omitempty"`
	// Included as Crypto-Key: p256ecdsa parameter.
	// Corresponds to the applicationServerKey parameter in the PushSubscriptionOptions in
	// the W3C API
	SenderVapid string `protobuf:"bytes,2,opt,name=sender_vapid" json:"sender_vapid,omitempty"`
}

func (*SubscribeRequest) Descriptor

func (*SubscribeRequest) Descriptor() ([]byte, []int)

func (*SubscribeRequest) ProtoMessage

func (*SubscribeRequest) ProtoMessage()

func (*SubscribeRequest) Reset

func (m *SubscribeRequest) Reset()

func (*SubscribeRequest) String

func (m *SubscribeRequest) String() string

type SubscribeResponse

type SubscribeResponse struct {
	// Returned as Link: rel="urn:ietf:params:push"
	// Spec examples use a full path ( /push/xxxx1 )
	// TODO: clarify if it can be a full URL
	Push string `protobuf:"bytes,1,opt,name=push" json:"push,omitempty"`
	// Optional response: it
	// returned as Link: rel=urn:ietf:params:push:set
	// Spec examples use a full path ( /subscription-set/xxxx2 ).
	// TODO: clarify it can be a full URL, like subscription
	PushSet string `protobuf:"bytes,2,opt,name=push_set" json:"push_set,omitempty"`
	// Push subscription resource. This is the full URL where the UA will use to
	// receive the messages, using the PUSH promise http2 frame.
	//
	//
	// Returned as Location header in the spec
	Location string `protobuf:"bytes,3,opt,name=location" json:"location,omitempty"`
}

Subscribe response includes the elements in the spec.

func (*SubscribeResponse) Descriptor

func (*SubscribeResponse) Descriptor() ([]byte, []int)

func (*SubscribeResponse) ProtoMessage

func (*SubscribeResponse) ProtoMessage()

func (*SubscribeResponse) Reset

func (m *SubscribeResponse) Reset()

func (*SubscribeResponse) String

func (m *SubscribeResponse) String() string

type Subscription

type Subscription struct {
	// Endpoint is the URL to send the Web Push message to. Comes from the
	// endpoint field of the PushSubscription.
	Endpoint string
	// Key is the client's public key. From the keys.p256dh field.
	Key []byte
	// Auth is a value used by the client to validate the encryption. From the
	// keys.auth field.
	Auth []byte
}

Subscription holds the useful values from a PushSubscription object acquired from the browser

func SubscriptionFromJSON

func SubscriptionFromJSON(b []byte) (*Subscription, error)

SubscriptionFromJSON is a convenience function that takes a JSON encoded PushSubscription object acquired from the browser and returns a pointer to a Subscription

type Target

type Target struct {
	// Queued messages
	Messages []Message
}

Target represents a delivery target, identified by a subscription or subscription set.

type UA

type UA struct {
	// URL of the subscribe for the push service
	PushService string
}

UA represents a "user agent" - or client using the webpush protocol This is intended for testing and simple use.

func (*UA) Read

func (ua *UA) Read() (sub UASubscription, err error)

Read will receive messages, using a hanging GET, for cases where HTTP/2 is not available.

func (*UA) Subscribe

func (ua *UA) Subscribe() (sub UASubscription, err error)

Create a subscription.

type UASubscription

type UASubscription struct {
	Subscription
	// contains filtered or unexported fields
}

UASubscription represents one app's subscription. A UA may host multiple apps.

type Vapid

type Vapid struct {
	// The EC256 public key, base64 urlsafe, uncompressed. This value should be
	// used in 'subscribe' requests and is included as p256ecdsa in
	// the Crypto-Key header.
	PublicKey string

	// Sub should be an email or URL, for identification
	Sub string
	// contains filtered or unexported fields
}

Vapid represents a sender identity.

func NewVapid

func NewVapid(publicKey, privateKey string) (v *Vapid)

NewVapid constructs a new Vapid generator from EC256 public and private keys, in uncompressed format.

func (*Vapid) Token

func (vapid *Vapid) Token(aud string) (res string)

Token creates a token with the specified endpoint, using configured Sub id and a default expiration (1h).

type WebpushClient

type WebpushClient interface {
	// Subscribe maps the the webpush subscribe request
	Subscribe(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (*SubscribeResponse, error)
	// Monitor allows a UA to receive push messages from the push service
	// Replaced push promises with a stream of Message objects.
	Monitor(ctx context.Context, in *MonitorRequest, opts ...grpc.CallOption) (Webpush_MonitorClient, error)
	Ack(ctx context.Context, in *AckRequest, opts ...grpc.CallOption) (*AckResponse, error)
	// Push allows an application server to send messages to UA, using the push service.
	Push(ctx context.Context, in *PushRequest, opts ...grpc.CallOption) (*PushResponse, error)
	// Monitor allows an AS to receive push messages receipts from the push service
	// Replaced push promises with a stream of Message objects.
	Receipts(ctx context.Context, in *ReceiptRequest, opts ...grpc.CallOption) (Webpush_ReceiptsClient, error)
}

func NewWebpushClient

func NewWebpushClient(cc *grpc.ClientConn) WebpushClient

type WebpushServer

type WebpushServer interface {
	// Subscribe maps the the webpush subscribe request
	Subscribe(context.Context, *SubscribeRequest) (*SubscribeResponse, error)
	// Monitor allows a UA to receive push messages from the push service
	// Replaced push promises with a stream of Message objects.
	Monitor(*MonitorRequest, Webpush_MonitorServer) error
	Ack(context.Context, *AckRequest) (*AckResponse, error)
	// Push allows an application server to send messages to UA, using the push service.
	Push(context.Context, *PushRequest) (*PushResponse, error)
	// Monitor allows an AS to receive push messages receipts from the push service
	// Replaced push promises with a stream of Message objects.
	Receipts(*ReceiptRequest, Webpush_ReceiptsServer) error
}

type Webpush_MonitorClient

type Webpush_MonitorClient interface {
	Recv() (*Message, error)
	grpc.ClientStream
}

type Webpush_MonitorServer

type Webpush_MonitorServer interface {
	Send(*Message) error
	grpc.ServerStream
}

type Webpush_ReceiptsClient

type Webpush_ReceiptsClient interface {
	Recv() (*Receipt, error)
	grpc.ClientStream
}

type Webpush_ReceiptsServer

type Webpush_ReceiptsServer interface {
	Send(*Receipt) error
	grpc.ServerStream
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL