diff options
author | Leah Neukirchen <leah@vuxu.org> | 2020-05-23 19:24:07 +0200 |
---|---|---|
committer | Leah Neukirchen <leah@vuxu.org> | 2020-05-23 19:24:07 +0200 |
commit | 245a12a610c235478a1370196b0a5f6e89828480 (patch) | |
tree | 94a1a6315d538cd26c4055bceb86324a8da021e8 | |
parent | 894ada34f43c1a12c3ad1c5f8c4d2c47356d912a (diff) | |
download | hittpd-245a12a610c235478a1370196b0a5f6e89828480.tar.gz hittpd-245a12a610c235478a1370196b0a5f6e89828480.tar.xz hittpd-245a12a610c235478a1370196b0a5f6e89828480.zip |
nicer index list, inspired by nginx
-rw-r--r-- | hittpd.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/hittpd.c b/hittpd.c index a9ead14..1f943de 100644 --- a/hittpd.c +++ b/hittpd.c @@ -609,16 +609,20 @@ on_message_complete(http_parser *p) { goto file; } - close(stream_fd); - data->stream_fd = -1; - if (path[strlen(path)-1] != '/') { + close(stream_fd); + data->stream_fd = -1; + send_dir_redirect(p); return 0; } - if (!show_index) + if (!show_index) { + close(stream_fd); + data->stream_fd = -1; + return send_error(p, 403, "Forbidden"); + } char *buf; size_t len; @@ -633,32 +637,53 @@ on_message_complete(http_parser *p) { fprintf(stream, "</title>" "<h1>Index of "); print_htmlencoded(stream, path); - fprintf(stream, "</h1>\n<ul>\n"); + fprintf(stream, "</h1>\n<hr>\n<pre>\n"); struct dirent **namelist; int n = scandir(name, &namelist, 0, alphasort); for (int i = 0; i < n; i++) { - if (namelist[i]->d_name[0] == '.' && - namelist[i]->d_name[1] == 0) + char *file = namelist[i]->d_name; + if (file[0] == '.' && file[1] == 0) continue; - fprintf(stream, "<li><a href=\""); - print_urlencoded(stream, namelist[i]->d_name); + struct stat ist; + if (fstatat(stream_fd, file, &ist, AT_SYMLINK_NOFOLLOW) < 0) + continue; + + fprintf(stream, "<a href=\""); + print_urlencoded(stream, file); fprintf(stream, "%s\">", - namelist[i]->d_type == DT_DIR ? "/" : ""); - print_htmlencoded(stream, namelist[i]->d_name); - fprintf(stream, "%s</a></li>\n", - namelist[i]->d_type == DT_DIR ? "/" : ""); + S_ISDIR(ist.st_mode) ? "/" : ""); + print_htmlencoded(stream, file); + fprintf(stream, "%s</a>", + S_ISDIR(ist.st_mode) ? "/" : ""); + + int len = strlen(file) + !!S_ISDIR(ist.st_mode); + fprintf(stream, "%-*.*s ", 48 - len, 48 - len, ""); + + char timestamp[64]; + strftime(timestamp, sizeof timestamp, + "%Y-%m-%d %H:%M", localtime(&ist.st_mtime)); + + if (S_ISDIR(ist.st_mode)) + fprintf(stream, " %s %12s\n", timestamp, "-"); + else + fprintf(stream, " %s %12jd\n", timestamp, + (intmax_t)ist.st_size); + } while (n--) free(namelist[n]); free(namelist); - fprintf(stream, "</ul>\n"); + fprintf(stream, "</pre>\n<hr>\n"); fclose(stream); + close(stream_fd); + data->stream_fd = -1; + data->buf = buf; data->first = 0; data->last = len; |