1 定义

ngx_http_process_user_agent 函数
定义在
./nginx-1.24.0/src/http/ngx_http_request.c

2 作用

`ngx_http_process_user_agent` 函数负责
解析 `User-Agent` 头部,
识别浏览器类型(如 MSIE、Chrome、Firefox 等)并在请求中设置相应标志位。

3 详解

1 函数签名

static ngx_int_t
ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
    ngx_uint_t offset)

1 返回值

用于统一表示操作状态码。

NGX_OK:User-Agent 头部处理成功。

NGX_ERROR:处理失败。


2 函数名

命名空间前缀 ngx_:Nginx 函数的标准前缀。

http:表明该函数属于 HTTP 模块。

process_user_agent
直接揭示了函数的功能——处理 User-Agent 请求头。
User-Agent 头部是客户端(如浏览器)标识自身软件类型和版本的信息,
Nginx 通过解析该头部来识别特定的浏览器,以便后续执行针对性的优化或兼容处理。

整体语义:
该函数是 Nginx 中专门用于处理 HTTP User-Agent 头部的回调。
它在请求头解析阶段被调用,负责解析该头部的值,
并将其转化为请求结构体中易于使用的浏览器标识标志位。


3 第一个参数 ngx_http_request_t *r
代表当前正在处理的 HTTP 请求。


4 第二个参数 ngx_table_elt_t *h

该结构体表示一个已解析的 HTTP 头部。


5 第三个参数 ngx_uint_t offset

表示 User-Agent 字段在结构体 ngx_http_headers_in_t 中的偏移量。


2 逻辑流程

1 保存
2 Internet Explorer(MSIE)浏览器
3 Opera 浏览器
4 非 MSIE,Opera
5 返回成功

{
    u_char  *user_agent, *msie;

局部变量声明


1 保存

    if (ngx_http_process_header_line(r, h, offset) != NGX_OK) {
        return NGX_ERROR;
    }

将当前已解析的 HTTP 头部(h)保存到请求结构体(r)中正确的位置。


2 Internet Explorer(MSIE)浏览器

    /* check some widespread browsers while the header is in CPU cache */

    user_agent = h->value.data;

    msie = ngx_strstrn(user_agent, "MSIE ", 5 - 1);

    if (msie && msie + 7 < user_agent + h->value.len) {

        r->headers_in.msie = 1;

        if (msie[6] == '.') {

            switch (msie[5]) {
            case '4':
            case '5':
                r->headers_in.msie6 = 1;
                break;
            case '6':
                if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
                    r->headers_in.msie6 = 1;
                }
                break;
            }
        }

#if 0
        /* MSIE ignores the SSL "close notify" alert */
        if (c->ssl) {
            c->ssl->no_send_shutdown = 1;
        }
#endif
    }

3 Opera 浏览器

    if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
        r->headers_in.opera = 1;
        r->headers_in.msie = 0;
        r->headers_in.msie6 = 0;
    }

4 非 MSIE,Opera

    if (!r->headers_in.msie && !r->headers_in.opera) {

        if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
            r->headers_in.gecko = 1;

        } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
            r->headers_in.chrome = 1;

        } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)
                   && ngx_strstrn(user_agent, "Mac OS X", 8 - 1))
        {
            r->headers_in.safari = 1;

        } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
            r->headers_in.konqueror = 1;
        }
    }

只有当请求既没有被识别为 MSIE,也没有被识别为 Opera 时,
才进入下面的浏览器检测。

检测除 MSIE 和 Opera 之外的四种主流浏览器:
Gecko(例如 Firefox)、Chrome、Safari 和 Konqueror。
检测通过用户代理字符串中的特征子串完成,并设置请求中相应的标识位。


5 返回成功

    return NGX_OK;
}
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐