Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add case-insensitive name sorting support #152

Merged
merged 2 commits into from
Jan 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ fancyindex_default_sort
:Description:
Defines sorting criterion by default.

fancyindex_case_sensitive
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Syntax: *fancyindex_case_sensitive* [*on* | *off*]
:Default: fancyindex_case_sensitive on
:Context: http, server, location
:Description:
If enabled (default setting), sorting by name will be case-sensitive.
If disabled, case will be ignored when sorting by name.

fancyindex_directories_first
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:Syntax: *fancyindex_directories_first* [*on* | *off*]
Expand Down
58 changes: 50 additions & 8 deletions ngx_http_fancyindex_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ typedef struct {
typedef struct {
ngx_flag_t enable; /**< Module is enabled. */
ngx_uint_t default_sort; /**< Default sort criterion. */
ngx_flag_t case_sensitive; /**< Case-sensitive name sorting */
ngx_flag_t dirs_first; /**< Group directories together first when sorting */
ngx_flag_t localtime; /**< File mtime dates are sent in local time. */
ngx_flag_t exact_size; /**< Sizes are sent always in bytes. */
Expand Down Expand Up @@ -336,13 +337,17 @@ typedef struct {


static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_name_desc(const void *one, const void *two);
ngx_http_fancyindex_cmp_entries_name_cs_desc(const void *one, const void *two);
static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_name_ci_desc(const void *one, const void *two);
static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_size_desc(const void *one, const void *two);
static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_mtime_desc(const void *one, const void *two);
static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_name_asc(const void *one, const void *two);
ngx_http_fancyindex_cmp_entries_name_cs_asc(const void *one, const void *two);
static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_name_ci_asc(const void *one, const void *two);
static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_size_asc(const void *one, const void *two);
static int ngx_libc_cdecl
Expand Down Expand Up @@ -391,6 +396,13 @@ static ngx_command_t ngx_http_fancyindex_commands[] = {
offsetof(ngx_http_fancyindex_loc_conf_t, default_sort),
&ngx_http_fancyindex_sort_criteria },

{ ngx_string("fancyindex_case_sensitive"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_fancyindex_loc_conf_t, case_sensitive),
NULL },

{ ngx_string("fancyindex_directories_first"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
Expand Down Expand Up @@ -950,12 +962,16 @@ make_content_buf(
case 'N': /* Sort by name */
default:
if (sort_descending) {
sort_cmp_func = ngx_http_fancyindex_cmp_entries_name_desc;
sort_cmp_func = alcf->case_sensitive
? ngx_http_fancyindex_cmp_entries_name_cs_desc
: ngx_http_fancyindex_cmp_entries_name_ci_desc;
if (alcf->default_sort != NGX_HTTP_FANCYINDEX_SORT_CRITERION_NAME_DESC)
sort_url_args = "?C=N&amp;O=D";
}
else {
sort_cmp_func = ngx_http_fancyindex_cmp_entries_name_asc;
sort_cmp_func = alcf->case_sensitive
? ngx_http_fancyindex_cmp_entries_name_cs_asc
: ngx_http_fancyindex_cmp_entries_name_ci_asc;
if (alcf->default_sort != NGX_HTTP_FANCYINDEX_SORT_CRITERION_NAME)
sort_url_args = "?C=N&amp;O=A";
}
Expand All @@ -977,11 +993,15 @@ make_content_buf(
sort_cmp_func = ngx_http_fancyindex_cmp_entries_size_asc;
break;
case NGX_HTTP_FANCYINDEX_SORT_CRITERION_NAME_DESC:
sort_cmp_func = ngx_http_fancyindex_cmp_entries_name_desc;
sort_cmp_func = alcf->case_sensitive
? ngx_http_fancyindex_cmp_entries_name_cs_desc
: ngx_http_fancyindex_cmp_entries_name_ci_desc;
break;
case NGX_HTTP_FANCYINDEX_SORT_CRITERION_NAME:
default:
sort_cmp_func = ngx_http_fancyindex_cmp_entries_name_asc;
sort_cmp_func = alcf->case_sensitive
? ngx_http_fancyindex_cmp_entries_name_cs_asc
: ngx_http_fancyindex_cmp_entries_name_ci_asc;
break;
}
}
Expand Down Expand Up @@ -1337,7 +1357,7 @@ ngx_http_fancyindex_handler(ngx_http_request_t *r)


static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_name_desc(const void *one, const void *two)
ngx_http_fancyindex_cmp_entries_name_cs_desc(const void *one, const void *two)
{
ngx_http_fancyindex_entry_t *first = (ngx_http_fancyindex_entry_t *) one;
ngx_http_fancyindex_entry_t *second = (ngx_http_fancyindex_entry_t *) two;
Expand All @@ -1346,6 +1366,16 @@ ngx_http_fancyindex_cmp_entries_name_desc(const void *one, const void *two)
}


static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_name_ci_desc(const void *one, const void *two)
{
ngx_http_fancyindex_entry_t *first = (ngx_http_fancyindex_entry_t *) one;
ngx_http_fancyindex_entry_t *second = (ngx_http_fancyindex_entry_t *) two;

return (int) ngx_strcasecmp(second->name.data, first->name.data);
}


static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_size_desc(const void *one, const void *two)
{
Expand All @@ -1367,7 +1397,7 @@ ngx_http_fancyindex_cmp_entries_mtime_desc(const void *one, const void *two)


static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_name_asc(const void *one, const void *two)
ngx_http_fancyindex_cmp_entries_name_cs_asc(const void *one, const void *two)
{
ngx_http_fancyindex_entry_t *first = (ngx_http_fancyindex_entry_t *) one;
ngx_http_fancyindex_entry_t *second = (ngx_http_fancyindex_entry_t *) two;
Expand All @@ -1376,6 +1406,16 @@ ngx_http_fancyindex_cmp_entries_name_asc(const void *one, const void *two)
}


static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_name_ci_asc(const void *one, const void *two)
{
ngx_http_fancyindex_entry_t *first = (ngx_http_fancyindex_entry_t *) one;
ngx_http_fancyindex_entry_t *second = (ngx_http_fancyindex_entry_t *) two;

return (int) ngx_strcasecmp(first->name.data, second->name.data);
}


static int ngx_libc_cdecl
ngx_http_fancyindex_cmp_entries_size_asc(const void *one, const void *two)
{
Expand Down Expand Up @@ -1431,6 +1471,7 @@ ngx_http_fancyindex_create_loc_conf(ngx_conf_t *cf)
*/
conf->enable = NGX_CONF_UNSET;
conf->default_sort = NGX_CONF_UNSET_UINT;
conf->case_sensitive = NGX_CONF_UNSET;
conf->dirs_first = NGX_CONF_UNSET;
conf->localtime = NGX_CONF_UNSET;
conf->exact_size = NGX_CONF_UNSET;
Expand All @@ -1454,6 +1495,7 @@ ngx_http_fancyindex_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)

ngx_conf_merge_value(conf->enable, prev->enable, 0);
ngx_conf_merge_uint_value(conf->default_sort, prev->default_sort, NGX_HTTP_FANCYINDEX_SORT_CRITERION_NAME);
ngx_conf_merge_value(conf->case_sensitive, prev->case_sensitive, 1);
ngx_conf_merge_value(conf->dirs_first, prev->dirs_first, 1);
ngx_conf_merge_value(conf->localtime, prev->localtime, 0);
ngx_conf_merge_value(conf->exact_size, prev->exact_size, 1);
Expand Down
8 changes: 8 additions & 0 deletions t/bug78-case-insensitive.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#! /bin/bash
cat <<---
This test checks that case-insensitive sorting works.
--

nginx_start 'fancyindex_case_sensitive off;'
content=$(fetch /case-sensitivity/)
grep -A 999 '\<alice\>' <<< "${content}" | grep '\<Bob\>' # Bob is after alice
8 changes: 8 additions & 0 deletions t/bug78-case-sensitive.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#! /bin/bash
cat <<---
This test checks that case-sensitive sorting works.
--

nginx_start 'fancyindex_case_sensitive on;'
content=$(fetch /case-sensitivity/)
grep -A 999 '\<Bob\>' <<< "${content}" | grep '\<alice\>' # alice is after Bob
Empty file added t/case-sensitivity/Bob
Empty file.
Empty file added t/case-sensitivity/alice
Empty file.