Mercurial > hg > nginx-ranges
view src/event/ngx_event_connect.c @ 326:9fc4ab6673f9 NGINX_0_6_7
nginx 0.6.7
*) Change: now the paths specified in the "include",
"auth_basic_user_file", "perl_modules", "ssl_certificate",
"ssl_certificate_key", and "ssl_client_certificate" directives are
relative to directory of nginx configuration file nginx.conf, but
not to nginx prefix directory.
*) Change: the --sysconfdir=PATH option in configure was canceled.
*) Change: the special make target "upgrade1" was defined for online
upgrade of 0.1.x versions.
*) Feature: the "server_name" and "valid_referers" directives support
regular expressions.
*) Feature: the "server" directive in the "upstream" context supports
the "backup" parameter.
*) Feature: the ngx_http_perl_module supports the
$r->discard_request_body.
*) Feature: the "add_header Last-Modified ..." directive changes the
"Last-Modified" response header line.
*) Bugfix: if an response different than 200 was returned to an request
with body and connection went to the keep-alive state after the
request, then nginx returned 400 for the next request.
*) Bugfix: a segmentation fault occurred in worker process if invalid
address was set in the "auth_http" directive.
*) Bugfix: now nginx uses default listen backlog value 511 on all
platforms except FreeBSD.
Thanks to Jiang Hong.
*) Bugfix: a worker process may got caught in an endless loop, if an
"server" inside "upstream" block was marked as "down"; bug appeared
in 0.6.6.
*) Bugfix: now Solaris sendfilev() is not used to transfer the client
request body to FastCGI-server via the unix domain socket.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 15 Aug 2007 00:00:00 +0400 |
parents | 0effe91f6083 |
children | 1c519aff5c0c |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev */ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> #include <ngx_event_connect.h> ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { int rc; u_int event; ngx_err_t err; ngx_uint_t level; ngx_socket_t s; ngx_event_t *rev, *wev; ngx_connection_t *c; rc = pc->get(pc, pc->data); if (rc != NGX_OK) { return rc; } s = ngx_socket(pc->sockaddr->sa_family, SOCK_STREAM, 0); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s); if (s == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_socket_n " failed"); return NGX_ERROR; } c = ngx_get_connection(s, pc->log); if (c == NULL) { if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_close_socket_n "failed"); } return NGX_ERROR; } if (pc->rcvbuf) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (const void *) &pc->rcvbuf, sizeof(int)) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, "setsockopt(SO_RCVBUF) failed"); ngx_free_connection(c); if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_close_socket_n " failed"); } return NGX_ERROR; } } if (ngx_nonblocking(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_nonblocking_n " failed"); ngx_free_connection(c); if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_close_socket_n " failed"); } return NGX_ERROR; } c->recv = ngx_recv; c->send = ngx_send; c->recv_chain = ngx_recv_chain; c->send_chain = ngx_send_chain; c->sendfile = 1; c->log_error = pc->log_error; if (pc->sockaddr->sa_family != AF_INET) { c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; #if (NGX_SOLARIS) /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */ c->sendfile = 0; #endif } rev = c->read; wev = c->write; rev->log = pc->log; wev->log = pc->log; pc->connection = c; /* * TODO: MT: - ngx_atomic_fetch_add() * or protection by critical section or mutex * * TODO: MP: - allocated in a shared memory * - ngx_atomic_fetch_add() * or protection by critical section or mutex */ c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); #if (NGX_THREADS) rev->lock = pc->lock; wev->lock = pc->lock; rev->own_lock = &c->lock; wev->own_lock = &c->lock; #endif if (ngx_add_conn) { if (ngx_add_conn(c) == NGX_ERROR) { return NGX_ERROR; } } ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connect to %V, fd:%d #%d", pc->name, s, c->number); rc = connect(s, pc->sockaddr, pc->socklen); if (rc == -1) { err = ngx_socket_errno; /* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */ if (err != NGX_EINPROGRESS && err != NGX_EAGAIN) { if (err == NGX_ECONNREFUSED || err == NGX_EHOSTUNREACH) { level = NGX_LOG_ERR; } else { level = NGX_LOG_CRIT; } ngx_log_error(level, c->log, err, "connect() to %V failed", pc->name); return NGX_DECLINED; } } if (ngx_add_conn) { if (rc == -1) { /* NGX_EINPROGRESS */ return NGX_AGAIN; } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected"); wev->ready = 1; return NGX_OK; } if (ngx_event_flags & NGX_USE_AIO_EVENT) { ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, ngx_socket_errno, "connect(): %d", rc); /* aio, iocp */ if (ngx_blocking(s) == -1) { ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ngx_blocking_n " failed"); return NGX_ERROR; } /* * FreeBSD's aio allows to post an operation on non-connected socket. * NT does not support it. * * TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT */ rev->ready = 1; wev->ready = 1; return NGX_OK; } if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { /* kqueue */ event = NGX_CLEAR_EVENT; } else { /* select, poll, /dev/poll */ event = NGX_LEVEL_EVENT; } if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { return NGX_ERROR; } if (rc == -1) { /* NGX_EINPROGRESS */ if (ngx_add_event(wev, NGX_WRITE_EVENT, event) != NGX_OK) { return NGX_ERROR; } return NGX_AGAIN; } ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected"); wev->ready = 1; return NGX_OK; } ngx_int_t ngx_event_get_peer(ngx_peer_connection_t *pc, void *data) { return NGX_OK; }