02_nginx开发自己的http服务
- 1. 下载源码
- 2. 添加文件
- 3. 配置config
- 4. 补充ngx_http_hello_module.c
- 4.1 添加头文件
- 4.2 定义HTTP模块
- 4.3 定义模块上下文信息
- 4.4 模块定义
- 4.5 定义模块触发函数
- 4.6 请求处理handler
- 4.7 大作业
- 5. 配置nginx.conf
- 6.配置、编译、运行
- 6.1 配置
- 6.2 编译
- 6.3 执行
1. 下载源码
略
2. 添加文件
在源码目录下新建extends\ngx_http_hello_module
目录,在目录下新建config
和ngx_http_hello_module.c
两个文件夹
目录结构如下:
3. 配置config
此处第三方模块的路径在配置时候需要我们手动添加,./configure --add-module=
#模块名称
ngx_addon_name=ngx_http_hello_module
#HTTP_MODULES表示定义HTTP_MODULES模块
HTTP_MODULES="$HTTP_MODULES ngx_http_hello_module"
#NGX_ADDON_SRCS 代表代码路径
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_module.c"
4. 补充ngx_http_hello_module.c
4.1 添加头文件
#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_config.h>
4.2 定义HTTP模块
/*
定义HTTP模块
*/
static ngx_command_t ngx_http_hello_commands[]={
{
ngx_string("hello"), //http服务模块名,这里需要和nginx.conf中一致
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,
ngx_http_hello, //hello模块的响应触发函数
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL
},
ngx_null_command
};
4.3 定义模块上下文信息
/* The module context. */
static ngx_http_module_t ngx_http_hello_module_ctx = {
NULL, /* 预配置 */
NULL, /* 后配置 */
NULL, /* 创建主配置 */
NULL, /* 初始化主配置 */
NULL, /* 创建服务配置 */
NULL, /* 合并服务配置 */
NULL, /* 创建本地配置 */
NULL, /* 合并本地配置 */
};
4.4 模块定义
ngx_module_t ngx_http_hello_module={
NGX_MODULE_V1,
&ngx_http_hello_module_ctx,
ngx_http_hello_commands,
NGX_HTTP_MODULE,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NGX_MODULE_V1_PADDING
};
4.5 定义模块触发函数
/*
定义模块触发函数
*/
static char* ngx_http_hello(ngx_conf_t *cf,ngx_command_t *cmd,void *conf)
{
ngx_http_core_loc_conf_t *clcf;
clcf = ngx_http_conf_get_module_loc_conf(cf,ngx_http_core_module);
clcf->handler = ngx_http_hello_handler; //此处的ngx_http_hello_handler()是真正的处理函数
return NGX_CONF_OK;
}
4.6 请求处理handler
/*
请求处理方法handler
*/
static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r)
{
ngx_buf_t *b;
ngx_chain_t out;
/*******************************设置报文内容************************/
ngx_str_t response;
response.data = (u_char*) "OK";
response.len = 3;
//为b分配空间
b = ngx_create_temp_buf(r->pool, response.len);
//将Hello World拷贝到ngx_buf_t指向的内存中
ngx_memcpy(b->pos, response.data, response.len);
//注意,一定要设置好last指针
b->last = b->pos + response.len;
//声明这是最后一块缓冲区
b->last_buf = 1;
/* 插入缓冲链。 */
out.buf = b;
out.next = NULL; /* just one buffer */
/*********************************修改报文头相关信息*****************/
/* 设置内容类型标题. */
r->headers_out.content_type.len = sizeof("text/plain") - 1;
r->headers_out.content_type.data = (u_char *)"text/plain";
/* 发送回复的标题. */
r->headers_out.status = NGX_HTTP_OK; /* 200 status code */
/* 获取正文的内容长度. */
r->headers_out.content_length_n = response.len - 1;
/********************************发送报文*************************/
//发送报文头部
ngx_http_send_header(r);
//发送报文内容:ngx_http_output_filter()是在连接r中发送out;
ngx_http_finalize_request(r, ngx_http_output_filter(r, &out));
}
4.7 大作业
#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_config.h>
static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r);
static char* ngx_http_hello(ngx_conf_t *cf,ngx_command_t *cmd,void *conf);
/*
定义HTTP模块
*/
static ngx_command_t ngx_http_hello_commands[]={
{
ngx_string("hello"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,
ngx_http_hello,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL
},
ngx_null_command
};
static ngx_http_module_t ngx_http_hello_module_ctx = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
ngx_module_t ngx_http_hello_module={
NGX_MODULE_V1,
&ngx_http_hello_module_ctx,
ngx_http_hello_commands,
NGX_HTTP_MODULE,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NGX_MODULE_V1_PADDING
};
/*
定义模块触发函数
*/
static char* ngx_http_hello(ngx_conf_t *cf,ngx_command_t *cmd,void *conf)
{
ngx_http_core_loc_conf_t *clcf;
clcf = ngx_http_conf_get_module_loc_conf(cf,ngx_http_core_module);
clcf->handler = ngx_http_hello_handler;
return NGX_CONF_OK;
}
static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r)
{
ngx_buf_t *b;
ngx_chain_t out;
/*******************************设置报文内容************************/
ngx_str_t response;
response.data = (u_char*) "OK";
response.len = 3;
//为b分配空间
b = ngx_create_temp_buf(r->pool, response.len);
//将Hello World拷贝到ngx_buf_t指向的内存中
ngx_memcpy(b->pos, response.data, response.len);
//注意,一定要设置好last指针
b->last = b->pos + response.len;
//声明这是最后一块缓冲区
b->last_buf = 1;
/* 插入缓冲链。 */
out.buf = b;
out.next = NULL; /* just one buffer */
/*********************************修改报文头相关信息*****************/
/* 设置内容类型标题. */
r->headers_out.content_type.len = sizeof("text/plain") - 1;
r->headers_out.content_type.data = (u_char *)"text/plain";
/* 发送回复的标题. */
r->headers_out.status = NGX_HTTP_OK; /* 200 status code */
/* 获取正文的内容长度. */
r->headers_out.content_length_n = response.len - 1;
/********************************发送报文*************************/
//发送报文头部
ngx_http_send_header(r);
//发送报文内容:ngx_http_output_filter()是在连接r中发送out;
ngx_http_finalize_request(r, ngx_http_output_filter(r, &out));
}
5. 配置nginx.conf
在server模块中添加或者修改
location /hello{
hello;
}
6.配置、编译、运行
6.1 配置
在源码的根目录下执行,此处路径就为config
和ngx_http_hello_module.c
的目录
./configure --add-module=/home/tianyiyi/nginx/nginx-1.19.6/extends/ngx_http_hello_module
6.2 编译
make && make install
6.3 执行
/usr/local/nginx/sbin/nginx -p /usr/local/nginx -c conf/nginx.conf