Mercurial > hg > nginx
annotate src/http/modules/ngx_http_browser_module.c @ 6244:055d1f63960a
Fixed segfault with incorrect location nesting.
A configuration with a named location inside a zero-length prefix
or regex location used to trigger a segmentation fault, as
ngx_http_core_location() failed to properly detect if a nested location
was created. Example configuration to reproduce the problem:
location "" {
location @foo {}
}
Fix is to not rely on a parent location name length, but rather check
command type we are currently parsing.
Identical fix is also applied to ngx_http_rewrite_if(), which used to
incorrectly assume the "if" directive is on server{} level in such
locations.
Reported by Markus Linnala.
Found with afl-fuzz.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 11 Sep 2015 17:04:04 +0300 |
parents | f84a98a03d0d |
children | 1b82e86dd3e7 |
rev | line source |
---|---|
700 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
700 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 /* | |
14 * The module can check browser versions conforming to the following formats: | |
15 * X, X.X, X.X.X, and X.X.X.X. The maximum values of each format may be | |
16 * 4000, 4000.99, 4000.99.99, and 4000.99.99.99. | |
17 */ | |
18 | |
19 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
20 #define NGX_HTTP_MODERN_BROWSER 0 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
21 #define NGX_HTTP_ANCIENT_BROWSER 1 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
22 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
23 |
700 | 24 typedef struct { |
25 u_char browser[12]; | |
26 size_t skip; | |
27 size_t add; | |
28 u_char name[12]; | |
29 } ngx_http_modern_browser_mask_t; | |
30 | |
31 | |
32 typedef struct { | |
33 ngx_uint_t version; | |
34 size_t skip; | |
35 size_t add; | |
36 u_char name[12]; | |
37 } ngx_http_modern_browser_t; | |
38 | |
39 | |
40 typedef struct { | |
41 ngx_str_t name; | |
42 ngx_http_get_variable_pt handler; | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
43 uintptr_t data; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
44 } ngx_http_browser_variable_t; |
700 | 45 |
46 | |
47 typedef struct { | |
48 ngx_array_t *modern_browsers; | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
49 ngx_array_t *ancient_browsers; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
50 ngx_http_variable_value_t *modern_browser_value; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
51 ngx_http_variable_value_t *ancient_browser_value; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
52 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
53 unsigned modern_unlisted_browsers:1; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
54 unsigned netscape4:1; |
700 | 55 } ngx_http_browser_conf_t; |
56 | |
57 | |
58 static ngx_int_t ngx_http_msie_variable(ngx_http_request_t *r, | |
59 ngx_http_variable_value_t *v, uintptr_t data); | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
60 static ngx_int_t ngx_http_browser_variable(ngx_http_request_t *r, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
61 ngx_http_variable_value_t *v, uintptr_t data); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
62 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
63 static ngx_uint_t ngx_http_browser(ngx_http_request_t *r, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
64 ngx_http_browser_conf_t *cf); |
754
4ac89c5aa10d
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
718
diff
changeset
|
65 |
700 | 66 static ngx_int_t ngx_http_browser_add_variable(ngx_conf_t *cf); |
67 static void *ngx_http_browser_create_conf(ngx_conf_t *cf); | |
68 static char *ngx_http_browser_merge_conf(ngx_conf_t *cf, void *parent, | |
69 void *child); | |
70 static int ngx_libc_cdecl ngx_http_modern_browser_sort(const void *one, | |
71 const void *two); | |
72 static char *ngx_http_modern_browser(ngx_conf_t *cf, ngx_command_t *cmd, | |
73 void *conf); | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
74 static char *ngx_http_ancient_browser(ngx_conf_t *cf, ngx_command_t *cmd, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
75 void *conf); |
700 | 76 static char *ngx_http_modern_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, |
77 void *conf); | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
78 static char *ngx_http_ancient_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
79 void *conf); |
700 | 80 |
81 | |
82 static ngx_command_t ngx_http_browser_commands[] = { | |
83 | |
84 { ngx_string("modern_browser"), | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
85 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, |
700 | 86 ngx_http_modern_browser, |
87 NGX_HTTP_LOC_CONF_OFFSET, | |
88 0, | |
89 NULL }, | |
90 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
91 { ngx_string("ancient_browser"), |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
92 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
93 ngx_http_ancient_browser, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
94 NGX_HTTP_LOC_CONF_OFFSET, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
95 0, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
96 NULL }, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
97 |
700 | 98 { ngx_string("modern_browser_value"), |
99 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
100 ngx_http_modern_browser_value, | |
101 NGX_HTTP_LOC_CONF_OFFSET, | |
102 0, | |
103 NULL }, | |
104 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
105 { ngx_string("ancient_browser_value"), |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
106 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
107 ngx_http_ancient_browser_value, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
108 NGX_HTTP_LOC_CONF_OFFSET, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
109 0, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
110 NULL }, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
111 |
700 | 112 ngx_null_command |
113 }; | |
114 | |
115 | |
116 static ngx_http_module_t ngx_http_browser_module_ctx = { | |
117 ngx_http_browser_add_variable, /* preconfiguration */ | |
118 NULL, /* postconfiguration */ | |
119 | |
120 NULL, /* create main configuration */ | |
121 NULL, /* init main configuration */ | |
122 | |
123 NULL, /* create server configuration */ | |
124 NULL, /* merge server configuration */ | |
125 | |
126 ngx_http_browser_create_conf, /* create location configuration */ | |
127 ngx_http_browser_merge_conf /* merge location configuration */ | |
128 }; | |
129 | |
130 | |
131 ngx_module_t ngx_http_browser_module = { | |
132 NGX_MODULE_V1, | |
133 &ngx_http_browser_module_ctx, /* module context */ | |
134 ngx_http_browser_commands, /* module directives */ | |
135 NGX_HTTP_MODULE, /* module type */ | |
136 NULL, /* init master */ | |
137 NULL, /* init module */ | |
138 NULL, /* init process */ | |
139 NULL, /* init thread */ | |
140 NULL, /* exit thread */ | |
141 NULL, /* exit process */ | |
142 NULL, /* exit master */ | |
143 NGX_MODULE_V1_PADDING | |
144 }; | |
145 | |
146 | |
147 static ngx_http_modern_browser_mask_t ngx_http_modern_browser_masks[] = { | |
148 | |
149 /* Opera must be the first browser to check */ | |
150 | |
151 /* | |
152 * "Opera/7.50 (X11; FreeBSD i386; U) [en]" | |
153 * "Mozilla/5.0 (X11; FreeBSD i386; U) Opera 7.50 [en]" | |
154 * "Mozilla/4.0 (compatible; MSIE 6.0; X11; FreeBSD i386) Opera 7.50 [en]" | |
155 * "Opera/8.0 (Windows NT 5.1; U; ru)" | |
156 * "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; en) Opera 8.0" | |
157 * "Opera/9.01 (X11; FreeBSD 6 i386; U; en)" | |
158 */ | |
159 | |
160 { "opera", | |
161 0, | |
162 sizeof("Opera ") - 1, | |
163 "Opera"}, | |
164 | |
165 /* "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" */ | |
166 | |
167 { "msie", | |
168 sizeof("Mozilla/4.0 (compatible; ") - 1, | |
169 sizeof("MSIE ") - 1, | |
170 "MSIE "}, | |
171 | |
172 /* | |
173 * "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020610" | |
174 * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.5) Gecko/20031006" | |
175 * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.6) Gecko/20040206 | |
176 * Firefox/0.8" | |
177 * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.8) | |
178 * Gecko/20050511 Firefox/1.0.4" | |
179 * "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.8.0.5) Gecko/20060729 | |
180 * Firefox/1.5.0.5" | |
181 */ | |
182 | |
183 { "gecko", | |
184 sizeof("Mozilla/5.0 (") - 1, | |
185 sizeof("rv:") - 1, | |
186 "rv:"}, | |
187 | |
188 /* | |
189 * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ru-ru) AppleWebKit/125.2 | |
190 * (KHTML, like Gecko) Safari/125.7" | |
191 * "Mozilla/5.0 (SymbianOS/9.1; U; en-us) AppleWebKit/413 | |
192 * (KHTML, like Gecko) Safari/413" | |
193 * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418 | |
194 * (KHTML, like Gecko) Safari/417.9.3" | |
195 * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ru-ru) AppleWebKit/418.8 | |
196 * (KHTML, like Gecko) Safari/419.3" | |
197 */ | |
198 | |
199 { "safari", | |
200 sizeof("Mozilla/5.0 (") - 1, | |
201 sizeof("Safari/") - 1, | |
202 "Safari/"}, | |
203 | |
204 /* | |
205 * "Mozilla/5.0 (compatible; Konqueror/3.1; Linux)" | |
206 * "Mozilla/5.0 (compatible; Konqueror/3.4; Linux) KHTML/3.4.2 (like Gecko)" | |
207 * "Mozilla/5.0 (compatible; Konqueror/3.5; FreeBSD) KHTML/3.5.1 | |
208 * (like Gecko)" | |
209 */ | |
210 | |
211 { "konqueror", | |
212 sizeof("Mozilla/5.0 (compatible; ") - 1, | |
213 sizeof("Konqueror/") - 1, | |
214 "Konqueror/"}, | |
215 | |
216 { "", 0, 0, "" } | |
217 | |
218 }; | |
219 | |
220 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
221 static ngx_http_browser_variable_t ngx_http_browsers[] = { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
222 { ngx_string("msie"), ngx_http_msie_variable, 0 }, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
223 { ngx_string("modern_browser"), ngx_http_browser_variable, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
224 NGX_HTTP_MODERN_BROWSER }, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
225 { ngx_string("ancient_browser"), ngx_http_browser_variable, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
226 NGX_HTTP_ANCIENT_BROWSER }, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
227 { ngx_null_string, NULL, 0 } |
700 | 228 }; |
229 | |
230 | |
231 static ngx_int_t | |
232 ngx_http_browser_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
233 uintptr_t data) | |
234 { | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
235 ngx_uint_t rc; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
236 ngx_http_browser_conf_t *cf; |
700 | 237 |
238 cf = ngx_http_get_module_loc_conf(r, ngx_http_browser_module); | |
239 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
240 rc = ngx_http_browser(r, cf); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
241 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
242 if (data == NGX_HTTP_MODERN_BROWSER && rc == NGX_HTTP_MODERN_BROWSER) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
243 *v = *cf->modern_browser_value; |
700 | 244 return NGX_OK; |
245 } | |
246 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
247 if (data == NGX_HTTP_ANCIENT_BROWSER && rc == NGX_HTTP_ANCIENT_BROWSER) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
248 *v = *cf->ancient_browser_value; |
700 | 249 return NGX_OK; |
250 } | |
251 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
252 *v = ngx_http_variable_null_value; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
253 return NGX_OK; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
254 } |
700 | 255 |
256 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
257 static ngx_uint_t |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
258 ngx_http_browser(ngx_http_request_t *r, ngx_http_browser_conf_t *cf) |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
259 { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
260 size_t len; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
261 u_char *name, *ua, *last, c; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
262 ngx_str_t *ancient; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
263 ngx_uint_t i, version, ver, scale; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
264 ngx_http_modern_browser_t *modern; |
700 | 265 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
266 if (r->headers_in.user_agent == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
267 if (cf->modern_unlisted_browsers) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
268 return NGX_HTTP_MODERN_BROWSER; |
700 | 269 } |
270 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
271 return NGX_HTTP_ANCIENT_BROWSER; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
272 } |
700 | 273 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
274 ua = r->headers_in.user_agent->value.data; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
275 len = r->headers_in.user_agent->value.len; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
276 last = ua + len; |
700 | 277 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
278 if (cf->modern_browsers) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
279 modern = cf->modern_browsers->elts; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
280 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
281 for (i = 0; i < cf->modern_browsers->nelts; i++) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
282 name = ua + modern[i].skip; |
700 | 283 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
284 if (name >= last) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
285 continue; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
286 } |
700 | 287 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
288 name = (u_char *) ngx_strstr(name, modern[i].name); |
700 | 289 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
290 if (name == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
291 continue; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
292 } |
700 | 293 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
294 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
295 "browser: \"%s\"", name); |
700 | 296 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
297 name += modern[i].add; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
298 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
299 if (name >= last) { |
700 | 300 continue; |
301 } | |
302 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
303 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
304 "version: \"%ui\" \"%s\"", modern[i].version, name); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
305 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
306 version = 0; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
307 ver = 0; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
308 scale = 1000000; |
700 | 309 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
310 while (name < last) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
311 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
312 c = *name++; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
313 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
314 if (c >= '0' && c <= '9') { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
315 ver = ver * 10 + (c - '0'); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
316 continue; |
700 | 317 } |
318 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
319 if (c == '.') { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
320 version += ver * scale; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
321 |
2510 | 322 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
323 "version: \"%ui\" \"%ui\"", | |
324 modern[i].version, version); | |
325 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
326 if (version > modern[i].version) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
327 return NGX_HTTP_MODERN_BROWSER; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
328 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
329 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
330 ver = 0; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
331 scale /= 100; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
332 continue; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
333 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
334 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
335 break; |
700 | 336 } |
337 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
338 version += ver * scale; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
339 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
340 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
341 "version: \"%ui\" \"%ui\"", |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
342 modern[i].version, version); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
343 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
344 if (version >= modern[i].version) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
345 return NGX_HTTP_MODERN_BROWSER; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
346 } |
2509
b4661481f198
the $ancient_browser variables did not treat as an ancient browser
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
347 |
b4661481f198
the $ancient_browser variables did not treat as an ancient browser
Igor Sysoev <igor@sysoev.ru>
parents:
1565
diff
changeset
|
348 return NGX_HTTP_ANCIENT_BROWSER; |
700 | 349 } |
350 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
351 if (!cf->modern_unlisted_browsers) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
352 return NGX_HTTP_ANCIENT_BROWSER; |
700 | 353 } |
354 } | |
355 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
356 if (cf->netscape4) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
357 if (len > sizeof("Mozilla/4.72 ") - 1 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
358 && ngx_strncmp(ua, "Mozilla/", sizeof("Mozilla/") - 1) == 0 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
359 && ua[8] > '0' && ua[8] < '5') |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
360 { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
361 return NGX_HTTP_ANCIENT_BROWSER; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
362 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
363 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
364 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
365 if (cf->ancient_browsers) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
366 ancient = cf->ancient_browsers->elts; |
700 | 367 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
368 for (i = 0; i < cf->ancient_browsers->nelts; i++) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
369 if (len >= ancient[i].len |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
370 && ngx_strstr(ua, ancient[i].data) != NULL) |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
371 { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
372 return NGX_HTTP_ANCIENT_BROWSER; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
373 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
374 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
375 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
376 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
377 if (cf->modern_unlisted_browsers) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
378 return NGX_HTTP_MODERN_BROWSER; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
379 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
380 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
381 return NGX_HTTP_ANCIENT_BROWSER; |
700 | 382 } |
383 | |
384 | |
385 static ngx_int_t | |
386 ngx_http_msie_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
387 uintptr_t data) | |
388 { | |
389 if (r->headers_in.msie) { | |
390 *v = ngx_http_variable_true_value; | |
391 return NGX_OK; | |
392 } | |
393 | |
394 *v = ngx_http_variable_null_value; | |
395 return NGX_OK; | |
396 } | |
397 | |
398 | |
399 static ngx_int_t | |
400 ngx_http_browser_add_variable(ngx_conf_t *cf) | |
401 { | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
402 ngx_http_browser_variable_t *var; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
403 ngx_http_variable_t *v; |
700 | 404 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
405 for (var = ngx_http_browsers; var->name.len; var++) { |
700 | 406 |
1565 | 407 v = ngx_http_add_variable(cf, &var->name, NGX_HTTP_VAR_CHANGEABLE); |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
408 if (v == NULL) { |
700 | 409 return NGX_ERROR; |
410 } | |
411 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
412 v->get_handler = var->handler; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
413 v->data = var->data; |
700 | 414 } |
415 | |
416 return NGX_OK; | |
417 } | |
418 | |
419 | |
420 static void * | |
421 ngx_http_browser_create_conf(ngx_conf_t *cf) | |
422 { | |
423 ngx_http_browser_conf_t *conf; | |
424 | |
425 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_browser_conf_t)); | |
426 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2510
diff
changeset
|
427 return NULL; |
700 | 428 } |
429 | |
430 /* | |
431 * set by ngx_pcalloc(): | |
432 * | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
433 * conf->modern_browsers = NULL; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
434 * conf->ancient_browsers = NULL; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
435 * conf->modern_browser_value = NULL; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
436 * conf->ancient_browser_value = NULL; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
437 * |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
438 * conf->modern_unlisted_browsers = 0; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
439 * conf->netscape4 = 0; |
700 | 440 */ |
441 | |
442 return conf; | |
443 } | |
444 | |
445 | |
446 static char * | |
447 ngx_http_browser_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
448 { | |
449 ngx_http_browser_conf_t *prev = parent; | |
450 ngx_http_browser_conf_t *conf = child; | |
451 | |
452 ngx_uint_t i, n; | |
453 ngx_http_modern_browser_t *browsers, *opera; | |
454 | |
455 /* | |
456 * At the merge the skip field is used to store the browser slot, | |
457 * it will be used in sorting and then will overwritten | |
458 * with a real skip value. The zero value means Opera. | |
459 */ | |
460 | |
4581
f84a98a03d0d
Fixed directives inheritance.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
461 if (conf->modern_browsers == NULL && conf->modern_unlisted_browsers == 0) { |
700 | 462 conf->modern_browsers = prev->modern_browsers; |
4581
f84a98a03d0d
Fixed directives inheritance.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
463 conf->modern_unlisted_browsers = prev->modern_unlisted_browsers; |
700 | 464 |
4581
f84a98a03d0d
Fixed directives inheritance.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
465 } else if (conf->modern_browsers != NULL) { |
700 | 466 browsers = conf->modern_browsers->elts; |
467 | |
468 for (i = 0; i < conf->modern_browsers->nelts; i++) { | |
469 if (browsers[i].skip == 0) { | |
470 goto found; | |
471 } | |
472 } | |
473 | |
474 /* | |
475 * Opera may contain MSIE string, so if Opera was not enumerated | |
476 * as modern browsers, then add it and set a unreachable version | |
477 */ | |
478 | |
479 opera = ngx_array_push(conf->modern_browsers); | |
480 if (opera == NULL) { | |
481 return NGX_CONF_ERROR; | |
482 } | |
483 | |
484 opera->skip = 0; | |
485 opera->version = 4001000000U; | |
486 | |
487 browsers = conf->modern_browsers->elts; | |
488 | |
489 found: | |
490 | |
491 ngx_qsort(browsers, (size_t) conf->modern_browsers->nelts, | |
492 sizeof(ngx_http_modern_browser_t), | |
493 ngx_http_modern_browser_sort); | |
494 | |
495 for (i = 0; i < conf->modern_browsers->nelts; i++) { | |
496 n = browsers[i].skip; | |
497 | |
498 browsers[i].skip = ngx_http_modern_browser_masks[n].skip; | |
499 browsers[i].add = ngx_http_modern_browser_masks[n].add; | |
500 (void) ngx_cpystrn(browsers[i].name, | |
501 ngx_http_modern_browser_masks[n].name, 12); | |
502 } | |
503 } | |
504 | |
4581
f84a98a03d0d
Fixed directives inheritance.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
505 if (conf->ancient_browsers == NULL && conf->netscape4 == 0) { |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
506 conf->ancient_browsers = prev->ancient_browsers; |
4581
f84a98a03d0d
Fixed directives inheritance.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
507 conf->netscape4 = prev->netscape4; |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
508 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
509 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
510 if (conf->modern_browser_value == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
511 conf->modern_browser_value = prev->modern_browser_value; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
512 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
513 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
514 if (conf->modern_browser_value == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
515 conf->modern_browser_value = &ngx_http_variable_true_value; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
516 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
517 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
518 if (conf->ancient_browser_value == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
519 conf->ancient_browser_value = prev->ancient_browser_value; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
520 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
521 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
522 if (conf->ancient_browser_value == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
523 conf->ancient_browser_value = &ngx_http_variable_true_value; |
700 | 524 } |
525 | |
526 return NGX_CONF_OK; | |
527 } | |
528 | |
529 | |
530 static int ngx_libc_cdecl | |
531 ngx_http_modern_browser_sort(const void *one, const void *two) | |
532 { | |
533 ngx_http_modern_browser_t *first = (ngx_http_modern_browser_t *) one; | |
534 ngx_http_modern_browser_t *second = (ngx_http_modern_browser_t *) two; | |
535 | |
536 return (first->skip - second->skip); | |
537 } | |
538 | |
539 | |
540 static char * | |
541 ngx_http_modern_browser(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
542 { | |
543 ngx_http_browser_conf_t *bcf = conf; | |
544 | |
545 u_char c; | |
546 ngx_str_t *value; | |
547 ngx_uint_t i, n, version, ver, scale; | |
548 ngx_http_modern_browser_t *browser; | |
549 ngx_http_modern_browser_mask_t *mask; | |
550 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
551 value = cf->args->elts; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
552 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
553 if (cf->args->nelts == 2) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
554 if (ngx_strcmp(value[1].data, "unlisted") == 0) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
555 bcf->modern_unlisted_browsers = 1; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
556 return NGX_CONF_OK; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
557 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
558 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
559 return NGX_CONF_ERROR; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
560 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
561 |
700 | 562 if (bcf->modern_browsers == NULL) { |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
563 bcf->modern_browsers = ngx_array_create(cf->pool, 5, |
700 | 564 sizeof(ngx_http_modern_browser_t)); |
565 if (bcf->modern_browsers == NULL) { | |
566 return NGX_CONF_ERROR; | |
567 } | |
568 } | |
569 | |
570 browser = ngx_array_push(bcf->modern_browsers); | |
571 if (browser == NULL) { | |
572 return NGX_CONF_ERROR; | |
573 } | |
574 | |
575 mask = ngx_http_modern_browser_masks; | |
576 | |
577 for (n = 0; mask[n].browser[0] != '\0'; n++) { | |
578 if (ngx_strcasecmp(mask[n].browser, value[1].data) == 0) { | |
579 goto found; | |
580 } | |
581 } | |
582 | |
583 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
584 "unknown browser name \"%V\"", &value[1]); | |
585 | |
586 return NGX_CONF_ERROR; | |
587 | |
588 found: | |
589 | |
590 /* | |
591 * at this stage the skip field is used to store the browser slot, | |
592 * it will be used in sorting in merge stage and then will overwritten | |
593 * with a real value | |
594 */ | |
595 | |
596 browser->skip = n; | |
597 | |
598 version = 0; | |
599 ver = 0; | |
600 scale = 1000000; | |
601 | |
602 for (i = 0; i < value[2].len; i++) { | |
603 | |
604 c = value[2].data[i]; | |
605 | |
606 if (c >= '0' && c <= '9') { | |
607 ver = ver * 10 + (c - '0'); | |
608 continue; | |
609 } | |
610 | |
611 if (c == '.') { | |
612 version += ver * scale; | |
613 ver = 0; | |
614 scale /= 100; | |
615 continue; | |
616 } | |
617 | |
618 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
619 "invalid browser version \"%V\"", &value[2]); | |
620 | |
621 return NGX_CONF_ERROR; | |
622 } | |
623 | |
624 version += ver * scale; | |
625 | |
626 browser->version = version; | |
627 | |
628 return NGX_CONF_OK; | |
629 } | |
630 | |
631 | |
632 static char * | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
633 ngx_http_ancient_browser(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
634 { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
635 ngx_http_browser_conf_t *bcf = conf; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
636 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
637 ngx_str_t *value, *browser; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
638 ngx_uint_t i; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
639 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
640 value = cf->args->elts; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
641 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
642 for (i = 1; i < cf->args->nelts; i++) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
643 if (ngx_strcmp(value[i].data, "netscape4") == 0) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
644 bcf->netscape4 = 1; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
645 continue; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
646 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
647 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
648 if (bcf->ancient_browsers == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
649 bcf->ancient_browsers = ngx_array_create(cf->pool, 4, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
650 sizeof(ngx_str_t)); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
651 if (bcf->ancient_browsers == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
652 return NGX_CONF_ERROR; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
653 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
654 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
655 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
656 browser = ngx_array_push(bcf->ancient_browsers); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
657 if (browser == NULL) { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
658 return NGX_CONF_ERROR; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
659 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
660 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
661 *browser = value[i]; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
662 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
663 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
664 return NGX_CONF_OK; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
665 } |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
666 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
667 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
668 static char * |
700 | 669 ngx_http_modern_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
670 { | |
671 ngx_http_browser_conf_t *bcf = conf; | |
672 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
673 ngx_str_t *value; |
700 | 674 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
675 bcf->modern_browser_value = ngx_palloc(cf->pool, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
676 sizeof(ngx_http_variable_value_t)); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
677 if (bcf->modern_browser_value == NULL) { |
700 | 678 return NGX_CONF_ERROR; |
679 } | |
680 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
681 value = cf->args->elts; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
682 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
683 bcf->modern_browser_value->len = value[1].len; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
684 bcf->modern_browser_value->valid = 1; |
1565 | 685 bcf->modern_browser_value->no_cacheable = 0; |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
686 bcf->modern_browser_value->not_found = 0; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
687 bcf->modern_browser_value->data = value[1].data; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
688 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
689 return NGX_CONF_OK; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
690 } |
700 | 691 |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
692 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
693 static char * |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
694 ngx_http_ancient_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
695 { |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
696 ngx_http_browser_conf_t *bcf = conf; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
697 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
698 ngx_str_t *value; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
699 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
700 bcf->ancient_browser_value = ngx_palloc(cf->pool, |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
701 sizeof(ngx_http_variable_value_t)); |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
702 if (bcf->ancient_browser_value == NULL) { |
700 | 703 return NGX_CONF_ERROR; |
704 } | |
705 | |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
706 value = cf->args->elts; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
707 |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
708 bcf->ancient_browser_value->len = value[1].len; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
709 bcf->ancient_browser_value->valid = 1; |
1565 | 710 bcf->ancient_browser_value->no_cacheable = 0; |
718
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
711 bcf->ancient_browser_value->not_found = 0; |
d488926182ea
ancient browsers support in ngx_http_browser_module
Igor Sysoev <igor@sysoev.ru>
parents:
713
diff
changeset
|
712 bcf->ancient_browser_value->data = value[1].data; |
700 | 713 |
714 return NGX_CONF_OK; | |
715 } |