~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/http/modules/ngx_http_browser_module.c

Version: ~ [ nginx-1.4.1 ] ~ [ nginx-1.5.0 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.