1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_router.h>
8#include <nxt_http.h>
9
10
11static nxt_int_t nxt_http_validate_host(nxt_str_t *host, nxt_mp_t *mp);
12static void nxt_http_request_start(nxt_task_t *task, void *obj, void *data);
13static nxt_int_t nxt_http_request_client_ip(nxt_task_t *task,
14 nxt_http_request_t *r);
15static nxt_sockaddr_t *nxt_http_request_client_ip_sockaddr(
16 nxt_http_request_t *r, u_char *start, size_t len);
17static void nxt_http_request_ready(nxt_task_t *task, void *obj, void *data);
18static void nxt_http_request_proto_info(nxt_task_t *task,
19 nxt_http_request_t *r);
20static void nxt_http_request_mem_buf_completion(nxt_task_t *task, void *obj,
21 void *data);
22static void nxt_http_request_done(nxt_task_t *task, void *obj, void *data);
23
24static u_char *nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now,

--- 246 unchanged lines hidden (view full) ---

271 .ready_handler = nxt_http_request_start,
272 .error_handler = nxt_http_request_close_handler,
273};
274
275
276static void
277nxt_http_request_start(nxt_task_t *task, void *obj, void *data)
278{
279 nxt_int_t ret;
280 nxt_http_request_t *r;
281
282 r = obj;
283
284 r->state = &nxt_http_request_body_state;
285
286 ret = nxt_http_request_client_ip(task, r);
287 if (nxt_slow_path(ret != NXT_OK)) {
288 nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
289 }
290
291 nxt_http_request_read_body(task, r);
292}
293
294
295static nxt_int_t
296nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r)
297{
298 u_char *start, *p;
299 nxt_int_t ret, i, len;
300 nxt_str_t *header;
301 nxt_array_t *fields_arr; /* of nxt_http_field_t * */
302 nxt_sockaddr_t *sa, *prev_sa;
303 nxt_http_field_t *f, **fields;
304 nxt_http_client_ip_t *client_ip;
305
306 client_ip = r->conf->socket_conf->client_ip;
307
308 if (client_ip == NULL) {
309 return NXT_OK;
310 }
311
312 ret = nxt_http_route_addr_rule(r, client_ip->source, r->remote);
313 if (ret <= 0) {
314 return NXT_OK;
315 }
316
317 header = client_ip->header;
318
319 fields_arr = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_field_t *));
320 if (nxt_slow_path(fields_arr == NULL)) {
321 return NXT_ERROR;
322 }
323
324 nxt_list_each(f, r->fields) {
325 if (f->hash == client_ip->header_hash
326 && f->name_length == client_ip->header->length
327 && f->value_length > 0
328 && nxt_memcasecmp(f->name, header->start, header->length) == 0)
329 {
330 fields = nxt_array_add(fields_arr);
331 if (nxt_slow_path(fields == NULL)) {
332 return NXT_ERROR;
333 }
334
335 *fields = f;
336 }
337 } nxt_list_loop;
338
339 prev_sa = r->remote;
340 fields = (nxt_http_field_t **) fields_arr->elts;
341
342 i = fields_arr->nelts;
343
344 while (i-- > 0) {
345 f = fields[i];
346 start = f->value;
347 len = f->value_length;
348
349 do {
350 for (p = start + len - 1; p > start; p--, len--) {
351 if (*p != ' ' && *p != ',') {
352 break;
353 }
354 }
355
356 for (/* void */; p > start; p--) {
357 if (*p == ' ' || *p == ',') {
358 p++;
359 break;
360 }
361 }
362
363 sa = nxt_http_request_client_ip_sockaddr(r, p, len - (p - start));
364 if (nxt_slow_path(sa == NULL)) {
365 if (prev_sa != NULL) {
366 r->remote = prev_sa;
367 }
368
369 return NXT_OK;
370 }
371
372 if (!client_ip->recursive) {
373 r->remote = sa;
374
375 return NXT_OK;
376 }
377
378 ret = nxt_http_route_addr_rule(r, client_ip->source, sa);
379 if (ret <= 0 || (i == 0 && p == start)) {
380 r->remote = sa;
381
382 return NXT_OK;
383 }
384
385 prev_sa = sa;
386 len = p - 1 - start;
387
388 } while (len > 0);
389 }
390
391 return NXT_OK;
392}
393
394
395static nxt_sockaddr_t *
396nxt_http_request_client_ip_sockaddr(nxt_http_request_t *r, u_char *start,
397 size_t len)
398{
399 nxt_str_t addr;
400 nxt_sockaddr_t *sa;
401
402 addr.start = start;
403 addr.length = len;
404
405 sa = nxt_sockaddr_parse_optport(r->mem_pool, &addr);
406 if (nxt_slow_path(sa == NULL)) {
407 return NULL;
408 }
409
410 switch (sa->u.sockaddr.sa_family) {
411 case AF_INET:
412 if (sa->u.sockaddr_in.sin_addr.s_addr == INADDR_ANY) {
413 return NULL;
414 }
415
416 break;
417
418#if (NXT_INET6)
419 case AF_INET6:
420 if (IN6_IS_ADDR_UNSPECIFIED(&sa->u.sockaddr_in6.sin6_addr)) {
421 return NULL;
422 }
423
424 break;
425#endif /* NXT_INET6 */
426
427 default:
428 return NULL;
429 }
430
431 return sa;
432}
433
434
435static const nxt_http_request_state_t nxt_http_request_body_state
436 nxt_aligned(64) =
437{
438 .ready_handler = nxt_http_request_ready,
439 .error_handler = nxt_http_request_close_handler,
440};
441
442

--- 310 unchanged lines hidden ---