Mercurial > hg > nginx-vendor-current
comparison src/core/ngx_inet.c @ 200:d2ae1c9f1fd3 NGINX_0_3_47
nginx 0.3.47
*) Feature: the "upstream" directive.
*) Change: now the "\" escape symbol in the "\"" and "\'" pairs in the
SSI command is always removed.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 23 May 2006 00:00:00 +0400 |
parents | 4cd3e70c4d60 |
children | 56688ed172c8 |
comparison
equal
deleted
inserted
replaced
199:869664706c09 | 200:d2ae1c9f1fd3 |
---|---|
215 } | 215 } |
216 | 216 |
217 in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - m)))); | 217 in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - m)))); |
218 | 218 |
219 return NGX_OK; | 219 return NGX_OK; |
220 } | |
221 | |
222 | |
223 ngx_int_t | |
224 ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u) | |
225 { | |
226 u_char *p; | |
227 size_t len; | |
228 ngx_int_t port; | |
229 ngx_uint_t i; | |
230 #if (NGX_HAVE_UNIX_DOMAIN) | |
231 struct sockaddr_un *saun; | |
232 #endif | |
233 | |
234 len = u->url.len; | |
235 p = u->url.data; | |
236 | |
237 if (ngx_strncasecmp(p, "unix:", 5) == 0) { | |
238 | |
239 #if (NGX_HAVE_UNIX_DOMAIN) | |
240 | |
241 u->type = NGX_PARSE_URL_UNIX; | |
242 | |
243 p += 5; | |
244 len -= 5; | |
245 | |
246 if (u->uri_part) { | |
247 for (i = 0; i < len; i++) { | |
248 | |
249 if (p[i] == ':') { | |
250 len = i; | |
251 | |
252 u->uri.len -= len + 1; | |
253 u->uri.data += len + 1; | |
254 | |
255 break; | |
256 } | |
257 } | |
258 } | |
259 | |
260 if (len == 0) { | |
261 u->err = "no path in the unix domain socket"; | |
262 return NGX_ERROR; | |
263 } | |
264 | |
265 if (len + 1 > sizeof(saun->sun_path)) { | |
266 u->err = "too long path in the unix domain socket"; | |
267 return NGX_ERROR; | |
268 } | |
269 | |
270 u->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)); | |
271 if (u->peers == NULL) { | |
272 return NGX_ERROR; | |
273 } | |
274 | |
275 saun = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_un)); | |
276 if (saun == NULL) { | |
277 return NGX_ERROR; | |
278 } | |
279 | |
280 u->peers->number = 1; | |
281 | |
282 saun->sun_family = AF_UNIX; | |
283 (void) ngx_cpystrn((u_char *) saun->sun_path, p, len + 1); | |
284 | |
285 u->peers->peer[0].sockaddr = (struct sockaddr *) saun; | |
286 u->peers->peer[0].socklen = sizeof(struct sockaddr_un); | |
287 u->peers->peer[0].name = u->url; | |
288 u->peers->peer[0].uri_separator = ":"; | |
289 | |
290 u->host_header.len = sizeof("localhost") - 1; | |
291 u->host_header.data = (u_char *) "localhost"; | |
292 | |
293 return NGX_OK; | |
294 | |
295 #else | |
296 u->err = "the unix domain sockets are not supported on this platform"; | |
297 | |
298 return NGX_ERROR; | |
299 | |
300 #endif | |
301 } | |
302 | |
303 if ((p[0] == ':' || p[0] == '/') && !u->listen) { | |
304 u->err = "invalid host"; | |
305 return NGX_ERROR; | |
306 } | |
307 | |
308 u->type = NGX_PARSE_URL_INET; | |
309 | |
310 u->host.data = p; | |
311 u->host_header.len = len; | |
312 u->host_header.data = p; | |
313 | |
314 for (i = 0; i < len; i++) { | |
315 | |
316 if (p[i] == ':') { | |
317 u->port.data = &p[i + 1]; | |
318 u->host.len = i; | |
319 | |
320 if (!u->uri_part) { | |
321 u->port.len = &p[len] - u->port.data; | |
322 break; | |
323 } | |
324 } | |
325 | |
326 if (p[i] == '/') { | |
327 u->uri.len = len - i; | |
328 u->uri.data = &p[i]; | |
329 u->host_header.len = i; | |
330 | |
331 if (u->host.len == 0) { | |
332 u->host.len = i; | |
333 } | |
334 | |
335 if (u->port.data == NULL) { | |
336 u->default_port = 1; | |
337 goto port; | |
338 } | |
339 | |
340 u->port.len = &p[i] - u->port.data; | |
341 | |
342 if (u->port.len == 0) { | |
343 u->err = "invalid port"; | |
344 return NGX_ERROR; | |
345 } | |
346 | |
347 break; | |
348 } | |
349 } | |
350 | |
351 if (u->port.data) { | |
352 | |
353 if (u->port.len == 0) { | |
354 u->port.len = &p[i] - u->port.data; | |
355 | |
356 if (u->port.len == 0) { | |
357 u->err = "invalid port"; | |
358 return NGX_ERROR; | |
359 } | |
360 } | |
361 | |
362 port = ngx_atoi(u->port.data, u->port.len); | |
363 | |
364 if (port == NGX_ERROR || port < 1 || port > 65536) { | |
365 u->err = "invalid port"; | |
366 return NGX_ERROR; | |
367 } | |
368 | |
369 } else { | |
370 port = ngx_atoi(p, len); | |
371 | |
372 if (port == NGX_ERROR) { | |
373 u->default_port = 1; | |
374 u->host.len = len; | |
375 | |
376 goto port; | |
377 } | |
378 | |
379 u->port.len = len; | |
380 u->port.data = p; | |
381 u->wildcard = 1; | |
382 } | |
383 | |
384 u->portn = (in_port_t) port; | |
385 | |
386 port: | |
387 | |
388 if (u->listen) { | |
389 return NGX_OK; | |
390 } | |
391 | |
392 if (u->default_port) { | |
393 | |
394 if (u->upstream) { | |
395 return NGX_OK; | |
396 } | |
397 | |
398 if (u->default_portn == 0) { | |
399 u->err = "no port"; | |
400 return NGX_ERROR; | |
401 } | |
402 | |
403 u->portn = u->default_portn; | |
404 | |
405 u->port.data = ngx_palloc(cf->pool, sizeof("65536") - 1); | |
406 if (u->port.data == NULL) { | |
407 return NGX_ERROR; | |
408 } | |
409 | |
410 u->port.len = ngx_sprintf(u->port.data, "%d", u->portn) - u->port.data; | |
411 | |
412 } else if (u->portn) { | |
413 if (u->portn == u->default_portn) { | |
414 u->default_port = 1; | |
415 } | |
416 | |
417 } else { | |
418 u->err = "no port"; | |
419 return NGX_ERROR; | |
420 } | |
421 | |
422 if (u->host.len == 0) { | |
423 u->err = "no host"; | |
424 return NGX_ERROR; | |
425 } | |
426 | |
427 u->peers = ngx_inet_resolve_peer(cf, &u->host, u->portn); | |
428 | |
429 if (u->peers == NULL) { | |
430 return NGX_ERROR; | |
431 } | |
432 | |
433 if (u->peers == NGX_CONF_ERROR) { | |
434 u->err = "host not found"; | |
435 return NGX_ERROR; | |
436 } | |
437 | |
438 return NGX_OK; | |
439 } | |
440 | |
441 | |
442 ngx_peers_t * | |
443 ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, in_port_t port) | |
444 { | |
445 u_char *host; | |
446 size_t len; | |
447 in_addr_t in_addr; | |
448 ngx_uint_t i; | |
449 ngx_peers_t *peers; | |
450 struct hostent *h; | |
451 struct sockaddr_in *sin; | |
452 | |
453 host = ngx_palloc(cf->temp_pool, name->len + 1); | |
454 if (host == NULL) { | |
455 return NULL; | |
456 } | |
457 | |
458 (void) ngx_cpystrn(host, name->data, name->len + 1); | |
459 | |
460 /* AF_INET only */ | |
461 | |
462 in_addr = inet_addr((char *) host); | |
463 | |
464 if (in_addr == INADDR_NONE) { | |
465 h = gethostbyname((char *) host); | |
466 | |
467 if (h == NULL || h->h_addr_list[0] == NULL) { | |
468 return NGX_CONF_ERROR; | |
469 } | |
470 | |
471 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ } | |
472 | |
473 /* MP: ngx_shared_palloc() */ | |
474 | |
475 peers = ngx_pcalloc(cf->pool, | |
476 sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1)); | |
477 if (peers == NULL) { | |
478 return NULL; | |
479 } | |
480 | |
481 peers->number = i; | |
482 peers->weight = 1; | |
483 | |
484 for (i = 0; h->h_addr_list[i] != NULL; i++) { | |
485 | |
486 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)); | |
487 if (sin == NULL) { | |
488 return NULL; | |
489 } | |
490 | |
491 sin->sin_family = AF_INET; | |
492 sin->sin_port = htons(port); | |
493 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]); | |
494 | |
495 peers->peer[i].sockaddr = (struct sockaddr *) sin; | |
496 peers->peer[i].socklen = sizeof(struct sockaddr_in); | |
497 | |
498 len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1; | |
499 | |
500 peers->peer[i].name.data = ngx_palloc(cf->pool, len); | |
501 if (peers->peer[i].name.data == NULL) { | |
502 return NULL; | |
503 } | |
504 | |
505 len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin, | |
506 peers->peer[i].name.data, len); | |
507 | |
508 peers->peer[i].name.len = | |
509 ngx_sprintf(&peers->peer[i].name.data[len], | |
510 ":%d", port) | |
511 - peers->peer[i].name.data; | |
512 | |
513 peers->peer[i].uri_separator = ""; | |
514 } | |
515 | |
516 } else { | |
517 | |
518 /* MP: ngx_shared_palloc() */ | |
519 | |
520 peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)); | |
521 if (peers == NULL) { | |
522 return NULL; | |
523 } | |
524 | |
525 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)); | |
526 if (sin == NULL) { | |
527 return NULL; | |
528 } | |
529 | |
530 peers->number = 1; | |
531 | |
532 sin->sin_family = AF_INET; | |
533 sin->sin_port = htons(port); | |
534 sin->sin_addr.s_addr = in_addr; | |
535 | |
536 peers->peer[0].sockaddr = (struct sockaddr *) sin; | |
537 peers->peer[0].socklen = sizeof(struct sockaddr_in); | |
538 | |
539 peers->peer[0].name.data = ngx_palloc(cf->pool, | |
540 name->len + sizeof(":65536") - 1); | |
541 if (peers->peer[0].name.data == NULL) { | |
542 return NULL; | |
543 } | |
544 | |
545 peers->peer[0].name.len = ngx_sprintf(peers->peer[0].name.data, "%V:%d", | |
546 name, port) | |
547 - peers->peer[0].name.data; | |
548 | |
549 peers->peer[0].uri_separator = ""; | |
550 } | |
551 | |
552 return peers; | |
220 } | 553 } |
221 | 554 |
222 | 555 |
223 ngx_peers_t * | 556 ngx_peers_t * |
224 ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u) | 557 ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u) |
239 "%s in upstream \"%V\"", err, &u->name); | 572 "%s in upstream \"%V\"", err, &u->name); |
240 return NULL; | 573 return NULL; |
241 } | 574 } |
242 | 575 |
243 if (u->default_port) { | 576 if (u->default_port) { |
577 | |
244 if (u->default_port_value == 0) { | 578 if (u->default_port_value == 0) { |
245 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 579 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
246 "no port in upstream \"%V\"", &u->name); | 580 "no port in upstream \"%V\"", &u->name); |
247 return NULL; | 581 return NULL; |
248 } | 582 } |
275 return NULL; | 609 return NULL; |
276 } | 610 } |
277 | 611 |
278 u->port = htons(u->port); | 612 u->port = htons(u->port); |
279 | 613 |
280 host = ngx_palloc(cf->pool, u->host.len + 1); | 614 host = ngx_palloc(cf->temp_pool, u->host.len + 1); |
281 if (host == NULL) { | 615 if (host == NULL) { |
282 return NULL; | 616 return NULL; |
283 } | 617 } |
284 | 618 |
285 (void) ngx_cpystrn(host, u->host.data, u->host.len + 1); | 619 (void) ngx_cpystrn(host, u->host.data, u->host.len + 1); |