-
Notifications
You must be signed in to change notification settings - Fork 103
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2572,6 +2572,33 @@ tfw_http_set_hdr_date(TfwHttpMsg *hm) | |
return r; | ||
} | ||
|
||
/* | ||
* Add 'Upgrade:' header for websocket upgrade messages | ||
*/ | ||
static int | ||
tfw_http_set_hdr_upgrade(TfwHttpMsg *hm, bool is_resp) | ||
{ | ||
int r = 0; | ||
|
||
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)) | ||
{ | ||
T_ERR("Unable to add uncompliant Upgrade: header " | ||
"to msg [%p]\n", hm); | ||
return -EINVAL; | ||
} | ||
r = tfw_http_msg_hdr_xfrm(hm, "upgrade", SLEN("upgrade"), | ||
"websocket", SLEN("websocket"), | ||
TFW_HTTP_HDR_UPGRADE, 0); | ||
if (r) | ||
T_ERR("Unable to add Upgrade: header to msg [%p]\n", hm); | ||
else | ||
T_DBG2("Added Upgrade: header to msg [%p]\n", hm); | ||
krizhanovsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
return r; | ||
} | ||
|
||
/* | ||
* Expand HTTP response with 'Date:' header field. | ||
*/ | ||
|
@@ -2677,23 +2704,38 @@ tfw_http_expand_hbh(TfwHttpResp *resp, unsigned short status) | |
static int | ||
tfw_http_set_hdr_connection(TfwHttpMsg *hm, unsigned long conn_flg) | ||
{ | ||
int r; | ||
BUILD_BUG_ON(BIT_WORD(__TFW_HTTP_MSG_M_CONN) != 0); | ||
if (((hm->flags[0] & __TFW_HTTP_MSG_M_CONN) == conn_flg) | ||
&& (!TFW_STR_EMPTY(&hm->h_tbl->tbl[TFW_HTTP_HDR_CONNECTION])) | ||
&& !test_bit(TFW_HTTP_B_CONN_EXTRA, hm->flags)) | ||
&& !test_bit(TFW_HTTP_B_CONN_EXTRA, hm->flags) | ||
&& !test_bit(TFW_HTTP_B_CONN_UPGRADE, hm->flags)) | ||
{ | ||
return 0; | ||
} | ||
|
||
switch (conn_flg) { | ||
case BIT(TFW_HTTP_B_CONN_CLOSE): | ||
return TFW_HTTP_MSG_HDR_XFRM(hm, "Connection", "close", | ||
TFW_HTTP_HDR_CONNECTION, 0); | ||
case BIT(TFW_HTTP_B_CONN_KA): | ||
return TFW_HTTP_MSG_HDR_XFRM(hm, "Connection", "keep-alive", | ||
TFW_HTTP_HDR_CONNECTION, 0); | ||
r = TFW_HTTP_MSG_HDR_XFRM(hm, "Connection", "keep-alive", | ||
TFW_HTTP_HDR_CONNECTION, 0); | ||
break; | ||
default: | ||
return TFW_HTTP_MSG_HDR_DEL(hm, "Connection", | ||
r = TFW_HTTP_MSG_HDR_DEL(hm, "Connection", | ||
TFW_HTTP_HDR_CONNECTION); | ||
} | ||
|
||
if (r < 0) | ||
return r; | ||
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That make sense. I'll fix it. |
||
|
||
return r; | ||
} | ||
|
||
/** | ||
|
@@ -3072,6 +3114,10 @@ tfw_h1_adjust_req(TfwHttpReq *req) | |
if (r < 0) | ||
return r; | ||
|
||
r = tfw_http_set_hdr_upgrade(hm, false); | ||
if (r < 0) | ||
return r; | ||
|
||
r = tfw_h1_set_loc_hdrs(hm, false, false); | ||
if (r < 0) | ||
return r; | ||
|
@@ -3642,6 +3688,10 @@ tfw_http_adjust_resp(TfwHttpResp *resp) | |
if (r < 0) | ||
return r; | ||
|
||
r = tfw_http_set_hdr_upgrade(hm, true); | ||
if (r < 0) | ||
return r; | ||
|
||
r = tfw_http_set_hdr_keep_alive(hm, conn_flg); | ||
if (r < 0) | ||
return r; | ||
|
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.
I'm not sure if I understand this. It seems this is about https://datatracker.ietf.org/doc/html/rfc7230#section-6.7
This piece of code is for response with something extra plus to
websocket
inUpgrader
header. Since we can only generateUpgrade: 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 sendUpgrade: websocket
from the server to the client?If I'm wrong, then a good comment with the RFC cite is required in the place.
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.
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
.