基于ngxin一个http模板

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 基于ngxin一个http模板,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

1.初始化

static char *
ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r);



static ngx_command_t  ngx_http_mytest_commands[] =
{

    {
        ngx_string("mytest"),
        NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS,
        ngx_http_mytest,
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        NULL
    },

    ngx_null_command
};

static ngx_http_module_t  ngx_http_mytest_module_ctx =
{
    NULL,                              /* preconfiguration */
    NULL,                  		/* postconfiguration */

    NULL,                              /* create main configuration */
    NULL,                              /* init main configuration */

    NULL,                              /* create server configuration */
    NULL,                              /* merge server configuration */

    NULL,       			/* create location configuration */
    NULL         			/* merge location configuration */
};

ngx_module_t  ngx_http_mytest_module =
{
    NGX_MODULE_V1,
    &ngx_http_mytest_module_ctx,           /* module context */
    ngx_http_mytest_commands,              /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};

1.解析 command

commands数组用于定义模块的配置文件参数,每一个数组元素都是ngx_command_t类型,数组的结尾用ngx_null_command表示。Nginx在解析配置文件中的一个配置项时首先会遍历所有的模块,对于每一个模块而言,即通过遍历commands数组进行,另外,在数组中检查到ngx_null_command时,会停止使用当前模块解析该配置项。每一个ngx_command_t结构体定义了自己感兴趣的一个配置项:

其余参考定义一个自己的http模板_编程界的谢菲尔德的博客-CSDN博客

2.回调实现
 

static char *
ngx_http_mytest(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_mytest_handler;

    return NGX_CONF_OK;
}


static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r)
{

// 必须是GET或者HEAD方法,否则返回405 Not Allowed
    
    if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD)))
    {
        return NGX_HTTP_NOT_ALLOWED;
    }
// 丢弃请求中的包体
   
    ngx_int_t rc = ngx_http_discard_request_body(r);
    if (rc != NGX_OK)
    {
        return rc;
    }
/*设置返回的Content-Type。注意,ngx_str_t有一个很方便的初始化宏
ngx_string,它可以把ngx_str_t的data和len成员都设置好*/
  
    ngx_str_t type = ngx_string("text/plain");

//返回的包体内容
    
    ngx_str_t response = ngx_string("Hello World!");
// 设置返回状态码
   
    r->headers_out.status = NGX_HTTP_OK;
// 响应包是有包体内容的,需要设置Content-Length长度

    
    r->headers_out.content_length_n = response.len;
// 设置Content-Type
 
 
    r->headers_out.content_type = type;

    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only)
    {
        return rc;
    }
   //构造ngx_buf_t结构体准备发送包

    ngx_buf_t                 *b;
    b = ngx_create_temp_buf(r->pool, response.len);
    if (b == NULL)
    {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
  
    ngx_memcpy(b->pos, response.data, response.len);

    b->last = b->pos + response.len;//这是最后一块缓冲区
 
    b->last_buf = 1;

  
    ngx_chain_t		out;
    
    out.buf = b;
   
    out.next = NULL;
/*最后一步为发送包体,发送结束后 HTTP框架会调用ngx_http_finalize_request方法结束请求*/
   
    return ngx_http_output_filter(r, &out);
}

1.ngx_http_mytest

.ngx_http_mytest是ngx_command_t结构体中的set成员(完整定义为char*(*set(ngx_conf_t*cf,ngx_command_t*cmd,void*conf);)当在某个配置块中出现mytest配置项时

nginx将会调用ngx_http_mytest方法

2.ngx_http_core_loc_conf_t:首先找到mytest配置项所属的配置块,clcf看上去像是location块内的数据结构,其实不然,它可以是main、srv或者loc级别配置项,也就是说,在每个http{}和server{}内也都有一个ngx_http_core_loc_conf_t结构体

3. HTTP框架在处理用户请求进行到NGX_HTTP_CONTENT_PHASE阶段时,如果请求的主机域名、URI与mytest配置项所在的配置块相匹配,就将调用我们实现的ngx_http_mytest_handler方法处理这个请求

2.static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r)

1.Content-Type(MediaType),即是Internet Media Type,互联网媒体类型,也叫做MIME类型。在互联网中有成百上千中不同的数据类型,HTTP在传输数据对象时会为他们打上称为MIME的数据格式标签,用于区分数据类型

2.内存问题:

基于ngxin一个http模板

分配完内存后,可以向这段内存写入数据。当写完数据后,要让b->last指针指向数据的 末尾,如果b->last与b->pos相等,那么HTTP框架是不会发送一个字节的包体的。

note:

注意 在向用户发送响应包体时,必须牢记Nginx是全异步的服务器,也就是说,不 可以在进程的栈里分配内存并将其作为包体发送。当一直ngx_http_output_filter方法返回时, 可能由于TCP连接上的缓冲区还不可写,所以导致ngx_buf_t缓冲区指向的内存还没有发送, 可这时方法返回已把控制权交给Nginx了,又会导致栈里的内存被释放,最后就会造成内存 越界错误。因此,在发送响应包体时,尽量将ngx_buf_t中的pos指针指向从内存池里分配的 内存。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/129616.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!