Skip to content

Notifier: 489/400 to incoming SUBSCRIBE, final NOTIFY on UA.stop() - #980

Open
neutrino38 wants to merge 1 commit into
versatica:masterfrom
neutrino38:notifier-incoming-subscribe
Open

neutrino38 wants to merge 1 commit into
versatica:masterfrom
neutrino38:notifier-incoming-subscribe

Conversation

@neutrino38

Copy link
Copy Markdown

Why

  • Without a newSubscribe listener, an incoming SUBSCRIBE gets 405 Method Not Allowed, even though SUBSCRIBE appears in the Allow header of
    that same response. What is unsupported is the event package, which is what 489 Bad Event says (RFC 6665 4.2.1.1).
  • A malformed SUBSCRIBE (no Contact, no Event, invalid Expires) also gets 405. It is a malformed request: 400 Bad Request.
  • UA.stop() leaves the subscriptions we serve open. Subscribers learn we are gone only when their subscription expires.
  • IncomingRequest.reply() is not declared, although every newSubscribe listener has to call it, so TypeScript users must cast the request.

What

  • UA.receiveRequest(): an incoming SUBSCRIBE with no listener gets 489 instead of 405.
  • Notifier.init_incoming(): a malformed SUBSCRIBE gets 400 instead of 405.
  • UA.stop() sends a final NOTIFY (Subscription-State: terminated) for every active Notifier, before the UA is closed. The UA tracks
    notifiers through newNotifier() and destroyNotifier(), as it does for sessions. A fetch SUBSCRIBE (Expires: 0) is not tracked, since it is
    already over. The final NOTIFY carries no reason, so subscribers may re-subscribe whenever they want (RFC 6665 4.1.3).
  • SIPMessage.d.ts now declares IncomingRequest.reply().

Behaviour changes

The response code becomes 489 or 400 where it used to be 405. Applications that already call notifier.terminate() before ua.stop() are
unaffected, because terminate() is idempotent.

Tests

src/test/test-Notifier.ts covers three cases: 489 without a listener, 400 on a SUBSCRIBE with no Event header, and the final NOTIFY on
UA.stop(). All three fail without this change. npm test and npm run lint pass.

- Without a `newSubscribe` listener, an incoming SUBSCRIBE got 405
  Method Not Allowed, although SUBSCRIBE is in the Allow header of that
  very response. What is missing is the event package: 489 Bad Event
  (RFC 6665 4.2.1.1).
- A SUBSCRIBE without Contact or Event, or with a bad Expires, got 405
  too; it is a malformed request: 400 Bad Request.
- UA.stop() ends every Notifier with a final NOTIFY
  (Subscription-State: terminated), sent before the UA is closed, as it
  does for sessions. Subscribers no longer wait for the subscription to
  expire to learn that we are gone.
- IncomingRequest.reply() is declared: every `newSubscribe` listener
  calls it, and had to cast the request to do so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant