push

package
v0.3.3 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package push defines notification targets, results, certificate sources and coalescing for MDM pushes.

Design

Pusher sends notifications for supplied targets, CertStore resolves topic credentials, and Coalescer combines repeated pushes within a configured window. Result.Outcome distinguishes acceptance, an inactive token, a rejected request and retryable failure. This vocabulary lets callers apply retry and notification policy without depending on a database.

The APNs implementation is appleplatformservices/push/apns. Enrollment and persisted-certificate lookup live in server/pushnotify; certificate parsing lives in pki/pushcert. StaticCertStore supports fixed credentials, and pushtest provides scripted implementations.

References

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoCertificate = errors.New("push: no push certificate for topic")
	ErrCertExpired   = errors.New("push: push certificate expired")
	ErrInvalidToken  = errors.New("push: device token invalid")
	ErrRejected      = errors.New("push: APNs rejected the request")
	ErrRateLimited   = errors.New("push: rate limited")
	ErrUpstream      = errors.New("push: APNs error")
)

Errors returned by this package.

View Source
var ErrCoalesced = errors.New("push: coalesced with a recent push")

ErrCoalesced marks a push that was skipped because one was sent recently.

Outcomes lists every outcome, for exhaustiveness tests and label sets.

Functions

This section is empty.

Types

type CertStore

type CertStore interface {
	// PushCertificate returns the certificate with its private key. The
	// certificate must contain the topic as its UID.
	PushCertificate(ctx context.Context, topic string) (tls.Certificate, error)
}

CertStore provides the APNs push certificate for a topic.

type Coalescer

type Coalescer struct {
	// contains filtered or unexported fields
}

Coalescer drops repeated pushes to the same enrollment inside a window: a device that was just woken will fetch every queued command anyway.

func Coalesce

func Coalesce(next Pusher, window time.Duration, c clock.Clock) *Coalescer

Coalesce wraps a Pusher.

func (*Coalescer) Push

func (c *Coalescer) Push(ctx context.Context, targets []Target) (map[mdm.EnrollmentID]Result, error)

Push implements Pusher.

type Outcome

type Outcome string

Outcome classifies what happened to one push. It is a closed set, so a caller may switch on it exhaustively and use it as a metric label.

The distinction that matters is between OutcomeInvalidToken and OutcomeRejected. The first says this device will never receive a push again; the second says this request was wrong, which is usually a property of the topic, the certificate, or the environment rather than of the device, and so is usually true of every device at once. Collapsing them lets one misconfiguration read as a fleet that has gone silent.

const (
	// OutcomeSent: APNs accepted the notification.
	OutcomeSent Outcome = "sent"
	// OutcomeInvalidToken: this token will not work again. Apple states this
	// only for status 410 ("there is no need to send further pushes to the
	// same device token"), so only 410 produces it.
	OutcomeInvalidToken Outcome = "invalid-token"
	// OutcomeRejected: APNs refused the request and will refuse an identical
	// one, but said nothing about the device. A wrong topic, an expired or
	// mismatched push certificate, the sandbox environment, or a malformed
	// request all land here. It needs an operator, not a retry, and it is
	// not grounds for treating the enrollment as gone.
	OutcomeRejected Outcome = "rejected"
	// OutcomeRateLimited: APNs asked for a pause. RetryAfter carries what it
	// asked for, when it said.
	OutcomeRateLimited Outcome = "rate-limited"
	// OutcomeUnavailable: APNs or the network failed in a way that may
	// succeed on retry.
	OutcomeUnavailable Outcome = "unavailable"
	// OutcomeSkipped: nothing was sent to APNs, because the enrollment has
	// no usable push info or because a Coalescer dropped the push as a
	// duplicate. Err says which.
	OutcomeSkipped Outcome = "skipped"
)

Push outcomes.

type Pusher

type Pusher interface {
	// Push sends to every target and returns a Result per enrollment id.
	// The error is for failures that affect the whole batch (no
	// certificate, context cancelled); per-target failures are in Results.
	Push(ctx context.Context, targets []Target) (map[mdm.EnrollmentID]Result, error)
}

Pusher sends MDM pushes.

type Result

type Result struct {
	// Outcome classifies the result. The zero value is not a valid outcome;
	// a Pusher always sets it.
	Outcome Outcome
	// RetryAfter is what APNs asked to wait, and zero when it asked for
	// nothing. It is not a recommendation this package invents: a caller
	// that wants a floor applies its own, or apns.DefaultRetryAfter.
	RetryAfter time.Duration
	// Status and Reason are the APNs HTTP status and reason string. Reason
	// is one of the values in apns.Reasons when APNs sent one.
	Status int
	Reason string
	// APNSID is the apns-id header of an accepted push.
	APNSID string
	Err    error
}

Result is the outcome for one target.

func (Result) Sent

func (r Result) Sent() bool

Sent reports whether APNs accepted the notification.

func (Result) TokenInvalid

func (r Result) TokenInvalid() bool

TokenInvalid reports whether APNs said this token will never work again, which is the only outcome that justifies giving up on an enrollment.

type StaticCertStore

type StaticCertStore map[string]tls.Certificate

StaticCertStore serves fixed certificates by topic.

func (StaticCertStore) PushCertificate

func (s StaticCertStore) PushCertificate(_ context.Context, topic string) (tls.Certificate, error)

PushCertificate implements CertStore.

type Target

type Target struct {
	ID   mdm.EnrollmentID
	Push mdm.Push
}

Target is one push destination.

Directories

Path Synopsis
Package apns implements certificate-authenticated APNs HTTP/2 clients for MDM wake-ups and ordinary app alert/background notifications.
Package apns implements certificate-authenticated APNs HTTP/2 clients for MDM wake-ups and ordinary app alert/background notifications.
Package pushtest provides a scripted push.Pusher and an in-process APNs server.
Package pushtest provides a scripted push.Pusher and an in-process APNs server.

Jump to

Keyboard shortcuts

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