From 8d9326a0e944add41819aff592221099ed185827 Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Sun, 27 Jul 2014 00:35:06 +0200 Subject: cleanup index --- server_file.c | 154 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 76 insertions(+), 78 deletions(-) diff --git a/server_file.c b/server_file.c index e31dc82..0aca57d 100644 --- a/server_file.c +++ b/server_file.c @@ -49,6 +49,7 @@ int server_file_access(struct http_descriptor *, char *, size_t, struct stat *); +int server_file_index(struct httpd *, struct client *); void server_file_error(struct bufferevent *, short, void *); int @@ -65,8 +66,6 @@ server_file_access(struct http_descriptor *desc, char *path, size_t len, } else if (stat(path, st) == -1) { goto fail; } else if (S_ISDIR(st->st_mode)) { - /* XXX Should we support directory listing? */ - if (!len) { /* Recursion - the index "file" is a directory? */ errno = EINVAL; @@ -122,7 +121,81 @@ server_file_access(struct http_descriptor *desc, char *path, size_t len, /* NOTREACHED */ } -static int +int +server_file(struct httpd *env, struct client *clt) +{ + char path[MAXPATHLEN]; + struct http_descriptor *desc = clt->clt_desc; + struct server_config *srv_conf = clt->clt_srv_conf; + struct media_type *media; + const char *errstr = NULL; + int fd = -1, ret; + struct stat st; + + /* Request path is already canonicalized */ + if ((size_t)snprintf(path, sizeof(path), "%s%s", + srv_conf->docroot, desc->http_path) >= sizeof(path)) { + /* Do not echo the uncanonicalized path */ + server_abort_http(clt, 500, desc->http_path); + return (-1); + } + + /* Returns HTTP status code on error */ + if ((ret = server_file_access(desc, path, sizeof(path), &st)) != 0) { + server_abort_http(clt, ret, desc->http_path); + return (-1); + } + + if (S_ISDIR(st.st_mode)) { + /* list directory index */ + return (server_file_index(env, clt)); + } + + /* Now open the file, should be readable or we have another problem */ + if ((fd = open(path, O_RDONLY)) == -1) + goto fail; + + /* File descriptor is opened, decrement inflight counter */ + server_inflight_dec(clt, __func__); + + media = media_find(env->sc_mediatypes, path); + ret = server_response_http(clt, 200, media, st.st_size); + switch (ret) { + case -1: + goto fail; + case 0: + /* Connection is already finished */ + close(fd); + return (0); + default: + break; + } + + clt->clt_fd = fd; + if (clt->clt_file != NULL) + bufferevent_free(clt->clt_file); + + clt->clt_file = bufferevent_new(clt->clt_fd, server_read, + server_write, server_file_error, clt); + if (clt->clt_file == NULL) { + errstr = "failed to allocate file buffer event"; + goto fail; + } + + bufferevent_settimeout(clt->clt_file, + srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec); + bufferevent_enable(clt->clt_file, EV_READ); + bufferevent_disable(clt->clt_bev, EV_READ); + + return (0); + fail: + if (errstr == NULL) + errstr = strerror(errno); + server_abort_http(clt, 500, errstr); + return (-1); +} + +int server_file_index(struct httpd *env, struct client *clt) { char path[MAXPATHLEN]; @@ -183,7 +256,6 @@ server_file_index(struct httpd *env, struct client *clt) free(dp); continue; } - width = 50 - strlen(dp->d_name); evbuffer_add_printf(evb, "%s%*s%llu bytes\n", @@ -234,80 +306,6 @@ server_file_index(struct httpd *env, struct client *clt) return (-1); } -int -server_file(struct httpd *env, struct client *clt) -{ - char path[MAXPATHLEN]; - struct http_descriptor *desc = clt->clt_desc; - struct server_config *srv_conf = clt->clt_srv_conf; - struct media_type *media; - const char *errstr = NULL; - int fd = -1, ret; - struct stat st; - - /* Request path is already canonicalized */ - if ((size_t)snprintf(path, sizeof(path), "%s%s", - srv_conf->docroot, desc->http_path) >= sizeof(path)) { - /* Do not echo the uncanonicalized path */ - server_abort_http(clt, 500, desc->http_path); - return (-1); - } - - /* Returns HTTP status code on error */ - if ((ret = server_file_access(desc, path, sizeof(path), &st)) != 0) { - server_abort_http(clt, ret, desc->http_path); - return (-1); - } - - if (S_ISDIR(st.st_mode)) { - /* list directory index */ - return (server_file_index(env, clt)); - } - - /* Now open the file, should be readable or we have another problem */ - if ((fd = open(path, O_RDONLY)) == -1) - goto fail; - - /* File descriptor is opened, decrement inflight counter */ - server_inflight_dec(clt, __func__); - - media = media_find(env->sc_mediatypes, path); - ret = server_response_http(clt, 200, media, st.st_size); - switch (ret) { - case -1: - goto fail; - case 0: - /* Connection is already finished */ - close(fd); - return (0); - default: - break; - } - - clt->clt_fd = fd; - if (clt->clt_file != NULL) - bufferevent_free(clt->clt_file); - - clt->clt_file = bufferevent_new(clt->clt_fd, server_read, - server_write, server_file_error, clt); - if (clt->clt_file == NULL) { - errstr = "failed to allocate file buffer event"; - goto fail; - } - - bufferevent_settimeout(clt->clt_file, - srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec); - bufferevent_enable(clt->clt_file, EV_READ); - bufferevent_disable(clt->clt_bev, EV_READ); - - return (0); - fail: - if (errstr == NULL) - errstr = strerror(errno); - server_abort_http(clt, 500, errstr); - return (-1); -} - void server_file_error(struct bufferevent *bev, short error, void *arg) { -- cgit v1.2.3-54-g00ecf