Subject: [Webpush] When UA should send an acknowledgement?

From: Idel Pivnitskiy <[email-masked]>
Date: Tue, 7 Jun 2016 02:02:40 +0300

Just a question: When should UA send an acknowledgement? Immediately after
receiving a push message or after decryption/decoding/processing a push
message?

Best regards,
Idel Pivnitskiy
--
Twitter: @idelpivnitskiy <https://twitter.com/idelpivnitskiy>
GitHub: @idelpivnitskiy <https://github.com/idelpivnitskiy>

---

From: Martin Thomson <[email-masked]>
Date: Wed, 8 Jun 2016 12:34:56 +1000

> receiving a push message or after decryption/decoding/processing a push

This is defined in
http://w3c.github.io/push-api/index.html#the-push-event  (Step 6.5.3
is the acknowledgment.)

What a user agent does with the message is outside this spec.

---

From: Benjamin Bangert <[email-masked]>
Date: Tue, 7 Jun 2016 19:59:42 -0700

On Tue, Jun 7, 2016 at 7:34 PM, Martin Thomson <[email-masked]> wrote:
> _______________________________________________
> Webpush mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/webpush

---

From: Benjamin Bangert <[email-masked]>
Date: Tue, 7 Jun 2016 20:17:34 -0700

> What a user agent does with the message is outside this spec.

For our implementation, we will actually never send more notifications
until all sent ones are ack'd. This means if a message is malformed or
causes a UA error in a UA that actually follows the DOM spec, it will
never get a notification again (except the notification it won't ack).

As such, our UA necessarily cannot and will not follow the DOM spec as
written. Instead we follow the WebPush spec which appears to conflict
with the DOM spec.

Per the WebPush spec, 6.2:
"To ensure that a push message is properly delivered to the user agent
at least once, the user agent MUST acknowledge receipt of the message
by performing a HTTP DELETE on the push message resource. "

The DOM spec in 6.5.3 notes that if the message is improperly
encrypted, the process is halted, and the webpush acknowledgement does
*not take place*.

The relevant portion of the DOM process:
"If the push message could not be decrypted for any reason, discard
the message and terminate this process. "

This makes it sound as if the following steps (including webpush ack)
*must not be run*.

Some clarification around this would be great.

Cheers,
Ben

---

From: Martin Thomson <[email-masked]>
Date: Wed, 8 Jun 2016 14:36:56 +1000

> never get a notification again (except the notification it won't ack).

This is fine, as long as you regard unacknowledged messages that you
thought were delivered as poisonous after a certain amount of time (or
retries, if you do that).  If you follow that advice, then progress
will eventually be made.

I expect that Costin will agree with you, but we've discussed this in
the past.  The problem here is that an acknowledgment from the user
agent doesn't constitute a useful signal.  You have moved the problem
to a second middle-man.  When the user agent acknowledges prior to
processing the message, how will the application know that it was
processed?  Can you guarantee that?  When the browser crashes, your
message is still lost.

The only way for this to be a good signal is to have the
acknowledgment be end-to-end.

(p.s., I don't know if your assertion is true or not.  I don't think
that it matters.  I should know that code, but it's an absolute rats
nest, despite Kit's recent efforts at cleanup.)

---

From: Benjamin Bangert <[email-masked]>
Date: Tue, 7 Jun 2016 22:15:12 -0700

> retries, if you do that).  If you follow that advice, then progress

This recommendation isn't in the WebPush spec. By mandating that the UA
MUST ack every message it's clear that failure to ack a message should
result in redelivery attempts.

If it's intended that a UA does not need to ack every message, the WebPush
spec should be updated to reflect that. I could see a PS reasonably
considering messages dead if other messages were ack'd or some other
command came over the connection such that the server knew that
the client is alive and likely processed it.

Automatically ack'ing a message in this manner for the PS has as many
problems if not more than requiring the UA to ack every message though.
It also introduces a lot of complexity into the PS and may result in very
long message delivery times should a UA get bogged down with many
improperly encrypted messages.

> processed?  Can you guarantee that?  When the browser crashes, your

Why not change the DOM spec to indicate that if a message was
processed and failed for some reason it should still be ack'd?

If the same message consistently crashes the browser, I would expect
the browser to track that fact and avoid the message again in the future.

Clearly we have the choice of guaranteeing that a message will be
processed at-most-once, or at-least-once, since a crash immediately
after processing could stop the ack from making it back. If the desire
is at-most-once, then the UA should ack immediately upon receipt of
the message (or the PS can consider it ack'd if a PING frame is
returned after sending a message, etc.).

The Push DOM spec seems to favor the at-least-once model, in which
case it would be appropriate for the UA to always ack a message even
if it decrypts improperly, or the SW throws an exception, etc.

---

From: Martin Thomson <[email-masked]>
Date: Wed, 8 Jun 2016 17:38:31 +1000

I'm sorry, I'm confused by your message.  I can't decide if you want
at-least-once, or at-most-once.  End-to-end ack, i.e., ack after
successful processing, is in support of at-least-once, which I think
is consistent with other decisions we've made in the overall design.

---

From: Benjamin Bangert <[email-masked]>
Date: Wed, 8 Jun 2016 06:42:59 -0700

I'm in support of at-least-once processing, so the ack would occur last per
the DOM API. The difference would be that the DOM spec should require
ack even if decryption fails or the SW fails for some reason.

---

From: Idel Pivnitskiy <[email-masked]>
Date: Thu, 9 Jun 2016 01:10:10 +0300

Agree with Benjamin,

In current spec if decryption or decoding fails, ack will not be
sent. Consequently, PS will try to resend a message after some delay
without ack and situation will repeat again. Lucky if it will not lead the
crash of an application again and again.

Best regards,
Idel Pivnitskiy

---

From: Martin Thomson <[email-masked]>
Date: Thu, 9 Jun 2016 10:58:56 +1000

> ack even if decryption fails or the SW fails for some reason.

So I get the point about decryption: if it is bad, then that won't
change next time.  But a SW failure makes the application vulnerable
to random chance.  Sure, the SW might be bad, but badness isn't a
terminal condition there in the same way that crypto is.

---

From: Benjamin Bangert <[email-masked]>
Date: Wed, 8 Jun 2016 18:38:54 -0700

> terminal condition there in the same way that crypto is.

Agreed, I think its sensible for a UA to try the message once more. If
a crash or something else bad still occurs, the UA can ack instead of
trying for a third time. Given the UA's manage to remember tabs open
right before a crash, it doesn't seem far-fetched for a UA to count
process attempts for a message-id where a crash occurred afterwards.

Cheers,
Ben

---

From: Martin Thomson <[email-masked]>
Date: Thu, 9 Jun 2016 11:46:45 +1000

> process attempts for a message-id where a crash occurred afterwards.

That I can get behind.  I have opened a PR for the decryption failure.
I will open a second one for the case that the SW rejects multiple
times.  I think that we have a bit of leeway on that one though.

(Note: all of these are for the push API spec.  Do you think that we
need any changes to the protocol spec as a result of all this?)