diff options
author | Kamil Dudka <kdudka@redhat.com> | 2015-07-30 12:01:20 +0200 |
---|---|---|
committer | Kamil Dudka <kdudka@redhat.com> | 2015-07-30 15:16:43 +0200 |
commit | f7dcc7c11817f6eaee61b1cd84ffc1b2b1fcac43 (patch) | |
tree | e46ddd5415d7f51ac19aab65724865da0c8a4249 /lib/http2.c | |
parent | ecf7618e1209ade74cf63ab10a460db582a06dbd (diff) |
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
Diffstat (limited to 'lib/http2.c')
-rw-r--r-- | lib/http2.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/lib/http2.c b/lib/http2.c index 1a2c48649..eec0c9fca 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -80,6 +80,7 @@ static int http2_getsock(struct connectdata *conn, static CURLcode http2_disconnect(struct connectdata *conn, bool dead_connection) { + struct HTTP *http = conn->data->req.protop; struct http_conn *c = &conn->proto.httpc; (void)dead_connection; @@ -89,6 +90,16 @@ static CURLcode http2_disconnect(struct connectdata *conn, Curl_safefree(c->inbuf); Curl_hash_destroy(&c->streamsh); + if(http) { + Curl_add_buffer_free(http->header_recvbuf); + http->header_recvbuf = NULL; /* clear the pointer */ + for(; http->push_headers_used > 0; --http->push_headers_used) { + free(http->push_headers[http->push_headers_used - 1]); + } + free(http->push_headers); + http->push_headers = NULL; + } + DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n")); return CURLE_OK; |