Mercurial > hg > nginx-vendor-0-6
comparison src/http/ngx_http.c @ 4:4b2dafa26fe2 NGINX_0_1_2
nginx 0.1.2
*) Feature: the --user=USER, --group=GROUP, and --with-ld-opt=OPTIONS
options in configure.
*) Feature: the server_name directive supports *.domain.tld.
*) Bugfix: the portability improvements.
*) Bugfix: if configuration file was set in command line, the
reconfiguration was impossible; bug appeared in 0.1.1.
*) Bugfix: proxy module may get caught in an endless loop when sendfile
is not used.
*) Bugfix: with sendfile the response was not recoded according to the
charset module directives; bug appeared in 0.1.1.
*) Bugfix: very seldom bug in the kqueue processing.
*) Bugfix: the gzip module compressed the proxied responses that was
already compressed.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 21 Oct 2004 00:00:00 +0400 |
parents | f0b350454894 |
children | 46833bd150cb |
comparison
equal
deleted
inserted
replaced
3:8beaf7b3241f | 4:4b2dafa26fe2 |
---|---|
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_http.h> | 10 #include <ngx_http.h> |
11 | 11 |
12 | 12 |
13 static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 13 static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
14 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, | |
15 ngx_http_in_port_t *in_port, | |
16 ngx_http_listen_t *lscf, | |
17 ngx_http_core_srv_conf_t *cscf); | |
18 static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, | |
19 ngx_http_in_addr_t *in_addr, | |
20 ngx_http_core_srv_conf_t *cscf); | |
21 | |
14 static char *ngx_http_merge_locations(ngx_conf_t *cf, | 22 static char *ngx_http_merge_locations(ngx_conf_t *cf, |
15 ngx_array_t *locations, | 23 ngx_array_t *locations, |
16 void **loc_conf, | 24 void **loc_conf, |
17 ngx_http_module_t *module, | 25 ngx_http_module_t *module, |
18 ngx_uint_t ctx_index); | 26 ngx_uint_t ctx_index); |
77 ngx_http_core_main_conf_t *cmcf; | 85 ngx_http_core_main_conf_t *cmcf; |
78 #if (WIN32) | 86 #if (WIN32) |
79 ngx_iocp_conf_t *iocpcf; | 87 ngx_iocp_conf_t *iocpcf; |
80 #endif | 88 #endif |
81 | 89 |
90 #if (NGX_SUPPRESS_WARN) | |
91 /* MSVC thinks 'in_ports' may be used without having been initialized */ | |
92 ngx_memzero(&in_ports, sizeof(ngx_array_t)); | |
93 #endif | |
94 | |
82 /* the main http context */ | 95 /* the main http context */ |
83 ngx_test_null(ctx, | 96 ngx_test_null(ctx, |
84 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), | 97 ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), |
85 NGX_CONF_ERROR); | 98 NGX_CONF_ERROR); |
86 | 99 |
272 NGX_CONF_ERROR); | 285 NGX_CONF_ERROR); |
273 cmcf->phases[NGX_HTTP_CONTENT_PHASE].type = NGX_OK; | 286 cmcf->phases[NGX_HTTP_CONTENT_PHASE].type = NGX_OK; |
274 | 287 |
275 | 288 |
276 /* | 289 /* |
277 * create the lists of the ports, the addresses and the server names | 290 * create the lists of ports, addresses and server names |
278 * to allow quickly find the server core module configuration at run-time | 291 * to quickly find the server core module configuration at run-time |
279 */ | 292 */ |
280 | 293 |
281 ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t), | 294 if (ngx_array_init(&in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t)) |
282 NGX_CONF_ERROR); | 295 == NGX_ERROR) |
296 { | |
297 return NGX_CONF_ERROR; | |
298 } | |
283 | 299 |
284 /* "server" directives */ | 300 /* "server" directives */ |
301 | |
285 cscfp = cmcf->servers.elts; | 302 cscfp = cmcf->servers.elts; |
286 for (s = 0; s < cmcf->servers.nelts; s++) { | 303 for (s = 0; s < cmcf->servers.nelts; s++) { |
287 | 304 |
288 /* "listen" directives */ | 305 /* "listen" directives */ |
306 | |
289 lscf = cscfp[s]->listen.elts; | 307 lscf = cscfp[s]->listen.elts; |
290 for (l = 0; l < cscfp[s]->listen.nelts; l++) { | 308 for (l = 0; l < cscfp[s]->listen.nelts; l++) { |
291 | 309 |
292 port_found = 0; | 310 port_found = 0; |
293 | 311 |
306 in_addr = in_port[p].addrs.elts; | 324 in_addr = in_port[p].addrs.elts; |
307 for (a = 0; a < in_port[p].addrs.nelts; a++) { | 325 for (a = 0; a < in_port[p].addrs.nelts; a++) { |
308 | 326 |
309 if (lscf[l].addr == in_addr[a].addr) { | 327 if (lscf[l].addr == in_addr[a].addr) { |
310 | 328 |
311 /* the address is already bound to this port */ | 329 /* the address is already in the address list */ |
312 | 330 |
313 /* "server_name" directives */ | 331 if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) |
314 s_name = cscfp[s]->server_names.elts; | 332 == NGX_ERROR) |
315 for (n = 0; n < cscfp[s]->server_names.nelts; n++) { | 333 { |
316 | 334 return NGX_CONF_ERROR; |
317 /* | |
318 * add the server name and server core module | |
319 * configuration to the address:port | |
320 */ | |
321 | |
322 /* TODO: duplicate names can be checked here */ | |
323 | |
324 ngx_test_null(name, | |
325 ngx_push_array(&in_addr[a].names), | |
326 NGX_CONF_ERROR); | |
327 | |
328 name->name = s_name[n].name; | |
329 name->core_srv_conf = s_name[n].core_srv_conf; | |
330 } | 335 } |
331 | 336 |
332 /* | 337 /* |
333 * check duplicate "default" server that | 338 * check the duplicate "default" server |
334 * serves this address:port | 339 * for this address:port |
335 */ | 340 */ |
336 | 341 |
337 if (lscf[l].default_server) { | 342 if (lscf[l].default_server) { |
343 | |
338 if (in_addr[a].default_server) { | 344 if (in_addr[a].default_server) { |
339 ngx_log_error(NGX_LOG_ERR, cf->log, 0, | 345 ngx_log_error(NGX_LOG_ERR, cf->log, 0, |
340 "duplicate default server in %s:%d", | 346 "the duplicate default server in %s:%d", |
341 lscf[l].file_name.data, | 347 lscf[l].file_name.data, |
342 lscf[l].line); | 348 lscf[l].line); |
343 | 349 |
344 return NGX_CONF_ERROR; | 350 return NGX_CONF_ERROR; |
345 } | 351 } |
346 | 352 |
347 in_addr[a].core_srv_conf = cscfp[s]; | 353 in_addr[a].core_srv_conf = cscfp[s]; |
352 | 358 |
353 break; | 359 break; |
354 | 360 |
355 } else if (in_addr[a].addr == INADDR_ANY) { | 361 } else if (in_addr[a].addr == INADDR_ANY) { |
356 | 362 |
363 /* the INADDR_ANY is always the last address */ | |
364 | |
365 if (!(inaddr = ngx_array_push(&in_port[p].addrs))) { | |
366 return NGX_CONF_ERROR; | |
367 } | |
368 | |
357 /* | 369 /* |
358 * "*:port" must be the last resort so move it | 370 * the INADDR_ANY must be the last resort |
359 * to the end of the address list and add | 371 * so we move it to the end of the address list |
360 * the new address at its place | 372 * and put the new address in its place |
361 */ | 373 */ |
362 | |
363 ngx_test_null(inaddr, | |
364 ngx_push_array(&in_port[p].addrs), | |
365 NGX_CONF_ERROR); | |
366 | 374 |
367 ngx_memcpy(inaddr, &in_addr[a], | 375 ngx_memcpy(inaddr, &in_addr[a], |
368 sizeof(ngx_http_in_addr_t)); | 376 sizeof(ngx_http_in_addr_t)); |
369 | 377 |
370 in_addr[a].addr = lscf[l].addr; | 378 in_addr[a].addr = lscf[l].addr; |
379 in_addr[a].names.elts = NULL; | |
371 in_addr[a].default_server = lscf[l].default_server; | 380 in_addr[a].default_server = lscf[l].default_server; |
372 in_addr[a].core_srv_conf = cscfp[s]; | 381 in_addr[a].core_srv_conf = cscfp[s]; |
373 | 382 |
374 /* | 383 if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) |
375 * create the empty list of the server names that | 384 == NGX_ERROR) |
376 * can be served on this address:port | 385 { |
377 */ | 386 return NGX_CONF_ERROR; |
378 | 387 } |
379 ngx_init_array(inaddr->names, cf->pool, 10, | |
380 sizeof(ngx_http_server_name_t), | |
381 NGX_CONF_ERROR); | |
382 | 388 |
383 addr_found = 1; | 389 addr_found = 1; |
384 | 390 |
385 break; | 391 break; |
386 } | 392 } |
391 /* | 397 /* |
392 * add the address to the addresses list that | 398 * add the address to the addresses list that |
393 * bound to this port | 399 * bound to this port |
394 */ | 400 */ |
395 | 401 |
396 ngx_test_null(inaddr, | 402 if (ngx_http_add_address(cf, &in_port[p], &lscf[l], |
397 ngx_push_array(&in_port[p].addrs), | 403 cscfp[s]) == NGX_ERROR) |
398 NGX_CONF_ERROR); | 404 { |
399 | 405 return NGX_CONF_ERROR; |
400 inaddr->addr = lscf[l].addr; | 406 } |
401 inaddr->default_server = lscf[l].default_server; | |
402 inaddr->core_srv_conf = cscfp[s]; | |
403 | |
404 /* | |
405 * create the empty list of the server names that | |
406 * can be served on this address:port | |
407 */ | |
408 | |
409 ngx_init_array(inaddr->names, cf->pool, 10, | |
410 sizeof(ngx_http_server_name_t), | |
411 NGX_CONF_ERROR); | |
412 } | 407 } |
413 } | 408 } |
414 } | 409 } |
415 | 410 |
416 if (!port_found) { | 411 if (!port_found) { |
417 | 412 |
418 /* add the port to the in_port list */ | 413 /* add the port to the in_port list */ |
419 | 414 |
420 ngx_test_null(in_port, | 415 if (!(in_port = ngx_array_push(&in_ports))) { |
421 ngx_push_array(&in_ports), | 416 return NGX_CONF_ERROR; |
422 NGX_CONF_ERROR); | 417 } |
423 | 418 |
424 in_port->port = lscf[l].port; | 419 in_port->port = lscf[l].port; |
425 | 420 in_port->addrs.elts = NULL; |
426 ngx_test_null(in_port->port_text.data, ngx_palloc(cf->pool, 7), | 421 |
427 NGX_CONF_ERROR); | 422 if (!(in_port->port_text.data = ngx_palloc(cf->pool, 7))) { |
428 in_port->port_text.len = ngx_snprintf((char *) | 423 return NGX_CONF_ERROR; |
429 in_port->port_text.data, | 424 } |
430 7, ":%d", | 425 |
431 in_port->port); | 426 in_port->port_text.len = ngx_sprintf(in_port->port_text.data, |
432 | 427 ":%d", in_port->port) |
433 /* create list of the addresses that bound to this port ... */ | 428 - in_port->port_text.data; |
434 | 429 |
435 ngx_init_array(in_port->addrs, cf->pool, 10, | 430 if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s]) |
436 sizeof(ngx_http_in_addr_t), | 431 == NGX_ERROR) |
437 NGX_CONF_ERROR); | 432 { |
438 | 433 return NGX_CONF_ERROR; |
439 ngx_test_null(inaddr, ngx_push_array(&in_port->addrs), | 434 } |
440 NGX_CONF_ERROR); | 435 } |
441 | 436 } |
442 /* ... and add the address to this list */ | 437 } |
443 | 438 |
444 inaddr->addr = lscf[l].addr; | 439 |
445 inaddr->default_server = lscf[l].default_server; | 440 /* optimize the lists of ports, addresses and server names */ |
446 inaddr->core_srv_conf = cscfp[s]; | |
447 | |
448 /* | |
449 * create the empty list of the server names that | |
450 * can be served on this address:port | |
451 */ | |
452 | |
453 ngx_init_array(inaddr->names, cf->pool, 10, | |
454 sizeof(ngx_http_server_name_t), | |
455 NGX_CONF_ERROR); | |
456 } | |
457 } | |
458 } | |
459 | |
460 /* optimize the lists of the ports, the addresses and the server names */ | |
461 | 441 |
462 /* AF_INET only */ | 442 /* AF_INET only */ |
463 | 443 |
464 in_port = in_ports.elts; | 444 in_port = in_ports.elts; |
465 for (p = 0; p < in_ports.nelts; p++) { | 445 for (p = 0; p < in_ports.nelts; p++) { |
466 | 446 |
467 /* check whether the all server names point to the same server */ | 447 /* |
448 * check whether all name-based servers have the same configuraiton | |
449 * as the default server, or some servers restrict the host names | |
450 */ | |
468 | 451 |
469 in_addr = in_port[p].addrs.elts; | 452 in_addr = in_port[p].addrs.elts; |
470 for (a = 0; a < in_port[p].addrs.nelts; a++) { | 453 for (a = 0; a < in_port[p].addrs.nelts; a++) { |
471 | 454 |
472 virtual_names = 0; | 455 virtual_names = 0; |
473 | 456 |
474 name = in_addr[a].names.elts; | 457 name = in_addr[a].names.elts; |
475 for (n = 0; n < in_addr[a].names.nelts; n++) { | 458 for (n = 0; n < in_addr[a].names.nelts; n++) { |
476 if (in_addr[a].core_srv_conf != name[n].core_srv_conf) { | 459 if (in_addr[a].core_srv_conf != name[n].core_srv_conf |
460 || name[n].core_srv_conf->restrict_host_names | |
461 != NGX_HTTP_RESTRICT_HOST_OFF) | |
462 { | |
477 virtual_names = 1; | 463 virtual_names = 1; |
478 break; | 464 break; |
479 } | 465 } |
480 } | 466 } |
481 | 467 |
482 /* | 468 /* |
483 * if the all server names point to the same server | 469 * if all name-based servers have the same configuration |
484 * then we do not need to check them at run-time | 470 * as the default server, and no servers restrict the host names |
471 * then we do not need to check them at run-time at all | |
485 */ | 472 */ |
486 | 473 |
487 if (!virtual_names) { | 474 if (!virtual_names) { |
488 in_addr[a].names.nelts = 0; | 475 in_addr[a].names.nelts = 0; |
489 } | 476 } |
586 a++; | 573 a++; |
587 } | 574 } |
588 } | 575 } |
589 | 576 |
590 #if (NGX_DEBUG) | 577 #if (NGX_DEBUG) |
578 { | |
579 u_char address[20]; | |
580 ngx_uint_t p, a, n; | |
581 | |
591 in_port = in_ports.elts; | 582 in_port = in_ports.elts; |
592 for (p = 0; p < in_ports.nelts; p++) { | 583 for (p = 0; p < in_ports.nelts; p++) { |
593 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 584 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, |
594 "port: %d %08x", in_port[p].port, &in_port[p]); | 585 "port: %d %08x", in_port[p].port, &in_port[p]); |
595 in_addr = in_port[p].addrs.elts; | 586 in_addr = in_port[p].addrs.elts; |
596 for (a = 0; a < in_port[p].addrs.nelts; a++) { | 587 for (a = 0; a < in_port[p].addrs.nelts; a++) { |
597 u_char ip[20]; | 588 ngx_inet_ntop(AF_INET, &in_addr[a].addr, address, 20); |
598 ngx_inet_ntop(AF_INET, &in_addr[a].addr, ip, 20); | 589 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0, |
599 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 590 "%s:%d %08x", |
600 "%s %08x", ip, in_addr[a].core_srv_conf); | 591 address, in_port[p].port, in_addr[a].core_srv_conf); |
601 s_name = in_addr[a].names.elts; | 592 s_name = in_addr[a].names.elts; |
602 for (n = 0; n < in_addr[a].names.nelts; n++) { | 593 for (n = 0; n < in_addr[a].names.nelts; n++) { |
603 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, | 594 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, cf->log, 0, |
604 "%s %08x", s_name[n].name.data, | 595 "%s:%d %s %08x", |
596 address, in_port[p].port, s_name[n].name.data, | |
605 s_name[n].core_srv_conf); | 597 s_name[n].core_srv_conf); |
606 } | 598 } |
607 } | 599 } |
608 } | 600 } |
601 } | |
609 #endif | 602 #endif |
610 | 603 |
611 return NGX_CONF_OK; | 604 return NGX_CONF_OK; |
605 } | |
606 | |
607 | |
608 /* | |
609 * add the server address, the server names and the server core module | |
610 * configurations to the port (in_port) | |
611 */ | |
612 | |
613 static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, | |
614 ngx_http_in_port_t *in_port, | |
615 ngx_http_listen_t *lscf, | |
616 ngx_http_core_srv_conf_t *cscf) | |
617 { | |
618 ngx_http_in_addr_t *in_addr; | |
619 | |
620 if (in_port->addrs.elts == NULL) { | |
621 if (ngx_array_init(&in_port->addrs, cf->pool, 10, | |
622 sizeof(ngx_http_in_addr_t)) == NGX_ERROR) | |
623 { | |
624 return NGX_ERROR; | |
625 } | |
626 } | |
627 | |
628 if (!(in_addr = ngx_array_push(&in_port->addrs))) { | |
629 return NGX_ERROR; | |
630 } | |
631 | |
632 in_addr->addr = lscf->addr; | |
633 in_addr->names.elts = NULL; | |
634 in_addr->default_server = lscf->default_server; | |
635 in_addr->core_srv_conf = cscf; | |
636 | |
637 #if (NGX_DEBUG) | |
638 { | |
639 u_char text[20]; | |
640 ngx_inet_ntop(AF_INET, &in_addr->addr, text, 20); | |
641 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "address: %s:%d", | |
642 text, in_port->port); | |
643 } | |
644 #endif | |
645 | |
646 return ngx_http_add_names(cf, in_addr, cscf); | |
647 } | |
648 | |
649 | |
650 /* | |
651 * add the server names and the server core module | |
652 * configurations to the address:port (in_addr) | |
653 */ | |
654 | |
655 static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, | |
656 ngx_http_in_addr_t *in_addr, | |
657 ngx_http_core_srv_conf_t *cscf) | |
658 { | |
659 ngx_uint_t i; | |
660 ngx_http_server_name_t *server_names, *name; | |
661 | |
662 if (in_addr->names.elts == NULL) { | |
663 if (ngx_array_init(&in_addr->names, cf->pool, 10, | |
664 sizeof(ngx_http_server_name_t)) == NGX_ERROR) | |
665 { | |
666 return NGX_ERROR; | |
667 } | |
668 } | |
669 | |
670 server_names = cscf->server_names.elts; | |
671 for (i = 0; i < cscf->server_names.nelts; i++) { | |
672 | |
673 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, | |
674 "name: %s", server_names[i].name.data); | |
675 | |
676 /* TODO: duplicate names can be checked here */ | |
677 | |
678 if (!(name = ngx_array_push(&in_addr->names))) { | |
679 return NGX_ERROR; | |
680 } | |
681 | |
682 *name = server_names[i]; | |
683 } | |
684 | |
685 return NGX_OK; | |
612 } | 686 } |
613 | 687 |
614 | 688 |
615 static char *ngx_http_merge_locations(ngx_conf_t *cf, | 689 static char *ngx_http_merge_locations(ngx_conf_t *cf, |
616 ngx_array_t *locations, | 690 ngx_array_t *locations, |