Skip to content

feat: swap over to websockets if initial derp exchange fails #8

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

Merged
merged 9 commits into from
Mar 1, 2023

Conversation

kylecarbs
Copy link
Member

@kylecarbs kylecarbs commented Feb 28, 2023

Many customers have load balancers that don't allow Upgrade: derp. We still want to allow connectivity, but show a warning as to why it's failing, and what customers can do to fix it.

A few of these fixes are going upstream here tailscale#7401

@kylecarbs kylecarbs requested a review from mafredri February 28, 2023 18:40
@kylecarbs kylecarbs self-assigned this Feb 28, 2023
@kylecarbs kylecarbs force-pushed the swapwebsockets branch 3 times, most recently from c2cd7d4 to acb075f Compare February 28, 2023 18:45
@deansheather deansheather self-requested a review March 1, 2023 17:15

// Only on StatusCode < 500 in case a gateway timeout
// or network intermittency occurs!
if resp.StatusCode < 500 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the only status code it could be? I could see a proxy just dropping the connection with no status if it didn't like the Upgrade, or returning 400 perhaps?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

400 seems to be the standard status code if an upgrade fails, but I'm not sure we can guarantee that with all load balancers that clouds may have. That's why I chose < 500 because it'd generally mean that the server intentionally chose to not accept the WebSocket for some reason, which coderd will never do.

Copy link
Member

@mafredri mafredri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except for the js error, looks good! 👍🏻

c, res, err := websocket.Dial(ctx, urlStr, &websocket.DialOptions{
Subprotocols: []string{"derp"},
HTTPClient: &http.Client{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't available in js, so we might want to move this assignment out to a separate file behind build tag. Maybe a function like wsDialOptionsWithHTTPClient(opts, tlsConfig).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! Will fix.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check now!


// Only on StatusCode < 500 in case a gateway timeout
// or network intermittency occurs!
if resp.StatusCode < 500 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we limit this to just 400 error codes or do we run into others as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The honest answer is that I'm not really sure, maybe it's safe to assume only 400, but I didn't want to be presumptuous for what all proxies might do... we get the error message surfaced, so it's not impossible for us to narrow this down in the future.

@kylecarbs kylecarbs merged commit fb16ae7 into main Mar 1, 2023
@kylecarbs kylecarbs deleted the swapwebsockets branch March 1, 2023 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants