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