Skip to content

Commit f7dcc7c

Browse files
committed
http: move HTTP/2 cleanup code off http_disconnect()
Otherwise it would never be called for an HTTP/2 connection, which has its own disconnect handler. I spotted this while debugging <https://bugzilla.redhat.com/1248389> where the http_disconnect() handler was called on an FTP session handle causing 'dnf' to crash. conn->data->req.protop of type (struct FTP *) was reinterpreted as type (struct HTTP *) which resulted in SIGSEGV in Curl_add_buffer_free() after printing the "Connection cache is full, closing the oldest one." message. A previously working version of libcurl started to crash after it was recompiled with the HTTP/2 support despite the HTTP/2 protocol was not actually used. This commit makes it work again although I suspect the root cause (reinterpreting session handle data of incompatible protocol) still has to be fixed. Otherwise the same will happen when mixing FTP and HTTP/2 connections and exceeding the connection cache limit. Reported-by: Tomas Tomecek Bug: https://bugzilla.redhat.com/1248389
1 parent ecf7618 commit f7dcc7c

File tree

2 files changed

+13
-23
lines changed

2 files changed

+13
-23
lines changed

lib/http.c

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@
8686
* Forward declarations.
8787
*/
8888

89-
static CURLcode http_disconnect(struct connectdata *conn, bool dead);
9089
static int http_getsock_do(struct connectdata *conn,
9190
curl_socket_t *socks,
9291
int numsocks);
@@ -117,7 +116,7 @@ const struct Curl_handler Curl_handler_http = {
117116
http_getsock_do, /* doing_getsock */
118117
ZERO_NULL, /* domore_getsock */
119118
ZERO_NULL, /* perform_getsock */
120-
http_disconnect, /* disconnect */
119+
ZERO_NULL, /* disconnect */
121120
ZERO_NULL, /* readwrite */
122121
PORT_HTTP, /* defport */
123122
CURLPROTO_HTTP, /* protocol */
@@ -141,7 +140,7 @@ const struct Curl_handler Curl_handler_https = {
141140
http_getsock_do, /* doing_getsock */
142141
ZERO_NULL, /* domore_getsock */
143142
ZERO_NULL, /* perform_getsock */
144-
http_disconnect, /* disconnect */
143+
ZERO_NULL, /* disconnect */
145144
ZERO_NULL, /* readwrite */
146145
PORT_HTTPS, /* defport */
147146
CURLPROTO_HTTPS, /* protocol */
@@ -169,26 +168,6 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
169168
return CURLE_OK;
170169
}
171170

172-
static CURLcode http_disconnect(struct connectdata *conn, bool dead_connection)
173-
{
174-
#ifdef USE_NGHTTP2
175-
struct HTTP *http = conn->data->req.protop;
176-
if(http) {
177-
Curl_add_buffer_free(http->header_recvbuf);
178-
http->header_recvbuf = NULL; /* clear the pointer */
179-
for(; http->push_headers_used > 0; --http->push_headers_used) {
180-
free(http->push_headers[http->push_headers_used - 1]);
181-
}
182-
free(http->push_headers);
183-
http->push_headers = NULL;
184-
}
185-
#else
186-
(void)conn;
187-
#endif
188-
(void)dead_connection;
189-
return CURLE_OK;
190-
}
191-
192171
/*
193172
* checkheaders() checks the linked list of custom HTTP headers for a
194173
* particular header (prefix).

lib/http2.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ static int http2_getsock(struct connectdata *conn,
8080
static CURLcode http2_disconnect(struct connectdata *conn,
8181
bool dead_connection)
8282
{
83+
struct HTTP *http = conn->data->req.protop;
8384
struct http_conn *c = &conn->proto.httpc;
8485
(void)dead_connection;
8586

@@ -89,6 +90,16 @@ static CURLcode http2_disconnect(struct connectdata *conn,
8990
Curl_safefree(c->inbuf);
9091
Curl_hash_destroy(&c->streamsh);
9192

93+
if(http) {
94+
Curl_add_buffer_free(http->header_recvbuf);
95+
http->header_recvbuf = NULL; /* clear the pointer */
96+
for(; http->push_headers_used > 0; --http->push_headers_used) {
97+
free(http->push_headers[http->push_headers_used - 1]);
98+
}
99+
free(http->push_headers);
100+
http->push_headers = NULL;
101+
}
102+
92103
DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
93104

94105
return CURLE_OK;

0 commit comments

Comments
 (0)