
/*
 * Copyright (C) Igor Sysoev
 */


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>


/*
 * The module can check browser versions conforming to the following formats:
 * X, X.X, X.X.X, and X.X.X.X.  The maximum values of each format may be
 * 4000, 4000.99, 4000.99.99, and 4000.99.99.99.
 */


typedef struct {
    u_char                      browser[12];
    size_t                      skip;
    size_t                      add;
    u_char                      name[12];
} ngx_http_modern_browser_mask_t;


typedef struct {
    ngx_uint_t                  version;
    size_t                      skip;
    size_t                      add;
    u_char                      name[12];
} ngx_http_modern_browser_t;


typedef struct {
    ngx_str_t                   name;
    ngx_http_get_variable_pt    handler;
} ngx_http_browser_t;


typedef struct {
    ngx_array_t                *modern_browsers;
    ngx_http_variable_value_t  *value;
} ngx_http_browser_conf_t;


static ngx_int_t ngx_http_msie_variable(ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_browser_add_variable(ngx_conf_t *cf);
static void *ngx_http_browser_create_conf(ngx_conf_t *cf);
static char *ngx_http_browser_merge_conf(ngx_conf_t *cf, void *parent,
    void *child);
static int ngx_libc_cdecl ngx_http_modern_browser_sort(const void *one,
    const void *two);
static char *ngx_http_modern_browser(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);
static char *ngx_http_modern_browser_value(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);


static ngx_command_t  ngx_http_browser_commands[] = {

    { ngx_string("modern_browser"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
      ngx_http_modern_browser,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },

    { ngx_string("modern_browser_value"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
      ngx_http_modern_browser_value,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },

      ngx_null_command
};


static ngx_http_module_t  ngx_http_browser_module_ctx = {
    ngx_http_browser_add_variable,         /* preconfiguration */
    NULL,                                  /* postconfiguration */

    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */

    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */

    ngx_http_browser_create_conf,          /* create location configuration */
    ngx_http_browser_merge_conf            /* merge location configuration */
};


ngx_module_t  ngx_http_browser_module = {
    NGX_MODULE_V1,
    &ngx_http_browser_module_ctx,          /* module context */
    ngx_http_browser_commands,             /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};


static ngx_http_modern_browser_mask_t  ngx_http_modern_browser_masks[] = {

    /* Opera must be the first browser to check */

    /*
     * "Opera/7.50 (X11; FreeBSD i386; U)  [en]"
     * "Mozilla/5.0 (X11; FreeBSD i386; U) Opera 7.50  [en]"
     * "Mozilla/4.0 (compatible; MSIE 6.0; X11; FreeBSD i386) Opera 7.50  [en]"
     * "Opera/8.0 (Windows NT 5.1; U; ru)"
     * "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; en) Opera 8.0"
     * "Opera/9.01 (X11; FreeBSD 6 i386; U; en)"
     */

    { "opera",
      0,
      sizeof("Opera ") - 1,
      "Opera"},

    /* "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" */

    { "msie",
      sizeof("Mozilla/4.0 (compatible; ") - 1,
      sizeof("MSIE ") - 1,
      "MSIE "},

    /*
     * "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020610"
     * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.5) Gecko/20031006"
     * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.6) Gecko/20040206
     *              Firefox/0.8"
     * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.8)
     *              Gecko/20050511 Firefox/1.0.4"
     * "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.8.0.5) Gecko/20060729
     *              Firefox/1.5.0.5"
     */

    { "gecko",
      sizeof("Mozilla/5.0 (") - 1,
      sizeof("rv:") - 1,
      "rv:"},

    /*
     * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ru-ru) AppleWebKit/125.2
     *              (KHTML, like Gecko) Safari/125.7"
     * "Mozilla/5.0 (SymbianOS/9.1; U; en-us) AppleWebKit/413
     *              (KHTML, like Gecko) Safari/413"
     * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418
     *              (KHTML, like Gecko) Safari/417.9.3"
     * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ru-ru) AppleWebKit/418.8
     *              (KHTML, like Gecko) Safari/419.3"
     */

    { "safari",
      sizeof("Mozilla/5.0 (") - 1,
      sizeof("Safari/") - 1,
      "Safari/"},

    /*
     * "Mozilla/5.0 (compatible; Konqueror/3.1; Linux)"
     * "Mozilla/5.0 (compatible; Konqueror/3.4; Linux) KHTML/3.4.2 (like Gecko)"
     * "Mozilla/5.0 (compatible; Konqueror/3.5; FreeBSD) KHTML/3.5.1
     *              (like Gecko)"
     */

    { "konqueror",
      sizeof("Mozilla/5.0 (compatible; ") - 1,
      sizeof("Konqueror/") - 1,
      "Konqueror/"},

    { "", 0, 0, "" }

};


static ngx_http_browser_t  ngx_http_browsers[] = {
    { ngx_string("msie"), ngx_http_msie_variable },
    { ngx_null_string, NULL }
};


static ngx_int_t
ngx_http_browser_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
    uintptr_t data)
{
    u_char                     *name, *ua, *last, c;
    ngx_uint_t                  i, version, ver, scale;
    ngx_http_browser_conf_t    *cf;
    ngx_http_modern_browser_t  *browsers;

    cf = ngx_http_get_module_loc_conf(r, ngx_http_browser_module);

    if (cf->modern_browsers == NULL || cf->value == NULL) {
        *v = ngx_http_variable_null_value;
        return NGX_OK;
    }

#if 0
    if (!r->headers_in.msie && !r->headers_in.opera
        && !r->headers_in.gecko && !r->headers_in.konqueror)
    {
        *v = ngx_http_variable_null_value;
        return NGX_OK;
    }
#endif

    if (r->headers_in.user_agent == NULL) {
        *v = ngx_http_variable_null_value;
        return NGX_OK;
    }


    ua = r->headers_in.user_agent->value.data;
    last = ua + r->headers_in.user_agent->value.len;

    browsers = cf->modern_browsers->elts;

    for (i = 0; i < cf->modern_browsers->nelts; i++) {
        name = ua + browsers[i].skip;

        if (name >= last) {
            continue;
        }

        name = (u_char *) ngx_strstr(name, browsers[i].name);

        if (name == NULL) {
            continue;
        }

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "browser: \"%s\"", name);

        name += browsers[i].add;

        if (name >= last) {
            continue;
        }

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "version: \"%ui\" \"%s\"", browsers[i].version, name);

        version = 0;
        ver = 0;
        scale = 1000000;

        while (name < last) {

            c = *name++;

            if (c >= '0' && c <= '9') {
                ver = ver * 10 + (c - '0');
                continue;
            }

            if (c == '.') {
                version += ver * scale;

                if (version > browsers[i].version) {
                    *v = *cf->value;
                    return NGX_OK;
                }

                ver = 0;
                scale /= 100;
                continue;
            }

            break;
        }

        version += ver * scale;

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "version: \"%ui\" \"%ui\"",
                       browsers[i].version, version);

        if (version >= browsers[i].version) {
            *v = *cf->value;
            return NGX_OK;
        }
    }

    *v = ngx_http_variable_null_value;

    return NGX_OK;
}


static ngx_int_t
ngx_http_msie_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
    uintptr_t data)
{
    if (r->headers_in.msie) {
        *v = ngx_http_variable_true_value;

        return NGX_OK;
    }

    *v = ngx_http_variable_null_value;

    return NGX_OK;
}


static ngx_int_t
ngx_http_browser_add_variable(ngx_conf_t *cf)
{
    ngx_http_browser_t   *browser;
    ngx_http_variable_t  *var;

    for (browser = ngx_http_browsers; browser->name.len; browser++) {

        var = ngx_http_add_variable(cf, &browser->name, NGX_HTTP_VAR_CHANGABLE);
        if (var == NULL) {
            return NGX_ERROR;
        }

        var->get_handler = browser->handler;
    }

    return NGX_OK;
}


static void *
ngx_http_browser_create_conf(ngx_conf_t *cf)
{
    ngx_http_browser_conf_t  *conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_browser_conf_t));
    if (conf == NULL) {
        return NGX_CONF_ERROR;
    }

    /*
     * set by ngx_pcalloc():
     *
     *     conf->browsers = NULL;
     *     conf->value = NULL;
     */

    return conf;
}


static char *
ngx_http_browser_merge_conf(ngx_conf_t *cf, void *parent, void *child)
{
    ngx_http_browser_conf_t *prev = parent;
    ngx_http_browser_conf_t *conf = child;

    ngx_uint_t                  i, n;
    ngx_http_modern_browser_t  *browsers, *opera;

    /*
     * At the merge the skip field is used to store the browser slot,
     * it will be used in sorting and then will overwritten
     * with a real skip value.  The zero value means Opera.
     */

    if (conf->modern_browsers == NULL) {
        conf->modern_browsers = prev->modern_browsers;

    } else {
        browsers = conf->modern_browsers->elts;

        for (i = 0; i < conf->modern_browsers->nelts; i++) {
            if (browsers[i].skip == 0) {
                goto found;
            }
        }

        /*
         * Opera may contain MSIE string, so if Opera was not enumerated
         * as modern browsers, then add it and set a unreachable version
         */

        opera = ngx_array_push(conf->modern_browsers);
        if (opera == NULL) {
            return NGX_CONF_ERROR;
        }

        opera->skip = 0;
        opera->version = 4001000000U;

        browsers = conf->modern_browsers->elts;

found:

        ngx_qsort(browsers, (size_t) conf->modern_browsers->nelts,
                  sizeof(ngx_http_modern_browser_t),
                  ngx_http_modern_browser_sort);

        for (i = 0; i < conf->modern_browsers->nelts; i++) {
             n = browsers[i].skip;

             browsers[i].skip = ngx_http_modern_browser_masks[n].skip;
             browsers[i].add = ngx_http_modern_browser_masks[n].add;
             (void) ngx_cpystrn(browsers[i].name,
                                ngx_http_modern_browser_masks[n].name, 12);
        }
    }

    if (conf->value == NULL) {
        conf->value = prev->value;
    }

    return NGX_CONF_OK;
}


static int ngx_libc_cdecl
ngx_http_modern_browser_sort(const void *one, const void *two)
{
    ngx_http_modern_browser_t *first = (ngx_http_modern_browser_t *) one;
    ngx_http_modern_browser_t *second = (ngx_http_modern_browser_t *) two;

    return (first->skip - second->skip);
}


static char *
ngx_http_modern_browser(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_browser_conf_t *bcf = conf;

    u_char                           c;
    ngx_str_t                       *value;
    ngx_uint_t                       i, n, version, ver, scale;
    ngx_http_modern_browser_t       *browser;
    ngx_http_modern_browser_mask_t  *mask;

    if (bcf->modern_browsers == NULL) {
        bcf->modern_browsers = ngx_array_create(cf->pool, 4,
                                            sizeof(ngx_http_modern_browser_t));
        if (bcf->modern_browsers == NULL) {
            return NGX_CONF_ERROR;
        }
    }

    browser = ngx_array_push(bcf->modern_browsers);
    if (browser == NULL) {
        return NGX_CONF_ERROR;
    }

    value = cf->args->elts;

    mask = ngx_http_modern_browser_masks;

    for (n = 0; mask[n].browser[0] != '\0'; n++) {
        if (ngx_strcasecmp(mask[n].browser, value[1].data) == 0) {
            goto found;
        }
    }

    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                       "unknown browser name \"%V\"", &value[1]);

    return NGX_CONF_ERROR;

found:

    /*
     * at this stage the skip field is used to store the browser slot,
     * it will be used in sorting in merge stage and then will overwritten
     * with a real value
     */

    browser->skip = n;

    version = 0;
    ver = 0;
    scale = 1000000;

    for (i = 0; i < value[2].len; i++) {

        c = value[2].data[i];

        if (c >= '0' && c <= '9') {
            ver = ver * 10 + (c - '0');
            continue;
        }

        if (c == '.') {
            version += ver * scale;
            ver = 0;
            scale /= 100;
            continue;
        }

        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid browser version \"%V\"", &value[2]);

        return NGX_CONF_ERROR;
    }

    version += ver * scale;

    browser->version = version;

    return NGX_CONF_OK;
}


static char *
ngx_http_modern_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_browser_conf_t *bcf = conf;

    ngx_str_t            *value, name;
    ngx_http_variable_t  *var;

    value = cf->args->elts;

    name.len = sizeof("browser") - 1;
    name.data = (u_char *) "browser";

    var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE);
    if (var == NULL) {
        return NGX_CONF_ERROR;
    }

    var->get_handler = ngx_http_browser_variable;

    bcf->value = ngx_palloc(cf->pool, sizeof(ngx_http_variable_value_t));
    if (bcf->value == NULL) {
        return NGX_CONF_ERROR;
    }

    bcf->value->len = value[1].len;
    bcf->value->valid = 1;
    bcf->value->no_cachable = 0;
    bcf->value->not_found = 0;
    bcf->value->data = value[1].data;

    return NGX_CONF_OK;
}
