~ubuntu-branches/ubuntu/jaunty/nginx/jaunty-updates

« back to all changes in this revision

Viewing changes to src/http/modules/ngx_http_referer_module.c

  • Committer: Bazaar Package Importer
  • Author(s): Jose Parrella
  • Date: 2007-12-08 11:27:54 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20071208112754-23ohg2b1zshkdayw
Tags: 0.5.33-1
* New stable upstream release (Closes: #451173)
* nginx now provides httpd, httpd-cgi virtual packages
  (Closes: #439468, #452025)
* sites-enabled/default link is now provided only on fresh 
  installations (Closes: #432961)
* Updated code for online upgrading of nginx (Closes: #445246)
* Reviewed maintainer scripts for correct behaviour on updates
  (Closes: #452787, #435965)
* Removed debian/nginx.links and debian/preinst.
* Changing Maintainer address to bureado@debian.org.
* Welcoming Fabio Tranchitella <kobold@debian.org> as an nginx 
  uploader for Debian. Thanks for your patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
#define NGX_HTTP_REFERER_NO_URI_PART  ((void *) 4)
13
13
 
14
 
typedef struct {
15
 
    ngx_hash_t               hash;
16
 
    ngx_hash_wildcard_t     *dns_wildcards;
 
14
#if (NGX_PCRE)
 
15
 
 
16
typedef struct {
 
17
    ngx_regex_t             *regex;
 
18
    ngx_str_t                name;
 
19
} ngx_http_referer_regex_t;
 
20
 
 
21
#else
 
22
 
 
23
#define ngx_regex_t          void
 
24
 
 
25
#endif
 
26
 
 
27
 
 
28
typedef struct {
 
29
    ngx_hash_combined_t      hash;
 
30
 
 
31
#if (NGX_PCRE)
 
32
    ngx_array_t             *regex;
 
33
#endif
17
34
 
18
35
    ngx_flag_t               no_referer;
19
36
    ngx_flag_t               blocked_referer;
29
46
    void *conf);
30
47
static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
31
48
    ngx_str_t *value, ngx_str_t *uri);
 
49
static char *ngx_http_add_regex_referer(ngx_conf_t *cf,
 
50
    ngx_http_referer_conf_t *rlcf, ngx_str_t *name, ngx_regex_t *regex);
32
51
static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
33
52
    const void *two);
34
53
 
81
100
ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
82
101
     uintptr_t data)
83
102
{
84
 
    u_char                   *p, *ref, *last;
85
 
    size_t                    len;
86
 
    ngx_str_t                *uri;
87
 
    ngx_uint_t                i, key;
88
 
    ngx_http_referer_conf_t  *rlcf;
89
 
    u_char                    buf[256];
 
103
    u_char                    *p, *ref, *last;
 
104
    size_t                     len;
 
105
    ngx_str_t                 *uri;
 
106
    ngx_uint_t                 i, key;
 
107
    ngx_http_referer_conf_t   *rlcf;
 
108
    u_char                     buf[256];
 
109
#if (NGX_PCRE)
 
110
    ngx_int_t                  n;
 
111
    ngx_str_t                  referer;
 
112
    ngx_http_referer_regex_t  *regex;
 
113
#endif
90
114
 
91
115
    rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
92
116
 
93
 
    if (rlcf->hash.buckets == NULL && rlcf->dns_wildcards == NULL) {
 
117
    if (rlcf->hash.hash.buckets == NULL
 
118
        && rlcf->hash.wc_head == NULL
 
119
        && rlcf->hash.wc_tail == NULL
 
120
#if (NGX_PCRE)
 
121
        && rlcf->regex == NULL
 
122
#endif
 
123
       )
 
124
    {
94
125
        goto valid;
95
126
    }
96
127
 
133
164
        }
134
165
    }
135
166
 
136
 
    len = p - ref;
137
 
 
138
 
    if (rlcf->hash.buckets) {
139
 
        uri = ngx_hash_find(&rlcf->hash, key, buf, len);
140
 
        if (uri) {
141
 
            goto uri;
142
 
        }
143
 
    }
144
 
 
145
 
    if (rlcf->dns_wildcards) {
146
 
        uri = ngx_hash_find_wildcard(rlcf->dns_wildcards, buf, len);
147
 
        if (uri) {
148
 
            goto uri;
149
 
        }
150
 
    }
 
167
    uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref);
 
168
 
 
169
    if (uri) {
 
170
        goto uri;
 
171
    }
 
172
 
 
173
#if (NGX_PCRE)
 
174
 
 
175
    if (rlcf->regex) {
 
176
 
 
177
        referer.len = len - 7;
 
178
        referer.data = ref;
 
179
 
 
180
        regex = rlcf->regex->elts;
 
181
 
 
182
        for (i = 0; i < rlcf->regex->nelts; i++) {
 
183
            n = ngx_regex_exec(regex[i].regex, &referer, NULL, 0);
 
184
 
 
185
            if (n == NGX_REGEX_NO_MATCHED) {
 
186
                continue;
 
187
            }
 
188
 
 
189
            if (n < 0) {
 
190
                ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
 
191
                              ngx_regex_exec_n
 
192
                              " failed: %d on \"%V\" using \"%V\"",
 
193
                              n, &referer, &regex[i].name);
 
194
                return NGX_ERROR;
 
195
            }
 
196
 
 
197
            /* match */
 
198
 
 
199
            goto valid;
 
200
        }
 
201
    }
 
202
 
 
203
#endif
151
204
 
152
205
invalid:
153
206
 
208
261
 
209
262
    if (conf->keys == NULL) {
210
263
        conf->hash = prev->hash;
211
 
        conf->dns_wildcards = prev->dns_wildcards;
212
264
 
213
265
        ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
214
266
        ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
217
269
    }
218
270
 
219
271
    if ((conf->no_referer == 1 || conf->blocked_referer == 1)
220
 
        && conf->keys->keys.nelts == 0 && conf->keys->dns_wildcards.nelts == 0)
 
272
        && conf->keys->keys.nelts == 0
 
273
        && conf->keys->dns_wc_head.nelts == 0
 
274
        && conf->keys->dns_wc_tail.nelts == 0)
221
275
    {
222
276
        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
223
277
                      "the \"none\" or \"blocked\" referers are specified "
233
287
    hash.pool = cf->pool;
234
288
 
235
289
    if (conf->keys->keys.nelts) {
236
 
        hash.hash = &conf->hash;
 
290
        hash.hash = &conf->hash.hash;
237
291
        hash.temp_pool = NULL;
238
292
 
239
293
        if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts)
243
297
        }
244
298
    }
245
299
 
246
 
    if (conf->keys->dns_wildcards.nelts) {
247
 
 
248
 
        ngx_qsort(conf->keys->dns_wildcards.elts,
249
 
                  (size_t) conf->keys->dns_wildcards.nelts,
250
 
                  sizeof(ngx_hash_key_t),
251
 
                  ngx_http_cmp_referer_wildcards);
252
 
 
253
 
        hash.hash = NULL;
254
 
        hash.temp_pool = cf->temp_pool;
255
 
 
256
 
        if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wildcards.elts,
257
 
                                   conf->keys->dns_wildcards.nelts)
258
 
            != NGX_OK)
259
 
        {
260
 
            return NGX_CONF_ERROR;
261
 
        }
262
 
 
263
 
        conf->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
 
300
    if (conf->keys->dns_wc_head.nelts) {
 
301
 
 
302
        ngx_qsort(conf->keys->dns_wc_head.elts,
 
303
                  (size_t) conf->keys->dns_wc_head.nelts,
 
304
                  sizeof(ngx_hash_key_t),
 
305
                  ngx_http_cmp_referer_wildcards);
 
306
 
 
307
        hash.hash = NULL;
 
308
        hash.temp_pool = cf->temp_pool;
 
309
 
 
310
        if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_head.elts,
 
311
                                   conf->keys->dns_wc_head.nelts)
 
312
            != NGX_OK)
 
313
        {
 
314
            return NGX_CONF_ERROR;
 
315
        }
 
316
 
 
317
        conf->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
 
318
    }
 
319
 
 
320
    if (conf->keys->dns_wc_tail.nelts) {
 
321
 
 
322
        ngx_qsort(conf->keys->dns_wc_tail.elts,
 
323
                  (size_t) conf->keys->dns_wc_tail.nelts,
 
324
                  sizeof(ngx_hash_key_t),
 
325
                  ngx_http_cmp_referer_wildcards);
 
326
 
 
327
        hash.hash = NULL;
 
328
        hash.temp_pool = cf->temp_pool;
 
329
 
 
330
        if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_tail.elts,
 
331
                                   conf->keys->dns_wc_tail.nelts)
 
332
            != NGX_OK)
 
333
        {
 
334
            return NGX_CONF_ERROR;
 
335
        }
 
336
 
 
337
        conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
264
338
    }
265
339
 
266
340
    if (conf->no_referer == NGX_CONF_UNSET) {
342
416
 
343
417
            sn = cscf->server_names.elts;
344
418
            for (n = 0; n < cscf->server_names.nelts; n++) {
 
419
 
 
420
#if (NGX_PCRE)
 
421
                if (sn[n].regex) {
 
422
 
 
423
                    if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name,
 
424
                                                   sn[n].regex)
 
425
                        != NGX_OK)
 
426
                    {
 
427
                        return NGX_CONF_ERROR;
 
428
                    }
 
429
 
 
430
                    continue;
 
431
                }
 
432
#endif
 
433
 
345
434
                if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
346
435
                    != NGX_OK)
347
436
                {
352
441
            continue;
353
442
        }
354
443
 
 
444
        if (value[i].data[0] == '~') {
 
445
            if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK)
 
446
            {
 
447
                return NGX_CONF_ERROR;
 
448
            }
 
449
 
 
450
            continue;
 
451
        }
 
452
 
355
453
        p = (u_char *) ngx_strchr(value[i].data, '/');
356
454
 
357
455
        if (p) {
373
471
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
374
472
    ngx_str_t *value, ngx_str_t *uri)
375
473
{
376
 
    u_char       ch;
377
 
    ngx_int_t    rc;
378
 
    ngx_str_t   *u;
379
 
    ngx_uint_t   flags;
380
 
 
381
 
    ch = value->data[0];
382
 
 
383
 
    if ((ch == '*' && (value->len < 3 || value->data[1] != '.'))
384
 
        || (ch == '.' && value->len < 2))
385
 
    {
386
 
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
387
 
                           "invalid DNS wildcard \"%V\"", value);
388
 
 
389
 
        return NGX_CONF_ERROR;
390
 
    }
391
 
 
392
 
    flags = (ch == '*' || ch == '.') ? NGX_HASH_WILDCARD_KEY : 0;
 
474
    ngx_int_t   rc;
 
475
    ngx_str_t  *u;
393
476
 
394
477
    if (uri->len == 0) {
395
478
        u = NGX_HTTP_REFERER_NO_URI_PART;
403
486
        *u = *uri;
404
487
    }
405
488
 
406
 
    rc = ngx_hash_add_key(keys, value, u, flags);
 
489
    rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
407
490
 
408
491
    if (rc == NGX_OK) {
409
492
        return NGX_CONF_OK;
410
493
    }
411
494
 
 
495
    if (rc == NGX_DECLINED) {
 
496
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
 
497
                           "invalid hostname or wildcard \"%V\"", value);
 
498
    }
 
499
 
412
500
    if (rc == NGX_BUSY) {
413
501
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
414
502
                           "conflicting parameter \"%V\"", value);
418
506
}
419
507
 
420
508
 
 
509
static char *
 
510
ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
 
511
    ngx_str_t *name, ngx_regex_t *regex)
 
512
{
 
513
#if (NGX_PCRE)
 
514
    ngx_str_t                  err;
 
515
    ngx_http_referer_regex_t  *rr;
 
516
    u_char                     errstr[NGX_MAX_CONF_ERRSTR];
 
517
 
 
518
    if (rlcf->regex == NULL) {
 
519
        rlcf->regex = ngx_array_create(cf->pool, 2,
 
520
                                       sizeof(ngx_http_referer_regex_t));
 
521
        if (rlcf->regex == NULL) {
 
522
            return NGX_CONF_ERROR;
 
523
        }
 
524
    }
 
525
 
 
526
    rr = ngx_array_push(rlcf->regex);
 
527
    if (rr == NULL) {
 
528
        return NGX_CONF_ERROR;
 
529
    }
 
530
 
 
531
    if (regex) {
 
532
        rr->regex = regex;
 
533
        rr->name = *name;
 
534
 
 
535
        return NGX_CONF_OK;
 
536
    }
 
537
 
 
538
    err.len = NGX_MAX_CONF_ERRSTR;
 
539
    err.data = errstr;
 
540
 
 
541
    name->len--;
 
542
    name->data++;
 
543
 
 
544
    rr->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err);
 
545
 
 
546
    if (rr->regex == NULL) {
 
547
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
 
548
        return NGX_CONF_ERROR;
 
549
    }
 
550
 
 
551
    rr->name = *name;
 
552
 
 
553
    return NGX_CONF_OK;
 
554
 
 
555
#else
 
556
 
 
557
    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
 
558
                       "the using of the regex \"%V\" requires PCRE library",
 
559
                       name);
 
560
 
 
561
    return NGX_CONF_ERROR;
 
562
 
 
563
#endif
 
564
}
 
565
 
 
566
 
421
567
static int ngx_libc_cdecl
422
568
ngx_http_cmp_referer_wildcards(const void *one, const void *two)
423
569
{