Bug 67335 - WebSocket binaryType should appear when functional
: WebSocket binaryType should appear when functional
Status: UNCONFIRMED
Product: WebKit
Classification: Unclassified
Component: New Bugs
: 528+ (Nightly build)
: All Linux
: P2 Normal
Assigned To: Nobody
:
Depends on: 68002
Blocks:
  Show dependency treegraph
 
Reported: 2011-08-31 16:29 PDT by Joel Martin
Modified: 2011-09-15 11:50 PDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joel Martin 2011-08-31 16:29:11 PDT
In Chrome/Chromium 15.0.868.0 (Developer Build 99067 Linux) I note that the binaryType property of the WebSocket instance is visible and set to "blob". It can also be set to "arraybuffer". This would be fine except for the fact that it is in fact non-functional and worse it is misleading.

This behavior means that currently there is no way to do object detection to determine if WebSocket supports binary data or not. This applies to Chrome 14 and 15 (I'm not sure exactly which WebKit builds that equates to). The support for arraybuffers and blobs in the WebSocket API has just landed (https://bugs.webkit.org/show_bug.cgi?id=67180, https://bugs.webkit.org/show_bug.cgi?id=67115) so the issue is going away, but for the intermediate builds (where binaryType appeared as a property but is non-functional) this is a major issue.

Please backport a fix so that binaryType doesn't show up until it actually does something.
Comment 1 Joel Martin 2011-08-31 16:52:17 PDT
I've filed a bug to have the WebSocket API tightened up in this area:

http://www.w3.org/Bugs/Public/show_bug.cgi?id=13984
Comment 2 Yuta Kitamura 2011-08-31 19:52:00 PDT
Receiving binary message has been implemented and was just landed yesterday, so in the next dev channel release binaryType attribute should work.

We usually do not merge a cherry-picked change onto dev channel release once it is shipped. Dev channel binary is released every week, so just wait for the next release which should fix the issue.
Comment 3 Joel Martin 2011-09-01 08:01:32 PDT
So you're saying that in order to make my application work with binary data I'm going to need to do version detection and avoid Chrome 14, 15? I understand why you don't typically backport cherry picks, but in this case it's a pretty big hassle for developers and it would be nice not to have a stable version of Chrome in the wild with this bug.
Comment 4 Joel Martin 2011-09-12 14:46:52 PDT
Yuta, not sure if you've addressed this already or not, but as Simon Pietrs points out (http://www.w3.org/Bugs/Public/show_bug.cgi?id=13984#c9), according to WebIDL, the binaryType property should appear on the WebSocket prototype.

Also, it would be nice if this is fixed in the version that actually has support for binary data type send/receive (to enable object detection). Thanks.
Comment 5 Yuta Kitamura 2011-09-12 19:55:25 PDT
For Chromium 14, WebSocket objects don't have binaryType attribute and binary messages aren't supported at all.

For Chromium 15, WebSocket objects do have the attribute and binary data type is fully supported (both sending and receiving). Most recent dev channel build (15.0.874.5) should have this functionality.

For prototype issue, this affects not only WebSockets but also all other interfaces in WebKit. Please open a bug if you feel this needs to be fixed.

I personally think, however, the current WebKit behavior is legitimate (hence WebIDL spec is wrong), because the value of binaryType attribute (and other attributes, such as readyState) is held by each WebSocket object, and changing such attributes shouldn't affect WebSocket prototype.
Comment 6 Joel Martin 2011-09-13 06:50:29 PDT
Okay, that's very good to hear that the binaryType attribute won't be visible until it is functional.

However, it still doesn't fully solve my problem due to the WebIDL prototype attributes issue. Without the attributes visible on the prototype it means that object detection can't be done without instantiating the object first. This isn't a problem with most objects because you can instantiate them without side-effects. However, in the case of a WebSocket object, instantiating triggers the opening of a network connection.

In my real-world case, I need to be able to determine before I create a connection whether the WebSocket object support binary data because this affects the values that I place in the sub-protocol field when I instantiate it.

Right now, the WebSocket prototype looks the same no matter what functionality is supported.

So yes, in this case at least, I very much object to binaryType not being visible in the prototype. However, for general efficiency of object detection, I think that the WebIDL spec as defined is correct: attributes should be visible in the prototype, even if they are object specific. This is correct in in firefox and opera so I will file a separate bug for this.

Can you suggest an alternative mechanism for object detecting binary support without instantiating a WebSocket object (and thus triggered an unwanted network connection)?
Comment 7 Joel Martin 2011-09-13 07:04:55 PDT
Re-opening since this issue isn't resolved and adjusting the summary slightly to reflect the real issue. Add dep on 68002 (WebIDL bug).
Comment 8 Joel Martin 2011-09-14 12:03:52 PDT
Please see Ian Hickson's comment http://www.w3.org/Bugs/Public/show_bug.cgi?id=13984#c11 

My understanding of the resolution of that API bug is that WebKit/Chrome are not compliant with the WebSocket API until binaryType is visible on the prototype.

In other words, this code should do the right thing in compliant browsers:

var binarySupported = 'binaryType' in WebSocket.prototype;
Comment 9 Simon Pieters 2011-09-15 07:51:43 PDT
(In reply to comment #5)
> I personally think, however, the current WebKit behavior is legitimate (hence WebIDL spec is wrong), because the value of binaryType attribute (and other attributes, such as readyState) is held by each WebSocket object, and changing such attributes shouldn't affect WebSocket prototype.

The WebIDL requirement for IDL attributes to be exposed as properties on the prototype is deliberate. It also simplifies feature detection for authors. If you think the WebIDL spec should be changed, you should file a bug on the WebIDL spec.
Comment 10 Sam Weinig 2011-09-15 10:21:00 PDT
(In reply to comment #9)
> (In reply to comment #5)
> > I personally think, however, the current WebKit behavior is legitimate (hence WebIDL spec is wrong), because the value of binaryType attribute (and other attributes, such as readyState) is held by each WebSocket object, and changing such attributes shouldn't affect WebSocket prototype.
> 
> The WebIDL requirement for IDL attributes to be exposed as properties on the prototype is deliberate. It also simplifies feature detection for authors. If you think the WebIDL spec should be changed, you should file a bug on the WebIDL spec.

For the record, it is currently our intention to eventually put attributes on the prototype, we just need to figure out a way to do it with regressing performance (which is a bit difficult).  In the mean time, one can always construct a dummy object and test for the attributes presence to do feature detection.
Comment 11 Joel Martin 2011-09-15 10:53:31 PDT
Sam. That's good to hear that it's going to be addressed eventually.

However, there really needs to be an near-term solution specifically for WebSocket.protocol.binaryType because you can't create a dummy WebSocket object without nasty side-effects.

For example:

    var wstest = new WebSocket('ws://localhost:57111');
    if (typeof(wstest.binaryType) !== "undefined") {
        ...  // binary
    } else {
        ...  // text only
    }
    wstest.close();
    wstest = null;

Bzzzt! Not only does this initiate a connection to localhost:57111 (which is obviously undesirable) it also triggers an async exception when the connection fails (even worse). I hope you agree that's not really acceptable.

I can see two options: delay the connection until after the current execution context (and have close() cancel it), or just put binaryType on the prototype until the full solution is addressed everywhere. I believe firefox does the former (although it's moot since binaryType is on the prototype). However, I suggest the latter since initiating the connection immediately seems desirable.
Comment 12 Joel Martin 2011-09-15 11:05:19 PDT
In newer builds of Chrome 15 and 16 the async error is different and actually being triggered by the close() call. However, with or without the close() call a network connection is still initiated.
Comment 13 Sam Weinig 2011-09-15 11:50:29 PDT
I see, seems too bad there is no way to create an inert WebSocket.