diff -pruN lighttpd-1.4.20/src/base.h lighttpd-1.4.20.httpx/src/base.h --- lighttpd-1.4.20/src/base.h 2008-08-19 12:40:42.000000000 -0500 +++ lighttpd-1.4.20.httpx/src/base.h 2008-10-23 16:41:06.000000000 -0500 @@ -485,6 +485,7 @@ typedef struct { unsigned short max_fds; unsigned short max_conns; unsigned short max_request_size; + unsigned short use_httpx; unsigned short log_request_header_on_error; unsigned short log_state_handling; diff -pruN lighttpd-1.4.20/src/configfile.c lighttpd-1.4.20.httpx/src/configfile.c --- lighttpd-1.4.20/src/configfile.c 2008-08-19 12:40:42.000000000 -0500 +++ lighttpd-1.4.20.httpx/src/configfile.c 2008-10-23 09:49:08.000000000 -0500 @@ -94,6 +94,7 @@ static int config_insert(server *srv) { { "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */ { "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */ { "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 51 */ + { "server.use-httpx", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 52 */ { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, @@ -135,6 +136,7 @@ static int config_insert(server *srv) { cv[43].destination = &(srv->srvconf.max_conns); cv[12].destination = &(srv->srvconf.max_request_size); + cv[52].destination = &(srv->srvconf.use_httpx); srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); assert(srv->config_storage); diff -pruN lighttpd-1.4.20/src/connections.c lighttpd-1.4.20.httpx/src/connections.c --- lighttpd-1.4.20/src/connections.c 2008-08-19 12:40:42.000000000 -0500 +++ lighttpd-1.4.20.httpx/src/connections.c 2008-10-23 16:36:19.000000000 -0500 @@ -1298,6 +1298,54 @@ connection *connection_accept(server *sr } else { connection *con; + if(srv_socket->addr.plain.sa_family == AF_UNIX && srv->srvconf.use_httpx) { + /* read the tcp socket over the unix domain socket */ + struct msghdr msg; + struct iovec iov[1]; + ssize_t n; + char b; + + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof(int))]; + } control_un; + struct cmsghdr *cmptr; + + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); + msg.msg_name = NULL; + msg.msg_namelen = 0; + iov[0].iov_base = &b; + iov[0].iov_len = 1; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + n = recvmsg(cnt, &msg, 0); + if(n <= 0) { + log_error_write(srv, __FILE__, __LINE__, "ssd", "recvmsg failed:", strerror(errno), errno); + return NULL; + } + + if((cmptr = CMSG_FIRSTHDR(&msg)) != NULL && + cmptr->cmsg_len == CMSG_LEN(sizeof(int))) { + if(cmptr->cmsg_level != SOL_SOCKET) { + log_error_write(srv, __FILE__, __LINE__, "ss", "cmsg failed:", "wrong level"); + return NULL; + } + if(cmptr->cmsg_type != SCM_RIGHTS) { + log_error_write(srv, __FILE__, __LINE__, "ss", "cmsg failed:", "wrong type"); + return NULL; + } + close(cnt); + cnt = *((int *)CMSG_DATA(cmptr)); + cnt_len = sizeof(cnt_addr); + getpeername(cnt, (struct sockaddr *)&cnt_addr, &cnt_len); + } else { + log_error_write(srv, __FILE__, __LINE__, "ss", "cmsg failed:", "no message"); + return NULL; + } + } + srv->cur_fds++; /* ok, we have the connection, register it */