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