-
Notifications
You must be signed in to change notification settings - Fork 296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
write: Protect against sending messages after close #476
base: master
Are you sure you want to change the base?
Conversation
Hey, thanks for the PR. I do think we should take a slightly different approach, though. Instead of piggy-backing on This has another nice benefit of catching the close message wherever it may originate from. Edit: Looks like CI failed with a test timeout so this did indeed introduce a deadlock: https://github.com/coder/websocket/actions/runs/10717638649/job/29717749114?pr=476#step:4:97 |
Sure great idea. I just had this bug and need it fixed and in my experience fixing it and opening a PR is the fastest way. I did not read nor understand the whole codebase, just stepped through it with my debugger and implemented this quick and dirty solution. Just for clarification if you say we, do you mean you or me? Clearly you already have the solution on your mind, but if you are busy I can also do it. |
As suggested I moved the writeSent read/write into writeFrame. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the changes! I took the liberty to push a few myself to your branch, hope you don't mind. (See review comments.)
Just for clarification if you say we, do you mean you or me? Clearly you already have the solution on your mind, but if you are busy I can also do it.
My thinking is that I'm happy to let you work on this since you started the PR, and hopefully land a contribution to the project.
Side-note: I typically write/talk in _we_s as I see coding as a group effort, this way both successes and failures are shared and not the responsibility of any one individual. My hope is that it also sparks inclusivity by feeling like a group effort instead of one person making decisions.
TBH I think this PR is in pretty good shape now, but I think we should add at least one test testing this new behavior. Would you want to tackle that?
Very interesting. I came to this PR because I am debugging our tests. In our tests we measure how many bytes we send over a websocket (using this library for both client and server in Go) and how many we get for a simple sending of text message With v1.8.10, before closing was rewritten, we had |
Nice to hear that it makes things more predictable. :) @mafredri Yeah a test would be great. Sadly I am on a business trip until next monday, so until then this PR would be stall, unless you would not mind. |
So I had a moment to have look and wrote several approaches, but I have to admit that I find it kindof hard to test. I am not familiar enough with the code, so I'll describe some assumptions here. My general idea is to open a server and a client connection, close one and count the amount of close messages received on both ends. Both are asserted to be one. Assumption 1: Assumption 2: I am tempting to have a private callback on the connection options, but introducing private dependency injection just to be able to test it seems overkill, and introduces to much complexity for the benefits. (IMHO). Second attempt would be to write a separat minimal websocket client / server that can count, but this seems like a bunch of work for such a simple test. I saw that there are some helpers like EchoServer, one could also introduce something similar that can count opcodes, but also this would need a separat implementation since it is not in the websocket package. For now I am using my fork (thanks to go mod replace thats pretty easy) to fix the problems i am currently experiencing in production. Looking forward to get some feedback on the testing issue. |
Another note: your last commit makes my test ( |
Thanks @FrauElster, I can reproduce this. I took a look and I'm pretty sure that the fix simply surfaced a new issue. Calling I appreciate you taking a look and thinking about ways to test for this, if you want though, I can take over as I want to look more closely at the way we close connections. PS. Are you using |
No I don't use CloseRead(ctx) in my application. I use the simple msgType, data, err := conn.Read(ctx)
if websocket.CloseStatus(err) != -1 { ... } or conn.Close(websocket.StatusInternalError, string(reason)) |
@FrauElster I pushed a fix for the @mitar I'm curious if c3613fc causes any change in the behavior you're seeing? I have noticed that there are still cases where the |
Sure go ahead. My production go.mod is pinned to a commit, so no worries. ;) |
Looks like need to run |
That fork includes a fix for the extra close frame problem. See: - coder/websocket#448 - coder/websocket#476
Closes #448