diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2018-01-13 12:45:55 +0100 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2018-01-13 12:45:55 +0100 |
commit | d2765b90ce67a26db4ff980842f0a0f3dc37d546 (patch) | |
tree | d2f8f20a06a5bfe27fc2e76bdef7324bad07c6f0 /src | |
parent | 0a7b600cc7903de58177499f699c25e0ae34369f (diff) | |
download | fileserv-d2765b90ce67a26db4ff980842f0a0f3dc37d546.tar.gz fileserv-d2765b90ce67a26db4ff980842f0a0f3dc37d546.tar.bz2 |
Bugfixes
* mimetypes/err.c (print_locus_range): Fix output length.
* mimetypes/grammar.y (rule_line): Initialize locus range.
* mimetypes/prloc.c (locus_range_format): Fix memory overrun;
terminate output with null byte.
* src/fileserv.c: New option -i (index page).
Diffstat (limited to 'src')
-rw-r--r-- | src/fileserv.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/src/fileserv.c b/src/fileserv.c index b1e9aaf..4490d73 100644 --- a/src/fileserv.c +++ b/src/fileserv.c @@ -42,6 +42,8 @@ int verbose; /* reserved for future use */ char *address = "0.0.0.0"; char *forwarded_header = "X-Forwarded-For"; +char *index_file; + #ifndef DEFAULT_SERVICE # define DEFAULT_SERVICE "8080" #endif @@ -186,6 +188,7 @@ struct urimap { size_t uri_len; char *dir; size_t dir_len; + int dir_index; struct urimap *next; }; @@ -203,7 +206,7 @@ urimap_find(char const *host, char const *url) if (map->uri_len > len) continue; if (memcmp(url, map->uri, map->uri_len) == 0 - && url[map->uri_len] == '/') + && (url[map->uri_len] == '/' || url[map->uri_len] == 0)) return map; } return NULL; @@ -278,28 +281,35 @@ cfname(char const *fname) return realpath(fname, NULL); } -char * -get_file_name(char const *host, char const *url) +int +get_file_name(char const *host, char const *url, char **fname) { struct urimap const *map; char *file_name; + char const *basename; size_t len; char *cf; map = urimap_find(host, url); if (!map) - return NULL; - - len = strlen(url) - map->uri_len + map->dir_len; + return MHD_HTTP_NOT_FOUND; + basename = url + map->uri_len; + if (basename[0] == 0 || (basename[0] == '/' && basename[1] == 0)) { + if (index_file) + basename = index_file; + else + return MHD_HTTP_FORBIDDEN; + } + len = map->dir_len + strlen(basename); file_name = xmalloc(len + 1); if (map->dir_len) memcpy(file_name, map->dir, map->dir_len); - strcpy(file_name + map->dir_len, url + map->uri_len); - + strcpy(file_name + map->dir_len, basename); + cf = cfname(file_name); if (!cf) { free(cf); - return NULL; + return MHD_HTTP_NOT_FOUND; } else if (strcmp(cf, file_name) == 0) { free(cf); } else if (urimap_find_dir(host, cf)) { @@ -308,9 +318,10 @@ get_file_name(char const *host, char const *url) } else { free(file_name); free(cf); - return NULL; + return MHD_HTTP_NOT_FOUND; } - return file_name; + *fname = file_name; + return MHD_HTTP_OK; } /* Returns 1 if ADDR is a valid string representation of IPv4 address */ @@ -653,18 +664,19 @@ http_log(struct MHD_Connection *connection, } static int -not_found(struct MHD_Connection *connection, - char const *method, char const *url) +http_error(struct MHD_Connection *connection, + char const *method, char const *url, + int status, char const *errtext) { int ret; struct MHD_Response *response; - static char errtext[] = "Not found"; - - http_log(connection, method, url, MHD_HTTP_NOT_FOUND, NULL); + if (!errtext) + errtext = ""; + http_log(connection, method, url, status, NULL); response = MHD_create_response_from_buffer (strlen(errtext), (void *) errtext, MHD_RESPMEM_PERSISTENT); - ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response); + ret = MHD_queue_response(connection, status, response); MHD_destroy_response(response); return ret; } @@ -687,6 +699,7 @@ fileserv_handler(void *cls, int ret; int fd; char const *type; + int status; if (strcmp(method, MHD_HTTP_METHOD_GET) && strcmp(method, MHD_HTTP_METHOD_HEAD)) @@ -698,14 +711,14 @@ fileserv_handler(void *cls, } *con_cls = NULL; - file_name = get_file_name(host, url); - if (!file_name) - return not_found(conn, method, url); + status = get_file_name(host, url, &file_name); + if (status != MHD_HTTP_OK) + return http_error(conn, method, url, status, NULL); fd = open(file_name, O_RDONLY); if (fd == -1) { free(file_name); - return not_found(conn, method, url); + return http_error(conn, method, url, MHD_HTTP_NOT_FOUND, NULL); } type = get_file_type(file_name); @@ -713,7 +726,7 @@ fileserv_handler(void *cls, if (fstat(fd, &st) || !S_ISREG(st.st_mode)) { close(fd); - return not_found(conn, method, url); + return http_error(conn, method, url, MHD_HTTP_NOT_FOUND, NULL); } response = MHD_create_response_from_fd64(st.st_size, fd); @@ -723,9 +736,9 @@ fileserv_handler(void *cls, } if (type) - MHD_add_response_header (response, - MHD_HTTP_HEADER_CONTENT_TYPE, - type); + MHD_add_response_header(response, + MHD_HTTP_HEADER_CONTENT_TYPE, + type); ret = MHD_queue_response(conn, MHD_HTTP_OK, response); MHD_destroy_response(response); @@ -768,7 +781,7 @@ main(int argc, char **argv) mimetypes_error_printer = fileserv_error_printer; - while ((c = getopt(argc, argv, "a:F:fg:hm:p:t:x:u:v")) != EOF) { + while ((c = getopt(argc, argv, "a:F:fg:i:hm:p:t:x:u:v")) != EOF) { switch (c) { case 'a': address = optarg; @@ -782,6 +795,11 @@ main(int argc, char **argv) case 'g': group = optarg; break; + case 'i': + index_file = xmalloc (strlen (optarg) + 2); + index_file[0] = '/'; + strcpy (index_file + 1, optarg); + break; case 'h': usage(); exit(0); |