X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuhttpd.git;a=blobdiff_plain;f=file.c;h=a4d9b1d4b2402e7dbec8dec893db224ef99b2f83;hp=480c40b2f14fc2290cda5169fe81bdf2112dacc9;hb=99957f6c6ff429f17d6d6002fef4d4ef7de8844a;hpb=618493e378e2239f0d30902e47adfa134e649fdc diff --git a/file.c b/file.c index 480c40b..a4d9b1d 100644 --- a/file.c +++ b/file.c @@ -26,13 +26,15 @@ #include #include #include -#include +#include #include #include "uhttpd.h" #include "mimetypes.h" +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + static LIST_HEAD(index_files); static LIST_HEAD(dispatch_handlers); static LIST_HEAD(pending_requests); @@ -125,7 +127,7 @@ next: /* Returns NULL on error. ** NB: improperly encoded URL should give client 400 [Bad Syntax]; returning ** NULL here causes 404 [Not Found], but that's not too unreasonable. */ -static struct path_info * +struct path_info * uh_path_lookup(struct client *cl, const char *url) { static char path_phys[PATH_MAX]; @@ -233,7 +235,8 @@ uh_path_lookup(struct client *cl, const char *url) url with trailing slash appended */ if (!slash) { uh_http_header(cl, 302, "Found"); - ustream_printf(cl->us, "Content-Length: 0\r\n"); + if (!uh_use_chunked(cl)) + ustream_printf(cl->us, "Content-Length: 0\r\n"); ustream_printf(cl->us, "Location: %s%s%s\r\n\r\n", &path_phys[docroot_len], p.query ? "?" : "", @@ -562,11 +565,12 @@ static void uh_file_free(struct client *cl) static void uh_file_data(struct client *cl, struct path_info *pi, int fd) { /* test preconditions */ - if (!uh_file_if_modified_since(cl, &pi->stat) || - !uh_file_if_match(cl, &pi->stat) || - !uh_file_if_range(cl, &pi->stat) || - !uh_file_if_unmodified_since(cl, &pi->stat) || - !uh_file_if_none_match(cl, &pi->stat)) { + if (!cl->dispatch.no_cache && + (!uh_file_if_modified_since(cl, &pi->stat) || + !uh_file_if_match(cl, &pi->stat) || + !uh_file_if_range(cl, &pi->stat) || + !uh_file_if_unmodified_since(cl, &pi->stat) || + !uh_file_if_none_match(cl, &pi->stat))) { ustream_printf(cl->us, "\r\n"); uh_request_done(cl); close(fd); @@ -614,7 +618,7 @@ static void uh_file_request(struct client *cl, const char *url, if (fd < 0) goto error; - req->respond_chunked = false; + req->disable_chunked = true; cl->dispatch.file.hdr = tb; uh_file_data(cl, pi, fd); cl->dispatch.file.hdr = NULL; @@ -696,8 +700,11 @@ static void uh_complete_request(struct client *cl) dr = list_first_entry(&pending_requests, struct deferred_request, list); list_del(&dr->list); + cl = dr->cl; dr->called = true; - uh_invoke_script(dr->cl, dr->d, dr->path ? &dr->pi : NULL); + cl->dispatch.data_blocked = false; + uh_invoke_script(cl, dr->d, dr->path ? &dr->pi : NULL); + client_poll_post_data(cl); } } @@ -727,14 +734,13 @@ static int field_len(const char *ptr) _field(phys) \ _field(name) \ _field(info) \ - _field(query) \ - _field(auth) + _field(query) static void uh_defer_script(struct client *cl, struct dispatch_handler *d, struct path_info *pi) { struct deferred_request *dr; - char *_root, *_phys, *_name, *_info, *_query, *_auth; + char *_root, *_phys, *_name, *_info, *_query; cl->dispatch.req_free = uh_free_pending_request; @@ -756,6 +762,7 @@ uh_defer_script(struct client *cl, struct dispatch_handler *d, struct path_info } cl->dispatch.req_data = dr; + cl->dispatch.data_blocked = true; dr->cl = cl; dr->d = d; list_add(&dr->list, &pending_requests); @@ -787,6 +794,7 @@ static bool __handle_file_request(struct client *cl, char *url) struct dispatch_handler *d; struct blob_attr *tb[__HDR_MAX]; struct path_info *pi; + char *user, *pass; pi = uh_path_lookup(cl, url); if (!pi) @@ -796,11 +804,15 @@ static bool __handle_file_request(struct client *cl, char *url) return true; blobmsg_parse(hdr_policy, __HDR_MAX, tb, blob_data(cl->hdr.head), blob_len(cl->hdr.head)); - if (tb[HDR_AUTHORIZATION]) - pi->auth = blobmsg_data(tb[HDR_AUTHORIZATION]); + if (tb[HDR_AUTHORIZATION]) { + if (!uh_auth_check(cl, pi->name, blobmsg_data(tb[HDR_AUTHORIZATION]), &user, &pass)) + return true; - if (!uh_auth_check(cl, pi)) - return true; + if (user && pass) { + blobmsg_add_string(&cl->hdr, "http-auth-user", user); + blobmsg_add_string(&cl->hdr, "http-auth-pass", pass); + } + } d = dispatch_find(url, pi); if (d) @@ -811,6 +823,44 @@ static bool __handle_file_request(struct client *cl, char *url) return true; } +static char *uh_handle_alias(char *old_url) +{ + struct alias *alias; + static char *new_url; + static int url_len; + + if (!list_empty(&conf.cgi_alias)) list_for_each_entry(alias, &conf.cgi_alias, list) { + int old_len; + int new_len; + int path_len = 0; + + if (!uh_path_match(alias->alias, old_url)) + continue; + + if (alias->path) + path_len = strlen(alias->path); + + old_len = strlen(old_url) + 1; + new_len = old_len + MAX(conf.cgi_prefix_len, path_len); + + if (new_len > url_len) { + new_url = realloc(new_url, new_len); + url_len = new_len; + } + + *new_url = '\0'; + + if (alias->path) + strcpy(new_url, alias->path); + else if (conf.cgi_prefix) + strcpy(new_url, conf.cgi_prefix); + strcat(new_url, old_url); + + return new_url; + } + return old_url; +} + void uh_handle_request(struct client *cl) { struct http_request *req = &cl->request; @@ -818,6 +868,13 @@ void uh_handle_request(struct client *cl) char *url = blobmsg_data(blob_data(cl->hdr.head)); char *error_handler; + blob_buf_init(&cl->hdr_response, 0); + url = uh_handle_alias(url); + + uh_handler_run(cl, &url, false); + if (!url) + return; + req->redirect_status = 200; d = dispatch_find(url, NULL); if (d) @@ -826,6 +883,15 @@ void uh_handle_request(struct client *cl) if (__handle_file_request(cl, url)) return; + if (uh_handler_run(cl, &url, true)) { + if (!url) + return; + + uh_handler_run(cl, &url, false); + if (__handle_file_request(cl, url)) + return; + } + req->redirect_status = 404; if (conf.error_handler) { error_handler = alloca(strlen(conf.error_handler) + 1);