@@ -16,6 +16,11 @@ static ngx_command_t ngx_http_accept_language_commands[] = {
1616 ngx_null_command
1717};
1818
19+ typedef struct ngx_http_accept_language_s {
20+ ngx_hash_t hash ;
21+ ngx_str_t default_language ;
22+ } ngx_http_accept_language_t ;
23+
1924// No need for any configuration callback
2025static ngx_http_module_t ngx_http_accept_language_module_ctx = {
2126 NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL
@@ -39,9 +44,11 @@ ngx_module_t ngx_http_accept_language_module = {
3944static char * ngx_http_accept_language (ngx_conf_t * cf , ngx_command_t * cmd , void * conf )
4045{
4146 ngx_uint_t i ;
42- ngx_str_t * value , * elt , name ;
47+ ngx_str_t * value , * snew , name ;
4348 ngx_http_variable_t * var ;
44- ngx_array_t * langs_array ;
49+ ngx_hash_init_t hash ;
50+ ngx_http_accept_language_t * al ;
51+ ngx_hash_keys_arrays_t hash_keys ;
4552
4653 value = cf -> args -> elts ;
4754 name = value [1 ];
@@ -63,31 +70,55 @@ static char * ngx_http_accept_language(ngx_conf_t *cf, ngx_command_t *cmd, void
6370 }
6471
6572 var -> get_handler = ngx_http_accept_language_variable ;
66- langs_array = ngx_array_create (cf -> pool , cf -> args -> nelts - 1 , sizeof (ngx_str_t ));
67- if (langs_array == NULL ) {
68- return NGX_CONF_ERROR ;
73+
74+ al = ngx_pcalloc (cf -> pool , sizeof (ngx_http_accept_language_t ));
75+ if (al == NULL ) {
76+ return NGX_CONF_ERROR ;
6977 }
70- var -> data = (uintptr_t ) langs_array ;
78+
79+ hash_keys .pool = cf -> pool ;
80+ hash_keys .temp_pool = cf -> temp_pool ;
81+
82+ ngx_hash_keys_array_init (& hash_keys , NGX_HASH_SMALL );
7183
7284 for (i = 2 ; i < cf -> args -> nelts ; i ++ ) {
73- elt = ngx_array_push (langs_array );
74- if (elt == NULL ) {
75- return NGX_CONF_ERROR ;
85+ ngx_conf_log_error (NGX_LOG_WARN , cf , 0 , "\"%V\" value" , & value [i ]);
86+
87+ if (al -> default_language .len == 0 ){
88+ al -> default_language = value [i ];
7689 }
77-
78- * elt = value [i ];
90+ snew = ngx_palloc (cf -> pool , sizeof (ngx_str_t ));
91+ if (snew == NULL ) {
92+ return NGX_CONF_ERROR ;
93+ }
94+ * snew = value [i ];
95+ ngx_hash_add_key (& hash_keys , snew , snew , 0 );
96+ }
97+
98+ hash .hash = & al -> hash ;
99+ hash .key = ngx_hash_key_lc ;
100+ hash .max_size = 512 ;
101+ hash .bucket_size = ngx_align (64 , ngx_cacheline_size );
102+ hash .name = "accept_key_hash" ;
103+ hash .pool = cf -> pool ;
104+ hash .temp_pool = cf -> temp_pool ;
105+
106+ if (ngx_hash_init (& hash , hash_keys .keys .elts , hash_keys .keys .nelts ) != NGX_OK ) {
107+ return NGX_CONF_ERROR ;
79108 }
109+
110+ var -> data = (uintptr_t )al ;
80111
81112 return NGX_CONF_OK ;
82113}
83114
84115static ngx_int_t ngx_http_accept_language_variable (ngx_http_request_t * r , ngx_http_variable_value_t * v , uintptr_t data )
85116{
86- ngx_uint_t i = 0 ;
87- ngx_uint_t found = 0 ;
88117 u_char * start , * pos , * end ;
89- ngx_array_t * langs_array = (ngx_array_t * ) data ;
90- ngx_str_t * langs = (ngx_str_t * ) langs_array -> elts ;
118+ ngx_http_accept_language_t * al = (ngx_http_accept_language_t * ) data ;
119+ ngx_str_t * l ;
120+ ngx_uint_t key ;
121+
91122
92123 if ( NULL != r -> headers_in .accept_language ) {
93124 start = r -> headers_in .accept_language -> value .data ;
@@ -101,17 +132,13 @@ static ngx_int_t ngx_http_accept_language_variable(ngx_http_request_t *r, ngx_ht
101132
102133 while (pos < end && * pos != ',' && * pos != ';' ) { pos ++ ; }
103134
104- for ( i = 0 ; i < langs_array -> nelts ; i ++ )
105- {
106- if (( ngx_uint_t )( pos - start ) >= langs [ i ]. len && ngx_strncasecmp ( start , langs [ i ]. data , langs [ i ]. len ) == 0 ) {
107- found = 1 ;
108- break ;
109- }
135+ key = ngx_hash_key ( start , end - start );
136+ l = ( ngx_str_t * ) ngx_hash_find ( & al -> hash , key , start , end - start );
137+ if ( l != NULL ) {
138+ v -> data = l -> data ;
139+ v -> len = l -> len ;
140+ goto set ;
110141 }
111- if (found )
112- break ;
113-
114- i = 0 ; // If not found default to the first language from the list
115142
116143 // We discard the quality value
117144 if (* pos == ';' ) {
@@ -125,9 +152,10 @@ static ngx_int_t ngx_http_accept_language_variable(ngx_http_request_t *r, ngx_ht
125152 }
126153 }
127154
128- v -> data = langs [ i ] .data ;
129- v -> len = langs [ i ] .len ;
155+ v -> data = al -> default_language .data ;
156+ v -> len = al -> default_language .len ;
130157
158+ set :
131159 /* Set all required params */
132160 v -> valid = 1 ;
133161 v -> no_cacheable = 0 ;
0 commit comments