From ea30f7fb2122d37dbd010eccd6bb172a2475c197 Mon Sep 17 00:00:00 2001 From: Adrian Perez de Castro Date: Fri, 25 Oct 2013 13:00:10 +0300 Subject: [PATCH] Preserve URL sorting arguments on directory links If a sorting criteria different than the default is used, carry the URL arguments to the links pointing to other directories, so the sorting is "remembered" when navigating across different directories. --- ngx_http_fancyindex_module.c | 121 +++++++++++++++++++++++------------ template.h | 5 +- template.html | 3 +- 3 files changed, 85 insertions(+), 44 deletions(-) diff --git a/ngx_http_fancyindex_module.c b/ngx_http_fancyindex_module.c index 0b69029..d6ede4b 100644 --- a/ngx_http_fancyindex_module.c +++ b/ngx_http_fancyindex_module.c @@ -375,7 +375,7 @@ make_content_buf( ngx_http_fancyindex_entry_t *entry; int (*sort_cmp_func) (const void*, const void*); - ngx_int_t sort_descending = 0; + const char *sort_url_args = ""; off_t length; size_t len, root, copy, allocated; @@ -559,6 +559,7 @@ make_content_buf( len = r->uri.len + ngx_sizeof_ssz(t05_body2) + ngx_sizeof_ssz(t06_list1) + + ngx_sizeof_ssz(t_parentdir_entry) + ngx_sizeof_ssz(t07_list2) ; @@ -569,12 +570,13 @@ make_content_buf( * is stripped out: * * - * fname + * fname * sizedate * */ len += ngx_sizeof_ssz("") + entry[i].name.len + entry[i].utf_len + NGX_HTTP_FANCYINDEX_NAME_LEN + ngx_sizeof_ssz(">") @@ -590,48 +592,62 @@ make_content_buf( if ((b = ngx_create_temp_buf(r->pool, len)) == NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; + /* + * Determine the sorting criteria. URL arguments look like: + * + * C=x[&O=y] + * + * Where x={M,S,N} and y={A,D} + */ + if ((r->args.len == 3 || (r->args.len == 7 && r->args.data[3] == '&')) && + r->args.data[0] == 'C' && r->args.data[1] == '=') + { + /* Determine whether the direction of the sorting */ + ngx_int_t sort_descending = r->args.len == 7 + && r->args.data[4] == 'O' + && r->args.data[5] == '=' + && r->args.data[6] == 'D'; + + /* Pick the sorting criteria */ + switch (r->args.data[2]) { + case 'M': /* Sort by mtime */ + if (sort_descending) { + sort_cmp_func = ngx_http_fancyindex_cmp_entries_mtime_desc; + sort_url_args = "?C=M&O=D"; + } + else { + sort_cmp_func = ngx_http_fancyindex_cmp_entries_mtime_asc; + sort_url_args = "?C=M&O=A"; + } + break; + case 'S': /* Sort by size */ + if (sort_descending) { + sort_cmp_func = ngx_http_fancyindex_cmp_entries_size_desc; + sort_url_args = "?C=S&O=D"; + } + else { + sort_cmp_func = ngx_http_fancyindex_cmp_entries_size_asc; + sort_url_args = "?C=S&O=A"; + } + break; + case 'N': /* Sort by name */ + default: + if (sort_descending) { + sort_cmp_func = ngx_http_fancyindex_cmp_entries_name_desc; + sort_url_args = "?C=N&O=D"; + } + else { + sort_cmp_func = ngx_http_fancyindex_cmp_entries_name_asc; + } + break; + } + } + else { + sort_cmp_func = ngx_http_fancyindex_cmp_entries_name_asc; + } + /* Sort entries, if needed */ if (entries.nelts > 1) { - /* - * Determine the sorting criteria. URL arguments look like: - * - * C=x[&O=y] - * - * Where x={M,S,N} and y={A,D} - */ - if ((r->args.len == 3 || (r->args.len == 7 && r->args.data[3] == '&')) && - r->args.data[0] == 'C' && r->args.data[1] == '=') - { - /* Determine whether the direction of the sorting */ - sort_descending = r->args.len == 7 - && r->args.data[4] == 'O' - && r->args.data[5] == '=' - && r->args.data[6] == 'D'; - - /* Pick the sorting criteria */ - switch (r->args.data[2]) { - case 'M': /* Sort by mtime */ - sort_cmp_func = sort_descending - ? ngx_http_fancyindex_cmp_entries_mtime_desc - : ngx_http_fancyindex_cmp_entries_mtime_asc; - break; - case 'S': /* Sort by size */ - sort_cmp_func = sort_descending - ? ngx_http_fancyindex_cmp_entries_size_desc - : ngx_http_fancyindex_cmp_entries_size_asc; - break; - case 'N': /* Sort by name */ - default: - sort_cmp_func = sort_descending - ? ngx_http_fancyindex_cmp_entries_name_desc - : ngx_http_fancyindex_cmp_entries_name_asc; - break; - } - } - else { - sort_cmp_func = ngx_http_fancyindex_cmp_entries_name_asc; - } - ngx_qsort(entry, (size_t) entries.nelts, sizeof(ngx_http_fancyindex_entry_t), sort_cmp_func); @@ -643,6 +659,22 @@ make_content_buf( tp = ngx_timeofday(); + /* "Parent dir" entry, always first */ + b->last = ngx_cpymem_ssz(b->last, + "" + "last = ngx_cpymem(b->last, + sort_url_args, + ngx_sizeof_ssz("?C=N&O=A")); + } + b->last = ngx_cpymem_ssz(b->last, + "\">Parent directory/" + "-" + "-" + ""); + + /* Entries for directories and files */ for (i = 0; i < entries.nelts; i++) { static const char _evenodd[] = { 'e', 'o' }; b->last = ngx_cpymem_ssz(b->last, "last++ = '/'; + if (*sort_url_args) { + b->last = ngx_cpymem(b->last, + sort_url_args, + ngx_sizeof_ssz("?C=x&O=y")); + } } *b->last++ = '"'; diff --git a/template.h b/template.h index 04962c7..66bb8c7 100644 --- a/template.h +++ b/template.h @@ -72,8 +72,10 @@ static const u_char t06_list1[] = "" "" "\n" "" +; +static const u_char t_parentdir_entry[] = "" "" -"Parent directory/" +"Parent directory/" "-" "-" "" @@ -93,6 +95,7 @@ static const u_char t08_foot1[] = "" + nfi_sizeof_ssz(t04_body1) \ + nfi_sizeof_ssz(t05_body2) \ + nfi_sizeof_ssz(t06_list1) \ + + nfi_sizeof_ssz(t_parentdir_entry) \ + nfi_sizeof_ssz(t07_list2) \ + nfi_sizeof_ssz(t08_foot1) \ ) diff --git a/template.html b/template.html index 1abe65c..5c18ab6 100644 --- a/template.html +++ b/template.html @@ -70,8 +70,9 @@ + - Parent directory/ + Parent directory/ - -