Router: forwared header replacement.
This commit is contained in:
@@ -31,6 +31,12 @@ NGINX Unit updated to 1.28.0.
|
|||||||
date="" time=""
|
date="" time=""
|
||||||
packager="Konstantin Pavlov <thresh@nginx.com>">
|
packager="Konstantin Pavlov <thresh@nginx.com>">
|
||||||
|
|
||||||
|
<change type="feature">
|
||||||
|
<para>
|
||||||
|
forwarded header to replace client address and protocol.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
</changes>
|
</changes>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,8 @@ static nxt_int_t nxt_conf_vldt_match_addr(nxt_conf_validation_t *vldt,
|
|||||||
nxt_conf_value_t *value);
|
nxt_conf_value_t *value);
|
||||||
static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt,
|
static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt,
|
||||||
nxt_conf_value_t *value, void *data);
|
nxt_conf_value_t *value, void *data);
|
||||||
|
static nxt_int_t nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt,
|
||||||
|
nxt_conf_value_t *value, void *data);
|
||||||
static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt,
|
static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt,
|
||||||
nxt_str_t *name, nxt_conf_value_t *value);
|
nxt_str_t *name, nxt_conf_value_t *value);
|
||||||
static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt,
|
static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt,
|
||||||
@@ -220,6 +222,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[];
|
|||||||
static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[];
|
static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[];
|
||||||
static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[];
|
static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[];
|
||||||
static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[];
|
static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[];
|
||||||
|
static nxt_conf_vldt_object_t nxt_conf_vldt_forwarded_members[];
|
||||||
static nxt_conf_vldt_object_t nxt_conf_vldt_client_ip_members[];
|
static nxt_conf_vldt_object_t nxt_conf_vldt_client_ip_members[];
|
||||||
#if (NXT_TLS)
|
#if (NXT_TLS)
|
||||||
static nxt_conf_vldt_object_t nxt_conf_vldt_tls_members[];
|
static nxt_conf_vldt_object_t nxt_conf_vldt_tls_members[];
|
||||||
@@ -365,6 +368,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = {
|
|||||||
.name = nxt_string("application"),
|
.name = nxt_string("application"),
|
||||||
.type = NXT_CONF_VLDT_STRING,
|
.type = NXT_CONF_VLDT_STRING,
|
||||||
.validator = nxt_conf_vldt_app_name,
|
.validator = nxt_conf_vldt_app_name,
|
||||||
|
}, {
|
||||||
|
.name = nxt_string("forwarded"),
|
||||||
|
.type = NXT_CONF_VLDT_OBJECT,
|
||||||
|
.validator = nxt_conf_vldt_forwarded,
|
||||||
}, {
|
}, {
|
||||||
.name = nxt_string("client_ip"),
|
.name = nxt_string("client_ip"),
|
||||||
.type = NXT_CONF_VLDT_OBJECT,
|
.type = NXT_CONF_VLDT_OBJECT,
|
||||||
@@ -385,6 +392,27 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_conf_vldt_object_t nxt_conf_vldt_forwarded_members[] = {
|
||||||
|
{
|
||||||
|
.name = nxt_string("client_ip"),
|
||||||
|
.type = NXT_CONF_VLDT_STRING,
|
||||||
|
}, {
|
||||||
|
.name = nxt_string("protocol"),
|
||||||
|
.type = NXT_CONF_VLDT_STRING,
|
||||||
|
}, {
|
||||||
|
.name = nxt_string("source"),
|
||||||
|
.type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY,
|
||||||
|
.validator = nxt_conf_vldt_match_addrs,
|
||||||
|
.flags = NXT_CONF_VLDT_REQUIRED
|
||||||
|
}, {
|
||||||
|
.name = nxt_string("recursive"),
|
||||||
|
.type = NXT_CONF_VLDT_BOOLEAN,
|
||||||
|
},
|
||||||
|
|
||||||
|
NXT_CONF_VLDT_END
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static nxt_conf_vldt_object_t nxt_conf_vldt_client_ip_members[] = {
|
static nxt_conf_vldt_object_t nxt_conf_vldt_client_ip_members[] = {
|
||||||
{
|
{
|
||||||
.name = nxt_string("source"),
|
.name = nxt_string("source"),
|
||||||
@@ -2317,6 +2345,28 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
nxt_conf_value_t *client_ip, *protocol;
|
||||||
|
|
||||||
|
static nxt_str_t client_ip_str = nxt_string("client_ip");
|
||||||
|
static nxt_str_t protocol_str = nxt_string("protocol");
|
||||||
|
|
||||||
|
client_ip = nxt_conf_get_object_member(value, &client_ip_str, NULL);
|
||||||
|
protocol = nxt_conf_get_object_member(value, &protocol_str, NULL);
|
||||||
|
|
||||||
|
if (client_ip == NULL && protocol == NULL) {
|
||||||
|
return nxt_conf_vldt_error(vldt, "The \"forwarded\" object must have "
|
||||||
|
"either \"client_ip\" or \"protocol\" "
|
||||||
|
"option set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return nxt_conf_vldt_object(vldt, value, nxt_conf_vldt_forwarded_members);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name,
|
nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name,
|
||||||
nxt_conf_value_t *value)
|
nxt_conf_value_t *value)
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ nxt_h1p_conn_request_init(nxt_task_t *task, void *obj, void *data)
|
|||||||
r->remote = c->remote;
|
r->remote = c->remote;
|
||||||
|
|
||||||
#if (NXT_TLS)
|
#if (NXT_TLS)
|
||||||
r->tls = c->u.tls;
|
r->tls = (c->u.tls != NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
r->task = c->task;
|
r->task = c->task;
|
||||||
|
|||||||
@@ -162,7 +162,6 @@ struct nxt_http_request_s {
|
|||||||
|
|
||||||
nxt_sockaddr_t *remote;
|
nxt_sockaddr_t *remote;
|
||||||
nxt_sockaddr_t *local;
|
nxt_sockaddr_t *local;
|
||||||
void *tls;
|
|
||||||
nxt_task_t task;
|
nxt_task_t task;
|
||||||
|
|
||||||
nxt_timer_t timer;
|
nxt_timer_t timer;
|
||||||
@@ -190,6 +189,7 @@ struct nxt_http_request_s {
|
|||||||
uint8_t pass_count; /* 8 bits */
|
uint8_t pass_count; /* 8 bits */
|
||||||
uint8_t app_target;
|
uint8_t app_target;
|
||||||
nxt_http_protocol_t protocol:8; /* 2 bits */
|
nxt_http_protocol_t protocol:8; /* 2 bits */
|
||||||
|
uint8_t tls; /* 1 bit */
|
||||||
uint8_t logged; /* 1 bit */
|
uint8_t logged; /* 1 bit */
|
||||||
uint8_t header_sent; /* 1 bit */
|
uint8_t header_sent; /* 1 bit */
|
||||||
uint8_t inconsistent; /* 1 bit */
|
uint8_t inconsistent; /* 1 bit */
|
||||||
@@ -281,6 +281,7 @@ typedef struct {
|
|||||||
|
|
||||||
struct nxt_http_forward_s {
|
struct nxt_http_forward_s {
|
||||||
nxt_http_forward_header_t client_ip;
|
nxt_http_forward_header_t client_ip;
|
||||||
|
nxt_http_forward_header_t protocol;
|
||||||
nxt_http_route_addr_rule_t *source;
|
nxt_http_route_addr_rule_t *source;
|
||||||
uint8_t recursive; /* 1 bit */
|
uint8_t recursive; /* 1 bit */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,10 +10,14 @@
|
|||||||
|
|
||||||
static nxt_int_t nxt_http_validate_host(nxt_str_t *host, nxt_mp_t *mp);
|
static nxt_int_t nxt_http_validate_host(nxt_str_t *host, nxt_mp_t *mp);
|
||||||
static void nxt_http_request_start(nxt_task_t *task, void *obj, void *data);
|
static void nxt_http_request_start(nxt_task_t *task, void *obj, void *data);
|
||||||
static nxt_int_t nxt_http_request_client_ip(nxt_task_t *task,
|
static nxt_int_t nxt_http_request_forward(nxt_task_t *task,
|
||||||
nxt_http_request_t *r);
|
nxt_http_request_t *r, nxt_http_forward_t *forward);
|
||||||
|
static void nxt_http_request_forward_client_ip(nxt_http_request_t *r,
|
||||||
|
nxt_http_forward_t *forward, nxt_array_t *fields);
|
||||||
static nxt_sockaddr_t *nxt_http_request_client_ip_sockaddr(
|
static nxt_sockaddr_t *nxt_http_request_client_ip_sockaddr(
|
||||||
nxt_http_request_t *r, u_char *start, size_t len);
|
nxt_http_request_t *r, u_char *start, size_t len);
|
||||||
|
static void nxt_http_request_forward_protocol(nxt_http_request_t *r,
|
||||||
|
nxt_http_field_t *field);
|
||||||
static void nxt_http_request_ready(nxt_task_t *task, void *obj, void *data);
|
static void nxt_http_request_ready(nxt_task_t *task, void *obj, void *data);
|
||||||
static void nxt_http_request_proto_info(nxt_task_t *task,
|
static void nxt_http_request_proto_info(nxt_task_t *task,
|
||||||
nxt_http_request_t *r);
|
nxt_http_request_t *r);
|
||||||
@@ -296,38 +300,46 @@ static void
|
|||||||
nxt_http_request_start(nxt_task_t *task, void *obj, void *data)
|
nxt_http_request_start(nxt_task_t *task, void *obj, void *data)
|
||||||
{
|
{
|
||||||
nxt_int_t ret;
|
nxt_int_t ret;
|
||||||
|
nxt_socket_conf_t *skcf;
|
||||||
nxt_http_request_t *r;
|
nxt_http_request_t *r;
|
||||||
|
|
||||||
r = obj;
|
r = obj;
|
||||||
|
|
||||||
r->state = &nxt_http_request_body_state;
|
r->state = &nxt_http_request_body_state;
|
||||||
|
|
||||||
ret = nxt_http_request_client_ip(task, r);
|
skcf = r->conf->socket_conf;
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
|
||||||
nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
|
if (skcf->forwarded != NULL) {
|
||||||
|
ret = nxt_http_request_forward(task, r, skcf->forwarded);
|
||||||
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skcf->client_ip != NULL) {
|
||||||
|
ret = nxt_http_request_forward(task, r, skcf->client_ip);
|
||||||
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_http_request_read_body(task, r);
|
nxt_http_request_read_body(task, r);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r)
|
nxt_http_request_forward(nxt_task_t *task, nxt_http_request_t *r,
|
||||||
|
nxt_http_forward_t *forward)
|
||||||
{
|
{
|
||||||
u_char *start, *p;
|
nxt_int_t ret;
|
||||||
nxt_int_t ret, i, len;
|
nxt_array_t *client_ip_fields;
|
||||||
nxt_str_t *header;
|
nxt_http_field_t *f, **fields, *protocol_field;
|
||||||
nxt_array_t *fields_arr; /* of nxt_http_field_t * */
|
nxt_http_forward_header_t *client_ip, *protocol;
|
||||||
nxt_sockaddr_t *sa, *prev_sa;
|
|
||||||
nxt_http_field_t *f, **fields;
|
|
||||||
nxt_http_forward_t *forward;
|
|
||||||
nxt_http_forward_header_t *client_ip;
|
|
||||||
|
|
||||||
forward = r->conf->socket_conf->client_ip;
|
|
||||||
|
|
||||||
if (forward == NULL) {
|
|
||||||
return NXT_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nxt_http_route_addr_rule(r, forward->source, r->remote);
|
ret = nxt_http_route_addr_rule(r, forward->source, r->remote);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
@@ -335,37 +347,78 @@ nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
client_ip = &forward->client_ip;
|
client_ip = &forward->client_ip;
|
||||||
header = client_ip->header;
|
protocol = &forward->protocol;
|
||||||
|
|
||||||
fields_arr = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_field_t *));
|
if (client_ip->header != NULL) {
|
||||||
if (nxt_slow_path(fields_arr == NULL)) {
|
client_ip_fields = nxt_array_create(r->mem_pool, 1,
|
||||||
return NXT_ERROR;
|
sizeof(nxt_http_field_t *));
|
||||||
|
if (nxt_slow_path(client_ip_fields == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
client_ip_fields = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protocol_field = NULL;
|
||||||
|
|
||||||
nxt_list_each(f, r->fields) {
|
nxt_list_each(f, r->fields) {
|
||||||
if (f->hash == client_ip->header_hash
|
if (client_ip_fields != NULL
|
||||||
&& f->name_length == client_ip->header->length
|
&& f->hash == client_ip->header_hash
|
||||||
&& f->value_length > 0
|
&& f->value_length > 0
|
||||||
&& nxt_memcasecmp(f->name, header->start, header->length) == 0)
|
&& f->name_length == client_ip->header->length
|
||||||
|
&& nxt_memcasecmp(f->name, client_ip->header->start,
|
||||||
|
client_ip->header->length) == 0)
|
||||||
{
|
{
|
||||||
fields = nxt_array_add(fields_arr);
|
fields = nxt_array_add(client_ip_fields);
|
||||||
if (nxt_slow_path(fields == NULL)) {
|
if (nxt_slow_path(fields == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*fields = f;
|
*fields = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (protocol->header != NULL
|
||||||
|
&& protocol_field == NULL
|
||||||
|
&& f->hash == protocol->header_hash
|
||||||
|
&& f->value_length > 0
|
||||||
|
&& f->name_length == protocol->header->length
|
||||||
|
&& nxt_memcasecmp(f->name, protocol->header->start,
|
||||||
|
protocol->header->length) == 0)
|
||||||
|
{
|
||||||
|
protocol_field = f;
|
||||||
|
}
|
||||||
} nxt_list_loop;
|
} nxt_list_loop;
|
||||||
|
|
||||||
prev_sa = r->remote;
|
if (client_ip_fields != NULL) {
|
||||||
fields = (nxt_http_field_t **) fields_arr->elts;
|
nxt_http_request_forward_client_ip(r, forward, client_ip_fields);
|
||||||
|
}
|
||||||
|
|
||||||
i = fields_arr->nelts;
|
if (protocol_field != NULL) {
|
||||||
|
nxt_http_request_forward_protocol(r, protocol_field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NXT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_http_request_forward_client_ip(nxt_http_request_t *r,
|
||||||
|
nxt_http_forward_t *forward, nxt_array_t *fields)
|
||||||
|
{
|
||||||
|
u_char *start, *p;
|
||||||
|
nxt_int_t ret, i, len;
|
||||||
|
nxt_sockaddr_t *sa, *prev_sa;
|
||||||
|
nxt_http_field_t **f;
|
||||||
|
|
||||||
|
prev_sa = r->remote;
|
||||||
|
f = (nxt_http_field_t **) fields->elts;
|
||||||
|
|
||||||
|
i = fields->nelts;
|
||||||
|
|
||||||
while (i-- > 0) {
|
while (i-- > 0) {
|
||||||
f = fields[i];
|
start = f[i]->value;
|
||||||
start = f->value;
|
len = f[i]->value_length;
|
||||||
len = f->value_length;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
for (p = start + len - 1; p > start; p--, len--) {
|
for (p = start + len - 1; p > start; p--, len--) {
|
||||||
@@ -387,20 +440,18 @@ nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r)
|
|||||||
r->remote = prev_sa;
|
r->remote = prev_sa;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NXT_OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forward->recursive) {
|
if (!forward->recursive) {
|
||||||
r->remote = sa;
|
r->remote = sa;
|
||||||
|
return;
|
||||||
return NXT_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nxt_http_route_addr_rule(r, forward->source, sa);
|
ret = nxt_http_route_addr_rule(r, forward->source, sa);
|
||||||
if (ret <= 0 || (i == 0 && p == start)) {
|
if (ret <= 0 || (i == 0 && p == start)) {
|
||||||
r->remote = sa;
|
r->remote = sa;
|
||||||
|
return;
|
||||||
return NXT_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_sa = sa;
|
prev_sa = sa;
|
||||||
@@ -408,8 +459,6 @@ nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r)
|
|||||||
|
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NXT_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -453,6 +502,28 @@ nxt_http_request_client_ip_sockaddr(nxt_http_request_t *r, u_char *start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
nxt_http_request_forward_protocol(nxt_http_request_t *r,
|
||||||
|
nxt_http_field_t *field)
|
||||||
|
{
|
||||||
|
if (field->value_length == 4) {
|
||||||
|
if (nxt_memcasecmp(field->value, "http", 4) == 0) {
|
||||||
|
r->tls = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (field->value_length == 5) {
|
||||||
|
if (nxt_memcasecmp(field->value, "https", 5) == 0) {
|
||||||
|
r->tls = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (field->value_length == 2) {
|
||||||
|
if (nxt_memcasecmp(field->value, "on", 2) == 0) {
|
||||||
|
r->tls = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const nxt_http_request_state_t nxt_http_request_body_state
|
static const nxt_http_request_state_t nxt_http_request_body_state
|
||||||
nxt_aligned(64) =
|
nxt_aligned(64) =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1949,14 +1949,13 @@ nxt_http_route_test_argument(nxt_http_request_t *r,
|
|||||||
static nxt_int_t
|
static nxt_int_t
|
||||||
nxt_http_route_scheme(nxt_http_request_t *r, nxt_http_route_rule_t *rule)
|
nxt_http_route_scheme(nxt_http_request_t *r, nxt_http_route_rule_t *rule)
|
||||||
{
|
{
|
||||||
nxt_bool_t tls, https;
|
nxt_bool_t https;
|
||||||
nxt_http_route_pattern_slice_t *pattern_slice;
|
nxt_http_route_pattern_slice_t *pattern_slice;
|
||||||
|
|
||||||
pattern_slice = rule->pattern[0].u.pattern_slices->elts;
|
pattern_slice = rule->pattern[0].u.pattern_slices->elts;
|
||||||
https = (pattern_slice->length == nxt_length("https"));
|
https = (pattern_slice->length == nxt_length("https"));
|
||||||
tls = (r->tls != NULL);
|
|
||||||
|
|
||||||
return (tls == https);
|
return (r->tls == https);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
107
src/nxt_router.c
107
src/nxt_router.c
@@ -108,8 +108,10 @@ static nxt_int_t nxt_router_conf_create(nxt_task_t *task,
|
|||||||
nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end);
|
nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end);
|
||||||
static nxt_int_t nxt_router_conf_process_static(nxt_task_t *task,
|
static nxt_int_t nxt_router_conf_process_static(nxt_task_t *task,
|
||||||
nxt_router_conf_t *rtcf, nxt_conf_value_t *conf);
|
nxt_router_conf_t *rtcf, nxt_conf_value_t *conf);
|
||||||
static nxt_int_t nxt_router_conf_process_client_ip(nxt_task_t *task,
|
static nxt_http_forward_t *nxt_router_conf_forward(nxt_task_t *task,
|
||||||
nxt_mp_t *mp, nxt_socket_conf_t *skcf, nxt_conf_value_t *conf);
|
nxt_mp_t *mp, nxt_conf_value_t *conf);
|
||||||
|
static nxt_int_t nxt_router_conf_forward_header(nxt_mp_t *mp,
|
||||||
|
nxt_conf_value_t *conf, nxt_http_forward_header_t *fh);
|
||||||
|
|
||||||
static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name);
|
static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name);
|
||||||
static nxt_int_t nxt_router_apps_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
|
static nxt_int_t nxt_router_apps_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
|
||||||
@@ -1513,6 +1515,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
#endif
|
#endif
|
||||||
static nxt_str_t static_path = nxt_string("/settings/http/static");
|
static nxt_str_t static_path = nxt_string("/settings/http/static");
|
||||||
static nxt_str_t websocket_path = nxt_string("/settings/http/websocket");
|
static nxt_str_t websocket_path = nxt_string("/settings/http/websocket");
|
||||||
|
static nxt_str_t forwarded_path = nxt_string("/forwarded");
|
||||||
static nxt_str_t client_ip_path = nxt_string("/client_ip");
|
static nxt_str_t client_ip_path = nxt_string("/client_ip");
|
||||||
|
|
||||||
root = nxt_conf_json_parse(tmcf->mem_pool, start, end, NULL);
|
root = nxt_conf_json_parse(tmcf->mem_pool, start, end, NULL);
|
||||||
@@ -1883,11 +1886,20 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
|||||||
t->length = nxt_strlen(t->start);
|
t->length = nxt_strlen(t->start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conf = nxt_conf_get_path(listener, &forwarded_path);
|
||||||
|
|
||||||
|
if (conf != NULL) {
|
||||||
|
skcf->forwarded = nxt_router_conf_forward(task, mp, conf);
|
||||||
|
if (nxt_slow_path(skcf->forwarded == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
conf = nxt_conf_get_path(listener, &client_ip_path);
|
conf = nxt_conf_get_path(listener, &client_ip_path);
|
||||||
|
|
||||||
if (conf != NULL) {
|
if (conf != NULL) {
|
||||||
ret = nxt_router_conf_process_client_ip(task, mp, skcf, conf);
|
skcf->client_ip = nxt_router_conf_forward(task, mp, conf);
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(skcf->client_ip == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2124,68 +2136,103 @@ nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
static nxt_http_forward_t *
|
||||||
nxt_router_conf_process_client_ip(nxt_task_t *task, nxt_mp_t *mp,
|
nxt_router_conf_forward(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *conf)
|
||||||
nxt_socket_conf_t *skcf, nxt_conf_value_t *conf)
|
|
||||||
{
|
{
|
||||||
char c;
|
nxt_int_t ret;
|
||||||
size_t i;
|
nxt_conf_value_t *header_conf, *client_ip_conf, *protocol_conf;
|
||||||
uint32_t hash;
|
nxt_conf_value_t *source_conf, *recursive_conf;
|
||||||
nxt_str_t header;
|
|
||||||
nxt_conf_value_t *source_conf, *header_conf, *recursive_conf;
|
|
||||||
nxt_http_forward_t *forward;
|
nxt_http_forward_t *forward;
|
||||||
nxt_http_forward_header_t *client_ip;
|
|
||||||
nxt_http_route_addr_rule_t *source;
|
nxt_http_route_addr_rule_t *source;
|
||||||
|
|
||||||
static nxt_str_t header_path = nxt_string("/header");
|
static nxt_str_t header_path = nxt_string("/header");
|
||||||
|
static nxt_str_t client_ip_path = nxt_string("/client_ip");
|
||||||
|
static nxt_str_t protocol_path = nxt_string("/protocol");
|
||||||
static nxt_str_t source_path = nxt_string("/source");
|
static nxt_str_t source_path = nxt_string("/source");
|
||||||
static nxt_str_t recursive_path = nxt_string("/recursive");
|
static nxt_str_t recursive_path = nxt_string("/recursive");
|
||||||
|
|
||||||
source_conf = nxt_conf_get_path(conf, &source_path);
|
|
||||||
header_conf = nxt_conf_get_path(conf, &header_path);
|
header_conf = nxt_conf_get_path(conf, &header_path);
|
||||||
|
|
||||||
|
if (header_conf != NULL) {
|
||||||
|
client_ip_conf = nxt_conf_get_path(conf, &header_path);
|
||||||
|
protocol_conf = NULL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
client_ip_conf = nxt_conf_get_path(conf, &client_ip_path);
|
||||||
|
protocol_conf = nxt_conf_get_path(conf, &protocol_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
source_conf = nxt_conf_get_path(conf, &source_path);
|
||||||
recursive_conf = nxt_conf_get_path(conf, &recursive_path);
|
recursive_conf = nxt_conf_get_path(conf, &recursive_path);
|
||||||
|
|
||||||
if (source_conf == NULL || header_conf == NULL) {
|
if (source_conf == NULL
|
||||||
return NXT_ERROR;
|
|| (protocol_conf == NULL && client_ip_conf == NULL))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
forward = nxt_mp_zget(mp, sizeof(nxt_http_forward_t));
|
forward = nxt_mp_zget(mp, sizeof(nxt_http_forward_t));
|
||||||
if (nxt_slow_path(forward == NULL)) {
|
if (nxt_slow_path(forward == NULL)) {
|
||||||
return NXT_ERROR;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
source = nxt_http_route_addr_rule_create(task, mp, source_conf);
|
source = nxt_http_route_addr_rule_create(task, mp, source_conf);
|
||||||
if (nxt_slow_path(source == NULL)) {
|
if (nxt_slow_path(source == NULL)) {
|
||||||
return NXT_ERROR;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
forward->source = source;
|
forward->source = source;
|
||||||
|
|
||||||
client_ip = &forward->client_ip;
|
|
||||||
|
|
||||||
nxt_conf_get_string(header_conf, &header);
|
|
||||||
|
|
||||||
if (recursive_conf != NULL) {
|
if (recursive_conf != NULL) {
|
||||||
forward->recursive = nxt_conf_get_boolean(recursive_conf);
|
forward->recursive = nxt_conf_get_boolean(recursive_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
client_ip->header = nxt_str_dup(mp, NULL, &header);
|
if (client_ip_conf != NULL) {
|
||||||
if (nxt_slow_path(client_ip->header == NULL)) {
|
ret = nxt_router_conf_forward_header(mp, client_ip_conf,
|
||||||
|
&forward->client_ip);
|
||||||
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (protocol_conf != NULL) {
|
||||||
|
ret = nxt_router_conf_forward_header(mp, protocol_conf,
|
||||||
|
&forward->protocol);
|
||||||
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static nxt_int_t
|
||||||
|
nxt_router_conf_forward_header(nxt_mp_t *mp, nxt_conf_value_t *conf,
|
||||||
|
nxt_http_forward_header_t *fh)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
size_t i;
|
||||||
|
uint32_t hash;
|
||||||
|
nxt_str_t header;
|
||||||
|
|
||||||
|
nxt_conf_get_string(conf, &header);
|
||||||
|
|
||||||
|
fh->header = nxt_str_dup(mp, NULL, &header);
|
||||||
|
if (nxt_slow_path(fh->header == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = NXT_HTTP_FIELD_HASH_INIT;
|
hash = NXT_HTTP_FIELD_HASH_INIT;
|
||||||
|
|
||||||
for (i = 0; i < client_ip->header->length; i++) {
|
for (i = 0; i < fh->header->length; i++) {
|
||||||
c = client_ip->header->start[i];
|
c = fh->header->start[i];
|
||||||
hash = nxt_http_field_hash_char(hash, nxt_lowcase(c));
|
hash = nxt_http_field_hash_char(hash, nxt_lowcase(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = nxt_http_field_hash_end(hash) & 0xFFFF;
|
hash = nxt_http_field_hash_end(hash) & 0xFFFF;
|
||||||
|
|
||||||
client_ip->header_hash = hash;
|
fh->header_hash = hash;
|
||||||
|
|
||||||
skcf->client_ip = forward;
|
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
}
|
}
|
||||||
@@ -5547,7 +5594,7 @@ nxt_router_prepare_msg(nxt_task_t *task, nxt_http_request_t *r,
|
|||||||
p = nxt_cpymem(p, nxt_sockaddr_address(r->local), r->local->address_length);
|
p = nxt_cpymem(p, nxt_sockaddr_address(r->local), r->local->address_length);
|
||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
|
|
||||||
req->tls = (r->tls != NULL);
|
req->tls = r->tls;
|
||||||
req->websocket_handshake = r->websocket_handshake;
|
req->websocket_handshake = r->websocket_handshake;
|
||||||
|
|
||||||
req->server_name_length = r->server_name.length;
|
req->server_name_length = r->server_name.length;
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ typedef struct {
|
|||||||
|
|
||||||
uint8_t discard_unsafe_fields; /* 1 bit */
|
uint8_t discard_unsafe_fields; /* 1 bit */
|
||||||
|
|
||||||
|
nxt_http_forward_t *forwarded;
|
||||||
nxt_http_forward_t *client_ip;
|
nxt_http_forward_t *client_ip;
|
||||||
|
|
||||||
#if (NXT_TLS)
|
#if (NXT_TLS)
|
||||||
|
|||||||
Reference in New Issue
Block a user