Subject: [hybi] Several questions/proposals about WebSocket Close Status Codes

From: David Jarry <[email-masked]>
Date: Sun, 30 Jan 2022 07:07:06 +0100

Hello,

I am a contributor to Wikipedia FR, I have several questions/proposals 
about WebSocket Close Status Codes.

I/

> RFC : 1003 indicates that an endpoint is terminating the connection 
> because it has received a type of data it cannot accept (e.g., an 
> endpoint that understands only text data MAY send this if it receives 
> a binary message).
> IANA : Unsupported Data.
>
> RFC : 1007 indicates that an endpoint is terminating the connection 
> because it has received data within a message that was not consistent 
> with the type of the message (e.g., non-UTF-8 data within a text message).
> IANA : Invalid frame payload data.

I don't understand how to choose between these two codes: How does a 
server expecting UTF-8 text know the difference between binary input and 
non-UTF-8 input?

It would be much simpler if one code corresponded to "I expect XML and I 
received JSON" (type error, encoding error, parsing error…) and if the 
other code corresponded to "I expect a JSON object ({}) and I received a 
JSON array ([])" (value error, precondition fail on data, wrong content…).

So if a server expects UTF-8 text:

  * The first code is returned if UTF-8 decoding fails (it doesn't
    matter if the input is binary or a nearly UTF-8 text).
  * The second code is returned if the text uses Egyptian hieroglyphs
    when an English text was expected.

II/

>  IANA 1014 : The server was acting as a gateway or proxy and received 
> an invalid response from the upstream server. This is similar to 502 
> HTTP Status Code.
> RFC : Status codes in the range 4000-4999 are reserved for private use 
> and thus can't be registered. Such codes can be used by prior 
> agreements between WebSocket applications. The interpretation of these 
> codes is undefined by this protocol. IANA : Reserved for Private Use.

Since the code 1014 admits the existence of gateway and proxy, shouldn't 
it be specified somewhere that the intermediate servers MUST pass 
without modifications any code in the range 4000-4999 that it does not 
understand, so that the agreement can be directly established between 
the end server and the end client (dispite of gateway and proxy)?

III/

Unlike HTTP, communication is two-way, but many codes assume that there 
is a service, a server, and a client. For certain uses, it may be 
interesting to use the WebSocket protocol between two servers (peer to 
peer). For example if a server on a local network wants to communicate 
with an external server through a Firewall which only accepts port 80 in 
both directions, then WebSocket makes it possible to create sockets in 
both directions even through an HTTPd. Everything should be done to 
reduce the difference between a server and a client (once the connection 
is established, think of it like peers).

> IANA 1014 : The server was acting as a gateway or proxy and received 
> an invalid response from the upstream server. This is similar to 502 
> HTTP Status Code.

Must be "Gateway or Proxy Error"! Please authorize a client to send this 
code. I don't understand why a client is forbidden to be behind a 
gateway or a proxy.

> IANA 1012 : Service Restart

Must be "Restart"! Please authorize a client to send this code. Maybe 
the server will decide to keep certain things cached (unlike code 1000 
where the server can destroy all its caches).

IV/

Proposals (codes for timeouts and version checks):

Gateway or Proxy Timeout:
The server was acting as a gateway or proxy and did not receive a timely 
response from the upstream server. This is similar to 504 HTTP Status Code.

Timeout:
A generic status code that can be returned when a timeout has occurred, 
meaning that the purpose for which the connection was established was 
not been fulfilled (something took too long).

Deprecated:
Please update. Even a client can send this code and try another server, 
a warning can be written in the server log.

Not Implemented:
I'm not updated.A client can reboot with backwards compatibility enabled 
or connect to another server. A server can treat this request as a 1012 
code, except that the last request was not understood (e.g., the 
clientbrowser should reload the page, then the serveur send back the 
last message)!

Cordially,

David Jarry.

---

From: Andy Green <[email-masked]>
Date: Sun, 30 Jan 2022 07:04:21 +0000

> server expecting UTF-8 text know the difference between binary input and 

In ws, messages come with an indication they are UTF-8 TEXT (started 
with opcode 1) or BINARY (opcode 2).  So "receives a binary message" 
isn't an ambiguous thing in ws, the server will always know clearly if 
he got the type he wasn't expecting.

> JSON array ([])" (value error, precondition fail on data, wrong content…).

It is simple since it tells you if it is BINARY or TEXT explicitly.  Ws 
doesn't attempt to define payload semantics so it's not the right layer 
to define what's wrong with them.  The server can send arbitrary 
diagnostic payload in the CLOSE frame extra data to help with analysis.

>     when an English text was expected.

First code is generally for "data it cannot accept", the example given 
is the case it was sent the wrong one of BINARY or TEXT message.

Second one is for if you see a TEXT message that violated the specific 
requirement that it must contain valid UTF-8.  It's written generally 
but IIRC TEXT + UTF-8 is the only time ws talks about judging payload 
contents themselves.

> the end server and the end client (dispite of gateway and proxy)?

It doesn't say that they shouldn't, so there is no conflict with doing 
so.  It would indeed be better if it did say they MUST.

> is established, think of it like peers).

I don't disagree with the observation, but it's like that because ws was 
defined as an upgrade protocol from http, which has this schism 
thoroughly baked in.

> code. I don't understand why a client is forbidden to be behind a 

He's not "forbidden to be behind a gateway or proxy", he just isn't 
given an explicit way to explain he's closing from shenanigans due to that.

> where the server can destroy all its caches).

Well, I guess it could be useful.

> response from the upstream server. This is similar to 504 HTTP Status Code.

I guess if you have 1014, this is also useful.

> not been fulfilled (something took too long).

Timeouts may not necessarily want to present at ws layer, eg, whatever 
timed out might be retryable inside the ws connection session without 
terminating and re-establishing it.  So I think this is of limited use.

> a warning can be written in the server log.

The idea of the subprotocol naming is to contain the necessary 
versioning cleanly.

https://datatracker.ietf.org/doc/html/rfc6455#section-1.9

> clientbrowser should reload the page, then the serveur send back the 

Unless I miss your point, again subprotocols are designed to absorb this 
kind of problem (and allow the client to propose multiple supported 
versions in one step).

-Andy

---

From: David Jarry <[email-masked]>
Date: Sun, 30 Jan 2022 20:42:33 +0100

I/
My bad. So I figured out:

  * 1003 is an opcode error (1 instead of 2 or vice versa)
  * 1007 is an payload data error (like an UTF-8 encoding error)
  * Judging payload data is delegated to the subprotocol, which may have
    its own error handling system (and subprotocol should handle almost
    all errors), socode 1007 should not be used on a server that expects
    binary data (Opcode=2).

I understand the rest (I generally agree, e.g. the sub-protocol should 
handle version issues).

Thank you for your time.

Le 30/01/2022 à 08:04, Andy Green a écrit :
>>> endpoint that understands only text data MAY send this if it 
>>> receives a binary message).
>>> IANA : Unsupported Data.
>>>
>>> because it has received data within a message that was not 
>>> consistent with the type of the message (e.g., non-UTF-8 data within 
>>> a text message).
>> server expecting UTF-8 text know the difference between binary input 
>> and non-UTF-8 input?
>
>> It would be much simpler if one code corresponded to "I expect XML 
>> and I received JSON" (type error, encoding error, parsing error…) and 
>> if the other code corresponded to "I expect a JSON object ({}) and I 
>> received a JSON array ([])" (value error, precondition fail on data, 
>> wrong content…).
>
> It is simple since it tells you if it is BINARY or TEXT explicitly.  
> Ws doesn't attempt to define payload semantics so it's not the right 
> layer to define what's wrong with them.  The server can send arbitrary 
>>>  IANA 1014 : The server was acting as a gateway or proxy and 
>>> received an invalid response from the upstream server. This is 
>>> similar to 502 HTTP Status Code.
>>> RFC : Status codes in the range 4000-4999 are reserved for private 
>>> use and thus can't be registered. Such codes can be used by prior 
>>> agreements between WebSocket applications. The interpretation of 
>>> these codes is undefined by this protocol. IANA : Reserved for 
>>> Private Use.
>>
>> Since the code 1014 admits the existence of gateway and proxy, 
>> shouldn't it be specified somewhere that the intermediate servers 
>> MUST pass without modifications any code in the range 4000-4999 that 
>> it does not understand, so that the agreement can be directly 
>> established between the end server and the end client (dispite of 
>> gateway and proxy)?
>
>> Unlike HTTP, communication is two-way, but many codes assume that 
>> there is a service, a server, and a client. For certain uses, it may 
>> be interesting to use the WebSocket protocol between two servers 
>> (peer to peer). For example if a server on a local network wants to 
>> communicate with an external server through a Firewall which only 
>> accepts port 80 in both directions, then WebSocket makes it possible 
>> to create sockets in both directions even through an HTTPd. 
>> Everything should be done to reduce the difference between a server 
>> and a client (once the connection is established, think of it like 
>> peers).
>
> I don't disagree with the observation, but it's like that because ws 
> was defined as an upgrade protocol from http, which has this schism 
> thoroughly baked in.
>
>> Must be "Gateway or Proxy Error"! Please authorize a client to send 
>> this code. I don't understand why a client is forbidden to be behind 
>> a gateway or a proxy.
>
>> the server will decide to keep certain things cached (unlike code 
>> 1000 where the server can destroy all its caches).
>
>> The server was acting as a gateway or proxy and did not receive a 
>> timely response from the upstream server. This is similar to 504 HTTP 
>> Status Code.
>
>> A generic status code that can be returned when a timeout has 
>> occurred, meaning that the purpose for which the connection was 
>> established was not been fulfilled (something took too long).
>
>> Please update. Even a client can send this code and try another 
>> server, a warning can be written in the server log.
>
>> I'm not updated.A client can reboot with backwards compatibility 
>> enabled or connect to another server. A server can treat this request 
>> as a 1012 code, except that the last request was not understood 
>> (e.g., the clientbrowser should reload the page, then the serveur 
>> send back the last message)!
>
> Unless I miss your point, again subprotocols are designed to absorb 
> this kind of problem (and allow the client to propose multiple 
> supported versions in one step).
>
> -Andy