mirror of
https://github.com/emikulic/darkhttpd.git
synced 2023-08-10 21:13:08 +03:00
. Linux needs _GNU_SOURCE defined.
. bindport is uint16_t like in Linux. . Fix a bounds error in make_safe_uri(). . Remember to free temporaries in make_safe_uri(). . Free if_mod_since in process_get() . Set reply_file to NULL after closing it in poll_send_reply() to avoid double fclose() in free_connection(). . Don't log connections with http_code == 0; these are connections that failed while receiving the request string. . Initialise timeout more cleanly in httpd_poll(). . Made MAX_FD_SET use a { block } to keep gcc 3 happy. . Don't free items in a LIST_FOREACH() block; use a temporary next pointer and LIST_NEXT(). . exit_quickly() closes logfile if it's open. . exit_quickly() doesn't re-throw the signal that triggered it.
This commit is contained in:
parent
d7bfc32d6d
commit
9d6d7533fe
@ -24,6 +24,10 @@
|
|||||||
* x Ensure URIs requested are safe.
|
* x Ensure URIs requested are safe.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
#define _GNU_SOURCE /* for strsignal() and vasprintf() */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -119,7 +123,7 @@ struct mime_mapping
|
|||||||
|
|
||||||
/* Defaults can be overridden on the command-line */
|
/* Defaults can be overridden on the command-line */
|
||||||
static in_addr_t bindaddr = INADDR_ANY;
|
static in_addr_t bindaddr = INADDR_ANY;
|
||||||
static u_int16_t bindport = 80;
|
static uint16_t bindport = 80;
|
||||||
static int max_connections = -1; /* kern.ipc.somaxconn */
|
static int max_connections = -1; /* kern.ipc.somaxconn */
|
||||||
static const char *index_name = "index.html";
|
static const char *index_name = "index.html";
|
||||||
|
|
||||||
@ -272,7 +276,9 @@ static char *make_safe_uri(const char *uri)
|
|||||||
for (; uri[i] == '/'; i++);
|
for (; uri[i] == '/'; i++);
|
||||||
|
|
||||||
/* look for the next slash */
|
/* look for the next slash */
|
||||||
for (j=i+1; uri[j] != '/' && uri[j] != '\0'; j++);
|
for (j=i+1; j < urilen && uri[j] != '/'; j++);
|
||||||
|
|
||||||
|
/* FIXME: test this whole function */
|
||||||
|
|
||||||
elements[elem++] = split_string(uri, i, j);
|
elements[elem++] = split_string(uri, i, j);
|
||||||
i = j; /* iterate */
|
i = j; /* iterate */
|
||||||
@ -322,6 +328,10 @@ static char *make_safe_uri(const char *uri)
|
|||||||
|
|
||||||
out = (char*) xrealloc(out, strlen(out)+1); /* shorten buffer */
|
out = (char*) xrealloc(out, strlen(out)+1); /* shorten buffer */
|
||||||
debugf("`%s' -safe-> `%s'\n", uri, out);
|
debugf("`%s' -safe-> `%s'\n", uri, out);
|
||||||
|
for (j=0; j<elem; j++)
|
||||||
|
if (elements[j] != NULL) free(elements[j]);
|
||||||
|
free(elements);
|
||||||
|
free(reassembly);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1072,8 +1082,10 @@ static void process_get(struct connection *conn)
|
|||||||
debugf("not modified since %s\n", if_mod_since);
|
debugf("not modified since %s\n", if_mod_since);
|
||||||
default_reply(conn, 304, "Not Modified", "");
|
default_reply(conn, 304, "Not Modified", "");
|
||||||
conn->header_only = 1;
|
conn->header_only = 1;
|
||||||
|
free(if_mod_since);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
free(if_mod_since);
|
||||||
|
|
||||||
if (conn->range_begin_given || conn->range_end_given)
|
if (conn->range_begin_given || conn->range_end_given)
|
||||||
{
|
{
|
||||||
@ -1342,7 +1354,11 @@ static void poll_send_reply(struct connection *conn)
|
|||||||
free(conn->reply);
|
free(conn->reply);
|
||||||
conn->reply = NULL;
|
conn->reply = NULL;
|
||||||
}
|
}
|
||||||
if (conn->reply_file != NULL) fclose(conn->reply_file);
|
if (conn->reply_file != NULL)
|
||||||
|
{
|
||||||
|
fclose(conn->reply_file);
|
||||||
|
conn->reply_file = NULL;
|
||||||
|
}
|
||||||
conn->state = DONE;
|
conn->state = DONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1356,8 +1372,8 @@ static void log_connection(const struct connection *conn)
|
|||||||
{
|
{
|
||||||
struct in_addr inaddr;
|
struct in_addr inaddr;
|
||||||
|
|
||||||
assert(conn->http_code != 0);
|
|
||||||
if (logfile == NULL) return;
|
if (logfile == NULL) return;
|
||||||
|
if (conn->http_code == 0) return; /* invalid - died in request */
|
||||||
|
|
||||||
/* Separated by tabs:
|
/* Separated by tabs:
|
||||||
* time client_ip method uri http_code bytes_sent "referer" "user-agent"
|
* time client_ip method uri http_code bytes_sent "referer" "user-agent"
|
||||||
@ -1385,21 +1401,27 @@ static void httpd_poll(void)
|
|||||||
fd_set recv_set, send_set;
|
fd_set recv_set, send_set;
|
||||||
int max_fd, select_ret;
|
int max_fd, select_ret;
|
||||||
struct connection *conn;
|
struct connection *conn;
|
||||||
struct timeval timeout = { IDLETIME, 0 };
|
|
||||||
int bother_with_timeout = 0;
|
int bother_with_timeout = 0;
|
||||||
|
struct timeval timeout;
|
||||||
|
|
||||||
|
timeout.tv_sec = IDLETIME;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
FD_ZERO(&recv_set);
|
FD_ZERO(&recv_set);
|
||||||
FD_ZERO(&send_set);
|
FD_ZERO(&send_set);
|
||||||
max_fd = 0;
|
max_fd = 0;
|
||||||
|
|
||||||
/* set recv/send fd_sets */
|
/* set recv/send fd_sets */
|
||||||
#define MAX_FD_SET(sock, fdset) FD_SET(sock,fdset), \
|
#define MAX_FD_SET(sock, fdset) { FD_SET(sock,fdset); \
|
||||||
max_fd = (max_fd<sock) ? sock : max_fd
|
max_fd = (max_fd<sock) ? sock : max_fd; }
|
||||||
|
|
||||||
MAX_FD_SET(sockin, &recv_set);
|
MAX_FD_SET(sockin, &recv_set);
|
||||||
|
|
||||||
LIST_FOREACH(conn, &connlist, entries)
|
conn = LIST_FIRST(&connlist);
|
||||||
|
while (conn != NULL)
|
||||||
{
|
{
|
||||||
|
struct connection *next = LIST_NEXT(conn, entries);
|
||||||
|
|
||||||
poll_check_timeout(conn);
|
poll_check_timeout(conn);
|
||||||
switch (conn->state)
|
switch (conn->state)
|
||||||
{
|
{
|
||||||
@ -1424,6 +1446,8 @@ static void httpd_poll(void)
|
|||||||
|
|
||||||
default: errx(1, "invalid state");
|
default: errx(1, "invalid state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn = next;
|
||||||
}
|
}
|
||||||
#undef MAX_FD_SET
|
#undef MAX_FD_SET
|
||||||
|
|
||||||
@ -1465,9 +1489,7 @@ static void httpd_poll(void)
|
|||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* SIG{INT,QUIT} handler - clean up quickly and exit by re-sending the signal
|
* Close all sockets and FILEs and exit.
|
||||||
*
|
|
||||||
* http://www.cons.org/cracauer/sigint.html
|
|
||||||
*/
|
*/
|
||||||
static void exit_quickly(int sig)
|
static void exit_quickly(int sig)
|
||||||
{
|
{
|
||||||
@ -1477,17 +1499,22 @@ static void exit_quickly(int sig)
|
|||||||
LIST_FOREACH(conn, &connlist, entries)
|
LIST_FOREACH(conn, &connlist, entries)
|
||||||
{
|
{
|
||||||
LIST_REMOVE(conn, entries);
|
LIST_REMOVE(conn, entries);
|
||||||
|
log_connection(conn);
|
||||||
free_connection(conn);
|
free_connection(conn);
|
||||||
free(conn);
|
|
||||||
}
|
}
|
||||||
close(sockin);
|
close(sockin);
|
||||||
|
if (logfile != NULL) fclose(logfile);
|
||||||
printf("done!\n");
|
printf("done!\n");
|
||||||
|
|
||||||
|
/* According to: http://www.cons.org/cracauer/sigint.html
|
||||||
|
* SIGINT and SIGQUIT should be sent to the default handler to ensure the
|
||||||
|
* correct exit codes are used:
|
||||||
|
|
||||||
/* Send back to the default handler - this ensures the correct exit
|
|
||||||
* value will be used.
|
|
||||||
*/
|
|
||||||
if (signal(sig, SIG_DFL) == SIG_ERR) err(1, "signal(SIG_DFL)");
|
if (signal(sig, SIG_DFL) == SIG_ERR) err(1, "signal(SIG_DFL)");
|
||||||
if (raise(sig) == -1) err(1, "raise()");
|
if (raise(sig) == -1) err(1, "raise()");
|
||||||
|
|
||||||
|
*/
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user