while (((rv = select(fd+1, write ? NULL : &fds, write ? &fds : NULL,
NULL, &timeout)) < 0) && (errno == EINTR))
{
- D("IO: Socket(%d) select interrupted: %s\n",
+ D("IO: FD(%d) select interrupted: %s\n",
fd, strerror(errno));
continue;
if (rv <= 0)
{
- D("IO: Socket(%d) appears dead (rv=%d)\n", fd, rv);
+ D("IO: FD(%d) appears dead (rv=%d)\n", fd, rv);
return false;
}
{
if (errno == EINTR)
{
- D("IO: Socket(%d) interrupted\n", cl->fd.fd);
+ D("IO: FD(%d) interrupted\n", cl->fd.fd);
continue;
}
else if ((sec > 0) && (errno == EAGAIN || errno == EWOULDBLOCK))
}
else
{
- D("IO: Socket(%d) write error: %s\n", fd, strerror(errno));
+ D("IO: FD(%d) write error: %s\n", fd, strerror(errno));
return -1;
}
}
*/
else if (rv == 0)
{
- D("IO: Socket(%d) closed\n", fd);
+ D("IO: FD(%d) appears closed\n", fd);
return 0;
}
else if (rv < len)
{
- D("IO: Socket(%d) short write %d/%d bytes\n", fd, rv, len);
+ D("IO: FD(%d) short write %d/%d bytes\n", fd, rv, len);
len -= rv;
buf += rv;
continue;
}
else
{
- D("IO: Socket(%d) sent %d/%d bytes\n", fd, rv, len);
+ D("IO: FD(%d) sent %d/%d bytes\n", fd, rv, len);
return rv;
}
}
}
else
{
- D("IO: Socket(%d) read error: %s\n", fd, strerror(errno));
+ D("IO: FD(%d) read error: %s\n", fd, strerror(errno));
return -1;
}
}
else if (rv == 0)
{
- D("IO: Socket(%d) closed\n", fd);
+ D("IO: FD(%d) appears closed\n", fd);
return 0;
}
else
{
- D("IO: Socket(%d) read %d bytes\n", fd, rv);
+ D("IO: FD(%d) read %d bytes\n", fd, rv);
return rv;
}
}
len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
- if ((req != NULL) && (req->version > 1.0))
+ if ((req != NULL) && (req->version > UH_HTTP_VER_1_0))
ensure_ret(uh_http_sendc(cl, buffer, len));
else if (len > 0)
ensure_ret(uh_tcp_send(cl, buffer, len));
if (len < 0)
len = strlen(buf);
- if ((req != NULL) && (req->version > 1.0))
+ if ((req != NULL) && (req->version > UH_HTTP_VER_1_0))
ensure_ret(uh_http_sendc(cl, buf, len));
else if (len > 0)
ensure_ret(uh_tcp_send(cl, buf, len));
/* 401 */
uh_http_sendf(cl, NULL,
- "HTTP/%.1f 401 Authorization Required\r\n"
- "WWW-Authenticate: Basic realm=\"%s\"\r\n"
- "Content-Type: text/plain\r\n"
- "Content-Length: 23\r\n\r\n"
- "Authorization Required\n",
- req->version, cl->server->conf->realm
- );
+ "%s 401 Authorization Required\r\n"
+ "WWW-Authenticate: Basic realm=\"%s\"\r\n"
+ "Content-Type: text/plain\r\n"
+ "Content-Length: 23\r\n\r\n"
+ "Authorization Required\n",
+ http_versions[req->version],
+ cl->server->conf->realm);
return 0;
}
}
-struct client * uh_client_add(int sock, struct listener *serv)
+struct client * uh_client_add(int sock, struct listener *serv,
+ struct sockaddr_in6 *peer)
{
struct client *new = NULL;
socklen_t sl;
if ((new = (struct client *)malloc(sizeof(struct client))) != NULL)
{
memset(new, 0, sizeof(struct client));
+ memcpy(&new->peeraddr, peer, sizeof(new->peeraddr));
new->fd.fd = sock;
new->server = serv;
- /* get remote endpoint addr */
- sl = sizeof(struct sockaddr_in6);
- memset(&(new->peeraddr), 0, sl);
- getpeername(sock, (struct sockaddr *) &(new->peeraddr), &sl);
+ new->rpipe.fd = -1;
+ new->wpipe.fd = -1;
/* get local endpoint addr */
sl = sizeof(struct sockaddr_in6);
- memset(&(new->servaddr), 0, sl);
getsockname(sock, (struct sockaddr *) &(new->servaddr), &sl);
new->next = uh_clients;
uh_clients = new;
serv->n_clients++;
+
+ D("IO: Client(%d) allocated\n", new->fd.fd);
}
return new;
for (cur = uh_clients; cur; prv = cur, cur = cur->next)
{
- if ((cur == cl) || (!cl && cur->dead))
+ if (cur == cl)
{
if (prv)
prv->next = cur->next;
if (cur->proc.pid)
uloop_process_delete(&cur->proc);
- if (cur->pipe.fd)
- uloop_fd_delete(&cur->pipe);
+ D("IO: Client(%d) freeing\n", cur->fd.fd);
- uloop_fd_delete(&cur->fd);
- close(cur->fd.fd);
+ uh_ufd_remove(&cur->rpipe);
+ uh_ufd_remove(&cur->wpipe);
+ uh_ufd_remove(&cur->fd);
- D("IO: Socket(%d) closing\n", cur->fd.fd);
cur->server->n_clients--;
free(cur);
}
+void uh_ufd_add(struct uloop_fd *u, uloop_fd_handler h, unsigned int ev)
+{
+ if (h != NULL)
+ {
+ u->cb = h;
+ uloop_fd_add(u, ev);
+ D("IO: FD(%d) added to uloop\n", u->fd);
+ }
+}
+
+void uh_ufd_remove(struct uloop_fd *u)
+{
+ if (u->cb != NULL)
+ {
+ uloop_fd_delete(u);
+ D("IO: FD(%d) removed from uloop\n", u->fd);
+ u->cb = NULL;
+ }
+
+ if (u->fd > -1)
+ {
+ close(u->fd);
+ D("IO: FD(%d) closed\n", u->fd);
+ u->fd = -1;
+ }
+}
+
+
#ifdef HAVE_CGI
static struct interpreter *uh_interpreters = NULL;