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 ¶
- Variables
- func Decrypt(sub *Subscription, crypt *EncryptionResult, subPrivate []byte) (plain []byte, err error)
- func InitServer(port string) (err error)
- func NewPushRequest(sub *Subscription, message string, token string) (*http.Request, error)
- func NewRequest(to *Subscription, message string, ttlSec int, vapid *Vapid) (*http.Request, error)
- func Poll(res http.ResponseWriter, req *http.Request)
- func RegisterWebpushServer(s *grpc.Server, srv WebpushServer)
- func Send(client *http.Client, sub *Subscription, message, token string) (*http.Response, error)
- func SendHandler(res http.ResponseWriter, req *http.Request)
- func SubscribeHandler(res http.ResponseWriter, req *http.Request)
- type AckRequest
- type AckResponse
- type Channel
- type EncryptionResult
- type Message
- type MonitorRequest
- type PushRequest
- type PushResponse
- type Receipt
- type ReceiptRequest
- type SubscribeRequest
- type SubscribeResponse
- type Subscription
- type Target
- type UA
- type UASubscription
- type Vapid
- type WebpushClient
- type WebpushServer
- type Webpush_MonitorClient
- type Webpush_MonitorServer
- type Webpush_ReceiptsClient
- type Webpush_ReceiptsServer
Constants ¶
This section is empty.
Variables ¶
var ReceiveBaseUrl = "https://localhost:9443"
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 NewPushRequest ¶
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 ¶
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 ¶
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 EncryptionResult ¶
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) ProtoMessage ¶
func (*Message) ProtoMessage()
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) ProtoMessage ¶
func (*Receipt) ProtoMessage()
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.
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 }