Nginx之http模块是如何解析http请求的,6个步骤一目了然-02

解析http请求:

在解析http请求之前,我们先来复习下http请求包含的各个部分及每个部分的协议格式。

一个http请求一般由 请求行、请求头、请求体、响应行、响应头、响应体 这6个部分组成。

我们就以 local.com/index为例:

1)请求行基本格式:

GET /index HTTP/1.1


2)请求头基本格式:

Host: local.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36

3)响应体基本格式:

// 这里比较多 先省略


4)响应行基本格式:

HTTP/1.1 200 OK


5)响应头基本格式:

Content-length: 34
Content-type: application/json
Date: Tue, 09 Nov 2021 08:29:33 GMT


6)响应体基本格式:

// 这里比较多 先省略


了解了HTTP请求的基本格式,我们就可以来看请求是如何解析的。

上面说过是从ngx_http_init_connection方法开始处理的。

// 文件名 ngx_http_request.c
void
ngx_http_init_connection(ngx_connection_t *c)
{
    ngx_event_t  *rev;
    rev = c->read;
    rev->handler = ngx_http_wait_request_handler;
    ngx_add_timer(rev, cscf->client_header_timeout);
}


可以看到这里将读事件的回调方法设置成了
ngx_http_wait_request_handler。也就是说建立连接后并没有立刻初始化请求,而是在链接对应的套接字有数据的时候才开始分配。用人话将就是只有当用户发来请求内容时才真正分配内存资源,以达到减少内存资源的浪费。

当我们追到
ngx_http_wait_request_handler里的时候发现,这里将读事件回调函数设置为
ngx_http_process_request_line方法

// 文件名 ngx_http_request.c
static void
ngx_http_wait_request_handler(ngx_event_t *rev)
{
    rev->handler = ngx_http_process_request_line;
    ngx_http_process_request_line(rev);
}

那么这里为什么多加一行设置成回调?

这是因为http请求的url长度不确定性,内核套接字缓存区未必能接收下整个请求行,因此将读事件的回调方法置为
ngx_http_process_request_line。后续epoll事件将调用该方法,直到完整解析请求行。


请求行解析完了就轮到请求头了。那请求头也一样,长度不确定。同理也需要设置回调方法
ngx_http_process_request_header(可以看到,读取请求头依然用的是
ngx_http_read_request_header方法),

然后调用
ngx_http_parse_header_line方法对请求头进行解析,每解析一个请求头就将其放入ngx_http_request_t结构体的headers_in中,并以链表的形式保存。

到此,Nginx已经获取请求行与请求头的全部信息,然后调用
ngx_http_process_request_header方法对请求头做简单验证后,就可正式进入请求的处理阶段。


那么Nginx到底是如何处理请求,如何响应的呢?我们明天继续。

相关文章

nginx proxy_pass 头信息处理

简介 有些应用需要验证请求和响应的头部信息。而现在的架构基本都会在前端使用nginx进行转发。如果没有处理头部信息,就会导致信息丢失,无法通过验证,出现403等请求异常的情况。nginx指令proxy...

Nginx之进程间通信-共享内存篇

前面我们介绍了Nginx的多进程模型,多个worker进程间通信 主要是用共享内存来实现的。今天我们就来学习下Nginx的共享内存。那么进程该如何创建共享内存呢?如果按照使用我们的malloc来分配...

Linux 系统信息命令大全,极其详细!

在日常运维、排障、性能优化或系统审计中,我们常常需要了解 Linux 系统的详细信息,包括内核版本、硬件配置、内存、磁盘、网络状态、进程负载等。掌握这些信息命令,不仅能让你看清系统运行的“全貌”,更是...

Nginx熔断操作:一行代码搞定临时流量控制!

直接在目标接口的location块中添加if判断,通过注释/取消注释一行代码,即可轻松控制熔断状态!无需复杂指令,简单高效!快速配置示例快速实现熔断!示例:熔断/api/order接口server {...

Nginx实现认证登录

Nginx 是一个很强大的高性能Web和反向代理服务,本配置实现Nginx认证登录以免重要信息暴露在公网。ngx_http_auth_basic_module模块实现让访问者访问,只有输入正确的用户密...