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.
pull/8/head
Adrian Perez de Castro 2013-10-25 13:00:10 +03:00
parent 9b3cdb5583
commit ea30f7fb21
3 changed files with 85 additions and 44 deletions

View File

@ -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:
*
* <tr class="X">
* <td><a href="U">fname</a></td>
* <td><a href="U[?sort]">fname</a></td>
* <td>size</td><td>date</td>
* </tr>
*/
len += ngx_sizeof_ssz("<tr class=\"X\"><td><a href=\"")
+ entry[i].name.len + entry[i].escape /* Escaped URL */
+ ngx_sizeof_ssz("?C=x&amp;O=y") /* URL sorting arguments */
+ ngx_sizeof_ssz("\">")
+ entry[i].name.len + entry[i].utf_len
+ NGX_HTTP_FANCYINDEX_NAME_LEN + ngx_sizeof_ssz("&gt;")
@ -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&amp;O=D";
}
else {
sort_cmp_func = ngx_http_fancyindex_cmp_entries_mtime_asc;
sort_url_args = "?C=M&amp;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&amp;O=D";
}
else {
sort_cmp_func = ngx_http_fancyindex_cmp_entries_size_asc;
sort_url_args = "?C=S&amp;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&amp;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,
"<tr class=\"o\">"
"<td><a href=\"../");
if (*sort_url_args) {
b->last = ngx_cpymem(b->last,
sort_url_args,
ngx_sizeof_ssz("?C=N&amp;O=A"));
}
b->last = ngx_cpymem_ssz(b->last,
"\">Parent directory/</a></td>"
"<td>-</td>"
"<td>-</td>"
"</tr>");
/* 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, "<tr class=\"");
@ -666,6 +698,11 @@ make_content_buf(
if (entry[i].dir) {
*b->last++ = '/';
if (*sort_url_args) {
b->last = ngx_cpymem(b->last,
sort_url_args,
ngx_sizeof_ssz("?C=x&amp;O=y"));
}
}
*b->last++ = '"';

View File

@ -72,8 +72,10 @@ static const u_char t06_list1[] = ""
"</thead>"
"\n"
"<tbody>"
;
static const u_char t_parentdir_entry[] = ""
"<tr class=\"o\">"
"<td><a href=\"../\">Parent directory/</a></td>"
"<td><a href=\"../?C=N&amp;O=A\">Parent directory/</a></td>"
"<td>-</td>"
"<td>-</td>"
"</tr>"
@ -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) \
)

View File

@ -70,8 +70,9 @@
</thead>
<tbody>
<!-- var t_parentdir_entry -->
<tr class="o">
<td><a href="../">Parent directory/</a></td>
<td><a href="../?C=N&amp;O=A">Parent directory/</a></td>
<td>-</td>
<td>-</td>
</tr>