mirror of
https://github.com/emikulic/darkhttpd.git
synced 2023-08-10 21:13:08 +03:00
When logging, escape strings.
While I'm here, rename urlencode[_filename]() and improve it.
This commit is contained in:
parent
77e050b4f4
commit
36f22757f3
102
darkhttpd.c
102
darkhttpd.c
@ -1077,9 +1077,34 @@ static void accept_connection(void) {
|
||||
poll_recv_request(conn);
|
||||
}
|
||||
|
||||
/* Should this character be logencoded?
|
||||
*/
|
||||
static int needs_logencoding(const unsigned char c) {
|
||||
return ((c <= 0x1F) || (c >= 0x7F) || (c == '"'));
|
||||
}
|
||||
|
||||
/* Encode string for logging.
|
||||
*/
|
||||
static void logencode(const char *src, char *dest) {
|
||||
static const char hex[] = "0123456789ABCDEF";
|
||||
int i, j;
|
||||
|
||||
for (i = j = 0; src[i] != '\0'; i++) {
|
||||
if (needs_logencoding((unsigned char)src[i])) {
|
||||
dest[j++] = '%';
|
||||
dest[j++] = hex[(src[i] >> 4) & 0xF];
|
||||
dest[j++] = hex[ src[i] & 0xF];
|
||||
}
|
||||
else
|
||||
dest[j++] = src[i];
|
||||
}
|
||||
dest[j] = '\0';
|
||||
}
|
||||
|
||||
/* Add a connection's details to the logfile. */
|
||||
static void log_connection(const struct connection *conn) {
|
||||
struct in_addr inaddr;
|
||||
char *safe_method, *safe_url, *safe_referer, *safe_user_agent;
|
||||
|
||||
if (logfile == NULL)
|
||||
return;
|
||||
@ -1088,20 +1113,45 @@ static void log_connection(const struct connection *conn) {
|
||||
if (conn->method == NULL)
|
||||
return; /* invalid - didn't parse - maybe too long */
|
||||
|
||||
/* Separated by tabs:
|
||||
* time client_ip method url http_code bytes_sent "referer" "user-agent"
|
||||
*/
|
||||
|
||||
inaddr.s_addr = conn->client;
|
||||
|
||||
fprintf(logfile, "%lu\t%s\t%s\t%s\t%d\t%llu\t\"%s\"\t\"%s\"\n",
|
||||
(unsigned long int)now, inet_ntoa(inaddr),
|
||||
conn->method, conn->url,
|
||||
conn->http_code, llu(conn->total_sent),
|
||||
(conn->referer == NULL)?"":conn->referer,
|
||||
(conn->user_agent == NULL)?"":conn->user_agent
|
||||
#define make_safe(x) \
|
||||
if (conn->x) { \
|
||||
safe_##x = xmalloc(strlen(conn->x)*3 + 1); \
|
||||
logencode(conn->x, safe_##x); \
|
||||
} else { \
|
||||
safe_##x = NULL; \
|
||||
}
|
||||
|
||||
make_safe(method);
|
||||
make_safe(url);
|
||||
make_safe(referer);
|
||||
make_safe(user_agent);
|
||||
|
||||
#define use_safe(x) safe_##x ? safe_##x : ""
|
||||
|
||||
fprintf(logfile, "%lu %s \"%s %s\" %d %llu \"%s\" \"%s\"\n",
|
||||
(unsigned long int)now,
|
||||
inet_ntoa(inaddr),
|
||||
use_safe(method),
|
||||
use_safe(url),
|
||||
conn->http_code,
|
||||
llu(conn->total_sent),
|
||||
use_safe(referer),
|
||||
use_safe(user_agent)
|
||||
);
|
||||
fflush(logfile);
|
||||
|
||||
#define free_safe(x) if (safe_##x) free(safe_##x);
|
||||
|
||||
free_safe(method);
|
||||
free_safe(url);
|
||||
free_safe(referer);
|
||||
free_safe(user_agent);
|
||||
|
||||
#undef make_safe
|
||||
#undef use_safe
|
||||
#undef free_safe
|
||||
}
|
||||
|
||||
/* Log a connection, then cleanly deallocate its internals. */
|
||||
@ -1535,41 +1585,41 @@ static void cleanup_sorted_dirlist(struct dlent **list, const ssize_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Should this character be urlencoded (according to RFC1738).
|
||||
/* Should this character be urlencoded? (according to RFC1738)
|
||||
* Contributed by nf.
|
||||
*/
|
||||
static int needs_urlencoding(unsigned char c) {
|
||||
static int needs_urlencoding(const unsigned char c) {
|
||||
unsigned int i;
|
||||
static const char bad[] = "<>\"%{}|^~[]`\\;:/?@#=&";
|
||||
|
||||
/* Non-US-ASCII characters */
|
||||
if ((c <= 0x1F) || (c >= 0x7F))
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < sizeof(bad) - 1; i++)
|
||||
if (c == bad[i])
|
||||
return 1;
|
||||
|
||||
/* Non-US-ASCII characters */
|
||||
if ((c <= 0x1F) || (c >= 0x80) || (c == 0x7F))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Encode filename to be an RFC1738-compliant URL part.
|
||||
/* Encode string to be an RFC1738-compliant URL part.
|
||||
* Contributed by nf.
|
||||
*/
|
||||
static void urlencode_filename(char *name, char *safe_url) {
|
||||
static void urlencode(const char *src, char *dest) {
|
||||
static const char hex[] = "0123456789ABCDEF";
|
||||
int i, j;
|
||||
|
||||
for (i = j = 0; name[i] != '\0'; i++) {
|
||||
if (needs_urlencoding((unsigned char)name[i])) {
|
||||
safe_url[j++] = '%';
|
||||
safe_url[j++] = hex[(name[i] >> 4) & 0xF];
|
||||
safe_url[j++] = hex[ name[i] & 0xF];
|
||||
for (i = j = 0; src[i] != '\0'; i++) {
|
||||
if (needs_urlencoding((unsigned char)src[i])) {
|
||||
dest[j++] = '%';
|
||||
dest[j++] = hex[(src[i] >> 4) & 0xF];
|
||||
dest[j++] = hex[ src[i] & 0xF];
|
||||
}
|
||||
else
|
||||
safe_url[j++] = name[i];
|
||||
dest[j++] = src[i];
|
||||
}
|
||||
safe_url[j] = '\0';
|
||||
dest[j] = '\0';
|
||||
}
|
||||
|
||||
static void generate_dir_listing(struct connection *conn, const char *path) {
|
||||
@ -1608,7 +1658,7 @@ static void generate_dir_listing(struct connection *conn, const char *path) {
|
||||
*/
|
||||
char safe_url[MAXNAMLEN*3 + 1];
|
||||
|
||||
urlencode_filename(list[i]->name, safe_url);
|
||||
urlencode(list[i]->name, safe_url);
|
||||
|
||||
append(listing, "<a href=\"");
|
||||
append(listing, safe_url);
|
||||
|
Loading…
Reference in New Issue
Block a user