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,