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");
|
||||
|
@ -165,14 +165,15 @@ static int logger_remaining(void) {
|
||||
void logger_set_name(const char *restrict format, ...) {
|
||||
va_list args;
|
||||
|
||||
void *ptr;
|
||||
if (key_name == -1) {
|
||||
// not initialized
|
||||
va_start(args, format);
|
||||
vsnprintf(global_name, sizeof(global_name), format, args);
|
||||
ptr = global_name;
|
||||
} else {
|
||||
int ret;
|
||||
void *ptr = pthread_getspecific(key_name);
|
||||
if (!ptr) {
|
||||
if ((ptr = pthread_getspecific(key_name)) == NULL) {
|
||||
ptr = malloc(LOG_NAME_LEN);
|
||||
if ((ret = pthread_setspecific(key_name, ptr)) != 0) {
|
||||
errno = ret;
|
||||
@ -185,6 +186,9 @@ void logger_set_name(const char *restrict format, ...) {
|
||||
vsnprintf(ptr, LOG_NAME_LEN, format, args);
|
||||
}
|
||||
|
||||
// set thread name
|
||||
pthread_setname_np(pthread_self(), global_name);
|
||||
|
||||
// cleanup
|
||||
va_end(args);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ typedef struct {
|
||||
char cc[3], host[256];
|
||||
char req_host[256], err_msg[256];
|
||||
char log_prefix[128];
|
||||
char _c_addr[ADDRSTRLEN + 1], _s_addr[ADDRSTRLEN + 1];
|
||||
char _c_addr[INET6_ADDRSTRLEN + 1], _s_addr[INET6_ADDRSTRLEN + 1];
|
||||
long cnx_s, cnx_e, req_s, res_ts, req_e;
|
||||
http_req req;
|
||||
http_res res;
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "../workers.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int proxy_handler_1(client_ctx_t *ctx);
|
||||
static int proxy_handler_2(client_ctx_t *ctx);
|
||||
|
@ -62,10 +62,8 @@ static void init_ctx(client_ctx_t *ctx) {
|
||||
memset(&ctx->req, 0, sizeof(ctx->req));
|
||||
memset(&ctx->res, 0, sizeof(ctx->res));
|
||||
|
||||
|
||||
ctx->res.status = http_get_status(501);
|
||||
http_init_hdr(&ctx->res.hdr);
|
||||
ctx->res.hdr.last_field_num = -1;
|
||||
sprintf(ctx->res.version, "1.1");
|
||||
|
||||
ctx->status.status = 0;
|
||||
|
@ -32,6 +32,8 @@ void tcp_acceptor_func(client_ctx_t *ctx) {
|
||||
static int tcp_acceptor(client_ctx_t *ctx) {
|
||||
struct sockaddr_in6 server_addr;
|
||||
|
||||
memset(ctx->_c_addr, 0, sizeof(ctx->_c_addr));
|
||||
memset(ctx->_s_addr, 0, sizeof(ctx->_s_addr));
|
||||
inet_ntop(ctx->socket._addr.ipv6.sin6_family, &ctx->socket._addr.ipv6.sin6_addr, ctx->_c_addr, sizeof(ctx->_c_addr));
|
||||
if (strstarts(ctx->_c_addr, "::ffff:")) {
|
||||
ctx->socket.addr = ctx->_c_addr + 7;
|
||||
|
Reference in New Issue
Block a user