X-Git-Url: https://unix4lyfe.org/gitweb/darkstat-debian/blobdiff_plain/a1e8056c92203d02860d719abb1d562453896da8..4da209d9116b41ab59eeedc5823bc2cb64b5bc3e:/http.c diff --git a/http.c b/http.c index 2835e8e..e39f16b 100644 --- a/http.c +++ b/http.c @@ -1,5 +1,5 @@ /* darkstat 3 - * copyright (c) 2001-2011 Emil Mikulic. + * copyright (c) 2001-2012 Emil Mikulic. * * http.c: embedded webserver. * This borrows a lot of code from darkhttpd. @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -55,7 +56,7 @@ struct connection { int socket; struct sockaddr_storage client; - time_t last_active; + long last_active_mono; enum { RECV_REQUEST, /* receiving request */ SEND_HEADER_AND_REPLY, /* try to send header+reply together */ @@ -266,7 +267,7 @@ static struct connection *new_connection(void) conn->socket = -1; memset(&conn->client, 0, sizeof(conn->client)); - conn->last_active = now; + conn->last_active_mono = now_mono(); conn->request = NULL; conn->request_length = 0; conn->accept_gzip = 0; @@ -363,13 +364,11 @@ static void free_connection(struct connection *conn) * buffer is returned for convenience. */ #define DATE_LEN 30 /* strlen("Fri, 28 Feb 2003 00:02:08 GMT")+1 */ -static char *rfc1123_date(char *dest, const time_t when) -{ - time_t tmp = when; +static char *rfc1123_date(char *dest, time_t when) { if (strftime(dest, DATE_LEN, - "%a, %d %b %Y %H:%M:%S %Z", gmtime(&tmp) ) == 0) + "%a, %d %b %Y %H:%M:%S %Z", gmtime(&when) ) == 0) errx(1, "strftime() failed [%s]", dest); - return (dest); + return dest; } static void generate_header(struct connection *conn, @@ -382,7 +381,7 @@ static void generate_header(struct connection *conn, if (conn->encoding == NULL) conn->encoding = encoding_identity; - verbosef("http: %d %s (%s: %d bytes)", code, text, + verbosef("http: %d %s (%s: %zu bytes)", code, text, conn->encoding, conn->reply_length); conn->header_length = xasprintf(&(conn->header), "HTTP/1.1 %d %s\r\n" @@ -397,7 +396,7 @@ static void generate_header(struct connection *conn, "\r\n" , code, text, - rfc1123_date(date, now), server, + rfc1123_date(date, now_real()), server, conn->mime_type, conn->reply_length, conn->encoding, conn->header_extra); conn->http_code = code; @@ -719,7 +718,7 @@ static void poll_recv_request(struct connection *conn) conn->state = DONE; return; } - conn->last_active = now; + conn->last_active_mono = now_mono(); /* append to conn->request */ conn->request = xrealloc(conn->request, conn->request_length+recvd+1); @@ -772,7 +771,7 @@ static void poll_send_header_and_reply(struct connection *conn) iov[1].iov_len = conn->reply_length; sent = writev(conn->socket, iov, 2); - conn->last_active = now; + conn->last_active_mono = now_mono(); /* handle any errors (-1) or closure (0) in send() */ if (sent < 1) { @@ -814,7 +813,7 @@ static void poll_send_header(struct connection *conn) sent = send(conn->socket, conn->header + conn->header_sent, conn->header_length - conn->header_sent, 0); - conn->last_active = now; + conn->last_active_mono = now_mono(); dverbosef("poll_send_header(%d) sent %d bytes", conn->socket, (int)sent); /* handle any errors (-1) or closure (0) in send() */ @@ -850,7 +849,7 @@ static void poll_send_reply(struct connection *conn) sent = send(conn->socket, conn->reply + conn->reply_sent, conn->reply_length - conn->reply_sent, 0); - conn->last_active = now; + conn->last_active_mono = now_mono(); dverbosef("poll_send_reply(%d) sent %d: [%d-%d] of %d", conn->socket, (int)sent, (int)conn->reply_sent, @@ -921,14 +920,18 @@ static void http_listen_one(struct addrinfo *ai, /* create incoming socket */ if ((sockin = socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol)) == -1) - err(1, "http_listen_one(%s, %u): socket(%d (%s), %d, %d) failed", + ai->ai_protocol)) == -1) { + warn("http_listen_one(%s, %u): socket(%d (%s), %d, %d) failed", ipaddr, (unsigned int)bindport, ai->ai_family, (ai->ai_family == AF_INET6) ? "AF_INET6" : (ai->ai_family == AF_INET) ? "AF_INET" : "?", ai->ai_socktype, ai->ai_protocol); + return; + } + + fd_set_nonblock(sockin); /* reuse address */ sockopt = 1; @@ -951,11 +954,12 @@ static void http_listen_one(struct addrinfo *ai, /* bind socket */ if (bind(sockin, ai->ai_addr, ai->ai_addrlen) == -1) { warn("bind(\"%s\") failed", ipaddr); + close(sockin); return; } /* listen on socket */ - if (listen(sockin, -1) == -1) + if (listen(sockin, 128) == -1) err(1, "listen() failed"); verbosef("listening on http://%s%s%s:%u/", @@ -993,7 +997,7 @@ void http_listen(const unsigned short bindport) free(bindaddr); } - if (insocks == 0) + if (insocks == NULL) errx(1, "was not able to bind any ports for http interface"); /* ignore SIGPIPE */ @@ -1022,7 +1026,7 @@ http_fd_set(fd_set *recv_set, fd_set *send_set, int *max_fd, LIST_FOREACH_SAFE(conn, &connlist, entries, next) { - int idlefor = now - conn->last_active; + int idlefor = now_mono() - conn->last_active_mono; /* Time out dead connections. */ if (idlefor >= idletime) {