Skip to content
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

Recreate upgrade headers for websocket request #1592

Merged
merged 4 commits into from
Mar 18, 2022

Conversation

ttaym
Copy link
Contributor

@ttaym ttaym commented Mar 16, 2022

Contributes to #755

Signed-off-by: Aleksey Mikhaylov aym@tempesta-tech.com

Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
@ttaym ttaym force-pushed the am-755-upgrade-adjust-request branch from 011fd2c to b3e04fe Compare March 16, 2022 14:24
Copy link
Contributor

@krizhanovsky krizhanovsky left a comment

Choose a reason for hiding this comment

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

It seems there are several places for improvement

fw/http.c Show resolved Hide resolved

if (test_bit(TFW_HTTP_B_UPGRADE_WEBSOCKET, hm->flags)) {
if (is_resp && ((TfwHttpResp *)hm)->status == 101
&& test_bit(TFW_HTTP_B_UPGRADE_EXTRA, hm->flags))
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if I understand this. It seems this is about https://datatracker.ietf.org/doc/html/rfc7230#section-6.7

A server that sends a 101 (Switching Protocols) response MUST send an
Upgrade header field to indicate the new protocol(s) to which the
connection is being switched; if multiple protocol layers are being
switched, the sender MUST list the protocols in layer-ascending
order. A server MUST NOT switch to a protocol that was not indicated
by the client in the corresponding request's Upgrade header field.

This piece of code is for response with something extra plus to websocket in Upgrader header. Since we can only generate Upgrade: websocket in adjusted client request and server MUST NOT add anything non-requested, then what could be in the response for the extra? Can't we just always send Upgrade: websocket from the server to the client?

If I'm wrong, then a good comment with the RFC cite is required in the place.

Copy link
Contributor Author

@ttaym ttaym Mar 17, 2022

Choose a reason for hiding this comment

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

My intention was as follows:

We always strip upgrade header from response and re-add it when needed. So we do not just pass it through tempesta as is. But when we recreate headers would be beneficially to do simple sane check because we essentially hide backend and act on behalf on it.

Imaging erroneous backend that we on our discretion silently transform into compliant backend. That would be destructive if you ask me.

But this intention is, i understand, subtle and subjective. It is up to you if we need just alway send Upgrade: websocket.

fw/http.c Outdated
if (test_bit(TFW_HTTP_B_UPGRADE_WEBSOCKET, hm->flags)
&& test_bit(TFW_HTTP_B_CONN_UPGRADE, hm->flags))
r = TFW_HTTP_MSG_HDR_XFRM(hm, "Connection", "upgrade",
TFW_HTTP_HDR_CONNECTION, 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Headers modification is a heavy operation, probably involving memory allocations and skb frarmentation (see #1103), so it'd be more beneficial to do bit more complex condition and call do only one transformation call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That make sense. I'll fix it.

@ttaym ttaym requested a review from krizhanovsky March 17, 2022 08:36
{
r = TFW_HTTP_MSG_HDR_XFRM(hm, "Connection",
"upgrade",
TFW_HTTP_HDR_CONNECTION, 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

If we have Connection: close, upgrade, then it seems we should send just Connection: close. Also could you please check whether a connection is considered keep-alive by default (there is neither close nor keep-alive)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

By default passed 0 in the function for responses, BIT(TFW_HTTP_B_CONN_KA) passed to function for responses only if paired request has TFW_HTTP_B_CONN_KA bit.

But for requests by default passed BIT(TFW_HTTP_B_CONN_KA).

And semantically connection is keep-alive by default for HTTP/1.1 and later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we have Connection: close, upgrade in response than now result depends on status. If status is 4XX than connection is closed without upgrade. If 101 than upgrade is finished and connection state than depends on actual closing on no-closing from backend.

May be that is right enough.

fw/http.c Outdated Show resolved Hide resolved
Copy link
Contributor

@krizhanovsky krizhanovsky left a comment

Choose a reason for hiding this comment

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

LGTM

Co-authored-by: Alexander Krizhanovsky <ak@tempesta-tech.com>
@ttaym ttaym merged commit 94be89e into master Mar 18, 2022
@ttaym ttaym deleted the am-755-upgrade-adjust-request branch March 18, 2022 07:53
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.

2 participants