05_Nginx_解析自定义的HTTP请求头
1. 导读
在HTTP请求中,除了在Body中添加数据外,也可以在请求头中添加一些key-value
值用于证书验证等操作。
2. 准备
2.1ngx_http_request_t
结构体
struct ngx_http_request_s {
.......(省略)
//ngx_http_process_request_headers在接收、解析完http请求的头部后,会把解析完的每一个http头部加入到headers_in的headers链表中,同时会构造headers_in中的其他成员
ngx_http_headers_in_t headers_in;
.......(省略)
}
2.2 ngx_http_headers_in_t
结构体
typedef struct {
// 链表结构体,
ngx_list_t headers;
// 自定义请求头声明
ngx_table_elt_t *ts;
// 解析函数执行后 存储host的数据,
ngx_table_elt_t *host;
ngx_table_elt_t *connection;
ngx_table_elt_t *if_modified_since;
ngx_table_elt_t *if_unmodified_since;
ngx_table_elt_t *if_match;
ngx_table_elt_t *if_none_match;
ngx_table_elt_t *user_agent;
ngx_table_elt_t *referer;
ngx_table_elt_t *content_length;
ngx_table_elt_t *content_range;
ngx_table_elt_t *content_type;
ngx_table_elt_t *range;
ngx_table_elt_t *if_range;
ngx_table_elt_t *transfer_encoding;
ngx_table_elt_t *te;
ngx_table_elt_t *expect;
ngx_table_elt_t *upgrade;
#if (NGX_HTTP_GZIP || NGX_HTTP_HEADERS)
ngx_table_elt_t *accept_encoding;
ngx_table_elt_t *via;
#endif
ngx_table_elt_t *authorization;
ngx_table_elt_t *keep_alive;
#if (NGX_HTTP_X_FORWARDED_FOR)
ngx_array_t x_forwarded_for;
#endif
#if (NGX_HTTP_REALIP)
ngx_table_elt_t *x_real_ip;
#endif
#if (NGX_HTTP_HEADERS)
ngx_table_elt_t *accept;
ngx_table_elt_t *accept_language;
#endif
#if (NGX_HTTP_DAV)
ngx_table_elt_t *depth;
ngx_table_elt_t *destination;
ngx_table_elt_t *overwrite;
ngx_table_elt_t *date;
#endif
ngx_str_t user;
ngx_str_t passwd;
ngx_array_t cookies;
ngx_str_t server;
off_t content_length_n;
time_t keep_alive_n;
unsigned connection_type:2;
unsigned chunked:1;
unsigned msie:1;
unsigned msie6:1;
unsigned opera:1;
unsigned gecko:1;
unsigned chrome:1;
unsigned safari:1;
unsigned konqueror:1;
} ngx_http_headers_in_t;
2.3 ngx_table_elt_t
结构体
typedef struct {
ngx_uint_t hash;
ngx_str_t key;
ngx_str_t value;
u_char *lowcase_key;
} ngx_table_elt_t;
2.4 ngx_http_headers_in[]
typedef struct {
ngx_str_t name; // 请求头名
ngx_uint_t offset; //
ngx_http_header_handler_pt handler; // 回调函数
} ngx_http_header_t;
// 解析相对应请求头的结构体
ngx_http_header_t ngx_http_headers_in[] = {
// 声明自定义请求头
{ ngx_string("ts"), offsetof(ngx_http_headers_in_t, ts),
ngx_http_process_unique_header_line },
{ ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
ngx_http_process_host },
....(省略)
};
2.5 回调函数
在ngx_http_headers_in[]
数组包含了25个常用的请求头,每个请求头都设置了一个处理函数,其中有两个公共的处理函数,ngx_http_process_header_line
和ngx_http_process_unique_header_line
,
3 实现
当我们需要自定义请求头的时候,只需要在ngx_http_headers_in_t
先进行声明,并在ngx_http_headers_in[]
中配置好回调函数,那么就可以通过ngx_http_request_s
进行调用了。
3.1 在ngx_http_headers_in_t
中进行声明
3.2 在 ngx_http_headers_in[]
数组中进行声明
3.3 在处理函数中获取值
// 请求头 ts
char request_header_in_ts[1000] = {0};
memcpy(request_header_in_ts, r->headers_in.ts->value.data, r->headers_in.ts->value.len);
printf("请求头:request_header_in_ts = %s\n", request_header_in_ts);
printf("=====================\n");
// 请求头 host
char request_header_in_host[1000] = {0};
memcpy(request_header_in_host, r->headers_in.host->value.data, r->headers_in.host->value.len);
printf("请求头:request_header_in_host = %s\n", request_header_in_host);
printf("=====================\n");
3.4 请求截图
-
发送的报文:
-
Nginx接收到的报文