Fix list pointer bug in proxy
This commit is contained in:
@ -88,6 +88,7 @@ void http_free_res(http_res *res) {
|
||||
}
|
||||
|
||||
int http_init_hdr(http_hdr *hdr) {
|
||||
hdr->last_field_num = -1;
|
||||
hdr->fields = list_create(sizeof(http_field), HTTP_INIT_HEADER_FIELD_NUM);
|
||||
if (hdr->fields == NULL)
|
||||
return error_http(HTTP_ERROR_SYSCALL);
|
||||
@ -122,8 +123,11 @@ int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr,
|
||||
str_trim_lws(&pos1, &pos2);
|
||||
long len2 = pos2 - pos1;
|
||||
|
||||
char header_name[256];
|
||||
sprintf(header_name, "%.*s", (int) len1, buf);
|
||||
|
||||
int field_num = list_size(hdr->fields);
|
||||
int found = http_get_header_field_num_len(hdr, buf, len1);
|
||||
int found = http_get_header_field_num(hdr, header_name);
|
||||
if (!(flags & HTTP_MERGE_FIELDS) || found == -1) {
|
||||
if (http_add_header_field_len(hdr, buf, len1, pos1, len2 < 0 ? 0 : len2) != 0)
|
||||
return error_http(HTTP_ERROR_TOO_MANY_HEADER_FIELDS);
|
||||
@ -206,7 +210,6 @@ int http_receive_request(sock *client, http_req *req) {
|
||||
memset(req->method, 0, sizeof(req->method));
|
||||
memset(req->version, 0, sizeof(req->version));
|
||||
req->uri = NULL;
|
||||
req->hdr.last_field_num = -1;
|
||||
http_init_hdr(&req->hdr);
|
||||
|
||||
rcv_len = sock_recv(client, buf, CLIENT_MAX_HEADER_SIZE - 1, MSG_PEEK);
|
||||
@ -227,21 +230,13 @@ int http_receive_request(sock *client, http_req *req) {
|
||||
}
|
||||
|
||||
const char *http_get_header_field(const http_hdr *hdr, const char *field_name) {
|
||||
return http_get_header_field_len(hdr, field_name, strlen(field_name));
|
||||
}
|
||||
|
||||
const char *http_get_header_field_len(const http_hdr *hdr, const char *field_name, unsigned long len) {
|
||||
int num = http_get_header_field_num_len(hdr, field_name, len);
|
||||
int num = http_get_header_field_num(hdr, field_name);
|
||||
return (num >= 0 && num < list_size(hdr->fields)) ? http_field_get_value(&hdr->fields[num]) : NULL;
|
||||
}
|
||||
|
||||
int http_get_header_field_num(const http_hdr *hdr, const char *field_name) {
|
||||
return http_get_header_field_num_len(hdr, field_name, strlen(field_name));
|
||||
}
|
||||
|
||||
int http_get_header_field_num_len(const http_hdr *hdr, const char *field_name, unsigned long len) {
|
||||
for (int i = 0; i < list_size(hdr->fields); i++) {
|
||||
if (strncasecmp(field_name, http_field_get_name(&hdr->fields[i]), len) == 0)
|
||||
if (strcasecmp(field_name, http_field_get_name(&hdr->fields[i])) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -156,12 +156,8 @@ int http_parse_header_field(http_hdr *hdr, const char *buf, const char *end_ptr,
|
||||
|
||||
const char *http_get_header_field(const http_hdr *hdr, const char *field_name);
|
||||
|
||||
const char *http_get_header_field_len(const http_hdr *hdr, const char *field_name, unsigned long len);
|
||||
|
||||
int http_get_header_field_num(const http_hdr *hdr, const char *field_name);
|
||||
|
||||
int http_get_header_field_num_len(const http_hdr *hdr, const char *field_name, unsigned long len);
|
||||
|
||||
int http_add_header_field(http_hdr *hdr, const char *field_name, const char *field_value);
|
||||
|
||||
int http_add_header_field_len(http_hdr *hdr, const char *name, unsigned long name_len, const char *value, unsigned long value_len);
|
||||
|
@ -113,7 +113,7 @@ void *list_remove(void *list_ptr, int n) {
|
||||
memset(array + list->size * list->elem_size, 0, list->elem_size);
|
||||
|
||||
list->size--;
|
||||
if (list->size < list->max_size / FACTOR / 2 && list->max_size / FACTOR >= list->init_size) {
|
||||
if (list->size <= list->max_size / FACTOR * 3 / 4 && list->max_size / FACTOR >= list->init_size) {
|
||||
if ((list = list_resize(list, list->max_size / FACTOR)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -135,8 +135,7 @@ void *list_clear(void *list_ptr) {
|
||||
list_meta_t *list = meta(list_ptr);
|
||||
list->size = 0;
|
||||
memset(list_ptr, 0, list->max_size * list->elem_size);
|
||||
list->max_size = list->init_size;
|
||||
return data(list_resize(list, list->max_size));
|
||||
return data(list_resize(list, list->init_size));
|
||||
}
|
||||
|
||||
void list_free(void *list_ptr) {
|
||||
|
@ -163,20 +163,19 @@ int proxy_request_header(http_req *req, sock *sock) {
|
||||
http_add_header_field(&req->hdr, "Via", buf2);
|
||||
}
|
||||
|
||||
const char *host = http_get_header_field(&req->hdr, "Host");
|
||||
const char *forwarded = http_get_header_field(&req->hdr, "Forwarded");
|
||||
int client_ipv6 = strchr(sock->addr, ':') != NULL;
|
||||
int server_ipv6 = strchr(sock->s_addr, ':') != NULL;
|
||||
|
||||
p_len = snprintf(buf1, sizeof(buf1), "by=%s%s%s;for=%s%s%s;host=%s;proto=%s",
|
||||
server_ipv6 ? "\"[" : "", sock->s_addr, server_ipv6 ? "]\"" : "",
|
||||
client_ipv6 ? "\"[" : "", sock->addr, client_ipv6 ? "]\"" : "",
|
||||
host, sock->enc ? "https" : "http");
|
||||
http_get_header_field(&req->hdr, "Host"), sock->enc ? "https" : "http");
|
||||
if (p_len < 0 || p_len >= sizeof(buf1)) {
|
||||
error("Appended part of header field 'Forwarded' too long");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *forwarded = http_get_header_field(&req->hdr, "Forwarded");
|
||||
if (forwarded == NULL) {
|
||||
http_add_header_field(&req->hdr, "Forwarded", buf1);
|
||||
} else {
|
||||
@ -199,9 +198,10 @@ int proxy_request_header(http_req *req, sock *sock) {
|
||||
}
|
||||
|
||||
const char *xfh = http_get_header_field(&req->hdr, "X-Forwarded-Host");
|
||||
forwarded = http_get_header_field(&req->hdr, "Forwarded");
|
||||
if (xfh == NULL) {
|
||||
if (forwarded == NULL) {
|
||||
http_add_header_field(&req->hdr, "X-Forwarded-Host", host);
|
||||
http_add_header_field(&req->hdr, "X-Forwarded-Host", http_get_header_field(&req->hdr, "Host"));
|
||||
} else {
|
||||
char *ptr = strchr(forwarded, ',');
|
||||
unsigned long len;
|
||||
@ -220,6 +220,7 @@ int proxy_request_header(http_req *req, sock *sock) {
|
||||
}
|
||||
|
||||
const char *xfp = http_get_header_field(&req->hdr, "X-Forwarded-Proto");
|
||||
forwarded = http_get_header_field(&req->hdr, "Forwarded");
|
||||
if (xfp == NULL) {
|
||||
if (forwarded == NULL) {
|
||||
http_add_header_field(&req->hdr, "X-Forwarded-Proto", sock->enc ? "https" : "http");
|
||||
|
Reference in New Issue
Block a user