Subject: [hybi] Clarify the role of closing handshake

From: Takeshi Yoshino <[email-masked]>
Date: Wed, 9 Feb 2011 16:05:13 -0800

Long time has passed since there was active discussion on closing handshake
design. Closing handshake detail has been gradually changed in -01 and -05
adopting suggestions from tickets and posts on the list, and now there is
some inconsistency between sections. I think now it's good time to discuss
again what closing handshake should realize, how it should be done, and what
_cleanly_ means.

== What closing handshake should realize ==
Now it seems closing handshake in -05 is designed to realize two things.
a) peer B assume that no more data is coming from peer A when B receives
closing initiation from A
b) peer A assume that all the data sent out has been successfully received
by peer B when A receives closing acknowledgement from B

Section 1.4 in -05 states only a), but I thought that b) is also closing
handshake's objective. e.g. this old post
http://www.ietf.org/mail-archive/web/hybi/current/msg01526.html by Hixie
says so.

How many people on this list are supportive for having feature-b) realized
by closing handshake? When I was talking with people offlist, some were
doubtful about the usefulness of this feature. It think most apps would
build their own shutdown protocol and doesn't rely on WebSocket closing
handshake.

== How it should be done for each option ==
1) If we need only a), a) can be simply realized by closing frame without
body.

2) If we need both a) and b), we have to distinguish closing initiation and
acknowledgement since it's possible that both sides initiate closing at the
same time.

Some sentences ("A received close message is deemed to be ..." in Section
4.5.1) were added to -01 to ask each peer to check the body of closing frame
to distinguish if it's acknowledgement or not". This was incomplete as
Gabriel pointed out in http://trac.tools.ietf.org/wg/hybi/trac/ticket/34,
but it's now almost addressed in -05. I think we need to make one more tiny
fix on 4.5.1, but then, I think it's perfect.

== What does _cleanly_ means? ==
By the word _cleanly_ all the information about closing handshake is passed
to the WebSocket API.

If we take 1), _cleanly_ means the user agent has received all data from the
server.

If we take 2),... in -05, _cleanly_ has different meaning depending on
whether client initiated close or server initiated close. If client
initiated close, _cleanly_ means the user agent has received all data from
the server and all the data sent to the server has been received by the
server. If server initiated close, _cleanly_ only means the user agent has
received all data from the server. Since we're going to assure b), the user
agent should initiate closure before sending back acknowledgement (we need
some change in 4.5.1). Then, _cleanly_ means the same for both cases.

====

Let's make decision here to clean-up closing handshake stuff in the spec.

1) keep feature-b)
- Change Section 1.4 to mention that closing handshake is designed to
realize feature-b)
- Fix 4.5.1 so that a peer wait until receiving acknowledgement if it has
initiated closing handshake
2) drop feature-b)
- Drop body comparison procedure added in -01
- Avoid using a word "acknowledgement". It's confusing IMO.

---

From: Gabriel Montenegro <[email-masked]>
Date: Thu, 10 Feb 2011 00:21:55 +0000

+1 on Dropping feature B (data draining) and only keeping the simple semantics of feature A as you say below:

a) peer B assume that no more data is coming from peer A when B receives closing initiation from A

Either side has to be ready for the other side going away without warning (a user just yanking the page in the browser). Any value for data draining is suspect and better handled at the application. There may be value in having it as a signal to intermediaries so they can claim state earlier than they might have otherwise (they also have to have timeouts as they cannot rely on the Close message being cleanly sent), but then the simplest form is enough.

My suggestion on Close is to simplify it along these lines:

*         Using simple close semantics (whoever sends it, closes the entire session).

*         No half-close semantics as in TCP

*         Assuming that any data draining must be taken care of by the app, so no need for acking a close.

*         Assuming that the primary purpose of a Close is to inform intermediaries that the session is now terminated.

Proposed text is:

4.5.1.  Close

   The Close message contains an opcode of 0x01 and no body.

   The websocket is considered fully closed when an endpoint has either sent or received a Close message.
   Accordingly, upon sending or receiving a Close message, no more data or control messages can be sent on  the websocket.

Comments?

Gabriel

From: [email-masked] [mailto:[email-masked]] On Behalf Of Takeshi Yoshino
Sent: Wednesday, February 09, 2011 16:05
To: [email-masked]
Subject: [hybi] Clarify the role of closing handshake

Long time has passed since there was active discussion on closing handshake design. Closing handshake detail has been gradually changed in -01 and -05 adopting suggestions from tickets and posts on the list, and now there is some inconsistency between sections. I think now it's good time to discuss again what closing handshake should realize, how it should be done, and what _cleanly_ means.

== What closing handshake should realize ==
Now it seems closing handshake in -05 is designed to realize two things.
a) peer B assume that no more data is coming from peer A when B receives closing initiation from A
b) peer A assume that all the data sent out has been successfully received by peer B when A receives closing acknowledgement from B

Section 1.4 in -05 states only a), but I thought that b) is also closing handshake's objective. e.g. this old post http://www.ietf.org/mail-archive/web/hybi/current/msg01526.html by Hixie says so.

How many people on this list are supportive for having feature-b) realized by closing handshake? When I was talking with people offlist, some were doubtful about the usefulness of this feature. It think most apps would build their own shutdown protocol and doesn't rely on WebSocket closing handshake.

== How it should be done for each option ==
1) If we need only a), a) can be simply realized by closing frame without body.

2) If we need both a) and b), we have to distinguish closing initiation and acknowledgement since it's possible that both sides initiate closing at the same time.

Some sentences ("A received close message is deemed to be ..." in Section 4.5.1) were added to -01 to ask each peer to check the body of closing frame to distinguish if it's acknowledgement or not". This was incomplete as Gabriel pointed out in http://trac.tools.ietf.org/wg/hybi/trac/ticket/34, but it's now almost addressed in -05. I think we need to make one more tiny fix on 4.5.1, but then, I think it's perfect.

== What does _cleanly_ means? ==
By the word _cleanly_ all the information about closing handshake is passed to the WebSocket API.

If we take 1), _cleanly_ means the user agent has received all data from the server.

If we take 2),... in -05, _cleanly_ has different meaning depending on whether client initiated close or server initiated close. If client initiated close, _cleanly_ means the user agent has received all data from the server and all the data sent to the server has been received by the server. If server initiated close, _cleanly_ only means the user agent has received all data from the server. Since we're going to assure b), the user agent should initiate closure before sending back acknowledgement (we need some change in 4.5.1). Then, _cleanly_ means the same for both cases.

====

1) keep feature-b)
- Change Section 1.4 to mention that closing handshake is designed to realize feature-b)
- Fix 4.5.1 so that a peer wait until receiving acknowledgement if it has initiated closing handshake
2) drop feature-b)
- Drop body comparison procedure added in -01
- Avoid using a word "acknowledgement". It's confusing IMO.

---

From: John Tamplin <[email-masked]>
Date: Wed, 9 Feb 2011 19:46:07 -0500

On Wed, Feb 9, 2011 at 7:21 PM, Gabriel Montenegro <
[email-masked]> wrote:

> Either side has to be ready for the other side going away without warning
> (a user just yanking the page in the browser). Any value for data draining
> is suspect and better handled at the application. There may be value in
> having it as a signal to intermediaries so they can claim state earlier than
> they might have otherwise (they also have to have timeouts as they cannot
> rely on the Close message being cleanly sent), but then the simplest form is
> enough.
>
>
>
> ·         Using simple close semantics (whoever sends it, closes the
> entire session).
>
> ·         No half-close semantics as in TCP
>
> ·         Assuming that any data draining must be taken care of by the
> app, so no need for acking a close.
>
> ·         Assuming that the primary purpose of a Close is to inform
> intermediaries that the session is now terminated.
>
>
>
> Proposed text is:
>
>
>
> 4.5.1.  Close
>
>
>
>    Accordingly, upon sending or receiving a Close message, no more data or
> control messages can be sent on  the websocket.
>
>
>
> Comments?
>

I would say it is fully closed when both sent and received a Close message,
or when the underlying channel is closed.

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 10 Feb 2011 12:04:12 +1100

One of the other aims of the closing handshake was to better identify
error condition, so as to prevent a client repeating unacceptable
operations.

For example, if a client sends a frame that is too large for the
server to handle, the server needs to indicate that an error condition
has occurred.  If the connection is closed (orderly or otherwise) ,
then the client might assume that it was an idle shutdown or transient
condition on the server and thus open a new connection and continue to
send over large frames.

Currently -05 says:

7.1.2.  Server-initiated closure
   Certain algorithms require or recommend that the server *abort the
   WebSocket connection* during the opening handshake.  To do so, the
   server must simply close the WebSocket connection.

the problem with this is that for a client such a close of the
websocket connection cannot be distinguished from a
network/intermediary failure.   I think that typically an aborted
connection should not be retried, but a network/intermediary failure
should be - so it would be good to be able to signal to the client the
difference.

Thus I'd like to suggest that the close handshake carry a single byte
of reason for the close.
I think it would be sufficient to define just:

  0x00 Normal close
  0x01 Abnormal close

But I could see an argument for something a little richer:

 0x00 Idle close
 0x01 close
 0x02 abnormal close

but I concede that the danger here is trying to define too many close states

---

From: Gabriel Montenegro <[email-masked]>
Date: Thu, 10 Feb 2011 09:25:50 +0000

I think your simple reason would be enough (either normal or abnormal close for now).

To be clear: you're not arguing against the simplified semantics of considering the websocket closed (no further data or control) upon either sending or receiving a Close message, correct?

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf Of Greg
> Wilkins
> Sent: Wednesday, February 09, 2011 17:04
> To: Takeshi Yoshino
> Cc: [email-masked]
> Subject: Re: [hybi] Clarify the role of closing handshake
> 
> One of the other aims of the closing handshake was to better identify error
> condition, so as to prevent a client repeating unacceptable operations.
> 
> For example, if a client sends a frame that is too large for the server to handle,
> the server needs to indicate that an error condition has occurred.  If the
> connection is closed (orderly or otherwise) , then the client might assume that it
> was an idle shutdown or transient condition on the server and thus open a new
> connection and continue to send over large frames.
> 
> 
> Currently -05 says:
> 
> the problem with this is that for a client such a close of the websocket
> connection cannot be distinguished from a
> connection should not be retried, but a network/intermediary failure should be -
> so it would be good to be able to signal to the client the difference.
> 
> Thus I'd like to suggest that the close handshake carry a single byte of reason for
> the close.
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 10 Feb 2011 20:44:03 +1100

> I think your simple reason would be enough (either normal or abnormal close for now).

cool

> To be clear: you're not arguing against the simplified semantics of considering the websocket closed (no further data or control) upon either sending or receiving a Close message, correct?

I'm not arguing either way.  I can see the benefits of half close and
flush through, but also the complexities, so I'm happy to follow herd
on this one.

cheers

---

From: Takeshi Yoshino <[email-masked]>
Date: Fri, 11 Feb 2011 04:18:06 +0900

Gabriel's idea is even simple. I don't object to that. I see the benefit of
Greg's idea, too.

A while back, Yuta listed error cases can happen during frame processing,
and suggested we define how we handle them. Maybe we would use abnormal
close frame for them.
http://www.ietf.org/mail-archive/web/hybi/current/msg05131.html

I think abnormal close frame should indicate only protocol level error
(frame parsing error, too large message, etc.). Any error inside application
can be exchanged on application level. So we don't have to extend close()
interface.

CloseEvent interface should be changed. _cleanly_ must be re-defined. We
would define three type of close, _normal close_, _abnormal close_,
_underlying channel terminated_, and replace "wasClean" with, say, "reason"
or something. I'm not sure if we should invoke error event, too. I
personally think it's redundant.

Then,
- close() called on WebSocket object -> send normal close frame -> "normal"
close event regardless of whatever happen
- any protocol level error happened on client side and sent abnormal close
frame -> "abnormal" close event
- received normal close frame -> "normal" close event
- received abnormal close frame -> "abnormal" close event
- underlying channel is closed without receiving close frame -> "underlying
channel terminated" close event

I think this modification on CloseEvent doesn't violate the security model
we now have to prevent WebSocket from being abused for port scanner.
Abnormal close is just a new variant of closure information explicitly sent
from the server. Thoughts?

So, by putting them together, like this?

----

4.5.1.  Close

The Close message contains an opcode of 0x01.

The Close message contains a body that is a single byte in length.  This
byte carrys the reason for the close.  For normal close, the body MUST be a
0x00. For abnormal close, the body MUST be a 0x01.

The websocket is considered fully closed when an endpoint has either sent or
received a Close message, or when the underlying channel is closed.

The application MUST NOT send any more data messages after sent or received
a Close message.

7.1.1.  Client-initiated closure

<I'm not sure how much it's useful to have client send normal/abnormal.
Server cannot retry by itself so, it's not the case Greg explained. But
maybe we can just add it as well as server.>

<No change on *abort WebSocket connection* during opening handshake>

Certain algorithms require or recommend that the server *abort2
the WebSocket connection* after WebSocket connection is established.  To do
so, the server must send a Close message with a single byte body 0x01
meaning abnormal closure and close the WebSocket connection.

<We need some verb to replace abort2>

7.2.  Normal closure of connections

To *close the WebSocket connection*, the user agent MUST send a Close
control frame with a single byte body 0x00 meaning normal closure, as
described in Section 4.5.1.  Once an endpoint has sent or received an Close
control frame, that endpoint must close the TCP ...  If the connection was
closed after the client sent or received normal close frame, then it's
called _normal close_. If the connection was closed after the client send or
received abnormal close frame, then it's called _abnormal close_. Otherwise,
it's called _underlying connection terminated_.

The user agent can distinguish protocol failure notified by abnormal close
frame from disconnection caused by network or intermediary to allow the
application to determine if it should retry connection or not.

...

On Thu, Feb 10, 2011 at 18:44, Greg Wilkins <[email-masked]> wrote:

> > To be clear: you're not arguing against the simplified semantics of
> considering the websocket closed (no further data or control) upon either
> sending or receiving a Close message, correct?
>
> error
> should be -

---

From: [email-masked]
Date: Thu, 10 Feb 2011 15:39:45 -0800

Hi,

Joining this thread from another one in reply to Takeshi's message. Let me 
try to through my
thoughts...

> > o Section 4.5.1 - Close handshake 
> > 
> > It is no clear to me what 0x43 and 0x53 are trying to achieve. In 
> > TCP, there is FIN with no 
> > details of why/who is closing for graceful shutdown. 
> 
> Actually, it's not intended to indicate who's closing, but to make 
> sure what the close frame really means, i.e. it's close initiation 
> or close acknowledgement. Using an analogy of TCP, close S from 
> server is FIN, and close S from client is ACK for server's FIN.
> 
> Without this, each peer cannot know
> - the other peer just initiated close
> or
> - the other peer received close frame and acknowledged it
> 
> Imagine both peers send out close initiation at approximately same 
> time. They looks like acknowledgement but are not.
> 
> Once we can perfectly distinguish initiation and acknowledgement as 
> described above, we can assume "If A received close acknowledgement 
> from B, B has received all the data sent from A before close 
successfully".
> 
> If you have any idea about the usefulness of this closing handshake 
> design, please come to the thread "Clarify the role of closing 
> handshake" and speak out. We're discussing it now.

The current -05 as is seems good to me. Now I think it would be good to 
have 1-byte body
0x43 and 0x53, if it is important to know whether all data sent 
successfully reached the peer.
I just do not know how import that is from application's perspective.

I agree, if simultaneous Close occurs, then both ends cannot be sure if 
all the data is received
by the other peer.

Stepping back a bit, if we could assume that client always initiate Close 
in normal operation, 
then Client can tell, on receipt of Close with 0x53 after sending Close 
0x43, that something 
happened at the server. (e.g. cannot retain persistent connection due to 
excessive load, 
or some kind of failover operation at server side).  In such case, client 
should assume that 
not all data may have not reached the server, and take necessary action if 
that is important 
for the client application. As being discussed in this thread, the server 
could send some 
reason code, but I am not so sure if  that helps any, and I'm leaning 
toward more on not 
revealing any details of the situation for security reasons.

At TCP stack level, it think it is a good practice to have client initiate 
TCP-FIN always
(shutdown(socket, SHUT_WR)) after sending Close frame where possible. This 
can 
minimize the number of TCP control block in kernel memory sitting and 
waiting in either 
FIN_WAIT_1/2 or TIME_WAIT state, which could cause server resource 
exhaustion 
unexpectedly. 

After calling shutdown(soc, SHUT_WR), you can still read data from the 
peer to 
receive remaining data and lastly Close frame to close websocket 
_cleanly_.

- Yutaka

Takeshi Yoshino <[email-masked]> 
Sent by: [email-masked]
02/10/2011 11:18 AM

To
Greg Wilkins <[email-masked]>
cc
"[email-masked]" <[email-masked]>, Gabriel Montenegro 
<[email-masked]>
Subject
Re: [hybi] Clarify the role of closing handshake

Gabriel's idea is even simple. I don't object to that. I see the benefit 
of Greg's idea, too.

I think abnormal close frame should indicate only protocol level error 
(frame parsing error, too large message, etc.). Any error inside 
application can be exchanged on application level. So we don't have to 
extend close() interface.

CloseEvent interface should be changed. _cleanly_ must be re-defined. We 
would define three type of close, _normal close_, _abnormal close_, 
_underlying channel terminated_, and replace "wasClean" with, say, 
"reason" or something. I'm not sure if we should invoke error event, too. 
I personally think it's redundant.

Then,
- close() called on WebSocket object -> send normal close frame -> 
"normal" close event regardless of whatever happen
- any protocol level error happened on client side and sent abnormal close 
frame -> "abnormal" close event
- received normal close frame -> "normal" close event
- received abnormal close frame -> "abnormal" close event
- underlying channel is closed without receiving close frame -> 
"underlying channel terminated" close event

I think this modification on CloseEvent doesn't violate the security model 
we now have to prevent WebSocket from being abused for port scanner. 
Abnormal close is just a new variant of closure information explicitly 
sent from the server. Thoughts?

----

4.5.1.  Close

The Close message contains a body that is a single byte in length.  This 
byte carrys the reason for the close.  For normal close, the body MUST be 
a 0x00. For abnormal close, the body MUST be a 0x01.
 
The websocket is considered fully closed when an endpoint has either sent 
or received a Close message, or when the underlying channel is closed.

The application MUST NOT send any more data messages after sent or 
received a Close message.

Certain algorithms require or recommend that the server *abort2 
the WebSocket connection* after WebSocket connection is established.  To 
do so, the server must send a Close message with a single byte body 0x01 
meaning abnormal closure and close the WebSocket connection.

To *close the WebSocket connection*, the user agent MUST send a Close 
control frame with a single byte body 0x00 meaning normal closure, as 
described in Section 4.5.1.  Once an endpoint has sent or received an 
Close control frame, that endpoint must close the TCP ...  If the 
connection was closed after the client sent or received normal close 
frame, then it's called _normal close_. If the connection was closed after 
the client send or received abnormal close frame, then it's called 
_abnormal close_. Otherwise, it's called _underlying connection 
terminated_.

...

cool

cheers

error
>> the problem with this is that for a client such a close of the 
websocket
should be -
>> Thus I'd like to suggest that the close handshake carry a single byte 
of reason for

---

From: Brodie Thiesfield <[email-masked]>
Date: Fri, 11 Feb 2011 10:14:59 +0900

I have been thankful many times for the amount of detail the http error status and message can return to a client. Having both a rich code space as well as a human readable message is invaluable for problem solving a connection problem. This is part of the http protocol, we shouldn't punt error condition reporting to the application level in websockets. 

Without a richer mechanism to return connection errors, debugging failures will turn into potluck of changing parameters and hoping that it works. 

When extensions are added, the sort of error conditions may expand beyond what can be imagined now. Why not just reuse the http error mechanism with both status and optional message.

Regards, 
Brodie

On 11/02/2011, at 4:18, Takeshi Yoshino <[email-masked]> wrote:

> Gabriel's idea is even simple. I don't object to that. I see the benefit of Greg's idea, too.
> 
> A while back, Yuta listed error cases can happen during frame processing, and suggested we define how we handle them. Maybe we would use abnormal close frame for them.
> I think abnormal close frame should indicate only protocol level error (frame parsing error, too large message, etc.). Any error inside application can be exchanged on application level. So we don't have to extend close() interface.
> 
> CloseEvent interface should be changed. _cleanly_ must be re-defined. We would define three type of close, _normal close_, _abnormal close_, _underlying channel terminated_, and replace "wasClean" with, say, "reason" or something. I'm not sure if we should invoke error event, too. I personally think it's redundant.
> 
> Then,
> - close() called on WebSocket object -> send normal close frame -> "normal" close event regardless of whatever happen
> - any protocol level error happened on client side and sent abnormal close frame -> "abnormal" close event
> - underlying channel is closed without receiving close frame -> "underlying channel terminated" close event
> 
> I think this modification on CloseEvent doesn't violate the security model we now have to prevent WebSocket from being abused for port scanner. Abnormal close is just a new variant of closure information explicitly sent from the server. Thoughts?
> 
> The Close message contains a body that is a single byte in length.  This byte carrys the reason for the close.  For normal close, the body MUST be a 0x00. For abnormal close, the body MUST be a 0x01.
>  
> The websocket is considered fully closed when an endpoint has either sent or received a Close message, or when the underlying channel is closed.
> 
> The application MUST NOT send any more data messages after sent or received a Close message.
> 
> <I'm not sure how much it's useful to have client send normal/abnormal. Server cannot retry by itself so, it's not the case Greg explained. But maybe we can just add it as well as server.>
> 
> Certain algorithms require or recommend that the server *abort2 the WebSocket connection* after WebSocket connection is established.  To do so, the server must send a Close message with a single byte body 0x01 meaning abnormal closure and close the WebSocket connection.
> 
> To *close the WebSocket connection*, the user agent MUST send a Close control frame with a single byte body 0x00 meaning normal closure, as described in Section 4.5.1.  Once an endpoint has sent or received an Close control frame, that endpoint must close the TCP ...  If the connection was closed after the client sent or received normal close frame, then it's called _normal close_. If the connection was closed after the client send or received abnormal close frame, then it's called _abnormal close_. Otherwise, it's called _underlying connection terminated_.
> 
> The user agent can distinguish protocol failure notified by abnormal close frame from disconnection caused by network or intermediary to allow the application to determine if it should retry connection or not.
> 
> ...
>

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 11 Feb 2011 12:37:12 +1100

On 11 February 2011 12:14, Brodie Thiesfield <[email-masked]> wrote:
> I have been thankful many times for the amount of detail the http error
> status and message can return to a client. Having both a rich code space as
> well as a human readable message is invaluable for problem solving a
> connection problem. This is part of the http protocol, we shouldn't punt
> error condition reporting to the application level in websockets.
> Without a richer mechanism to return connection errors, debugging failures
> will turn into potluck of changing parameters and hoping that it works.
> When extensions are added, the sort of error conditions may expand beyond
> what can be imagined now. Why not just reuse the http error mechanism with
> both status and optional message.

There is indeed a great deal of goodness in 2xx/3xx for normal, 4xx
for bad client and 5xx for bad server.
If somebody could propose a similar nice error space for WS that would
get broad agreement, then I'd certainly support it.

But I don't want to get distracted with a prolonged discussion about a
detailed error space.  Normal vs Abnormal gives us the major
functional information we need, so I'm cautious about losing agreement
about that in a wider debate.    But then, so far nobody has spoken
out against such a status field.

cheers

---

From: Brodie Thiesfield <[email-masked]>
Date: Fri, 11 Feb 2011 22:59:27 +0900

> out against such a status field.

Agreed. I certainly don't have any interest in discussing what codes
are necessary or not right now. That's why I suggest that we simply
reuse the HTTP status code format of 3 digits(but not the actual
status codes), allow an optional message (single space followed by a
free-form UTF-8 message). For the moment, if only normal or abnormal
exit is required, then only specify those two errors, but at least
allow for a textual description as to what is causing the abnormal
termination. I would suggest reusing the 2xx for normal, 4xx for
client error (or message sender error) and 5xx for server error (or
message receiver) form since they are already familiar. Disallow other
error ranges.

status = [245] [0-9] [0-9]
message = ' ' utf8_character+
close_body = status message?

Normal:
200 normal

Abnormal:
400 bad request
500 internal server error

This would allow servers to at least close connections on a client
that has sent a bad request and give the client an idea of if the
connection was closed due to their fault or something that happened in
the server.

Status codes that I could imagine would be useful as well as a few
codes to cover the list that Yuta mentioned:

4xx
* timeout
* invalid opcode
* invalid encoding
* unexpected
* too long

5xx
* overloaded / service unavailable
* not supported

But as I said, at the very least, the 200/400/500 + optional text message.

Regards,
Brodie

---

From: Salvatore Loreto <[email-masked]>
Date: Fri, 11 Feb 2011 18:32:53 +0100

On 2/11/11 12:39 AM, [email-masked] wrote:
>
> Hi,
>
> Joining this thread from another one in reply to Takeshi's message. 
> Let me try to through my
> thoughts...
>
> The current -05 as is seems good to me. Now I think it would be good 
> to have 1-byte body

Hi Yutaka

People seems agree that this can be handled at application level,
(the fact that you also say that it is difficult to know how important 
that is
from an application's prospective seem that you agree on that, but then
the rest of your message confuse me, can you clarify what you would like?)

People seems agree, withing this thread, that at protocol level it is 
enough to go for the simplest scenario:

- Peer B assumes that no more data is coming from peer A when B receives 
closing
initiation from A.

please read the text suggested from Takeshi in
http://www.ietf.org/mail-archive/web/hybi/current/msg06285.html
and check if it works for you

cheers
/Sal

-- 
Salvatore Loreto
www.sloreto.com

---

From: Gabriel Montenegro <[email-masked]>
Date: Fri, 11 Feb 2011 20:51:41 +0000

+1 on Takeshi's text

People seems agree, withing this thread, that at protocol level it is enough to go for the simplest scenario:

- Peer B assumes that no more data is coming from peer A when B receives closing
initiation from A.

---

From: [email-masked]
Date: Fri, 11 Feb 2011 12:54:13 -0800

Hi,

> - Peer B assumes that no more data is coming from peer A when B 

I agree - much simpler

As a side note, the other option (b) requires one extra state to wait 
for an acknowledgement upon sending Close frame. I was wondering who 
would be responsible for managing lifetime of the extra state, and 
yet it would be complicated.

Here is my comments to Takeshi's proposal in: 
http://www.ietf.org/mail-archive/web/hybi/current/msg06285.html 

> The Close message contains a body that is a single byte in length. 
>  This byte carrys the reason for the close.  For normal close, the 
> body MUST be a 0x00. For abnormal close, the body MUST be a 0x01.
>  
> The websocket is considered fully closed when an endpoint has either
> sent or received a Close message, or when the underlying channel is 
closed.
> received a Close message.

Looks good.

> <I'm not sure how much it's useful to have client send 
> normal/abnormal. Server cannot retry by itself so, it's not the case
> Greg explained. But maybe we can just add it as well as server.>

I do not see the usefulness of the normal/abnormal at app level either.
But it may be helpful for counting such events to monitor for admin 
purposes or for trouble shooting.

> the WebSocket connection* after WebSocket connection is established.
>  To do so, the server must send a Close message with a single byte 
> body 0x01 meaning abnormal closure and close the WebSocket connection.
> 

I am ok this to be as is (besides 'abort2')

> To *close the WebSocket connection*, the user agent MUST send 
> a Close control frame with a single byte body 0x00 meaning normal 
> closure, as described in Section 4.5.1.  Once an endpoint has sent 
> or received an Close control frame, that endpoint must close the TCP

As long as we cannot rule out the case where there may be incoming
data in the TCP buffer at the time of Close frame send, the endpoint
should not close socket right away, otherwise TCP-RST is sent to the 
peer, and the Close frame that has just sent may not reach the 
remote app. So, WebSocket layer needs to take care of this cleanup
sequence:

[App]          [WS-layer]     [TCP socket]
  |    close()     |               |<--- data
  +--------------->|  send(Close)  |<--- data
  |<- - - - - - - -|-------------->|----> FIN
  |                |  * recv()     |<--- data
  |                |till EOS(0 rtn)|
  |                |-------------->|
  |                |    close(|    |
  |                |-------------->x
  |                |

This is an implementation issue, but worth mentioning.

> ...  If the connection was closed after the client sent or received 
> normal close frame, then it's called _normal close_. If the 
> connection was closed after the client send or received abnormal 
> close frame, then it's called _abnormal close_. Otherwise, it's 
> called _underlying connection terminated_.
> 
> The user agent can distinguish protocol failure notified by abnormal
> close frame from disconnection caused by network or intermediary to 
> allow the application to determine if it should retry connection or not.

Sounds good.

Best.
--
Yutaka Takeda - US R&D Sony Computer Entertainment, Inc.
Office: 650 655 7484   Fax: 650 655 8060

that is
> People seems agree, withing this thread, that at protocol level it 
> is enough to go for the simplest scenario:
>

---

From: [email-masked]
Date: Fri, 11 Feb 2011 13:15:01 -0800

Let me correct some typo in the diagram:

[App]          [WS-layer]     [TCP socket] 
  |    close()     |               |
  +--------------->|  send(Close)  |<--- data 
  |<- - - - - - - -|-------------->|
  |                |  shutdown(WR) |<--- data 
  |                |-------------->| ----> FIN 
  |                |  * recv()     |<--- data 
  |                |till EOS(0 rtn)| 
  |                |-------------->| 
  |                |    close()    | <--- FIN 
  |                |-------------->x 
  |                |               : 

# It's not so simpler after all, is it? :)

This is what it takes to send 'data'(in this case 'Close frame'  to peer 
right before
closing TCP connection.

If this is too complicated, then don't bother sending 'Close' but just 
close TCP socket,
which would be the simplest. My preference is to do above cleanup 
properly.

Best.

closed.

> > (the fact that you also say that it is difficult to know how 
> important that is

---

From: Takeshi Yoshino <[email-masked]>
Date: Fri, 11 Feb 2011 16:17:44 -0800

Hi Yutaka,

Thank you for joining the discussion.

Good point. I know that close(2) with incoming data remaining unread in
kernel causes RST for example on Linux. It looks like this is very platform
dependent.

Let me confirm your claim. Here, you mean that RST coming after PSH(Close
frame octets) may cause trouble the receiver side in recv-ing Close frame
octets? In a bit different context but I see that Jamie is also saying so
in http://www.ietf.org/mail-archive/web/hybi/current/msg01044.html. On what
platform this really occurs for example? Just curious. Linux socket allows
us to recv data PSH-ed before RST, then ECONNRESET is returned, so I missed
this point.

If we still take the way to drop Close reply,
- Just as a hint for intermediaries to know the session is abandoned earlier
than transport layer phenomenon (as Gabriel first suggested), it's still
worth try to send out Close and let intermediaries see it, I think. We don't
have to make it sure that it's seen by intermediaries or delivered to the
other peer.
- If we decide to let a Close frame carry error code (as Greg and Brodie
suggest), yes, it may be problematic that Close frames are dropped even
though there's no network/intermediate problem.

Let's go through again what each case means,
- received abnormal Close frame means there was any protocol level problem
- received normal Close frame means the other peer is satisfied. this never
means data is delivered
- didn't receive Close means (?)
-- because of RST issue
-- because of network issue

We have to give (?) some semantics that's not confusing.
- (?) := "there was network layer error" : this statement is bad, confusing.
application that frequently exchanges data may suffer RST issue, and retry
though it's actually caused by their own traffic.
- (?) := "there was transport layer error" : still not so clear
- (?) := ... any suggestion?

On Fri, Feb 11, 2011 at 13:15, <[email-masked]> wrote:

> which would be the simplest. My preference is to do above cleanup properly.
>
>
IIRC, there was discussion in designing -00 closing handshake that we should
avoid underlying transport layer's semantics in realizing WebSocket layer
event. To follow this philosophy, we could replace the last FIN with Close
frame. i.e. we again ask both sides send a Close frame so that both sides
can safely invoke close(2) after seeing Close frame.

...snip

> >   |<- - - - - - - -|-------------->|----> FIN

...snip

---

From: Takeshi Yoshino <[email-masked]>
Date: Fri, 11 Feb 2011 17:25:27 -0800

> We have to give (?) some semantics that's not confusing.

s/semantics/explanation/

> IIRC, there was discussion in designing -00 closing handshake that we
> should avoid underlying transport layer's semantics in realizing WebSocket
> layer event.
>

Citing Hixie's post
http://www.ietf.org/mail-archive/web/hybi/current/msg01526.html

... -- people cited numerous examples of cases where we can't rely on
TCP semantics in practice -- ...

> To follow this philosophy, we could replace the last FIN with Close frame.
> i.e. we again ask both sides send a Close frame so that both sides can
> safely invoke close(2) after seeing Close frame.
>
>
Note that this is the same as "2) drop feature-b)" in my first post in this
thread
- a bit more complicated than what Gabriel proposed and I've cleaned up into
text
- intermediaries have to keep the connection until it sees Close frame on
both direction
- a peer have to wait for reply just to deal with this RST hazard even
though it's not interested in the other peer any more

---

From: Takeshi Yoshino <[email-masked]>
Date: Mon, 14 Feb 2011 11:32:32 -0800

I'd like to summarize proposals again. It seems there's consensus on
dropping acknowledgement feature, so I list only the others.

I prefer [B].

[Proposal A-1]
Role of Close frame
- Help intermediaries know the session is no longer used
- Pass status code to the other peer

Algorithm
- To initiate close, a peer MUST send Close frame, and then the peer MUST
-- close the underlying transport channel ... (*)
- Once a peer received a Close frame, the peer MUST close the underlying
transport channel
- A peer MUST NOT send any more data (including control) after sending or
receiving a Close frame

Pros
- There's no wait state needs to be handled after a peer decided to abandon
the WebSocket

Cons
- When a peer call close(2) with some data left not recv-ed, the peer's TCP
stack may send out RST. This can impede the other peer from receiving Close
frame or even some data before a Close frame

[Proposal A-2]
Replace (*) in A-2 with this
-- wait until the underlying transport channel is closed (by recv until EoS,
wait for close event, etc.) with some timeout

Pros
- There's a wait state needs to be handled after a peer decided to abandon
the WebSocket

Cons
- No more data is coming after Close frame, and therefore a peer can call
close(2) on its TCP socket safely
- The algorithm depends on the underlying transport channel's EoS signal

[Proposal B]
Role of Close frame
- Help intermediaries know the session is no longer used
- Pass status code to the other peer
- Let each peer call close(2) on its TCP socket safely

Algorithm
- To initiate close, send a Close frame
- Once received a Close frame
-- (already sent a Close frame) close the underlying transport channel
-- (otherwise) send a Close frame, and then close the underlying transport
channel
- A peer MUST NOT send any more data (including control) after sending a
Close frame

Reception of a Close frame means
- All data the other peer sent has arrived

Reception of a Close frame DOES NOT mean
- All data has been delivered to the other peer

Pros
- There's a wait state needs to be handled after a peer decided to abandon
the WebSocket

Cons
- No more data is coming after a Close frame, and therefore a peer can call
close(2) on its TCP socket safely

---

From: Takeshi Yoshino <[email-masked]>
Date: Mon, 14 Feb 2011 11:49:24 -0800

> message receiver) form since they are already familiar. Disallow other

+1 for using these terms, message sender error and message receiver error

> But as I said, at the very least, the 200/400/500 + optional text message.

Sounds not bad.

This must be aligned with what discussed on another thread about opening
handshake status code. Having very similar code for two purposes can be
confusing.

---

From: Gabriel Montenegro <[email-masked]>
Date: Mon, 14 Feb 2011 20:34:01 +0000

In A-2 and B, it seems you reversed the Pros and Cons.

I'm not clear on the algorithm for B. Could you formulate in terms of peers A and B and clarify which side is doing what?

At any rate, the cons of adding a wait state and additional complexity in the protocol is why I prefer the simplicity of A.

Most of the time, there won't be a gracious Close, as users will kill the browser window, exit out of the tab, etc. So I fear we're complicating the protocol for dubious benefits. We have to deal with sudden termination anyway.  At any rate, even if the RST prevents the other peer from receiving the WS_Close, the intermediaries will see it.

This is a case of added complexity for very little benefit.

From: [email-masked] [mailto:[email-masked]] On Behalf Of Takeshi Yoshino
Sent: Monday, February 14, 2011 11:33
To: [email-masked]
Subject: Re: [hybi] Clarify the role of closing handshake

I'd like to summarize proposals again. It seems there's consensus on dropping acknowledgement feature, so I list only the others.

I prefer [B].

[Proposal A-1]
Role of Close frame

Algorithm
- To initiate close, a peer MUST send Close frame, and then the peer MUST
-- close the underlying transport channel ... (*)
- Once a peer received a Close frame, the peer MUST close the underlying transport channel
- A peer MUST NOT send any more data (including control) after sending or receiving a Close frame

Pros
- There's no wait state needs to be handled after a peer decided to abandon the WebSocket

Cons
- When a peer call close(2) with some data left not recv-ed, the peer's TCP stack may send out RST. This can impede the other peer from receiving Close frame or even some data before a Close frame

[Proposal A-2]
Replace (*) in A-2 with this
-- wait until the underlying transport channel is closed (by recv until EoS, wait for close event, etc.) with some timeout

Pros
- There's a wait state needs to be handled after a peer decided to abandon the WebSocket

Cons
- No more data is coming after Close frame, and therefore a peer can call close(2) on its TCP socket safely
- The algorithm depends on the underlying transport channel's EoS signal

[Proposal B]
Role of Close frame

Algorithm
- To initiate close, send a Close frame
- Once received a Close frame
-- (already sent a Close frame) close the underlying transport channel
-- (otherwise) send a Close frame, and then close the underlying transport channel
- A peer MUST NOT send any more data (including control) after sending a Close frame

Pros
- There's a wait state needs to be handled after a peer decided to abandon the WebSocket

Cons
- No more data is coming after a Close frame, and therefore a peer can call close(2) on its TCP socket safely

---

From: Andy Green <[email-masked]>
Date: Mon, 14 Feb 2011 20:37:42 +0000

> handshake status code. Having very similar code for two purposes can be

Well I don't mind what is decided in either case, but to be clear in the 
opening handshake case it's in http protocol and using http conventions, 
even the server response is valid http.  So it uses http status concept.

But in the close case all that is long gone and it's websocket protocol 
which is totally different from http conventions.  So it seems it would 
be OK if it uses a different status concept if it wants to use any 
status concept at all at websocket close time.

-Andy

---

From: Takeshi Yoshino <[email-masked]>
Date: Mon, 14 Feb 2011 15:25:49 -0800

> In A-2 and B, it seems you reversed the Pros and Cons.

Oops. Yes, it's reversed...

> I’m not clear on the algorithm for B. Could you formulate in terms of peers
> A and B and clarify which side is doing what?
>

Here's pseudo code for [B].

private closeWriteChannel() {
  socket.send(CLOSE_FRAME);
  writeChannelClosed = true;
}

public initiateClose() {
  closeWriteChannel();
}

public onReceivedCloseFrame() {
  if (!writeChannelClosed) {
    closeWriteChannel();
  }
  socket.close();
}

Here's what happens on each peer.

Normal case:

1. Peer A initiates close by sending a Close frame to peer B
2. Peer B receives a Close frame
3. Peer B sends a Close frame to peer A
4. Peer B closes the underlying transport channel
5. Peer A receives a Close frame
6. Peer A closes the underlying transport channel

In case both side initiate close at approximately same time:

1.
Peer A initiates close by sending a Close frame to peer B
Peer B initiates close by sending a Close frame to peer A
2.
Peer A receives a Close frame
Peer B receives a Close frame
3.
Peer A closes the underlying transport channel
Peer B closes the underlying transport channel

> At any rate, the cons of adding a wait state and additional complexity in
> the protocol is why I prefer the simplicity of A.
>
>
>
> Most of the time, there won’t be a gracious Close, as users will kill the
> browser window, exit out of the tab, etc. So I fear we’re complicating the
> protocol for dubious benefits. We have to deal with sudden termination
> anyway.  At any rate, even if the RST prevents the other peer from receiving
> the WS_Close, the intermediaries will see it.
>

Yes, as far as intermediaries are built to deal with such RST.

> This is a case of added complexity for very little benefit.

I'm not so eager to adopt B. Hmm, ok, how about putting only A-1 as required
spec, and some note for implementor explaining the RST issue and A-2
(Yutaka's idea) as optional solution?

Takeshi

---

From: [email-masked]
Date: Mon, 14 Feb 2011 16:14:35 -0800

Hi Takeshi-san,

My comments inline..

Takeshi Yoshino <[email-masked]> wrote on 02/11/2011 04:17:44 PM:

> Good point. I know that close(2) with incoming data remaining unread
> in kernel causes RST for example on Linux. It looks like this is 
> very platform dependent.

Yes, that may be platform dependent. At least, my linux (Ubuntu 9.04)
and my Windows XP SP3 send RST on close() when there's data in the receive
buffer.

> Let me confirm your claim. Here, you mean that RST coming after 
> PSH(Close frame octets) may cause trouble the receiver side in recv-
> ing Close frame octets?

Yes, but not limited to it. recv() may allow receiver to read data reached 

before RST(on Linux), but any send() after RST will fail with ECONRESET 
for sure. 
On this send error, typical implementation may close socket without 
bothering 
to read data in the receive buffer.

> In a bit different context but I see that 
> Jamie is also saying so in http://www.ietf.org/mail-
> archive/web/hybi/current/msg01044.html. On what platform this really
> occurs for example? Just curious. Linux socket allows us to recv 
> data PSH-ed before RST, then ECONNRESET is returned, so I missed this 
point.

Yes, my linux, too it lets receiver to read data received before RST.
My windows, though, does not seem to let receiver to read the data and 
recv()
returned 'ECONNRESET' right away.

# If we need some experiment, I can help.

> - Just as a hint for intermediaries to know the session is abandoned
> earlier than transport layer phenomenon (as Gabriel first 
> suggested), it's still worth try to send out Close and let 
> intermediaries see it, I think. We don't have to make it sure that 
> it's seen by intermediaries or delivered to the other peer.

# I am still not sure why 'intermediaries' need to see it. I will look 
into Gabriels suggestion.

> - If we decide to let a Close frame carry error code (as Greg and 
> Brodie suggest), yes, it may be problematic that Close frames are 
> dropped even though there's no network/intermediate problem.

Right.

> IIRC, there was discussion in designing -00 closing handshake that 
> we should avoid underlying transport layer's semantics in realizing 
> WebSocket layer event. To follow this philosophy, we could replace 
> the last FIN with Close frame. i.e. we again ask both sides send a 
> Close frame so that both sides can safely invoke close(2) after 
> seeing Close frame.

In browser usage, can we actually wait for Close frame from the peer
after sending Close frame (=app already closed.) ?
When user jumps to another page, or close browser, is WS-layer able
to wait for Close frame to begin with? It just occurred to me...
(I have no knowledge in browser design/policy.)

Best.
- Yutaka

---

From: [email-masked]
Date: Mon, 14 Feb 2011 17:21:42 -0800

Hi Gabriel,

> Most of the time, there won?t be a gracious Close, as users will 
> kill the browser window, exit out of the tab, etc. So I fear we?re 
> complicating the protocol for dubious benefits. We have to deal with
> sudden termination anyway.  At any rate, even if the RST prevents 
> the other peer from receiving the WS_Close, the intermediaries will see 
it. 

I was wondering about it.

> This is a case of added complexity for very little benefit.

Say, a client is trying to send an application data (for example, 
'presence' update) before closing 
WebSocket. The application data may not reach the server application 
either in some 
condition. It is not just 'Close frame' that may not reach.

If we cannot handle 'closing state' in the case where user kills the 
browser window, then the
consequence would be the loss of *application data*, which may not be 
trivial...

Any thoughts?

[email-masked] wrote on 02/14/2011 12:34:01 PM:

> I?m not clear on the algorithm for B. Could you formulate in terms 
> of peers A and B and clarify which side is doing what?
> 
> At any rate, the cons of adding a wait state and additional 
> complexity in the protocol is why I prefer the simplicity of A.
> 
> Most of the time, there won?t be a gracious Close, as users will 
> kill the browser window, exit out of the tab, etc. So I fear we?re 
> complicating the protocol for dubious benefits. We have to deal with
> sudden termination anyway.  At any rate, even if the RST prevents 
> the other peer from receiving the WS_Close, the intermediaries will see 
it. 
> - When a peer call close(2) with some data left not recv-ed, the 
> peer's TCP stack may send out RST. This can impede the other peer 
> from receiving Close frame or even some data before a Close frame
> 
> [Proposal A-2]
> -- wait until the underlying transport channel is closed (by recv 
> until EoS, wait for close event, etc.) with some timeout
> 
> Pros
> - No more data is coming after a Close frame, and therefore a peer 
> can call close(2) on its TCP socket safely

---

From: Gabriel Montenegro <[email-masked]>
Date: Tue, 15 Feb 2011 01:31:50 +0000

Not sure why the presence update would not have happened beforehand. At any rate, I'm sure there's apps where that last bit of data matters. But there's also apps in which that last bit of data doesn't matter at all. If an app really cares, it should handle its data draining itself, and only issue the WS_Close() afterwards.

From: [email-masked] [mailto:[email-masked]]
Sent: 14 February, 2011 17:22
To: Gabriel Montenegro
Cc: [email-masked]; [email-masked]; Takeshi Yoshino
Subject: Re: [hybi] Clarify the role of closing handshake

Hi Gabriel,

> Most of the time, there won't be a gracious Close, as users will
> kill the browser window, exit out of the tab, etc. So I fear we're
> the other peer from receiving the WS_Close, the intermediaries will see it.

> This is a case of added complexity for very little benefit.

Say, a client is trying to send an application data (for example, 'presence' update) before closing
WebSocket. The application data may not reach the server application either in some
condition. It is not just 'Close frame' that may not reach.

If we cannot handle 'closing state' in the case where user kills the browser window, then the
consequence would be the loss of *application data*, which may not be trivial...

Any thoughts?

[email-masked]<mailto:[email-masked]> wrote on 02/14/2011 12:34:01 PM:

> I'm not clear on the algorithm for B. Could you formulate in terms
> Most of the time, there won't be a gracious Close, as users will
> kill the browser window, exit out of the tab, etc. So I fear we're
> the other peer from receiving the WS_Close, the intermediaries will see it.
>
> From: [email-masked]<mailto:[email-masked]> [mailto:[email-masked]]<mailto:[mailto:[email-masked]]> On Behalf Of
> Takeshi Yoshino
> To: [email-masked]<mailto:[email-masked]>
> [email-masked]<mailto:[email-masked]>

---

From: [email-masked]
Date: Tue, 15 Feb 2011 12:25:06 -0800

> If an app really cares, it should handle its data 
> draining itself, and only issue the WS_Close() afterwards. 

So, now the question here is WHO should be responsible for the 'last-bit 
draining'.

If application wants to send a data to a server when browser is closing 
(triggered by user),
for example, is there a way to be sure that the server app received it?

I have embarrassingly limited knowledge of JavaScript but from my 
understanding,
you can catch such event by using

   window.onbeforeunload = function()
   {   return do_something() }

With XmlHttpRequest, you can send data *synchrnously" to be sure that the 
data has
reached the server. But WebSocket, there's no way to block send() 
operation (there's
no build-in response to websocket). What could be the possible workaround 
to this case?
(Brwoser/JS/WSAPI expert should chime in here...)

I personally think that WS-layer should be responsible for the last-bit 
draining rather than
pushing the responsibility to the application. WebSocket being 
"bidirectional" raises 
this issue we did not see in request/response based HTTP. With the same 
reason why
TCP has rather complicated graceful shutdown mechanism, WebSocket should 
also
take care of this issue, IMO.

Best.

- Yutaka

[email-masked] wrote on 02/14/2011 05:31:50 PM:

> Not sure why the presence update would not have happened beforehand.
> At any rate, I?m sure there?s apps where that last bit of data 
> matters. But there?s also apps in which that last bit of data doesn?
> t matter at all. If an app really cares, it should handle its data 
> draining itself, and only issue the WS_Close() afterwards. 
>  
> > From: [email-masked] [mailto:[email-masked]] On Behalf 
Of

---

From: John Tamplin <[email-masked]>
Date: Tue, 15 Feb 2011 15:29:02 -0500

>    {   return do_something() }
I don't know how reliable that is, but certainly the browser could crash,
the user could close the browser, the machine could be suspended, the
network connection may be lost, etc.  There are any number of things that
would prevent the last bit of application data from getting to the server,
and the client/server has to be able to deal with that already.

---

From: Brian <[email-masked]>
Date: Tue, 15 Feb 2011 12:30:54 -0800

This kind of practice is a really bad design.  You should *always*
build your web application knowing that any client could just drop off
the face of the planet at any moment.  Never, ever, rely on a
beforeunload type event to send some final data to the server or save
state, *especially* with XHR synchronous mode, as that creates a slow
response time for the user to leave the page.  If you need to sync
state to the server, that should be done continuously throughout the
user's time on the page.

Such things should always, categorically, be handled in some other
fashion.  If you need, with websocket, to detect that the user's gone
away (such as for an IM system to show that they're offline), you can
do that on the server when you detect the connection is closed.  If
you're using xhr-polling or similar, a reasonably short timeout on the
server during which the user doesn't reconnect for more data should
suffice as a suitable "user has gone away" event.

Brian

On Tue, Feb 15, 2011 at 12:25 PM,  <[email-masked]> wrote:
> reached the server. But WebSocket, there's no way to block send() operation
> (there's
> no build-in response to websocket). What could be the possible workaround to
> this case?
>> At any rate, I’m sure there’s apps where that last bit of data
>> matters. But there’s also apps in which that last bit of data doesn’
>> > Most of the time, there won’t be a gracious Close, as users will
>> > kill the browser window, exit out of the tab, etc. So I fear we’re
>> > I’m not clear on the algorithm for B. Could you formulate in terms
>> > Most of the time, there won’t be a gracious Close, as users will
>> > kill the browser window, exit out of the tab, etc. So I fear we’re

---

From: Peter Saint-Andre <[email-masked]>
Date: Tue, 15 Feb 2011 13:33:28 -0700

On 2/15/11 1:30 PM, Brian wrote:

> If you need, with websocket, to detect that the user's gone

Agreed. And this is what we do in IM systems like XMPP (whether using
the TCP binding or BOSH).

Peter

-- 
Peter Saint-Andre
https://stpeter.im/

---

From: [email-masked]
Date: Tue, 15 Feb 2011 13:45:22 -0800

Okay, I admit my example was bad.

Just to be clear, even with this code:

      websocket.send("a-message-needs-to-reach-server")
      websocket.close()

>From your opinions, programmers should not expect that the message always 
reach the server. (granted)

Now, here's another question for you.

If onclose() callback is made on the websocket, would it be helpful if 
that callback (with wasClean=true) guarantees
that the message has been delivered to the server?

# trying to figure out whether graceful shutdown at least during 'closing' 
state would ever be helpful.

Thanks,
- Yutaka

[email-masked] wrote on 02/15/2011 12:33:28 PM:

> [attachment "smime.p7s" deleted by Yutaka Takeda/R&D/SCEA]

---

From: Ian Fette (イアンフェッティ) <[email-masked]>
Date: Tue, 15 Feb 2011 14:27:58 -0800

On Tue, Feb 15, 2011 at 1:45 PM, <[email-masked]> wrote:

> If onclose() callback is made on the websocket, would it be helpful if that
> callback (with wasClean=true) guarantees
I am not sure how many people would use it, but I think it would be
straightforward and cheap to provide that information so I wouldn't have any
problem with it.

I am trying to get out a -06 that resolves some of the CLOSE issues, but
currently I'm getting caught up by a few other things at work today.

What I'm currently looking at is this: (comments welcome)

         <t>The Close message contains an opcode of 0x01.</t>
          <t>The Close message contains no body (the body has zero
length).</t>
          <t>The application MUST NOT send any more data messages after
sending
          a close message.</t>
          <t>If an endpoint receives a Close message and that endpoint did
not
          previously send a Close message, the endpoint MUST send a Close
          message in response. It SHOULD do so as soon as is practical.
          </t>
          <t>After both sending and receiving a close message, an endpoint
          considers the websocket connection closed, and
          SHOULD close the underlying TCP connection.</t>
          <t>If a client and server both send a Close message at the same
time,
          both endpoints will have sent and received a Close message and
should
          consider the websocket connection closed and close the underlying
          TCP connection.</t>

---

From: Takeshi Yoshino <[email-masked]>
Date: Tue, 15 Feb 2011 14:45:36 -0800

> reach the server. (granted)
Yes, this point should be noted in the spec, or developers may
misunderstand.

> that the message has been delivered to the server?
Just to be sure, again I'd like to note that ... the complex algorithm in
-05 realizes this (wasClean=true iff received Close frame with "C"), but any
of the proposal A-1, A-2, B I wrote don't. What A-2 and B can do is just
avoiding RST hazard case.

> state would ever be helpful.
I personally think since an application can have its own ack to take care of
this, we don't have to have this feature as mandatory in WebSocket.

---

From: Justin Lee <[email-masked]>
Date: Tue, 15 Feb 2011 17:49:06 -0500

> Yes, this point should be noted in the spec, or developers may

In the grizzly version, I actually just queue up the close frame behind the
others.  Is this not what should happen?  Should the close frame jump to the
front of the line?

> I personally think since an application can have its own ack to take care
> of this, we don't have to have this feature as mandatory in WebSocket.
>
>
>> Thanks,
>> - Yutaka
>>
>>

-- 
You can find me on the net at:
http://antwerkz.com
http://www.linkedin.com/in/justinlee
http://www.twitter.com/evanchooly

---

From: Takeshi Yoshino <[email-masked]>
Date: Tue, 15 Feb 2011 15:53:16 -0800

On Tue, Feb 15, 2011 at 14:49, Justin Lee <[email-masked]> wrote:

>> On Tue, Feb 15, 2011 at 13:45, <[email-masked]>wrote:
>>
>>>

At least I can say that is not incorrect behavior. Whether "Send something"
in *start the WebSocket closing handshake* algorithm should break in or just
queue behind the others is not specified in the spec, I think. IMO, we
should queue Close frame behind the others. If close() breaks in, preceding
send()s are cancelled. That's bad programming model though I can imagine
some implementation might have urgent_close() or something that breaks in if
they need. FYI, we queue a Close frame behind the others in pywebsocket,
too.

Here what we're talking about is how to let the client know if
"a-message-needs-to-reach-server" is received by the other peer or not by
using closing handshake. Even "a-message-needs-to-reach-server" is queued
before a Close frame, it's possible that it cannot make it to the other peer
for some network problem, etc.

---

From: [email-masked]
Date: Tue, 15 Feb 2011 16:04:47 -0800

Ian Fette (イアンフェッティ) <[email-masked]> wrote on 02/15/2011 
02:27:58 PM:

>           <t>The application MUST NOT send any more data messages 
> after sending
>           a close message.</t>
>           <t>If an endpoint receives a Close message and that endpoint 
did not
>           <t>If a client and server both send a Close message at thesame 
time,
>           both endpoints will have sent and received a Close messageand 
should
>           consider the websocket connection closed and close the 
underlying

I would replace corresponding texts with something along the line of the 
following for more completeness:

(1) The endpoint SHOULD close write channel of the TCP connection 
    immediately after Close message is sent. (e.g. shutdown(SHUT_WR))

(2) After both sending and receiving a Close message, both endpoints
    SHOULD wait for EoS(End of Stream; i.e. recv() returning 0) before
    closing TCP socket and discard any data received after the Close
    message.

(3) After both sending and receiving a Close message and the endpoint
    has detected EoS, then the WebSocket connection is said to have been
    closed _cleanly_.

Justification:
- (1) is to ensure that no more data will be written to the 
  underlying TCP socket after the Close message, and to indicate
  that sender has reached the EoS at TCP level.
- (2) is to prevent the endpoint from generating spurious RST
  due to a bug at the remote endpoint injecting data after Close frame.
- Presence of Close frame helps intermediaries to detect normal closure
  of WebSocket connection.

Best.
- Yutaka

---

From: Brodie Thiesfield <[email-masked]>
Date: Wed, 16 Feb 2011 09:06:50 +0900

>           consider the websocket connection closed and close the underlying

I would like to see support in the close message for a status
code/reason to show the reason for an abnormal close. The goal is
purely to provide useful information for interop troubleshooting.

At the moment the spec has a number of cases where the connection is
just dropped with no information provided to the peer as to why.
Although from the normal operation of the server this may be optimal,
it is going to make integration testing hell. There needs to be some
way to find out why the remote server is dropping the connection.

I propose that the close message contain a status code and an optional
message. Further, I propose that the peer that following a successful
handshake, the peer that is about to abort the connection SHOULD send
a close message with a valid status code and optionally a more
detailed human readable message. This is valid for both client and
server aborts (i.e. the client is aborting because of an invalid
opcode/incorrectly formatted server message).

An example of the text that I am suggesting, modifying the relevant
bits of what you supplied.

----
The Close message contains an opcode of 0x01.The Close message
contains a body made up of a status code and an optional
human-readable message following the format:

  status = [123] [0-9] [0-9]
  msg    = SP CHAR+
  close  = status msg

The status code ranges are 1xx normal, 2xx message sender error, 3xx
message receiver error.

The application MUST NOT send any more data messages after sending a
close message.
----

If a reply Close message is required as per Ian's text, then I would
modify it as:
----
If an endpoint receives a Close message and that endpoint did not
previously send a Close message, the endpoint MUST send a Close
message with a 100 status (normal close) in response. It SHOULD do so
as soon as is practical.
----

The text on aborts would be changed to note that an abort is actually
a Close with abnormal status + close of transport. If a close message
requires a close reply then the aborting peer would need to wait
around to receive that message (or at least drain the socket to avoid
TCP problems).

Suggested status codes (trying to not get too detailed):

  1xx  Normal close range
    100  Normal close

  2xx  Message sender error range
    200  Message sender general error
    201  Invalid opcode
    202  Invalid framing (e.g. RSV bits used but not negotiated,
fragmented control msg)
    203  Invalid encoding (e.g. invalid UTF-8)

  3xx  Message receiver error range
    300  Message receiver internal error
    301  Overloaded / service unavailable
    302  Message too long (i.e. longer than this server/intermediatary supports)

Regards,
Brodie

---

From: [email-masked]
Date: Tue, 15 Feb 2011 16:10:29 -0800

Typo correction: The "SHOULD" in my text need to be "MUST" because both 
endpoints 
communicate using EoS in the proposed close handshake:

(1) The endpoint MUST close write channel of the TCP connection 
    immediately after Close message is sent. (e.g. shutdown(SHUT_WR)) 

(2) After both sending and receiving a Close message, both endpoints 
    MUST wait for EoS(End of Stream; i.e. recv() returning 0) before 
    closing TCP socket and discard any data received after the Close 
    message. 

Yutaka Takeda/R&D/SCEA@Playstation 
Sent by: [email-masked]
02/15/2011 04:05 PM

To
[email-masked]
cc
[email-masked]
Subject

did not 
time, 
should 

Justification: 

Best. 
- Yutaka _______________________________________________
hybi mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/hybi

---

From: Takeshi Yoshino <[email-masked]>
Date: Tue, 15 Feb 2011 16:21:44 -0800

In case you missed this part of my post citing Ian's thought.

<http://www.ietf.org/mail-archive/web/hybi/current/msg01526.html>
>
> I think the net result is that ideally .close() should map to sending a
> FIN, aka using shutdown(SHUT_WR). Unfortunately this is not always
> possible -- people cited numerous examples of cases where we can't rely on
> TCP semantics in practice -- so we probably want to simulate this at the
> WebSocket layer or the application layer. Since the JS API exposes a
> .close() method, we should probably expose it at the WebSocket layer.

What do you think about this? I think it's nice to put your method just for
implementor's information together with Gabriel's idea in case we decide to
adopt Gabriel's idea, but reluctant to put it as mandatory protocol because
of this.

Takeshi

On Tue, Feb 15, 2011 at 16:10, <[email-masked]> wrote:

>  *Yutaka Takeda/R&D/SCEA@Playstation*
> Ian Fette (イアンフェッティ) <[email-masked]> wrote on 02/15/2011 02:27:58 PM:
>

---

From: Takeshi Yoshino <[email-masked]>
Date: Tue, 15 Feb 2011 17:35:38 -0800

On Mon, Feb 14, 2011 at 16:14, <[email-masked]> wrote:

> Thanks for the information

> When user jumps to another page,

Though it depends on design as you say, network stack may continue to take
care of those abandoned socket (send 2xx Close and wait for Close). I'm fine
with making draining (either your idea based on SHUT_WR or my idea using
Close frame) optional so that people who takes this just a kind of waste of
resource/time.

> or close browser,

I think sudden close like this can be grouped with network trouble.

> is WS-layer able

---

From: [email-masked]
Date: Tue, 15 Feb 2011 17:41:08 -0800

Hi Takeshi and all:

Although the Ian Hickson's message did not explain why TCP FIN 
(shutdown(SHUT_WR)) was 
not always possible, it made me realize that I have completely missed 
cases where we have 
intermediary nodes (e.g. proxy) along the path which terminate TCP layer. 
(We can not terminate
TCP connection before end-to-end WS-layer close handshake.)

Thank you for the heads-up, and please accept my apologies for any 
confusion I may have caused.

Ian Fette's text for -06 looks good to me now. If we are to exchange Close 
frames as a normal
close handshake, then spurious RST issue should also be resolved in the 
normal sequence.
In abnormal case, the RST issue may prevent the last bit including Close 
frame also from reaching
the destination, which we need to be aware.

Best regards,

- Yutaka

02/15/2011 04:22 PM

To
Yutaka Takeda/R&D/SCEA@Playstation
cc
[email-masked], [email-masked]
Subject
Re: [hybi] Clarify the role of closing handshake

What do you think about this? I think it's nice to put your method just 
for implementor's information together with Gabriel's idea in case we 
decide to adopt Gabriel's idea, but reluctant to put it as mandatory 
protocol because of this.

Takeshi

   message. 

To
[email-masked] 
cc
[email-masked] 
Subject

did not 
time, 
should 

Justification: 

Best. 

hybi mailing list
[email-masked]

---

From: Takeshi Yoshino <[email-masked]>
Date: Tue, 15 Feb 2011 18:34:19 -0800

On Tue, Feb 15, 2011 at 17:41, <[email-masked]> wrote:

> not always possible, it made me realize that I have completely missed cases
> where we have

FYI,
http://www.ietf.org/mail-archive/web/hybi/current/msg01147.html by Maciej
http://www.ietf.org/mail-archive/web/hybi/current/msg01173.html by Jamie
etc.

> the destination, which we need to be aware.
Good. Thanks,

Gabriel, are you fine with Ian Fette's text for -06?
According to Maciej's message
http://www.ietf.org/mail-archive/web/hybi/current/msg01181.html and others
on the thread, it looks like there was consensus that we should have some
method to deal with RST hazard.

You can still terminate TCP for abandoned WebSocket immediately for some
case where it makes sense though that will be taken as abnormal case above
in Yutaka's message. Making "wait for a Close frame in response" SHOULD is
another option.

Takeshi

---

From: Gabriel Montenegro <[email-masked]>
Date: Wed, 16 Feb 2011 15:57:57 +0000

Hi Takeshi,

I'm currently on vacation with very limited connectivity and time on the net. I'll look at this again next week.

It seems like Ian's proposed text still has the data draining in it. I thought a few of us were converging towards some of the text proposed previously by you (without the data draining). TCP RST issues are not WS protocol and could be taken care of by some implementation advice as previously suggested. I'd really question our complicating the WS protocol for anything that is not absolutely necessary.

Thanks,

Gabriel

From: [email-masked] [mailto:[email-masked]] On Behalf Of Takeshi Yoshino
Sent: Tuesday, February 15, 2011 18:34
To: [email-masked]; Gabriel Montenegro
Cc: [email-masked]
Subject: Re: [hybi] Clarify the role of closing handshake

On Tue, Feb 15, 2011 at 17:41, <[email-masked]<mailto:[email-masked]>> wrote:
Although the Ian Hickson's message did not explain why TCP FIN (shutdown(SHUT_WR)) was
not always possible, it made me realize that I have completely missed cases where we have

FYI,

intermediary nodes (e.g. proxy) along the path which terminate TCP layer. (We can not terminate
TCP connection before end-to-end WS-layer close handshake.)

Thank you for the heads-up, and please accept my apologies for any confusion I may have caused.

Ian Fette's text for -06 looks good to me now. If we are to exchange Close frames as a normal
close handshake, then spurious RST issue should also be resolved in the normal sequence.
In abnormal case, the RST issue may prevent the last bit including Close frame also from reaching
the destination, which we need to be aware.

Good. Thanks,

Gabriel, are you fine with Ian Fette's text for -06?
According to Maciej's message http://www.ietf.org/mail-archive/web/hybi/current/msg01181.html and others on the thread, it looks like there was consensus that we should have some method to deal with RST hazard.

You can still terminate TCP for abandoned WebSocket immediately for some case where it makes sense though that will be taken as abnormal case above in Yutaka's message. Making "wait for a Close frame in response" SHOULD is another option.

Takeshi

---

From: [email-masked]
Date: Wed, 16 Feb 2011 12:49:06 -0800

I can see Gabriel and a few others' point in which WS application 
programmers cannot rely
on WebSocket's data draining for delivery critical data anyway with a 
number of reasons which 
includes poor implementation of a browser, lack of consistency in behavior 
across browsers, 
unexpected user actions, network or server failures, etc, and abandon the 
draining by WS-layer
for more simplicity.

What bothers me, however, though is that immediate TCP socket closure can 
cause RST
which can be avoided in the normal close handshake currently proposed.

I would imagine one WS application would be some kind of streaming where a 
client is consistently
receiving data from a server while allowing client to control the stream 
(switch channels, 
fastfoward, rewind, etc.). When the client needs to go away, the RST would 
be generated
at high chances as there would more likely be some data in the TCP kernel 
buffer. I certainly do 
not want to see RST from the client at least in such normal operation for 
trouble shooting or for more 
robust sanity checking in our system development/deployment. (RST does not 
tell nothing!)

Some people have expressed a desire to have some reason code in Close 
frame to identify 
problems (I have no objection to it, but to some extent where it does not 
reveal too much information
on the wire.) Again. this Close frame also may not reach the other end due 
to the RST hazard.

I have no problem with implementing the close handshake currently proposed 
and
I do not think at all that it is that complicated for my non-browser 
WS-layer library. (I just do not know
exactly if this applies to the implementation for browsers.) We can also 
consider using 
wasClear equivalent  to take some action (re-connect, report the incident 
to a server, logging, etc.), too.

- Yutaka

[email-masked] wrote on 02/16/2011 07:57:57 AM:

> Hi Takeshi,
> 
> I?m currently on vacation with very limited connectivity and time on
> the net. I?ll look at this again next week.
> 
> It seems like Ian?s proposed text still has the data draining in it.
> I thought a few of us were converging towards some of the text 
> proposed previously by you (without the data draining). TCP RST 
> issues are not WS protocol and could be taken care of by some 
> implementation advice as previously suggested. I?d really question 
> our complicating the WS protocol for anything that is not absolutely
> necessary. 
> 
> Thanks,
> 
> Gabriel
> 
> According to Maciej's message http://www.ietf.org/mail-
> archive/web/hybi/current/msg01181.html and others on the thread, it 
> looks like there was consensus that we should have some method to 
> deal with RST hazard.
> 
> You can still terminate TCP for abandoned WebSocket immediately for 
> some case where it makes sense though that will be taken as abnormal
> case above in Yutaka's message. Making "wait for a Close frame in 
> response" SHOULD is another option.
> 
> Takeshi_______________________________________________
> hybi mailing list
> [email-masked]