Fix memory leak on location rewrite in rev_proxy
This commit is contained in:
@ -498,9 +498,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
|
|||||||
const char *content_type = http_get_header_field(&res.hdr, "Content-Type");
|
const char *content_type = http_get_header_field(&res.hdr, "Content-Type");
|
||||||
const char *content_length_f = http_get_header_field(&res.hdr, "Content-Length");
|
const char *content_length_f = http_get_header_field(&res.hdr, "Content-Length");
|
||||||
const char *content_encoding = http_get_header_field(&res.hdr, "Content-Encoding");
|
const char *content_encoding = http_get_header_field(&res.hdr, "Content-Encoding");
|
||||||
if (content_encoding == NULL && content_type != NULL && content_length_f != NULL &&
|
if (content_encoding == NULL && content_type != NULL && content_length_f != NULL && strncmp(content_type, "text/html", 9) == 0) {
|
||||||
strncmp(content_type, "text/html", 9) == 0)
|
|
||||||
{
|
|
||||||
long content_len = strtol(content_length_f, NULL, 10);
|
long content_len = strtol(content_length_f, NULL, 10);
|
||||||
if (content_len <= sizeof(msg_content) - 1) {
|
if (content_len <= sizeof(msg_content) - 1) {
|
||||||
ctx.status = res.status->code;
|
ctx.status = res.status->code;
|
||||||
|
@ -48,22 +48,25 @@ const char *http_field_get_value(const http_field *field) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void http_free_field(http_field *f) {
|
||||||
|
if (f->type == HTTP_FIELD_NORMAL) {
|
||||||
|
f->normal.name[0] = 0;
|
||||||
|
f->normal.value[0] = 0;
|
||||||
|
} else if (f->type == HTTP_FIELD_EX_VALUE) {
|
||||||
|
f->ex_value.name[0] = 0;
|
||||||
|
free(f->ex_value.value);
|
||||||
|
f->ex_value.value = NULL;
|
||||||
|
} else if (f->type == HTTP_FIELD_EX_NAME) {
|
||||||
|
free(f->ex_name.name);
|
||||||
|
free(f->ex_name.value);
|
||||||
|
f->ex_name.name = NULL;
|
||||||
|
f->ex_name.value = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void http_free_hdr(http_hdr *hdr) {
|
void http_free_hdr(http_hdr *hdr) {
|
||||||
for (int i = 0; i < hdr->field_num; i++) {
|
for (int i = 0; i < hdr->field_num; i++) {
|
||||||
http_field *f = &hdr->fields[i];
|
http_free_field(&hdr->fields[i]);
|
||||||
if (f->type == HTTP_FIELD_NORMAL) {
|
|
||||||
f->normal.name[0] = 0;
|
|
||||||
f->normal.value[0] = 0;
|
|
||||||
} else if (f->type == HTTP_FIELD_EX_VALUE) {
|
|
||||||
f->ex_value.name[0] = 0;
|
|
||||||
free(f->ex_value.value);
|
|
||||||
f->ex_value.value = NULL;
|
|
||||||
} else if (f->type == HTTP_FIELD_EX_NAME) {
|
|
||||||
free(f->ex_name.name);
|
|
||||||
free(f->ex_name.value);
|
|
||||||
f->ex_name.name = NULL;
|
|
||||||
f->ex_name.value = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hdr->field_num = 0;
|
hdr->field_num = 0;
|
||||||
hdr->last_field_num = -1;
|
hdr->last_field_num = -1;
|
||||||
@ -326,6 +329,7 @@ void http_remove_header_field(http_hdr *hdr, const char *field_name, int mode) {
|
|||||||
strcpy(field_name_2, http_field_get_name(&hdr->fields[i]));
|
strcpy(field_name_2, http_field_get_name(&hdr->fields[i]));
|
||||||
http_to_camel_case(field_name_2, HTTP_LOWER);
|
http_to_camel_case(field_name_2, HTTP_LOWER);
|
||||||
if (strcmp(field_name_1, field_name_2) == 0) {
|
if (strcmp(field_name_1, field_name_2) == 0) {
|
||||||
|
http_free_field(&hdr->fields[i]);
|
||||||
memmove(&hdr->fields[i], &hdr->fields[i + 1], sizeof(hdr->fields[0]) * (hdr->field_num - i));
|
memmove(&hdr->fields[i], &hdr->fields[i + 1], sizeof(hdr->fields[0]) * (hdr->field_num - i));
|
||||||
hdr->field_num--;
|
hdr->field_num--;
|
||||||
if (mode == HTTP_REMOVE_ALL) {
|
if (mode == HTTP_REMOVE_ALL) {
|
||||||
|
@ -130,6 +130,8 @@ const char *http_field_get_name(const http_field *field);
|
|||||||
|
|
||||||
const char *http_field_get_value(const http_field *field);
|
const char *http_field_get_value(const http_field *field);
|
||||||
|
|
||||||
|
void http_free_field(http_field *f);
|
||||||
|
|
||||||
void http_free_hdr(http_hdr *hdr);
|
void http_free_hdr(http_hdr *hdr);
|
||||||
|
|
||||||
void http_free_req(http_req *req);
|
void http_free_req(http_req *req);
|
||||||
|
@ -29,8 +29,7 @@ int rev_proxy_preload() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int rev_proxy_request_header(http_req *req, int enc) {
|
int rev_proxy_request_header(http_req *req, int enc) {
|
||||||
char buf1[256];
|
char buf1[256], buf2[256];
|
||||||
char buf2[256];
|
|
||||||
int p_len;
|
int p_len;
|
||||||
http_remove_header_field(&req->hdr, "Connection", HTTP_REMOVE_ALL);
|
http_remove_header_field(&req->hdr, "Connection", HTTP_REMOVE_ALL);
|
||||||
http_add_header_field(&req->hdr, "Connection", "keep-alive");
|
http_add_header_field(&req->hdr, "Connection", "keep-alive");
|
||||||
@ -52,7 +51,7 @@ int rev_proxy_request_header(http_req *req, int enc) {
|
|||||||
const char *host = http_get_header_field(&req->hdr, "Host");
|
const char *host = http_get_header_field(&req->hdr, "Host");
|
||||||
const char *forwarded = http_get_header_field(&req->hdr, "Forwarded");
|
const char *forwarded = http_get_header_field(&req->hdr, "Forwarded");
|
||||||
int client_ipv6 = strchr(client_addr_str, ':') != NULL;
|
int client_ipv6 = strchr(client_addr_str, ':') != NULL;
|
||||||
int server_ipv6 = strchr(server_addr_str, ':') != NULL;
|
int server_ipv6 = strchr(server_addr_str, ':') != NULL;
|
||||||
|
|
||||||
p_len = snprintf(buf1, sizeof(buf1), "by=%s%s%s;for=%s%s%s;host=%s;proto=%s",
|
p_len = snprintf(buf1, sizeof(buf1), "by=%s%s%s;for=%s%s%s;host=%s;proto=%s",
|
||||||
server_ipv6 ? "\"[" : "", server_addr_str, server_ipv6 ? "]\"" : "",
|
server_ipv6 ? "\"[" : "", server_addr_str, server_ipv6 ? "]\"" : "",
|
||||||
@ -62,6 +61,7 @@ int rev_proxy_request_header(http_req *req, int enc) {
|
|||||||
print(ERR_STR "Appended part of header field 'Forwarded' too long" CLR_STR);
|
print(ERR_STR "Appended part of header field 'Forwarded' too long" CLR_STR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forwarded == NULL) {
|
if (forwarded == NULL) {
|
||||||
http_add_header_field(&req->hdr, "Forwarded", buf1);
|
http_add_header_field(&req->hdr, "Forwarded", buf1);
|
||||||
} else {
|
} else {
|
||||||
@ -129,8 +129,7 @@ int rev_proxy_request_header(http_req *req, int enc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int rev_proxy_response_header(http_req *req, http_res *res, host_config *conf) {
|
int rev_proxy_response_header(http_req *req, http_res *res, host_config *conf) {
|
||||||
char buf1[256];
|
char buf1[256], buf2[256];
|
||||||
char buf2[256];
|
|
||||||
int p_len;
|
int p_len;
|
||||||
|
|
||||||
const char *via = http_get_header_field(&res->hdr, "Via");
|
const char *via = http_get_header_field(&res->hdr, "Via");
|
||||||
@ -172,20 +171,19 @@ int rev_proxy_response_header(http_req *req, http_res *res, host_config *conf) {
|
|||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
match:
|
match:
|
||||||
|
strcpy(buf1, location + p_len - 1);
|
||||||
http_remove_header_field(&res->hdr, "Location", HTTP_REMOVE_ALL);
|
http_remove_header_field(&res->hdr, "Location", HTTP_REMOVE_ALL);
|
||||||
http_add_header_field(&res->hdr, "Location", location + p_len - 1);
|
http_add_header_field(&res->hdr, "Location", buf1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config *conf, sock *client,
|
int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config *conf, sock *client, http_status *custom_status, char *err_msg) {
|
||||||
http_status *custom_status, char *err_msg) {
|
|
||||||
char buffer[CHUNK_SIZE];
|
char buffer[CHUNK_SIZE];
|
||||||
long ret;
|
long ret;
|
||||||
int tries = 0;
|
int tries = 0, retry = 0;
|
||||||
int retry = 0;
|
|
||||||
|
|
||||||
if (rev_proxy.socket != 0 && strcmp(rev_proxy_host, conf->name) == 0 && sock_check(&rev_proxy) == 0) {
|
if (rev_proxy.socket != 0 && strcmp(rev_proxy_host, conf->name) == 0 && sock_check(&rev_proxy) == 0) {
|
||||||
goto rev_proxy;
|
goto rev_proxy;
|
||||||
@ -455,13 +453,9 @@ int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_conf
|
|||||||
|
|
||||||
int rev_proxy_send(sock *client, unsigned long len_to_send, int flags) {
|
int rev_proxy_send(sock *client, unsigned long len_to_send, int flags) {
|
||||||
// TODO handle websockets
|
// TODO handle websockets
|
||||||
long ret = 0;
|
char buffer[CHUNK_SIZE], comp_out[CHUNK_SIZE], buf[256], *ptr;
|
||||||
char buffer[CHUNK_SIZE];
|
long ret = 0, len, snd_len;
|
||||||
char comp_out[CHUNK_SIZE];
|
|
||||||
char buf[256];
|
|
||||||
long len, snd_len;
|
|
||||||
int finish_comp = 0;
|
int finish_comp = 0;
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
compress_ctx comp_ctx;
|
compress_ctx comp_ctx;
|
||||||
if (flags & REV_PROXY_COMPRESS_BR) {
|
if (flags & REV_PROXY_COMPRESS_BR) {
|
||||||
|
Reference in New Issue
Block a user