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

Bootstrap websocket connection with http2 CONNECT #1625

Closed
wants to merge 1 commit into from

Conversation

ttaym
Copy link
Contributor

@ttaym ttaym commented May 9, 2022

Contributes to #755

This PR adds CONNECT method and :protocol header field for HTTP/2 parsing.

CONNECT HTTP/2 messages with :protocol equals to websocket transformed to HTTP/1.1 messages for backend with method GET, headers Connection: upgrade and Upgrade: websocket.

Responses from backend with headers Connection: upgrade, Upgrade: websocket and status 101 transformed to :status 200 HTTP/2 responses to client.

When sending 200-success to CONNECT request with websocket :protocol we need not to send END_STREAM frame flag. So to gracefully shutting down stream we need to detect Close websocket control frame or rely on closing tcp connection from backend or closing stream from client.

Note that Sec-WebSocket-Accept stripped from HTTP/1.1 responses and Sec-WebSocket-Key added to HTTP/1.1 request to backend.

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

@ttaym ttaym marked this pull request as ready for review May 9, 2022 14:50
@ttaym ttaym requested a review from krizhanovsky May 9, 2022 14:50
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.

Quite good and big work. I didn't find and severe issues, but there are several vague changes, which are good to discuss. Also bunch of cleanups is required.

fw/websocket.h Show resolved Hide resolved
fw/http_parser.c Outdated Show resolved Hide resolved
fw/http_parser.c Outdated Show resolved Hide resolved
fw/http.c Outdated Show resolved Hide resolved
fw/http.c Outdated Show resolved Hide resolved
fw/http.c Show resolved Hide resolved
fw/http.c Outdated Show resolved Hide resolved
fw/http_frame.c Show resolved Hide resolved
fw/http_frame.c Outdated Show resolved Hide resolved
fw/http_frame.c Show resolved Hide resolved
@ttaym ttaym requested a review from krizhanovsky May 23, 2022 13:38
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.

The only confusing part is freeing request. Maybe just a good comment is required. Possible memory leaks do require a lot of attention.

Also please consider this patch for coding style cleanup style.diff.txt

@ttaym
Copy link
Contributor Author

ttaym commented May 30, 2022

In response to #1625 (review)

I have applied suggested style amendments.

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.

Basically there are the same questions: it seems with this patch set we free messages in smaller number of cases (under more narrow conditions), but do not introduce new places to free the messages - this looks like a memory leak.

I'd suggest to make an instrumentation patch with a counter for currently allocated/freed messages and verify websockets and say regular loading of our website through HTTP/2.

Also could you please elaborate on the problem of HTTP/2 client sending data right after Upgrade and immediately closing the stream - where the problem appears? Ideally with the sequence of called functions.

fw/http_frame.c Outdated Show resolved Hide resolved
* cases controlled by server connection side (after adding to
* @fwd_queue): successful response sending, eviction etc.
*/
if (!test_bit(TFW_HTTP_B_FULLY_PARSED, hmreq->flags) && !hmreq->resp)
tfw_http_conn_msg_free(hmreq);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does !hmreq->resp implies websockets? If so, then we should make an assertion that this is a websocket request, otherwise this isn't clear. If not, then where the request with empty resp is freed now for regular HTTP/2 messages?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To my understanding for regular requests request cannot have linked response and at the same time be not fully parsed. So that change do not narrow set of freed reqeusts here.

In our settings i suppose that only h2 websockets will have linked response here. I'll add assert.

@@ -936,7 +950,10 @@ tfw_h2_resp_fwd(TfwHttpResp *resp)

tfw_hpack_enc_release(&ctx->hpack, resp->flags);

tfw_http_resp_pair_free(req);
if (tfw_http_resp_is_websocket_upgrade(resp))
tfw_http_conn_msg_free(req->pair);
Copy link
Contributor

Choose a reason for hiding this comment

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

The question is still the same: if we don't free resp for webosockets here, then we do we free it?

@ttaym
Copy link
Contributor Author

ttaym commented May 31, 2022

In response to #1625 (comment)

My idea is that in connection drop requests that linked to stream will be freed.

@ttaym ttaym force-pushed the am-755-websocket-bootstrap-http2 branch from b7f4bf5 to f9e7527 Compare May 31, 2022 15:25
@krizhanovsky krizhanovsky mentioned this pull request Jun 6, 2022
@krizhanovsky
Copy link
Contributor

Decided not to go with Webosckets over HTTP/2 #755 (comment)

@krizhanovsky krizhanovsky deleted the am-755-websocket-bootstrap-http2 branch June 6, 2022 18:06
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