Closed gopherbot closed 9 years ago
Here is a potential patch for this issue. I've changed the code handling PongFrame in Hybi's HandleFrame() function to return nil data and nil error (similar to how the PingFrame is handled). Returning nil nil here makes WebSocket.Receive() wait for another frame which is the intended behavior. diff -r bc411e2ac33f websocket/hybi.go --- a/websocket/hybi.go Thu Aug 15 13:52:04 2013 +1000 +++ b/websocket/hybi.go Thu Sep 12 18:20:12 2013 -0400 @@ -301,7 +301,7 @@ } return nil, nil case PongFrame: - return nil, ErrNotImplemented + return nil, nil } return frame, nil }
I noticed that while it is returning ErrNotImplemented, can it be further made useful by discarding the entire frame itself, similar to what the PingFrame handler does? The connection becomes useless after receiving a Pong frame because of the frame not being fully junked away. I did a test by sending a PingFrame from the server and just waited until a Pong was received from the browser: conn.PayloadTyhpe = websocket.PingFrame _, err = conn.Write([]byte("ping")
aicomman...@gmail.com ... returning nil, nil will not be sufficient as there's seems to remain the frame payload which hasn't been skipped, so per my previous message, the PongFrame needs to be discarded the similar to PingFrame: diff -r 93f5aef8cb25 websocket/hybi.go --- a/websocket/hybi.go Wed Jan 29 10:23:52 2014 +0900 +++ b/websocket/hybi.go Wed Feb 26 10:00:05 2014 -0800 @@ -288,20 +288,21 @@ handler.payloadType = frame.PayloadType() case CloseFrame: return nil, io.EOF - case PingFrame: + case PingFrame, PongFrame: pingMsg := make([]byte, maxControlFramePayloadLength) n, err := io.ReadFull(frame, pingMsg) if err != nil && err != io.ErrUnexpectedEOF { return nil, err } io.Copy(ioutil.Discard, frame) + if frame.PayloadType() == PongFrame { + return nil, ErrNotImplemented + } n, err = handler.WritePong(pingMsg[:n]) if err != nil { return nil, err } return nil, nil - case PongFrame: - return nil, ErrNotImplemented } return frame, nil }
ledangs...@gmail.com : your patch seems to return EOF err for an unexpected Pong frame, which an application cannot distinguish from a normal client disconnect. I think PongFrame needs to be handled separately from PingFrame: --- hybi.go 2014-09-04 11:03:07.000000000 -0700 +++ hybi.go.patched 2014-09-04 11:02:58.000000000 -0700 @@ -301,7 +301,14 @@ } return nil, nil case PongFrame: - return nil, ErrNotImplemented + //discard unexpected Pong frame + pongMsg := make([]byte, maxControlFramePayloadLength) + _, err := io.ReadFull(frame, pongMsg) + if err != nil && err != io.EOF { + return nil, err + } + io.Copy(ioutil.Discard, frame) + return nil, nil } return frame, nil } It would be nice if the code was actually fixed in the repo, since it causes real world disconnects with IE11.
matu...@gmail.com: that's a weird misbehavior of io.EOF (golang spec says/recommends the use of EOF to indicate an end of stream - due to connection being disconnected). If io.ReadFull() is getting an EOF, then there's a bug somewhere in the hybi frame Read handler. btw, have you tested this against all the other browsers? I don't have ie11 on hand to play with. Like you, I don't have control of the repo.
i have tested this patch with IE 11, Chrome, Safari and firefox and it fixes the issue (websockets unusable on ie, and does not effect other browsers). Any chance this gets integrated soon? It's very hard/impossible to patch this through forking when releasing a product.
This is also an issue with the WebSocket implementation in WinJS. Is there any chance we can get an estimate on when this issue will be resolved?
It looks like people have an idea as to what to fix. Can somebody send in a CL?
We're going to create a PR for this. We'll take the patch from comment 8 and test it with the AppRTC server and WinJS which is where we're having issues. Is there anything else we should know before starting this effort? Thanks.
If by PR you mean pull request, please be aware that Go does not accept Github pull requests. In to contribute, please see https://golang.org/doc/contribute.html . Thanks.
CL https://golang.org/cl/13054 mentions this issue.
by aicommander: