Mercurial > hg > nginx
comparison src/http/ngx_http.c @ 89:29bf798b583f
nginx-0.0.1-2003-05-15-19:42:53 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 15 May 2003 15:42:53 +0000 |
parents | 674d333f4296 |
children | 37530da31268 |
comparison
equal
deleted
inserted
replaced
88:674d333f4296 | 89:29bf798b583f |
---|---|
43 | 43 |
44 {ngx_string("http"), | 44 {ngx_string("http"), |
45 NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, | 45 NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, |
46 ngx_http_block, | 46 ngx_http_block, |
47 0, | 47 0, |
48 0}, | 48 0, |
49 | 49 NULL}, |
50 {ngx_string(""), 0, NULL, 0, 0} | 50 |
51 {ngx_string(""), 0, NULL, 0, 0, NULL} | |
51 }; | 52 }; |
52 | 53 |
53 | 54 |
54 ngx_module_t ngx_http_module = { | 55 ngx_module_t ngx_http_module = { |
55 0, /* module index */ | 56 0, /* module index */ |
69 ngx_array_t in_ports; | 70 ngx_array_t in_ports; |
70 ngx_listen_t *ls; | 71 ngx_listen_t *ls; |
71 ngx_http_module_t *module; | 72 ngx_http_module_t *module; |
72 ngx_conf_t prev; | 73 ngx_conf_t prev; |
73 ngx_http_conf_ctx_t *ctx; | 74 ngx_http_conf_ctx_t *ctx; |
74 ngx_http_in_port_t *in_port; | 75 ngx_http_in_port_t *in_port, *inport; |
75 ngx_http_in_addr_t *in_addr, *inaddr; | 76 ngx_http_in_addr_t *in_addr, *inaddr; |
76 ngx_http_core_srv_conf_t **cscf; | 77 ngx_http_core_srv_conf_t **cscf; |
77 ngx_http_listen_t *lscf; | 78 ngx_http_listen_t *lscf; |
78 ngx_http_server_name_t *s_name, *name;; | 79 ngx_http_server_name_t *s_name, *name; |
79 | 80 |
80 ngx_init_array(ngx_http_servers, cf->pool, 10, | 81 ngx_init_array(ngx_http_servers, cf->pool, 10, |
81 sizeof(ngx_http_core_srv_conf_t *), NGX_CONF_ERROR); | 82 sizeof(ngx_http_core_srv_conf_t *), NGX_CONF_ERROR); |
82 | 83 |
83 ngx_test_null(ctx, | 84 ngx_test_null(ctx, |
146 cf->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); | 147 cf->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); |
147 | 148 |
148 ngx_init_array(ngx_http_index_handlers, | 149 ngx_init_array(ngx_http_index_handlers, |
149 cf->pool, 3, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); | 150 cf->pool, 3, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); |
150 | 151 |
151 /* create lists of the ports, the addresses and the server names */ | 152 |
153 /* create the lists of the ports, the addresses and the server names | |
154 to allow quickly find the server core module configuration at run-time */ | |
152 | 155 |
153 ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t), | 156 ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t), |
154 NGX_CONF_ERROR); | 157 NGX_CONF_ERROR); |
155 | 158 |
159 /* "server" directives */ | |
156 cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts; | 160 cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts; |
157 for (s = 0; s < ngx_http_servers.nelts; s++) { | 161 for (s = 0; s < ngx_http_servers.nelts; s++) { |
158 | 162 |
163 /* "listen" directives */ | |
159 lscf = (ngx_http_listen_t *) cscf[s]->listen.elts; | 164 lscf = (ngx_http_listen_t *) cscf[s]->listen.elts; |
160 for (l = 0; l < cscf[s]->listen.nelts; l++) { | 165 for (l = 0; l < cscf[s]->listen.nelts; l++) { |
161 | 166 |
162 port_found = 0; | 167 port_found = 0; |
163 | 168 |
166 in_port = (ngx_http_in_port_t *) in_ports.elts; | 171 in_port = (ngx_http_in_port_t *) in_ports.elts; |
167 for (p = 0; p < in_ports.nelts; p++) { | 172 for (p = 0; p < in_ports.nelts; p++) { |
168 | 173 |
169 if (lscf[l].port == in_port[p].port) { | 174 if (lscf[l].port == in_port[p].port) { |
170 | 175 |
176 /* the port is already in the port list */ | |
177 | |
171 port_found = 1; | 178 port_found = 1; |
172 addr_found = 0; | 179 addr_found = 0; |
173 | 180 |
174 in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; | 181 in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; |
175 for (a = 0; a < in_port[p].addr.nelts; a++) { | 182 for (a = 0; a < in_port[p].addrs.nelts; a++) { |
176 | 183 |
177 if (lscf[l].addr == in_addr[a].addr) { | 184 if (lscf[l].addr == in_addr[a].addr) { |
185 | |
186 /* the address is already bound to this port */ | |
187 | |
188 /* "server_name" directives */ | |
178 s_name = (ngx_http_server_name_t *) | 189 s_name = (ngx_http_server_name_t *) |
179 cscf[s]->server_names.elts; | 190 cscf[s]->server_names.elts; |
180 for (n = 0; n < cscf[s]->server_names.nelts; n++) { | 191 for (n = 0; n < cscf[s]->server_names.nelts; n++) { |
192 | |
193 /* add the server name and server core module | |
194 configuration to the address:port */ | |
195 | |
196 /* TODO: duplicate names can be checked here */ | |
197 | |
181 ngx_test_null(name, | 198 ngx_test_null(name, |
182 ngx_push_array(&in_addr[a].names), | 199 ngx_push_array(&in_addr[a].names), |
183 NGX_CONF_ERROR); | 200 NGX_CONF_ERROR); |
184 | 201 |
185 name->name = s_name[n].name; | 202 name->name = s_name[n].name; |
186 name->core_srv_conf = s_name[n].core_srv_conf; | 203 name->core_srv_conf = s_name[n].core_srv_conf; |
187 } | 204 } |
205 | |
206 /* check duplicate "default" server that | |
207 serves this address:port */ | |
188 | 208 |
189 if (lscf[l].flags & NGX_HTTP_DEFAULT_SERVER) { | 209 if (lscf[l].flags & NGX_HTTP_DEFAULT_SERVER) { |
190 if (in_addr[a].flags | 210 if (in_addr[a].flags |
191 & NGX_HTTP_DEFAULT_SERVER) { | 211 & NGX_HTTP_DEFAULT_SERVER) { |
192 | 212 |
204 | 224 |
205 addr_found = 1; | 225 addr_found = 1; |
206 | 226 |
207 break; | 227 break; |
208 | 228 |
209 /* "*:XX" is the last resort */ | 229 } else if (in_addr[a].addr == INADDR_ANY) { |
210 } else if (in_addr[p].addr == INADDR_ANY) { | 230 |
231 /* "*:port" must be the last resort so move it | |
232 to the end of the address list and add | |
233 the new address at its place */ | |
234 | |
211 ngx_test_null(inaddr, | 235 ngx_test_null(inaddr, |
212 ngx_push_array(&in_port[p].addr), | 236 ngx_push_array(&in_port[p].addrs), |
213 NGX_CONF_ERROR); | 237 NGX_CONF_ERROR); |
214 | 238 |
215 ngx_memcpy(inaddr, &in_addr[a], | 239 ngx_memcpy(inaddr, &in_addr[a], |
216 sizeof(ngx_http_in_addr_t)); | 240 sizeof(ngx_http_in_addr_t)); |
217 | 241 |
218 inaddr->addr = lscf[l].addr; | 242 in_addr[a].addr = lscf[l].addr; |
219 inaddr->flags = lscf[l].flags; | 243 in_addr[a].flags = lscf[l].flags; |
220 inaddr->core_srv_conf = cscf[s]; | 244 in_addr[a].core_srv_conf = cscf[s]; |
245 | |
246 /* create the empty list of the server names that | |
247 can be served on this address:port */ | |
221 | 248 |
222 ngx_init_array(inaddr->names, cf->pool, 10, | 249 ngx_init_array(inaddr->names, cf->pool, 10, |
223 sizeof(ngx_http_server_name_t), | 250 sizeof(ngx_http_server_name_t), |
224 NGX_CONF_ERROR); | 251 NGX_CONF_ERROR); |
225 | 252 |
228 break; | 255 break; |
229 } | 256 } |
230 } | 257 } |
231 | 258 |
232 if (!addr_found) { | 259 if (!addr_found) { |
260 | |
261 /* add the address to the addresses list that | |
262 bound to this port */ | |
263 | |
233 ngx_test_null(inaddr, | 264 ngx_test_null(inaddr, |
234 ngx_push_array(&in_port[p].addr), | 265 ngx_push_array(&in_port[p].addrs), |
235 NGX_CONF_ERROR); | 266 NGX_CONF_ERROR); |
236 | 267 |
237 inaddr->addr = lscf[l].addr; | 268 inaddr->addr = lscf[l].addr; |
238 inaddr->flags = lscf[l].flags; | 269 inaddr->flags = lscf[l].flags; |
239 inaddr->core_srv_conf = cscf[s]; | 270 inaddr->core_srv_conf = cscf[s]; |
271 | |
272 /* create the empty list of the server names that | |
273 can be served on this address:port */ | |
240 | 274 |
241 ngx_init_array(inaddr->names, cf->pool, 10, | 275 ngx_init_array(inaddr->names, cf->pool, 10, |
242 sizeof(ngx_http_server_name_t), | 276 sizeof(ngx_http_server_name_t), |
243 NGX_CONF_ERROR); | 277 NGX_CONF_ERROR); |
244 } | 278 } |
245 } | 279 } |
246 } | 280 } |
247 | 281 |
248 if (!port_found) { | 282 if (!port_found) { |
283 | |
284 /* add the port to the in_port list */ | |
285 | |
249 ngx_test_null(in_port, | 286 ngx_test_null(in_port, |
250 ngx_push_array(&in_ports), | 287 ngx_push_array(&in_ports), |
251 NGX_CONF_ERROR); | 288 NGX_CONF_ERROR); |
252 | 289 |
253 in_port->port = lscf[l].port; | 290 in_port->port = lscf[l].port; |
254 | 291 |
255 ngx_init_array(in_port->addr, cf->pool, 10, | 292 /* create list of the addresses that bound to this port ... */ |
293 | |
294 ngx_init_array(in_port->addrs, cf->pool, 10, | |
256 sizeof(ngx_http_in_addr_t), | 295 sizeof(ngx_http_in_addr_t), |
257 NGX_CONF_ERROR); | 296 NGX_CONF_ERROR); |
258 | 297 |
259 ngx_test_null(inaddr, ngx_push_array(&in_port->addr), | 298 ngx_test_null(inaddr, ngx_push_array(&in_port->addrs), |
260 NGX_CONF_ERROR); | 299 NGX_CONF_ERROR); |
300 | |
301 /* ... and add the address to this list */ | |
261 | 302 |
262 inaddr->addr = lscf[l].addr; | 303 inaddr->addr = lscf[l].addr; |
263 inaddr->flags = lscf[l].flags; | 304 inaddr->flags = lscf[l].flags; |
264 inaddr->core_srv_conf = cscf[s]; | 305 inaddr->core_srv_conf = cscf[s]; |
306 | |
307 /* create the empty list of the server names that | |
308 can be served on this address:port */ | |
265 | 309 |
266 ngx_init_array(inaddr->names, cf->pool, 10, | 310 ngx_init_array(inaddr->names, cf->pool, 10, |
267 sizeof(ngx_http_server_name_t), | 311 sizeof(ngx_http_server_name_t), |
268 NGX_CONF_ERROR); | 312 NGX_CONF_ERROR); |
269 } | 313 } |
270 } | 314 } |
271 } | 315 } |
272 | 316 |
273 /* optimzie lists of ports, addresses and server names */ | 317 /* optimize the lists of the ports, the addresses and the server names */ |
274 | 318 |
275 /* AF_INET only */ | 319 /* AF_INET only */ |
276 | 320 |
277 in_port = (ngx_http_in_port_t *) in_ports.elts; | 321 in_port = (ngx_http_in_port_t *) in_ports.elts; |
278 for (p = 0; p < in_ports.nelts; p++) { | 322 for (p = 0; p < in_ports.nelts; p++) { |
279 | 323 |
280 in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; | 324 /* check whether the all server names point to the same server */ |
281 for (a = 0; a < in_port[p].addr.nelts; a++) { | 325 |
326 in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; | |
327 for (a = 0; a < in_port[p].addrs.nelts; a++) { | |
282 | 328 |
283 virtual_names = 0; | 329 virtual_names = 0; |
284 | 330 |
285 name = (ngx_http_server_name_t *) in_addr[a].names.elts; | 331 name = (ngx_http_server_name_t *) in_addr[a].names.elts; |
286 for (n = 0; n < in_addr[a].names.nelts; n++) { | 332 for (n = 0; n < in_addr[a].names.nelts; n++) { |
288 virtual_names = 1; | 334 virtual_names = 1; |
289 break; | 335 break; |
290 } | 336 } |
291 } | 337 } |
292 | 338 |
293 /* if all server names point to the same server | 339 /* if the all server names point to the same server |
294 then we do not need to check them at run time */ | 340 then we do not need to check them at run-time */ |
341 | |
295 if (!virtual_names) { | 342 if (!virtual_names) { |
296 in_addr[a].names.nelts = 0; | 343 in_addr[a].names.nelts = 0; |
297 } | 344 } |
298 } | 345 } |
299 | 346 |
300 /* if there is binding to "*:XX" then we need to bind to "*:XX" only | 347 /* if there's the binding to "*:port" then we need to bind() |
301 and ignore other binding */ | 348 to "*:port" only and ignore the other bindings */ |
349 | |
302 if (in_addr[a - 1].addr == INADDR_ANY) { | 350 if (in_addr[a - 1].addr == INADDR_ANY) { |
303 start = a - 1; | 351 a--; |
304 | 352 |
305 } else { | 353 } else { |
306 start = 0; | 354 a = 0; |
307 } | 355 } |
308 | 356 |
309 in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; | 357 in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; |
310 for (a = start; a < in_port[p].addr.nelts; a++) { | 358 while (a < in_port[p].addrs.nelts) { |
311 | 359 |
312 ngx_test_null(ls, ngx_push_array(&ngx_listening_sockets), | 360 ngx_test_null(ls, ngx_push_array(&ngx_listening_sockets), |
313 NGX_CONF_ERROR); | 361 NGX_CONF_ERROR); |
314 ngx_memzero(ls, sizeof(ngx_listen_t)); | 362 ngx_memzero(ls, sizeof(ngx_listen_t)); |
315 | 363 |
324 ngx_test_null(ls->addr_text.data, | 372 ngx_test_null(ls->addr_text.data, |
325 ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6), | 373 ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6), |
326 NGX_CONF_ERROR); | 374 NGX_CONF_ERROR); |
327 | 375 |
328 ls->addr_text.len = | 376 ls->addr_text.len = |
329 ngx_snprintf(ls->addr_text.data | 377 ngx_snprintf(ls->addr_text.data |
330 + ngx_inet_ntop(AF_INET, | 378 + ngx_inet_ntop(AF_INET, |
331 (char *) &in_addr[a].addr, | 379 (char *) &in_addr[a].addr, |
332 ls->addr_text.data, | 380 ls->addr_text.data, |
333 INET_ADDRSTRLEN), | 381 INET_ADDRSTRLEN), |
334 6, ":%d", in_port[p].port); | 382 6, ":%d", in_port[p].port); |
335 | 383 |
336 ls->family = AF_INET; | 384 ls->family = AF_INET; |
337 ls->type = SOCK_STREAM; | 385 ls->type = SOCK_STREAM; |
338 ls->protocol = IPPROTO_IP; | 386 ls->protocol = IPPROTO_IP; |
339 #if (NGX_OVERLAPPED) | 387 #if (NGX_OVERLAPPED) |
349 | 397 |
350 ls->handler = ngx_http_init_connection; | 398 ls->handler = ngx_http_init_connection; |
351 ls->log = cf->log; | 399 ls->log = cf->log; |
352 ls->pool_size = ngx_http_connection_pool_size; | 400 ls->pool_size = ngx_http_connection_pool_size; |
353 ls->ctx = ctx; | 401 ls->ctx = ctx; |
354 ls->servers = &in_port[p]; | 402 |
355 | 403 if (in_port[p].addrs.nelts > 1) { |
356 #if 0 | 404 |
357 if (in_port[p].addr.nelts == 1) { | 405 in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; |
358 in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; | 406 if (in_addr[in_port[p].addrs.nelts - 1].addr != INADDR_ANY) { |
359 | 407 |
360 /* if there is the single address for this port and no virtual | 408 /* if this port has not the "*:port" binding then create |
361 name servers so we do not need to check addresses | 409 the separate ngx_http_in_port_t for the all bindings */ |
362 at run time */ | 410 |
363 if (in_addr[a].names.nelts == 0) { | 411 ngx_test_null(inport, |
364 ls->ctx = in_addr->core_srv_conf->ctx; | 412 ngx_palloc(cf->pool, |
365 ls->servers = NULL; | 413 sizeof(ngx_http_in_port_t)), |
414 NGX_CONF_ERROR); | |
415 | |
416 inport->port = in_port[p].port; | |
417 | |
418 /* init list of the addresses ... */ | |
419 | |
420 ngx_init_array(inport->addrs, cf->pool, 1, | |
421 sizeof(ngx_http_in_addr_t), | |
422 NGX_CONF_ERROR); | |
423 | |
424 /* ... and set up it with the first address */ | |
425 | |
426 inport->addrs.nelts = 1; | |
427 inport->addrs.elts = in_port[p].addrs.elts; | |
428 | |
429 ls->servers = inport; | |
430 | |
431 /* prepare for the next cycle */ | |
432 | |
433 in_port[p].addrs.elts += in_port[p].addrs.size; | |
434 in_port[p].addrs.nelts--; | |
435 | |
436 in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; | |
437 a = 0; | |
438 | |
439 continue; | |
366 } | 440 } |
367 } | 441 } |
368 #endif | 442 |
369 ngx_log_debug(cf->log, "ls ctx: %d:%08x" _ in_port[p].port _ ls->ctx); | 443 ls->servers = &in_port[p]; |
444 a++; | |
370 } | 445 } |
371 } | 446 } |
372 | 447 |
373 /* DEBUG STUFF */ | 448 /* DEBUG STUFF */ |
374 in_port = (ngx_http_in_port_t *) in_ports.elts; | 449 in_port = (ngx_http_in_port_t *) in_ports.elts; |
375 for (p = 0; p < in_ports.nelts; p++) { | 450 for (p = 0; p < in_ports.nelts; p++) { |
376 ngx_log_debug(cf->log, "port: %d" _ in_port[p].port); | 451 ngx_log_debug(cf->log, "port: %d" _ in_port[p].port); |
377 in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; | 452 in_addr = (ngx_http_in_addr_t *) in_port[p].addrs.elts; |
378 for (a = 0; a < in_port[p].addr.nelts; a++) { | 453 for (a = 0; a < in_port[p].addrs.nelts; a++) { |
379 char ip[20]; | 454 char ip[20]; |
380 ngx_inet_ntop(AF_INET, (char *) &in_addr[a].addr, ip, 20); | 455 ngx_inet_ntop(AF_INET, (char *) &in_addr[a].addr, ip, 20); |
381 ngx_log_debug(cf->log, "%s %08x" _ ip _ in_addr[a].core_srv_conf); | 456 ngx_log_debug(cf->log, "%s %08x" _ ip _ in_addr[a].core_srv_conf); |
382 } | 457 } |
383 } | 458 } |