Router: forwared header replacement.
This commit is contained in:
@@ -10,10 +10,14 @@
|
||||
|
||||
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 nxt_int_t nxt_http_request_client_ip(nxt_task_t *task,
|
||||
nxt_http_request_t *r);
|
||||
static nxt_int_t nxt_http_request_forward(nxt_task_t *task,
|
||||
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(
|
||||
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_proto_info(nxt_task_t *task,
|
||||
nxt_http_request_t *r);
|
||||
@@ -296,38 +300,46 @@ static void
|
||||
nxt_http_request_start(nxt_task_t *task, void *obj, void *data)
|
||||
{
|
||||
nxt_int_t ret;
|
||||
nxt_socket_conf_t *skcf;
|
||||
nxt_http_request_t *r;
|
||||
|
||||
r = obj;
|
||||
|
||||
r->state = &nxt_http_request_body_state;
|
||||
|
||||
ret = nxt_http_request_client_ip(task, r);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
|
||||
skcf = r->conf->socket_conf;
|
||||
|
||||
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);
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
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, i, len;
|
||||
nxt_str_t *header;
|
||||
nxt_array_t *fields_arr; /* of nxt_http_field_t * */
|
||||
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;
|
||||
}
|
||||
nxt_int_t ret;
|
||||
nxt_array_t *client_ip_fields;
|
||||
nxt_http_field_t *f, **fields, *protocol_field;
|
||||
nxt_http_forward_header_t *client_ip, *protocol;
|
||||
|
||||
ret = nxt_http_route_addr_rule(r, forward->source, r->remote);
|
||||
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;
|
||||
header = client_ip->header;
|
||||
protocol = &forward->protocol;
|
||||
|
||||
fields_arr = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_field_t *));
|
||||
if (nxt_slow_path(fields_arr == NULL)) {
|
||||
return NXT_ERROR;
|
||||
if (client_ip->header != NULL) {
|
||||
client_ip_fields = nxt_array_create(r->mem_pool, 1,
|
||||
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) {
|
||||
if (f->hash == client_ip->header_hash
|
||||
&& f->name_length == client_ip->header->length
|
||||
if (client_ip_fields != NULL
|
||||
&& f->hash == client_ip->header_hash
|
||||
&& 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)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
*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;
|
||||
|
||||
prev_sa = r->remote;
|
||||
fields = (nxt_http_field_t **) fields_arr->elts;
|
||||
if (client_ip_fields != NULL) {
|
||||
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) {
|
||||
f = fields[i];
|
||||
start = f->value;
|
||||
len = f->value_length;
|
||||
start = f[i]->value;
|
||||
len = f[i]->value_length;
|
||||
|
||||
do {
|
||||
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;
|
||||
}
|
||||
|
||||
return NXT_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!forward->recursive) {
|
||||
r->remote = sa;
|
||||
|
||||
return NXT_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nxt_http_route_addr_rule(r, forward->source, sa);
|
||||
if (ret <= 0 || (i == 0 && p == start)) {
|
||||
r->remote = sa;
|
||||
|
||||
return NXT_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
prev_sa = sa;
|
||||
@@ -408,8 +459,6 @@ nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r)
|
||||
|
||||
} 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
|
||||
nxt_aligned(64) =
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user