nxt_http_request.c (2132:34d63ed988dc) nxt_http_request.c (2133:46433e3cef45)
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);
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);
13static nxt_int_t nxt_http_request_forward(nxt_task_t *task,
14 nxt_http_request_t *r, nxt_http_forward_t *forward);
15static void nxt_http_request_forward_client_ip(nxt_http_request_t *r,
16 nxt_http_forward_t *forward, nxt_array_t *fields);
15static nxt_sockaddr_t *nxt_http_request_client_ip_sockaddr(
16 nxt_http_request_t *r, u_char *start, size_t len);
17static nxt_sockaddr_t *nxt_http_request_client_ip_sockaddr(
18 nxt_http_request_t *r, u_char *start, size_t len);
19static void nxt_http_request_forward_protocol(nxt_http_request_t *r,
20 nxt_http_field_t *field);
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,

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

291 .error_handler = nxt_http_request_close_handler,
292};
293
294
295static void
296nxt_http_request_start(nxt_task_t *task, void *obj, void *data)
297{
298 nxt_int_t ret;
21static void nxt_http_request_ready(nxt_task_t *task, void *obj, void *data);
22static void nxt_http_request_proto_info(nxt_task_t *task,
23 nxt_http_request_t *r);
24static void nxt_http_request_mem_buf_completion(nxt_task_t *task, void *obj,
25 void *data);
26static void nxt_http_request_done(nxt_task_t *task, void *obj, void *data);
27
28static u_char *nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now,

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

295 .error_handler = nxt_http_request_close_handler,
296};
297
298
299static void
300nxt_http_request_start(nxt_task_t *task, void *obj, void *data)
301{
302 nxt_int_t ret;
303 nxt_socket_conf_t *skcf;
299 nxt_http_request_t *r;
300
301 r = obj;
302
303 r->state = &nxt_http_request_body_state;
304
304 nxt_http_request_t *r;
305
306 r = obj;
307
308 r->state = &nxt_http_request_body_state;
309
305 ret = nxt_http_request_client_ip(task, r);
306 if (nxt_slow_path(ret != NXT_OK)) {
307 nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
310 skcf = r->conf->socket_conf;
311
312 if (skcf->forwarded != NULL) {
313 ret = nxt_http_request_forward(task, r, skcf->forwarded);
314 if (nxt_slow_path(ret != NXT_OK)) {
315 goto fail;
316 }
308 }
309
317 }
318
319 if (skcf->client_ip != NULL) {
320 ret = nxt_http_request_forward(task, r, skcf->client_ip);
321 if (nxt_slow_path(ret != NXT_OK)) {
322 goto fail;
323 }
324 }
325
310 nxt_http_request_read_body(task, r);
326 nxt_http_request_read_body(task, r);
327
328 return;
329
330fail:
331 nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
311}
312
313
314static nxt_int_t
332}
333
334
335static nxt_int_t
315nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r)
336nxt_http_request_forward(nxt_task_t *task, nxt_http_request_t *r,
337 nxt_http_forward_t *forward)
316{
338{
317 u_char *start, *p;
318 nxt_int_t ret, i, len;
319 nxt_str_t *header;
320 nxt_array_t *fields_arr; /* of nxt_http_field_t * */
321 nxt_sockaddr_t *sa, *prev_sa;
322 nxt_http_field_t *f, **fields;
323 nxt_http_forward_t *forward;
324 nxt_http_forward_header_t *client_ip;
339 nxt_int_t ret;
340 nxt_array_t *client_ip_fields;
341 nxt_http_field_t *f, **fields, *protocol_field;
342 nxt_http_forward_header_t *client_ip, *protocol;
325
343
326 forward = r->conf->socket_conf->client_ip;
327
328 if (forward == NULL) {
329 return NXT_OK;
330 }
331
332 ret = nxt_http_route_addr_rule(r, forward->source, r->remote);
333 if (ret <= 0) {
334 return NXT_OK;
335 }
336
337 client_ip = &forward->client_ip;
344 ret = nxt_http_route_addr_rule(r, forward->source, r->remote);
345 if (ret <= 0) {
346 return NXT_OK;
347 }
348
349 client_ip = &forward->client_ip;
338 header = client_ip->header;
350 protocol = &forward->protocol;
339
351
340 fields_arr = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_field_t *));
341 if (nxt_slow_path(fields_arr == NULL)) {
342 return NXT_ERROR;
352 if (client_ip->header != NULL) {
353 client_ip_fields = nxt_array_create(r->mem_pool, 1,
354 sizeof(nxt_http_field_t *));
355 if (nxt_slow_path(client_ip_fields == NULL)) {
356 return NXT_ERROR;
357 }
358
359 } else {
360 client_ip_fields = NULL;
343 }
344
361 }
362
363 protocol_field = NULL;
364
345 nxt_list_each(f, r->fields) {
365 nxt_list_each(f, r->fields) {
346 if (f->hash == client_ip->header_hash
347 && f->name_length == client_ip->header->length
366 if (client_ip_fields != NULL
367 && f->hash == client_ip->header_hash
348 && f->value_length > 0
368 && f->value_length > 0
349 && nxt_memcasecmp(f->name, header->start, header->length) == 0)
369 && f->name_length == client_ip->header->length
370 && nxt_memcasecmp(f->name, client_ip->header->start,
371 client_ip->header->length) == 0)
350 {
372 {
351 fields = nxt_array_add(fields_arr);
373 fields = nxt_array_add(client_ip_fields);
352 if (nxt_slow_path(fields == NULL)) {
353 return NXT_ERROR;
354 }
355
356 *fields = f;
357 }
374 if (nxt_slow_path(fields == NULL)) {
375 return NXT_ERROR;
376 }
377
378 *fields = f;
379 }
380
381 if (protocol->header != NULL
382 && protocol_field == NULL
383 && f->hash == protocol->header_hash
384 && f->value_length > 0
385 && f->name_length == protocol->header->length
386 && nxt_memcasecmp(f->name, protocol->header->start,
387 protocol->header->length) == 0)
388 {
389 protocol_field = f;
390 }
358 } nxt_list_loop;
359
391 } nxt_list_loop;
392
393 if (client_ip_fields != NULL) {
394 nxt_http_request_forward_client_ip(r, forward, client_ip_fields);
395 }
396
397 if (protocol_field != NULL) {
398 nxt_http_request_forward_protocol(r, protocol_field);
399 }
400
401 return NXT_OK;
402}
403
404
405static void
406nxt_http_request_forward_client_ip(nxt_http_request_t *r,
407 nxt_http_forward_t *forward, nxt_array_t *fields)
408{
409 u_char *start, *p;
410 nxt_int_t ret, i, len;
411 nxt_sockaddr_t *sa, *prev_sa;
412 nxt_http_field_t **f;
413
360 prev_sa = r->remote;
414 prev_sa = r->remote;
361 fields = (nxt_http_field_t **) fields_arr->elts;
415 f = (nxt_http_field_t **) fields->elts;
362
416
363 i = fields_arr->nelts;
417 i = fields->nelts;
364
365 while (i-- > 0) {
418
419 while (i-- > 0) {
366 f = fields[i];
367 start = f->value;
368 len = f->value_length;
420 start = f[i]->value;
421 len = f[i]->value_length;
369
370 do {
371 for (p = start + len - 1; p > start; p--, len--) {
372 if (*p != ' ' && *p != ',') {
373 break;
374 }
375 }
376

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

382 }
383
384 sa = nxt_http_request_client_ip_sockaddr(r, p, len - (p - start));
385 if (nxt_slow_path(sa == NULL)) {
386 if (prev_sa != NULL) {
387 r->remote = prev_sa;
388 }
389
422
423 do {
424 for (p = start + len - 1; p > start; p--, len--) {
425 if (*p != ' ' && *p != ',') {
426 break;
427 }
428 }
429

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

435 }
436
437 sa = nxt_http_request_client_ip_sockaddr(r, p, len - (p - start));
438 if (nxt_slow_path(sa == NULL)) {
439 if (prev_sa != NULL) {
440 r->remote = prev_sa;
441 }
442
390 return NXT_OK;
443 return;
391 }
392
393 if (!forward->recursive) {
394 r->remote = sa;
444 }
445
446 if (!forward->recursive) {
447 r->remote = sa;
395
396 return NXT_OK;
448 return;
397 }
398
399 ret = nxt_http_route_addr_rule(r, forward->source, sa);
400 if (ret <= 0 || (i == 0 && p == start)) {
401 r->remote = sa;
449 }
450
451 ret = nxt_http_route_addr_rule(r, forward->source, sa);
452 if (ret <= 0 || (i == 0 && p == start)) {
453 r->remote = sa;
402
403 return NXT_OK;
454 return;
404 }
405
406 prev_sa = sa;
407 len = p - 1 - start;
408
409 } while (len > 0);
410 }
455 }
456
457 prev_sa = sa;
458 len = p - 1 - start;
459
460 } while (len > 0);
461 }
411
412 return NXT_OK;
413}
414
415
416static nxt_sockaddr_t *
417nxt_http_request_client_ip_sockaddr(nxt_http_request_t *r, u_char *start,
418 size_t len)
419{
420 nxt_str_t addr;

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

448 default:
449 return NULL;
450 }
451
452 return sa;
453}
454
455
462}
463
464
465static nxt_sockaddr_t *
466nxt_http_request_client_ip_sockaddr(nxt_http_request_t *r, u_char *start,
467 size_t len)
468{
469 nxt_str_t addr;

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

497 default:
498 return NULL;
499 }
500
501 return sa;
502}
503
504
505static void
506nxt_http_request_forward_protocol(nxt_http_request_t *r,
507 nxt_http_field_t *field)
508{
509 if (field->value_length == 4) {
510 if (nxt_memcasecmp(field->value, "http", 4) == 0) {
511 r->tls = 0;
512 }
513
514 } else if (field->value_length == 5) {
515 if (nxt_memcasecmp(field->value, "https", 5) == 0) {
516 r->tls = 1;
517 }
518
519 } else if (field->value_length == 2) {
520 if (nxt_memcasecmp(field->value, "on", 2) == 0) {
521 r->tls = 1;
522 }
523 }
524}
525
526
456static const nxt_http_request_state_t nxt_http_request_body_state
457 nxt_aligned(64) =
458{
459 .ready_handler = nxt_http_request_ready,
460 .error_handler = nxt_http_request_close_handler,
461};
462
463

--- 648 unchanged lines hidden ---
527static const nxt_http_request_state_t nxt_http_request_body_state
528 nxt_aligned(64) =
529{
530 .ready_handler = nxt_http_request_ready,
531 .error_handler = nxt_http_request_close_handler,
532};
533
534

--- 648 unchanged lines hidden ---