mirror of
https://github.com/emikulic/darkhttpd.git
synced 2023-08-10 21:13:08 +03:00
. Made all sockets non-blocking
. Used simpler way of ignoring SIGPIPE . Made sure closed sockets aren't written to
This commit is contained in:
parent
70cbd12463
commit
3dc4ce1216
@ -34,6 +34,7 @@
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
@ -71,6 +72,7 @@ struct connection
|
||||
char *request;
|
||||
unsigned int request_length;
|
||||
|
||||
/* request fields */
|
||||
char *method, *uri, *referer, *user_agent;
|
||||
|
||||
char *header;
|
||||
@ -211,6 +213,17 @@ static unsigned int xasprintf(char **ret, const char *format, ...)
|
||||
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Make the specified socket non-blocking.
|
||||
*/
|
||||
static void nonblock_socket(const int sock)
|
||||
{
|
||||
if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
|
||||
err(1, "fcntl() to set O_NONBLOCK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Split string out of src with range [left:right-1]
|
||||
*/
|
||||
@ -468,6 +481,8 @@ static void init_sockin(void)
|
||||
&sockopt, sizeof(sockopt)) == -1)
|
||||
err(1, "setsockopt(SO_REUSEADDR)");
|
||||
|
||||
nonblock_socket(sockin);
|
||||
|
||||
/* bind socket */
|
||||
addrin.sin_family = (u_char)PF_INET;
|
||||
addrin.sin_port = htons(bindport);
|
||||
@ -677,6 +692,8 @@ static void accept_connection(void)
|
||||
&sin_size);
|
||||
if (conn->socket == -1) err(1, "accept()");
|
||||
|
||||
nonblock_socket(conn->socket);
|
||||
|
||||
conn->state = RECV_REQUEST;
|
||||
conn->client = addrin.sin_addr.s_addr;
|
||||
LIST_INSERT_HEAD(&connlist, conn, entries);
|
||||
@ -819,7 +836,7 @@ static void default_reply(struct connection *conn,
|
||||
"HTTP/1.1 %d %s\r\n"
|
||||
"Date: %s\r\n"
|
||||
"Server: %s\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Connection: close\r\n" /* FIXME: remove for keepalive */
|
||||
"Content-Length: %d\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"\r\n",
|
||||
@ -851,7 +868,8 @@ static char *parse_field(const struct connection *conn, const char *field)
|
||||
/* find end */
|
||||
for (bound2 = bound1;
|
||||
conn->request[bound2] != '\r' &&
|
||||
bound2 < conn->request_length; bound2++);
|
||||
bound2 < conn->request_length; bound2++)
|
||||
;
|
||||
|
||||
/* copy to buffer */
|
||||
return split_string(conn->request, bound1, bound2);
|
||||
@ -899,6 +917,9 @@ static void process_get(struct connection *conn)
|
||||
const char *mimetype = NULL;
|
||||
struct stat filestat;
|
||||
|
||||
/* FIXME */
|
||||
printf("-----\n%s-----\n\n", conn->request);
|
||||
|
||||
/* work out path of file being requested */
|
||||
decoded_url = urldecode(conn->uri);
|
||||
|
||||
@ -957,7 +978,7 @@ static void process_get(struct connection *conn)
|
||||
conn->reply_length = filestat.st_size;
|
||||
conn->lastmod = xstrdup(rfc1123_date(filestat.st_mtime));
|
||||
|
||||
/* the browser might already have it */
|
||||
/* check for If-Modified-Since, may not have to send */
|
||||
if_mod_since = parse_field(conn, "If-Modified-Since: ");
|
||||
if (if_mod_since != NULL &&
|
||||
strcmp(if_mod_since, conn->lastmod) == 0)
|
||||
@ -972,7 +993,7 @@ static void process_get(struct connection *conn)
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Date: %s\r\n"
|
||||
"Server: %s\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Connection: close\r\n" /* FIXME: remove this for keepalive */
|
||||
"Content-Length: %d\r\n"
|
||||
"Content-Type: %s\r\n"
|
||||
"Last-Modified: %s\r\n"
|
||||
@ -1084,9 +1105,11 @@ static void poll_send_header(struct connection *conn)
|
||||
conn->header_length - conn->header_sent, 0);
|
||||
conn->last_active = time(NULL);
|
||||
debugf("poll_send_header(%d) sent %d bytes\n", conn->socket, sent);
|
||||
if (sent == -1) err(1, "send()");
|
||||
if (sent == 0)
|
||||
|
||||
/* handle any errors (-1) or closure (0) in send() */
|
||||
if (sent < 1)
|
||||
{
|
||||
if (sent == -1) debugf("send() error: %s\n", strerror(errno));
|
||||
conn->state = DONE;
|
||||
return;
|
||||
}
|
||||
@ -1144,10 +1167,10 @@ static void poll_send_reply(struct connection *conn)
|
||||
debugf("poll_send_reply(%d) sent %d bytes [%d to %d]\n",
|
||||
conn->socket, sent, conn->reply_sent, conn->reply_sent+sent-1);
|
||||
|
||||
/* handle any errors in send() */
|
||||
if (sent == -1) err(1, "send()");
|
||||
if (sent == 0)
|
||||
/* handle any errors (-1) or closure (0) in send() */
|
||||
if (sent < 1)
|
||||
{
|
||||
if (sent == -1) debugf("send() error: %s\n", strerror(errno));
|
||||
conn->state = DONE;
|
||||
return;
|
||||
}
|
||||
@ -1284,16 +1307,6 @@ static void httpd_poll(void)
|
||||
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Ignore SIGPIPE
|
||||
*/
|
||||
static void ignore_signal(int signum)
|
||||
{
|
||||
if (signum == signum) { /* do nothing */ }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Execution starts here.
|
||||
*/
|
||||
@ -1311,8 +1324,8 @@ int main(int argc, char *argv[])
|
||||
if (logfile == NULL) err(1, "fopen(\"%s\")", logfile_name);
|
||||
}
|
||||
|
||||
if (signal(SIGPIPE, ignore_signal) == SIG_ERR)
|
||||
err(1, "signal(SIG_PIPE)");
|
||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||
err(1, "signal(ignore SIGPIPE)");
|
||||
|
||||
for (;;) httpd_poll();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user