跳转至

http处理


更新于 2024-11-30

处理流程

接受请求

Text Only
1
2
3
4
5
ngx_event_accept  接受新连接
├─ngx_http_init_connection 创建ngx_connection_t 
├──ngx_http_wait_request_hander 读取数据并处理
├───ngx_http_create_request 创建ngx_http_request_t
└───ngx_http_process_request_line 请求处理回调

处理请求行

Text Only
1
2
3
ngx_http_process_request_line
├──ngx_http_read_request_header 读取请求头
└──ngx_http_parse_request_line  处理请求行

处理头部

Text Only
1
2
3
4
5
6
7
8
ngx_http_process_request_headers 处理请求头
├────ngx_http_read_request_header 继续读取头部
├────ngx_http_parse_header_line 解析头
├────ngx_list_push(&r->headers_in.headers)头部存入hash表
├────ngx_http_process_request_header 检测头部
├────ngx_http_process_request
├───ngx_http_run_posted_requests 调用子请求
└──ngx_http_run_posted_requests

处理消息体

Text Only
1
2
3
4
5
6
7
8
ngx_http_process_request 处理消息体
├─ngx_http_request_handler
├─ngx_http_handler
└─ngx_http_core_run_phases

ngx_http_read_client_request_body 处理消息body,保存到ngx_http_request_body_t
├─ngx_http_do_read_client_request_body        
├─ngx_http_request_body_filter

结束请求

Text Only
1
2
3
4
5
ngx_http_finalize_request  结束请求
├─ngx_http_writer
├──ngx_http_finalize_connection
├───ngx_http_set_keepalive
├───ngx_http_close_request

处理阶段

    graph TD
    POST_READ(POST_READ<br>ngx_http_realip_module);
    SERVER_REWRITE(SERVER_REWRITE<br>ngx_http_rewrite_nmodule);
    FIND_CONFIG(FIND_CONFIG<br>根据URI查找Location);
    REWRITE(REWRITE<br>处理lcation里rewrite指令);
    POST_REWRITE(POST_REWRITE<br>若URI重写,重新查找Location);
    PREACCESS(PREACCESS<br>ngx_http_limit_conn_module<br>ngx_http_limit_req_module<br>限速);
    ACCESS(AACCESS<br>ngx_http_access_module<br>ngx_http_auth_basic_module<br>用户鉴权);
    POST_ACCESS(POST_ACCESS<br>处理satisfy any指令);
    PRECONTENT(PRECONTENT<br>处理try files指令);
    CONTENT(CONTENT<br>产生应答);
    LOG(LOG<br>ngx_http_log_module<br>产生日志);

    POST_READ-->SERVER_REWRITE;
    SERVER_REWRITE-->FIND_CONFIG;
    FIND_CONFIG-->REWRITE;
    REWRITE-->POST_REWRITE;
    POST_REWRITE--URI被重写-->FIND_CONFIG;
    POST_REWRITE-->PREACCESS;
    PREACCESS-->ACCESS;
    ACCESS-->POST_ACCESS;
    POST_ACCESS-->PRECONTENT;
    PRECONTENT-->CONTENT;
    CONTENT-->LOG;

配置处理流程

请求处理

  • 根据Host头匹配选择server
  • 若无Host头或不匹配,将第一个作为默认server处理请求
  • 使用default_server指定默认server

server_name

符号 说明 示例
准确得名字 www.abc.com
* 首尾包含*的字串 .abc.com, abc., .abc
~ perl正则 ~
Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
server {
    listen      80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}
Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#当同时配置IP和域名时,先匹配IP,再匹配域名
server {
    listen      192.168.1.1:80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      192.168.1.1:80 default_server;
    server_name example.net www.example.net;
    ...
}

server {
    listen      192.168.1.2:80 default_server;
    server_name example.com www.example.com;
    ...
}

阻止访问

Host为空的请求拒绝

Text Only
1
2
3
4
5
server {
    listen      80;
    server_name "";
    return      444;
}

location

选定server后,将从server内选择location

Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
server {
    listen      80;
    server_name example.org www.example.org;
    root        /data/www;

    location / {
        index   index.html index.php;
    }

    location ~* \.(gif|jpg|png)$ {
        expires 30d;
    }

    location ~ \.php$ {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME
                      $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

location [=||*|^~] /uri/ { … }

符号 说明
= 开头表示精确匹配
^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可,匹配符合后,不再向下匹配
~ 开头表示区分大小写的正则匹配
~* 开头表示不区分大小写的正则匹配
!~ 区分大小写不匹配正则
!~* 不区分大小写不匹配的正则
/ 通用匹配,任何请求都会匹配到