Mercurial > hg > nginx
annotate src/http/modules/ngx_http_referer_module.c @ 7060:1adc6b0d5eaa stable-1.12
Range filter: protect from total size overflows.
The overflow can be used to circumvent the restriction on total size of
ranges introduced in c2a91088b0c0 (1.1.2). Additionally, overflow
allows producing ranges with negative start (such ranges can be created
by using a suffix, "bytes=-100"; normally this results in 200 due to
the total size check). These can result in the following errors in logs:
[crit] ... pread() ... failed (22: Invalid argument)
[alert] ... sendfile() failed (22: Invalid argument)
When using cache, it can be also used to reveal cache file header.
It is believed that there are no other negative effects, at least with
standard nginx modules.
In theory, this can also result in memory disclosure and/or segmentation
faults if multiple ranges are allowed, and the response is returned in a
single in-memory buffer. This never happens with standard nginx modules
though, as well as known 3rd party modules.
Fix is to properly protect from possible overflow when incrementing size.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 11 Jul 2017 16:06:23 +0300 |
parents | 2cd019520210 |
children | 7564a919d333 |
rev | line source |
---|---|
577 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
577 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
595 | 13 #define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4) |
14 | |
1388 | 15 |
577 | 16 typedef struct { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
17 ngx_hash_combined_t hash; |
577 | 18 |
1388 | 19 #if (NGX_PCRE) |
20 ngx_array_t *regex; | |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
21 ngx_array_t *server_name_regex; |
1388 | 22 #endif |
23 | |
593 | 24 ngx_flag_t no_referer; |
25 ngx_flag_t blocked_referer; | |
5351
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
26 ngx_flag_t server_names; |
577 | 27 |
593 | 28 ngx_hash_keys_arrays_t *keys; |
3939
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
29 |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
30 ngx_uint_t referer_hash_max_size; |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
31 ngx_uint_t referer_hash_bucket_size; |
577 | 32 } ngx_http_referer_conf_t; |
33 | |
34 | |
35 static void * ngx_http_referer_create_conf(ngx_conf_t *cf); | |
36 static char * ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, | |
37 void *child); | |
38 static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, | |
39 void *conf); | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
40 static ngx_int_t ngx_http_add_referer(ngx_conf_t *cf, |
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
41 ngx_hash_keys_arrays_t *keys, ngx_str_t *value, ngx_str_t *uri); |
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
42 static ngx_int_t ngx_http_add_regex_referer(ngx_conf_t *cf, |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
43 ngx_http_referer_conf_t *rlcf, ngx_str_t *name); |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
44 #if (NGX_PCRE) |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
45 static ngx_int_t ngx_http_add_regex_server_name(ngx_conf_t *cf, |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
46 ngx_http_referer_conf_t *rlcf, ngx_http_regex_t *regex); |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
47 #endif |
593 | 48 static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one, |
49 const void *two); | |
577 | 50 |
51 | |
52 static ngx_command_t ngx_http_referer_commands[] = { | |
53 | |
54 { ngx_string("valid_referers"), | |
55 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
56 ngx_http_valid_referers, | |
57 NGX_HTTP_LOC_CONF_OFFSET, | |
58 0, | |
59 NULL }, | |
60 | |
3939
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
61 { ngx_string("referer_hash_max_size"), |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
62 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
63 ngx_conf_set_num_slot, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
64 NGX_HTTP_LOC_CONF_OFFSET, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
65 offsetof(ngx_http_referer_conf_t, referer_hash_max_size), |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
66 NULL }, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
67 |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
68 { ngx_string("referer_hash_bucket_size"), |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
69 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
70 ngx_conf_set_num_slot, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
71 NGX_HTTP_LOC_CONF_OFFSET, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
72 offsetof(ngx_http_referer_conf_t, referer_hash_bucket_size), |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
73 NULL }, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
74 |
577 | 75 ngx_null_command |
76 }; | |
77 | |
78 | |
79 static ngx_http_module_t ngx_http_referer_module_ctx = { | |
80 NULL, /* preconfiguration */ | |
81 NULL, /* postconfiguration */ | |
82 | |
83 NULL, /* create main configuration */ | |
84 NULL, /* init main configuration */ | |
85 | |
86 NULL, /* create server configuration */ | |
87 NULL, /* merge server configuration */ | |
88 | |
89 ngx_http_referer_create_conf, /* create location configuration */ | |
90 ngx_http_referer_merge_conf /* merge location configuration */ | |
91 }; | |
92 | |
93 | |
94 ngx_module_t ngx_http_referer_module = { | |
95 NGX_MODULE_V1, | |
96 &ngx_http_referer_module_ctx, /* module context */ | |
97 ngx_http_referer_commands, /* module directives */ | |
98 NGX_HTTP_MODULE, /* module type */ | |
99 NULL, /* init master */ | |
100 NULL, /* init module */ | |
101 NULL, /* init process */ | |
102 NULL, /* init thread */ | |
103 NULL, /* exit thread */ | |
104 NULL, /* exit process */ | |
105 NULL, /* exit master */ | |
106 NGX_MODULE_V1_PADDING | |
107 }; | |
108 | |
109 | |
110 static ngx_int_t | |
111 ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
6474 | 112 uintptr_t data) |
577 | 113 { |
1388 | 114 u_char *p, *ref, *last; |
115 size_t len; | |
116 ngx_str_t *uri; | |
117 ngx_uint_t i, key; | |
118 ngx_http_referer_conf_t *rlcf; | |
119 u_char buf[256]; | |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
120 #if (NGX_PCRE) |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
121 ngx_int_t rc; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
122 ngx_str_t referer; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
123 #endif |
577 | 124 |
593 | 125 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module); |
577 | 126 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
127 if (rlcf->hash.hash.buckets == NULL |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
128 && rlcf->hash.wc_head == NULL |
1388 | 129 && rlcf->hash.wc_tail == NULL |
130 #if (NGX_PCRE) | |
131 && rlcf->regex == NULL | |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
132 && rlcf->server_name_regex == NULL |
1388 | 133 #endif |
134 ) | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
135 { |
595 | 136 goto valid; |
577 | 137 } |
138 | |
139 if (r->headers_in.referer == NULL) { | |
593 | 140 if (rlcf->no_referer) { |
595 | 141 goto valid; |
142 } | |
577 | 143 |
595 | 144 goto invalid; |
577 | 145 } |
146 | |
147 len = r->headers_in.referer->value.len; | |
148 ref = r->headers_in.referer->value.data; | |
149 | |
3459 | 150 if (len >= sizeof("http://i.ru") - 1) { |
151 last = ref + len; | |
152 | |
153 if (ngx_strncasecmp(ref, (u_char *) "http://", 7) == 0) { | |
154 ref += 7; | |
5321
9806f7932474
Referer module: fixed regex matching against HTTPS referers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5221
diff
changeset
|
155 len -= 7; |
3459 | 156 goto valid_scheme; |
157 | |
158 } else if (ngx_strncasecmp(ref, (u_char *) "https://", 8) == 0) { | |
159 ref += 8; | |
5321
9806f7932474
Referer module: fixed regex matching against HTTPS referers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5221
diff
changeset
|
160 len -= 8; |
3459 | 161 goto valid_scheme; |
595 | 162 } |
577 | 163 } |
164 | |
3459 | 165 if (rlcf->blocked_referer) { |
166 goto valid; | |
167 } | |
168 | |
169 goto invalid; | |
170 | |
171 valid_scheme: | |
172 | |
595 | 173 i = 0; |
174 key = 0; | |
577 | 175 |
595 | 176 for (p = ref; p < last; p++) { |
593 | 177 if (*p == '/' || *p == ':') { |
178 break; | |
577 | 179 } |
595 | 180 |
181 if (i == 256) { | |
182 goto invalid; | |
183 } | |
5352
ec0be12c8e29
Referer: fixed hostname buffer overflow check.
Valentin Bartenev <vbart@nginx.com>
parents:
5351
diff
changeset
|
184 |
ec0be12c8e29
Referer: fixed hostname buffer overflow check.
Valentin Bartenev <vbart@nginx.com>
parents:
5351
diff
changeset
|
185 buf[i] = ngx_tolower(*p); |
ec0be12c8e29
Referer: fixed hostname buffer overflow check.
Valentin Bartenev <vbart@nginx.com>
parents:
5351
diff
changeset
|
186 key = ngx_hash(key, buf[i++]); |
593 | 187 } |
577 | 188 |
1388 | 189 uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref); |
577 | 190 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
191 if (uri) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
192 goto uri; |
577 | 193 } |
194 | |
1388 | 195 #if (NGX_PCRE) |
196 | |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
197 if (rlcf->server_name_regex) { |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
198 referer.len = p - ref; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
199 referer.data = buf; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
200 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
201 rc = ngx_regex_exec_array(rlcf->server_name_regex, &referer, |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
202 r->connection->log); |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
203 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
204 if (rc == NGX_OK) { |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
205 goto valid; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
206 } |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
207 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
208 if (rc == NGX_ERROR) { |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
209 return rc; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
210 } |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
211 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
212 /* NGX_DECLINED */ |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
213 } |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
214 |
1388 | 215 if (rlcf->regex) { |
5321
9806f7932474
Referer module: fixed regex matching against HTTPS referers.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5221
diff
changeset
|
216 referer.len = len; |
1388 | 217 referer.data = ref; |
218 | |
1785 | 219 rc = ngx_regex_exec_array(rlcf->regex, &referer, r->connection->log); |
1388 | 220 |
1785 | 221 if (rc == NGX_OK) { |
1388 | 222 goto valid; |
223 } | |
1785 | 224 |
225 if (rc == NGX_ERROR) { | |
226 return rc; | |
227 } | |
228 | |
229 /* NGX_DECLINED */ | |
1388 | 230 } |
231 | |
232 #endif | |
233 | |
595 | 234 invalid: |
235 | |
577 | 236 *v = ngx_http_variable_true_value; |
237 | |
238 return NGX_OK; | |
595 | 239 |
240 uri: | |
241 | |
242 for ( /* void */ ; p < last; p++) { | |
243 if (*p == '/') { | |
244 break; | |
245 } | |
246 } | |
247 | |
248 len = last - p; | |
249 | |
250 if (uri == NGX_HTTP_REFERER_NO_URI_PART) { | |
251 goto valid; | |
252 } | |
253 | |
254 if (len < uri->len || ngx_strncmp(uri->data, p, uri->len) != 0) { | |
255 goto invalid; | |
256 } | |
257 | |
258 valid: | |
259 | |
260 *v = ngx_http_variable_null_value; | |
261 | |
262 return NGX_OK; | |
577 | 263 } |
264 | |
265 | |
266 static void * | |
267 ngx_http_referer_create_conf(ngx_conf_t *cf) | |
268 { | |
269 ngx_http_referer_conf_t *conf; | |
270 | |
593 | 271 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_referer_conf_t)); |
577 | 272 if (conf == NULL) { |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
1800
diff
changeset
|
273 return NULL; |
577 | 274 } |
275 | |
5351
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
276 /* |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
277 * set by ngx_pcalloc(): |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
278 * |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
279 * conf->hash = { NULL }; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
280 * conf->server_names = 0; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
281 * conf->keys = NULL; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
282 */ |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
283 |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
284 #if (NGX_PCRE) |
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
285 conf->regex = NGX_CONF_UNSET_PTR; |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
286 conf->server_name_regex = NGX_CONF_UNSET_PTR; |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
287 #endif |
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
288 |
577 | 289 conf->no_referer = NGX_CONF_UNSET; |
290 conf->blocked_referer = NGX_CONF_UNSET; | |
3939
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
291 conf->referer_hash_max_size = NGX_CONF_UNSET_UINT; |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
292 conf->referer_hash_bucket_size = NGX_CONF_UNSET_UINT; |
577 | 293 |
294 return conf; | |
295 } | |
296 | |
297 | |
298 static char * | |
299 ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
300 { | |
301 ngx_http_referer_conf_t *prev = parent; | |
302 ngx_http_referer_conf_t *conf = child; | |
303 | |
5351
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
304 ngx_uint_t n; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
305 ngx_hash_init_t hash; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
306 ngx_http_server_name_t *sn; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
307 ngx_http_core_srv_conf_t *cscf; |
593 | 308 |
309 if (conf->keys == NULL) { | |
310 conf->hash = prev->hash; | |
311 | |
1800 | 312 #if (NGX_PCRE) |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
313 ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL); |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
314 ngx_conf_merge_ptr_value(conf->server_name_regex, |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
315 prev->server_name_regex, NULL); |
1800 | 316 #endif |
577 | 317 ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0); |
318 ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0); | |
3939
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
319 ngx_conf_merge_uint_value(conf->referer_hash_max_size, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
320 prev->referer_hash_max_size, 2048); |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
321 ngx_conf_merge_uint_value(conf->referer_hash_bucket_size, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
322 prev->referer_hash_bucket_size, 64); |
593 | 323 |
324 return NGX_CONF_OK; | |
325 } | |
326 | |
5351
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
327 if (conf->server_names == 1) { |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
328 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module); |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
329 |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
330 sn = cscf->server_names.elts; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
331 for (n = 0; n < cscf->server_names.nelts; n++) { |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
332 |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
333 #if (NGX_PCRE) |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
334 if (sn[n].regex) { |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
335 |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
336 if (ngx_http_add_regex_server_name(cf, conf, sn[n].regex) |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
337 != NGX_OK) |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
338 { |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
339 return NGX_CONF_ERROR; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
340 } |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
341 |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
342 continue; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
343 } |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
344 #endif |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
345 |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
346 if (ngx_http_add_referer(cf, conf->keys, &sn[n].name, NULL) |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
347 != NGX_OK) |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
348 { |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
349 return NGX_CONF_ERROR; |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
350 } |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
351 } |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
352 } |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
353 |
603 | 354 if ((conf->no_referer == 1 || conf->blocked_referer == 1) |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
355 && conf->keys->keys.nelts == 0 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
356 && conf->keys->dns_wc_head.nelts == 0 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
357 && conf->keys->dns_wc_tail.nelts == 0) |
603 | 358 { |
359 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
360 "the \"none\" or \"blocked\" referers are specified " | |
361 "in the \"valid_referers\" directive " | |
362 "without any valid referer"); | |
363 return NGX_CONF_ERROR; | |
364 } | |
365 | |
3939
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
366 ngx_conf_merge_uint_value(conf->referer_hash_max_size, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
367 prev->referer_hash_max_size, 2048); |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
368 ngx_conf_merge_uint_value(conf->referer_hash_bucket_size, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
369 prev->referer_hash_bucket_size, 64); |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
370 conf->referer_hash_bucket_size = ngx_align(conf->referer_hash_bucket_size, |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
371 ngx_cacheline_size); |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
372 |
593 | 373 hash.key = ngx_hash_key_lc; |
3939
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
374 hash.max_size = conf->referer_hash_max_size; |
3cbbe86a7a95
referer_hash_max_size and referer_hash_bucket_size directives
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
375 hash.bucket_size = conf->referer_hash_bucket_size; |
4008
debb2f235aa3
Fix names of the referer hash size directives introduced in r3940.
Igor Sysoev <igor@sysoev.ru>
parents:
3939
diff
changeset
|
376 hash.name = "referer_hash"; |
593 | 377 hash.pool = cf->pool; |
378 | |
379 if (conf->keys->keys.nelts) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
380 hash.hash = &conf->hash.hash; |
593 | 381 hash.temp_pool = NULL; |
382 | |
383 if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts) | |
384 != NGX_OK) | |
385 { | |
386 return NGX_CONF_ERROR; | |
387 } | |
388 } | |
389 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
390 if (conf->keys->dns_wc_head.nelts) { |
593 | 391 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
392 ngx_qsort(conf->keys->dns_wc_head.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
393 (size_t) conf->keys->dns_wc_head.nelts, |
593 | 394 sizeof(ngx_hash_key_t), |
395 ngx_http_cmp_referer_wildcards); | |
396 | |
397 hash.hash = NULL; | |
398 hash.temp_pool = cf->temp_pool; | |
399 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
400 if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_head.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
401 conf->keys->dns_wc_head.nelts) |
593 | 402 != NGX_OK) |
403 { | |
404 return NGX_CONF_ERROR; | |
405 } | |
406 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
407 conf->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
408 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
409 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
410 if (conf->keys->dns_wc_tail.nelts) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
411 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
412 ngx_qsort(conf->keys->dns_wc_tail.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
413 (size_t) conf->keys->dns_wc_tail.nelts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
414 sizeof(ngx_hash_key_t), |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
415 ngx_http_cmp_referer_wildcards); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
416 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
417 hash.hash = NULL; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
418 hash.temp_pool = cf->temp_pool; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
419 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
420 if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_tail.elts, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
421 conf->keys->dns_wc_tail.nelts) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
422 != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
423 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
424 return NGX_CONF_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
425 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
426 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
427 conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash; |
577 | 428 } |
429 | |
1800 | 430 #if (NGX_PCRE) |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
431 ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL); |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
432 ngx_conf_merge_ptr_value(conf->server_name_regex, prev->server_name_regex, |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
433 NULL); |
1800 | 434 #endif |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
435 |
577 | 436 if (conf->no_referer == NGX_CONF_UNSET) { |
437 conf->no_referer = 0; | |
438 } | |
439 | |
440 if (conf->blocked_referer == NGX_CONF_UNSET) { | |
441 conf->blocked_referer = 0; | |
442 } | |
443 | |
611 | 444 conf->keys = NULL; |
445 | |
577 | 446 return NGX_CONF_OK; |
447 } | |
448 | |
449 | |
450 static char * | |
451 ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
452 { | |
593 | 453 ngx_http_referer_conf_t *rlcf = conf; |
577 | 454 |
593 | 455 u_char *p; |
595 | 456 ngx_str_t *value, uri, name; |
5351
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
457 ngx_uint_t i; |
577 | 458 ngx_http_variable_t *var; |
459 | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3459
diff
changeset
|
460 ngx_str_set(&name, "invalid_referer"); |
577 | 461 |
5221
8f74cf107137
Referer module: added $invalid_referer to variables hash.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
462 var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE); |
577 | 463 if (var == NULL) { |
464 return NGX_CONF_ERROR; | |
465 } | |
466 | |
637 | 467 var->get_handler = ngx_http_referer_variable; |
577 | 468 |
593 | 469 if (rlcf->keys == NULL) { |
470 rlcf->keys = ngx_pcalloc(cf->temp_pool, sizeof(ngx_hash_keys_arrays_t)); | |
471 if (rlcf->keys == NULL) { | |
472 return NGX_CONF_ERROR; | |
473 } | |
577 | 474 |
593 | 475 rlcf->keys->pool = cf->pool; |
476 rlcf->keys->temp_pool = cf->pool; | |
477 | |
478 if (ngx_hash_keys_array_init(rlcf->keys, NGX_HASH_SMALL) != NGX_OK) { | |
577 | 479 return NGX_CONF_ERROR; |
480 } | |
481 } | |
482 | |
483 value = cf->args->elts; | |
484 | |
485 for (i = 1; i < cf->args->nelts; i++) { | |
486 if (value[i].len == 0) { | |
487 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
488 "invalid referer \"%V\"", &value[i]); | |
489 return NGX_CONF_ERROR; | |
490 } | |
491 | |
492 if (ngx_strcmp(value[i].data, "none") == 0) { | |
593 | 493 rlcf->no_referer = 1; |
577 | 494 continue; |
495 } | |
496 | |
497 if (ngx_strcmp(value[i].data, "blocked") == 0) { | |
593 | 498 rlcf->blocked_referer = 1; |
577 | 499 continue; |
500 } | |
501 | |
502 if (ngx_strcmp(value[i].data, "server_names") == 0) { | |
5351
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
503 rlcf->server_names = 1; |
577 | 504 continue; |
505 } | |
506 | |
1388 | 507 if (value[i].data[0] == '~') { |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
508 if (ngx_http_add_regex_referer(cf, rlcf, &value[i]) != NGX_OK) { |
1388 | 509 return NGX_CONF_ERROR; |
510 } | |
511 | |
512 continue; | |
513 } | |
514 | |
5351
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
515 ngx_str_null(&uri); |
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
516 |
1242 | 517 p = (u_char *) ngx_strchr(value[i].data, '/'); |
577 | 518 |
593 | 519 if (p) { |
595 | 520 uri.len = (value[i].data + value[i].len) - p; |
521 uri.data = p; | |
593 | 522 value[i].len = p - value[i].data; |
577 | 523 } |
524 | |
595 | 525 if (ngx_http_add_referer(cf, rlcf->keys, &value[i], &uri) != NGX_OK) { |
577 | 526 return NGX_CONF_ERROR; |
527 } | |
528 } | |
529 | |
530 return NGX_CONF_OK; | |
531 } | |
593 | 532 |
533 | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
534 static ngx_int_t |
593 | 535 ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys, |
595 | 536 ngx_str_t *value, ngx_str_t *uri) |
593 | 537 { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
538 ngx_int_t rc; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
539 ngx_str_t *u; |
593 | 540 |
5351
a2c772963b04
Referer: "server_names" parsing deferred to merge phase.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5350
diff
changeset
|
541 if (uri == NULL || uri->len == 0) { |
595 | 542 u = NGX_HTTP_REFERER_NO_URI_PART; |
543 | |
544 } else { | |
545 u = ngx_palloc(cf->pool, sizeof(ngx_str_t)); | |
546 if (u == NULL) { | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
547 return NGX_ERROR; |
595 | 548 } |
549 | |
550 *u = *uri; | |
551 } | |
552 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
553 rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY); |
593 | 554 |
555 if (rc == NGX_OK) { | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
556 return NGX_OK; |
593 | 557 } |
558 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
559 if (rc == NGX_DECLINED) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
560 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
561 "invalid hostname or wildcard \"%V\"", value); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
562 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
1242
diff
changeset
|
563 |
593 | 564 if (rc == NGX_BUSY) { |
565 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
566 "conflicting parameter \"%V\"", value); | |
567 } | |
568 | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
569 return NGX_ERROR; |
593 | 570 } |
571 | |
572 | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
573 static ngx_int_t |
1388 | 574 ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf, |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
575 ngx_str_t *name) |
1388 | 576 { |
577 #if (NGX_PCRE) | |
3325 | 578 ngx_regex_elt_t *re; |
579 ngx_regex_compile_t rc; | |
580 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
1388 | 581 |
3122
3e994ac670dc
test space between "~" and regex in server_name and invalid_referers
Igor Sysoev <igor@sysoev.ru>
parents:
3116
diff
changeset
|
582 if (name->len == 1) { |
3e994ac670dc
test space between "~" and regex in server_name and invalid_referers
Igor Sysoev <igor@sysoev.ru>
parents:
3116
diff
changeset
|
583 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name); |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
584 return NGX_ERROR; |
3122
3e994ac670dc
test space between "~" and regex in server_name and invalid_referers
Igor Sysoev <igor@sysoev.ru>
parents:
3116
diff
changeset
|
585 } |
3e994ac670dc
test space between "~" and regex in server_name and invalid_referers
Igor Sysoev <igor@sysoev.ru>
parents:
3116
diff
changeset
|
586 |
1782
db07cb9d1cbc
regex valid_referers were not inherited
Igor Sysoev <igor@sysoev.ru>
parents:
1704
diff
changeset
|
587 if (rlcf->regex == NGX_CONF_UNSET_PTR) { |
1785 | 588 rlcf->regex = ngx_array_create(cf->pool, 2, sizeof(ngx_regex_elt_t)); |
1388 | 589 if (rlcf->regex == NULL) { |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
590 return NGX_ERROR; |
1388 | 591 } |
592 } | |
593 | |
1785 | 594 re = ngx_array_push(rlcf->regex); |
595 if (re == NULL) { | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
596 return NGX_ERROR; |
1388 | 597 } |
598 | |
599 name->len--; | |
600 name->data++; | |
601 | |
3325 | 602 ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); |
1388 | 603 |
3325 | 604 rc.pattern = *name; |
605 rc.pool = cf->pool; | |
606 rc.options = NGX_REGEX_CASELESS; | |
607 rc.err.len = NGX_MAX_CONF_ERRSTR; | |
608 rc.err.data = errstr; | |
609 | |
610 if (ngx_regex_compile(&rc) != NGX_OK) { | |
611 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err); | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
612 return NGX_ERROR; |
1388 | 613 } |
614 | |
3325 | 615 re->regex = rc.regex; |
1785 | 616 re->name = name->data; |
1388 | 617 |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
618 return NGX_OK; |
1388 | 619 |
620 #else | |
621 | |
622 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
623 "the using of the regex \"%V\" requires PCRE library", | |
624 name); | |
625 | |
5349
9b8a634e348a
Referer: fixed error type usage inconsistency for ngx_http_add*().
Sergey Kandaurov <pluknet@nginx.com>
parents:
5321
diff
changeset
|
626 return NGX_ERROR; |
1388 | 627 |
628 #endif | |
629 } | |
630 | |
631 | |
5350
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
632 #if (NGX_PCRE) |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
633 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
634 static ngx_int_t |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
635 ngx_http_add_regex_server_name(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf, |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
636 ngx_http_regex_t *regex) |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
637 { |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
638 ngx_regex_elt_t *re; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
639 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
640 if (rlcf->server_name_regex == NGX_CONF_UNSET_PTR) { |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
641 rlcf->server_name_regex = ngx_array_create(cf->pool, 2, |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
642 sizeof(ngx_regex_elt_t)); |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
643 if (rlcf->server_name_regex == NULL) { |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
644 return NGX_ERROR; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
645 } |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
646 } |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
647 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
648 re = ngx_array_push(rlcf->server_name_regex); |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
649 if (re == NULL) { |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
650 return NGX_ERROR; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
651 } |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
652 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
653 re->regex = regex->regex; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
654 re->name = regex->name.data; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
655 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
656 return NGX_OK; |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
657 } |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
658 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
659 #endif |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
660 |
8220e393c241
Referer: fixed server_name regex matching.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5349
diff
changeset
|
661 |
593 | 662 static int ngx_libc_cdecl |
663 ngx_http_cmp_referer_wildcards(const void *one, const void *two) | |
664 { | |
665 ngx_hash_key_t *first, *second; | |
666 | |
667 first = (ngx_hash_key_t *) one; | |
668 second = (ngx_hash_key_t *) two; | |
669 | |
3116
98e288c6dac3
If .domain.com, .sub.domain.com, and .domain-some.com were defined,
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
670 return ngx_dns_strcmp(first->key.data, second->key.data); |
593 | 671 } |