summaryrefslogtreecommitdiff
path: root/download.c
diff options
context:
space:
mode:
Diffstat (limited to 'download.c')
-rw-r--r--download.c136
1 files changed, 91 insertions, 45 deletions
diff --git a/download.c b/download.c
index af490e1..f4a1881 100644
--- a/download.c
+++ b/download.c
@@ -76,94 +76,140 @@ build_download_url(struct kreq * r, struct file * file)
}
static char *
-strsplit(char * str, char c) {
- char *right, *result;
- size_t right_len;
+strsplit(char *str, char c)
+{
+ char *right, *result;
+ size_t right_len;
right = strrchr(str, c);
- if(!right || right == str)
+ if (!right || right == str)
return NULL;
- // move right part to new buffer
+ /* move right part to new buffer */
right_len = strlen(right);
result = malloc(sizeof(char) * right_len);
- if(result == NULL)
+ if (result == NULL)
return NULL;
- if(strlcpy(result, right + 1, right_len) >= right_len) {
+ if (strlcpy(result, right + 1, right_len) >= right_len) {
free(result);
return NULL;
}
-
- // remove right part from src buffer
+ /* remove right part from src buffer */
*right = '\0';
return result;
}
-void
+struct http_ret
download(struct kreq * r)
{
char *file_name;
void *buffer;
- struct file* f;
- int fd;
+ struct file *f;
+ int fd;
char file_path[PATH_MAX], request_path[PATH_MAX];
size_t path_size;
+ struct http_ret ret;
+
+ /* initialize empty file and return struct to success */
+ f = NULL;
+ ret = (struct http_ret) {
+ KHTTP_200, ""
+ };
/* check that the requested URL can be safely processed */
- if (strlen(r->path) == 0 || !check_request_path(r->path, r->suffix))
- http_exit(r, KHTTP_400, "download: invalid request path");
-
- /* build requested file path */
- if(strlen(r->suffix) > 0) {
- /* request with suffix */
- if(snprintf(request_path, sizeof(request_path), "%s.%s", r->path, r->suffix)
- >= (int) sizeof(request_path))
- http_exit(r, KHTTP_414, NULL);
+ if (strlen(r->path) == 0 || !check_request_path(r->path, r->suffix)) {
+ ret = (struct http_ret) {
+ KHTTP_400,
+ "download: invalid request path"
+ };
+ goto end;
}
- else {
- if(snprintf(request_path, sizeof(request_path), "%s", r->path) >= (int) sizeof(request_path))
- http_exit(r, KHTTP_414, NULL);
+ /* build requested file path, with suffix or without */
+ if (strlen(r->suffix) > 0) {
+ if (snprintf(request_path, sizeof(request_path), "%s.%s", r->path, r->suffix)
+ >= (int) sizeof(request_path)) {
+ ret = (struct http_ret) {
+ KHTTP_414,
+ "download: request too long"
+ };
+ goto end;
+ }
+ } else {
+ if (snprintf(request_path, sizeof(request_path), "%s", r->path)
+ >= (int) sizeof(request_path)) {
+ ret = (struct http_ret) {
+ KHTTP_414,
+ "download: request too long"
+ };
+ goto end;
+ }
}
path_size = url_build(file_path, PATH_MAX, DATA_DIR, request_path,
NULL);
- if (path_size == 0)
- http_exit(r, KHTTP_404, "download: unable to build file path");
- if (path_size >= PATH_MAX)
- http_exit(r, KHTTP_414, NULL);
-
+ if (path_size == 0) {
+ ret = (struct http_ret) {
+ KHTTP_404,
+ "download: unable to build file path"
+ };
+ goto end;
+ }
+ if (path_size >= PATH_MAX) {
+ ret = (struct http_ret) {
+ KHTTP_414,
+ "download: request too long"
+ };
+ goto end;
+ }
/* build file metadata */
file_name = strsplit(request_path, '/');
- if(file_name == NULL)
- f = file_new("/", 1, request_path, strlen(request_path)); /* ROOT file */
+ if (file_name == NULL)
+ f = file_new("/", 1, request_path, strlen(request_path)); /* ROOT file */
else {
f = file_new(request_path, strlen(request_path), file_name,
- strlen(file_name));
- free(file_name); /* copied in file_new */
+ strlen(file_name));
+ free(file_name);/* copied in file_new */
+ }
+ if (f == NULL) {
+ ret = (struct http_ret) {
+ KHTTP_404,
+ "download: file metadata failure"
+ };
+ goto end;
}
- if(f == NULL)
- http_exit(r, KHTTP_404, "download: file metadata failure");
-
/* memory map the file */
fd = open(file_path, O_RDONLY);
- if(fd < 0)
- http_exit(r, KHTTP_404, "download: unable to open file");
+ if (fd < 0) {
+ ret = (struct http_ret) {
+ KHTTP_404,
+ "download: unable to open file"
+ };
+ goto end;
+ }
/* mmap does not work with empty file: st_size = 0 */
- if(f->size > 0) {
+ if (f->size > 0) {
buffer = mmap(NULL, f->size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (buffer == MAP_FAILED)
- http_exit(r, KHTTP_500, "download: mmap failed");
+ if (buffer == MAP_FAILED) {
+ ret = (struct http_ret) {
+ KHTTP_500,
+ "download: mmap failed"
+ };
+ goto end;
+ }
}
-
/* write the file */
http_open_file(r, KHTTP_200, f);
- if(f->size > 0)
+ if (f->size > 0)
K_OK(khttp_write(r, (const char *) buffer, f->size), r);
/* cleanup */
- if(f->size > 0)
+end:
+ if (f != NULL && f->size > 0)
munmap(buffer, f->size);
- free(f);
+ if (f != NULL)
+ free(f);
+
+ return ret;
}