http2: push headers better cleanup

- provide common cleanup method for push headers

Closes #13054
This commit is contained in:
Stefan Eissing 2024-03-06 09:36:08 +01:00 committed by Daniel Stenberg
parent 1347cf255b
commit deca803999
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -271,6 +271,15 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf,
return CURLE_OK; return CURLE_OK;
} }
static void free_push_headers(struct h2_stream_ctx *stream)
{
size_t i;
for(i = 0; i<stream->push_headers_used; i++)
free(stream->push_headers[i]);
Curl_safefree(stream->push_headers);
stream->push_headers_used = 0;
}
static void http2_data_done(struct Curl_cfilter *cf, static void http2_data_done(struct Curl_cfilter *cf,
struct Curl_easy *data, bool premature) struct Curl_easy *data, bool premature)
{ {
@ -306,15 +315,7 @@ static void http2_data_done(struct Curl_cfilter *cf,
Curl_bufq_free(&stream->sendbuf); Curl_bufq_free(&stream->sendbuf);
Curl_h1_req_parse_free(&stream->h1); Curl_h1_req_parse_free(&stream->h1);
Curl_dynhds_free(&stream->resp_trailers); Curl_dynhds_free(&stream->resp_trailers);
if(stream->push_headers) { free_push_headers(stream);
/* if they weren't used and then freed before */
for(; stream->push_headers_used > 0; --stream->push_headers_used) {
free(stream->push_headers[stream->push_headers_used - 1]);
}
free(stream->push_headers);
stream->push_headers = NULL;
}
free(stream); free(stream);
H2_STREAM_LCTX(data) = NULL; H2_STREAM_LCTX(data) = NULL;
} }
@ -860,7 +861,6 @@ static int push_promise(struct Curl_cfilter *cf,
struct curl_pushheaders heads; struct curl_pushheaders heads;
CURLMcode rc; CURLMcode rc;
CURLcode result; CURLcode result;
size_t i;
/* clone the parent */ /* clone the parent */
struct Curl_easy *newhandle = h2_duphandle(cf, data); struct Curl_easy *newhandle = h2_duphandle(cf, data);
if(!newhandle) { if(!newhandle) {
@ -905,11 +905,7 @@ static int push_promise(struct Curl_cfilter *cf,
Curl_set_in_callback(data, false); Curl_set_in_callback(data, false);
/* free the headers again */ /* free the headers again */
for(i = 0; i<stream->push_headers_used; i++) free_push_headers(stream);
free(stream->push_headers[i]);
free(stream->push_headers);
stream->push_headers = NULL;
stream->push_headers_used = 0;
if(rv) { if(rv) {
DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT)); DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
@ -1430,14 +1426,14 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
if(stream->push_headers_alloc > 1000) { if(stream->push_headers_alloc > 1000) {
/* this is beyond crazy many headers, bail out */ /* this is beyond crazy many headers, bail out */
failf(data_s, "Too many PUSH_PROMISE headers"); failf(data_s, "Too many PUSH_PROMISE headers");
Curl_safefree(stream->push_headers); free_push_headers(stream);
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
} }
stream->push_headers_alloc *= 2; stream->push_headers_alloc *= 2;
headp = Curl_saferealloc(stream->push_headers, headp = realloc(stream->push_headers,
stream->push_headers_alloc * sizeof(char *)); stream->push_headers_alloc * sizeof(char *));
if(!headp) { if(!headp) {
stream->push_headers = NULL; free_push_headers(stream);
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
} }
stream->push_headers = headp; stream->push_headers = headp;