BUG/MAJOR: compression: Be sure to release the compression state in all cases
This patch fixes an obvious memory leak in the compression filter. The compression state (comp_state) is allocated when a HTTP transaction starts, in channel_start_analyze callback, Whether we are able to compression the response or not. So it must be released when the transaction ends, in channel_end_analyze callback. But there is a bug here. The state is released on the response side only. So, if a transaction ends before the response is started, it is never released. This happens when a connection is closed before the response is started. To fix the bug, statistics about the HTTP compression are now updated in http_end callback, when the response parsing ends. It happens only if no error is encountered and when the response is compressed. So, it is safe to release the compression state in channel_end_analyze callback, regardless the channel's type. This patch must be backported in 1.7.
This commit is contained in:
parent
8d85aa44da
commit
d60b3cf431
@ -107,21 +107,12 @@ comp_end_analyze(struct stream *s, struct filter *filter, struct channel *chn)
|
||||
{
|
||||
struct comp_state *st = filter->ctx;
|
||||
|
||||
if (!st || !(chn->flags & CF_ISRESP))
|
||||
if (!st)
|
||||
goto end;
|
||||
|
||||
if (!st->comp_algo || !s->txn->status)
|
||||
goto release_ctx;
|
||||
|
||||
if (strm_fe(s)->mode == PR_MODE_HTTP)
|
||||
strm_fe(s)->fe_counters.p.http.comp_rsp++;
|
||||
if ((s->flags & SF_BE_ASSIGNED) && (s->be->mode == PR_MODE_HTTP))
|
||||
s->be->be_counters.p.http.comp_rsp++;
|
||||
|
||||
/* release any possible compression context */
|
||||
st->comp_algo->end(&st->comp_ctx);
|
||||
|
||||
release_ctx:
|
||||
if (st->comp_algo)
|
||||
st->comp_algo->end(&st->comp_ctx);
|
||||
free(st);
|
||||
filter->ctx = NULL;
|
||||
end:
|
||||
@ -299,6 +290,22 @@ comp_http_forward_data(struct stream *s, struct filter *filter,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
comp_http_end(struct stream *s, struct filter *filter,
|
||||
struct http_msg *msg)
|
||||
{
|
||||
struct comp_state *st = filter->ctx;
|
||||
|
||||
if (!(msg->chn->flags & CF_ISRESP) || !st || !st->comp_algo)
|
||||
goto end;
|
||||
|
||||
if (strm_fe(s)->mode == PR_MODE_HTTP)
|
||||
strm_fe(s)->fe_counters.p.http.comp_rsp++;
|
||||
if ((s->flags & SF_BE_ASSIGNED) && (s->be->mode == PR_MODE_HTTP))
|
||||
s->be->be_counters.p.http.comp_rsp++;
|
||||
end:
|
||||
return 1;
|
||||
}
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* Selects a compression algorithm depending on the client request.
|
||||
@ -761,6 +768,7 @@ struct flt_ops comp_ops = {
|
||||
.http_data = comp_http_data,
|
||||
.http_chunk_trailers = comp_http_chunk_trailers,
|
||||
.http_forward_data = comp_http_forward_data,
|
||||
.http_end = comp_http_end,
|
||||
};
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user