百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Nginx基础入门006(nginx 实战教程)

nanshan 2024-10-22 12:57 12 浏览 0 评论

这个社会,是赢家通吃,输者一无所有,社会,永远都是只以成败论英雄。

  • 上一篇:ailx10:Nginx基础入门005 ;

ailx10

网络安全优秀回答者

网络安全硕士

如何定义自己的HTTP模块?

首先问自己:

  • 我希望自己的模块在哪个时刻开始处理请求?
  • 是希望自己的模块对到达Nginx的所有请求都起作用?
  • 还是希望只对某一类请求(URL匹配了location后表达式的请求)起作用?

mytest模块:

  • 定义mytest模块
ngx_module_t ngx_http_mytest_module = {  
    NGX_MODULE_V1,  
    &ngx_http_mytest_module_ctx,  
    ngx_http_mytest_commands,  
    NGX_HTTP_MODULE,  
    NULL,  
    NULL,  
    NULL,  
    NULL,  
    NULL,  
    NULL,  
    NULL,  
    NGX_MODULE_V1_PADDING  
};  
  • 定义ctx指针
static ngx_http_module_t ngx_http_mytest_module_ctx = {  
    NULL,  
    NULL,  
    NULL,  
    NULL,  
    NULL,  
    NULL,  
    NULL,  
    NULL  
};
  • 定义command指针

当在某个配置块中出现mytest配置项时,Nginx将会调用ngx_http_mytest方法。

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     
};
  • set函数的实现,解析配置文件

首先找到mytest配置项所属的配置块。

clcf看上去像是location块内的数据结构,其实,它可以是main、srv或者loc级别配置项。

也就是说,在每个http{}和server{}内也都有一个ngx_http_core_loc_conf_t结构体。

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;  
}
  • 配置的处理函数实现

HTTP框架在接收完HTTP请求的头部后,会调用handler指向的方法。

static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r)  
{  
    if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) {  
        return NGX_HTTP_NOT_ALLOWED;  
    }  

    ngx_int_t rc = ngx_http_discard_request_body(r);  
    //如果不想处理请求中的包体,那么可以调用ngx_http_discard_request_body方法将接收自客户端的HTTP包体丢弃掉。
    if (rc != NGX_OK) {  
        return rc;  
    }  
  
    // Send response header  
    ngx_str_t type = ngx_string("text/plain");  
    ngx_str_t response = ngx_string("Hello World!");  
    r->headers_out.status = NGX_HTTP_OK;  
    r->headers_out.content_length_n = response.len;  
    r->headers_out.content_type = type;  

    /*
    请求处理完毕后,需要向用户发送HTTP响应,告知客户端Nginx的执行结果。HTTP响应主要包括响应行、响应头部、包体三部分。
    发送HTTP响应时需要执行发送HTTP头部(发送HTTP头部时也会发送响应行)和发送HTTP包体两步操作。
    */
    rc = ngx_http_send_header(r);  
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {  
        return rc;  
    }  
    // Send response body  
    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;  

    return ngx_http_output_filter(r, &out);  
}  

Nginx HTTP处理的11个阶段:

各个阶段的http框架check函数见ngx_http_init_phase_handlers ,所有阶段的checker在ngx_http_core_run_phases中调用。

  • NGX_HTTP_POST_READ_PHASE
//在接收到完整的HTTP头部后处理的HTTP阶段   主要是获取客户端真实IP,因为客户端到nginx可能通过了vanish等缓存,
//ngx_http_realip_module(ngx_http_realip_init->ngx_http_realip_handler)
NGX_HTTP_POST_READ_PHASE = 0, //该阶段方法有:ngx_http_realip_handler  POST有"在....后"的意思,POST_READ应该就是在解析完请求行和头部行后
  • NGX_HTTP_SERVER_REWRITE_PHASE
/*在还没有查询到URI匹配的location前,这时rewrite重写URL也作为一个独立的HTTP阶段   Server内请求地址重写阶段 */
NGX_HTTP_SERVER_REWRITE_PHASE, //该阶段handler方法有:ngx_http_rewrite_module(ngx_http_rewrite_init->ngx_http_rewrite_handler) 
  • NGX_HTTP_FIND_CONFIG_PHASE
/*根据URI寻找匹配的location,这个阶段通常由ngx_http_core_module模块实现,不建议其他HTTP模块重新定义这一阶段的行为*/
NGX_HTTP_FIND_CONFIG_PHASE,//该阶段handler方法有:无,不允许用户添加hander方法在该阶段  该阶段完成的是Nginx的特定任务,即进行Location定位
  • NGX_HTTP_REWRITE_PHASE
//在NGX_HTTP_FIND_CONFIG_PHASE阶段寻找到匹配的location之后再修改请求的URI  Location内请求地址重写阶段
/*在NGX_HTTP_FIND_CONFIG_PHASE阶段之后重写URL的意义与NGX_HTTP_SERVER_REWRITE_PHASE阶段显然是不同的,因为这两者会导致查找到不同的location块(location是与URI进行匹配的)*/
NGX_HTTP_REWRITE_PHASE,//该阶段handler方法有:ngx_http_rewrite_handler
  • NGX_HTTP_POST_REWRITE_PHASE
/*这一阶段是用于在rewrite重写URL后,防止错误的nginx.conf配置导致死循环(递归地修改URI),因此,这一阶段仅由ngx_http_core_module模块处理。
目前,控制死循环的方式很简单,首先检查rewrite的次数,如果一个请求超过10次重定向,扰认为进入了rewrite死循环,这时在NGX_HTTP_POSTREWRITE_PHASE
阶段就会向用户返回500,表示服务器内部错误*/
NGX_HTTP_POST_REWRITE_PHASE,//该阶段handler方法有:无,不允许用户添加hander方法在该阶段
  • NGX_HTTP_PREACCESS_PHASE
/* NGX_HTTP_PRE_ACCESS_PHASE、NGX_HTTP_ACCESS_PHASE、NGX_HTTP_POST_ACCESS_PHASE,很好理解,做访问权限检查的前期、中期、后期工作,
其中后期工作是固定的,判断前面访问权限检查的结果(状态码存故在字段r->access_code内),如果当前请求没有访问权限,那么直接返回状
态403错误,所以这个阶段也无法去挂载额外的回调函数。*/
//处理NGX_HTTP_ACCESS_PHASE阶段前,HTTP模块可以介入的处理阶段
NGX_HTTP_PREACCESS_PHASE,//该阶段handler方法有:ngx_http_degradation_handler  ngx_http_limit_conn_handler  ngx_http_limit_req_handler ngx_http_realip_handler
  • NGX_HTTP_ACCESS_PHASE
/*这个阶段用于让HTTP模块判断是否允许这个请求访问Nginx服务器*/
NGX_HTTP_ACCESS_PHASE,//该阶段handler方法有:ngx_http_access_handler  ngx_http_auth_basic_handler  ngx_http_auth_request_handler
  • NGX_HTTP_POST_ACCESS_PHASE
/*当NGX_HTTP_ACCESS_PHASE阶段中HTTP模块的handler处理方法返回不允许访问的错误码时(实际是NGX_HTTP_FORBIDDEN或者NGX_HTTP_UNAUTHORIZED),
这个阶段将负责构造拒绝服务的用户响应。所以,这个阶段实际上用于给NGX_HTTP_ACCESS_PHASE阶段收尾*/
NGX_HTTP_POST_ACCESS_PHASE,//该阶段handler方法有:无,不允许用户添加hander方法在该阶段
  • NGX_HTTP_TRY_FILES_PHASE
/*这个阶段完全是为了try_files配置项而设立的。当HTTP请求访问静态文件资源时,try_files配置项可以使这个请求顺序地访问多个静态文件资源,
如果某一次访问失败,则继续访问try_files中指定的下一个静态资源。另外,这个功能完全是在NGX_HTTP_TRY_FILES_PHASE阶段中实现的*/
NGX_HTTP_TRY_FILES_PHASE,//该阶段handler方法有:无,不允许用户添加hander方法在该阶段
  • NGX_HTTP_CONTENT_PHASE
/* 其余10个阶段中各HTTP模块的处理方法都是放在全局的ngx_http_core_main_conf_t结构体中的,
也就是说,它们对任何一个HTTP请求都是有效的,NGX_HTTP_CONTENT_PHASE 仅仅针对某种请求唯一生效。
ngx_http_handler_pt处理方法不再应用于所有的HTTP请求,仅仅当用户请求的URI匹配了location时(也就是mytest配置项所在的location)才会被调用。
这也就意味着它是一种完全不同于其他阶段的使用方式。 因此,当HTTP模块实现了某个ngx_http_handler_pt处理方法并希望介入NGX_HTTP_CONTENT_PHASE阶
段来处理用户请求时,如果希望这个ngx_http_handler_pt方法应用于所有的用户请求,则应该在ngx_http_module_t接口的postconfiguration方法中,
向ngx_http_core_main_conf_t结构体的phases[NGX_HTTP_CONTENT_PHASE]动态数组中添加ngx_http_handler_pt处理方法;反之,如果希望这个方式
仅应用于URI匹配丁某些location的用户请求,则应该在一个location下配置项的回调方法中,把ngx_http_handler_pt方法设置到ngx_http_core_loc_conf_t
结构体的handler中。
    注意ngx_http_core_loc_conf_t结构体中仅有一个handler指针,它不是数组,这也就意味着如果采用上述的第二种方法添加ngx_http_handler_pt处理方法,
那么每个请求在NGX_HTTP_CONTENT PHASE阶段只能有一个ngx_http_handler_pt处理方法。而使用第一种方法时是没有这个限制的,NGX_HTTP_CONTENT_PHASE阶
段可以经由任意个HTTP模块处理。 */
//用于处理HTTP请求内容的阶段,这是大部分HTTP模块最喜欢介入的阶段  //CONTENT_PHASE阶段的处理回调函数ngx_http_handler_pt比较特殊,见ngx_http_core_content_phase 
 NGX_HTTP_CONTENT_PHASE, //该阶段handler方法有:ngx_http_autoindex_handler  ngx_http_dav_handler ngx_http_gzip_static_handler  ngx_http_index_handler ngx_http_random_index_handler ngx_http_static_handler 
  • NGX_HTTP_LOG_PHASE
/*处理完请求后记录日志的阶段。例如,ngx_http_log_module模块就在这个阶段中加入了一个handler处理方法,使得每个HTTP请求处理完毕后会记录access_log日志*/
NGX_HTTP_LOG_PHASE //该阶段handler方法有: ngx_http_log_handler


博主ailx10 正在疯狂学习 觉得好的话 点个关注? .... bling ~

相关推荐

F5负载均衡器如何通过irules实现应用的灵活转发?

F5是非常强大的商业负载均衡器。除了处理性能强劲,以及高稳定性之外,F5还可以通过irules编写强大灵活的转发规则,实现web业务的灵活应用。irules是基于TCL语法的,每个iRules必须包含...

映射域名到NAS

前面介绍已经将域名映射到家庭路由器上,现在只需要在路由器上设置一下端口转发即可。假设NAS在内网的IP是192.168.1.100,NAS管理端口2000.你的域名是www.xxx.com,配置外部端...

转发(Forward)和重定向(Redirect)的区别

转发是服务器行为,重定向是客户端行为。转发(Forward)通过RequestDispatcher对象的forward(HttpServletRequestrequest,HttpServletRe...

SpringBoot应用中使用拦截器实现路由转发

1、背景项目中有一个SpringBoot开发的微服务,经过业务多年的演进,代码已经累积到令人恐怖的规模,亟需重构,将之拆解成多个微服务。该微服务的接口庞大,调用关系非常复杂,且实施重构的人员大部分不是...

公司想搭建个网站,网站如何进行域名解析?

域名解析是将域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务。IP地址是网络上标识站点的数字地址,为方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转...

域名和IP地址什么关系?如何通过域名解析IP?

一般情况下,访客通过域名和IP地址都能访问到网站,那么两者之间有什么关系吗?本文中科三方针对域名和IP地址的关系和区别,以及如何实现域名与IP的绑定做下介绍。域名与IP地址之间的关系IP地址是计算机的...

分享网站域名301重定向的知识

网站域名做301重定向操作时,一般需要由专业的技术来协助完成,如果用户自己在维护,可以按照相应的说明进行操作。好了,下面说说重点,域名301重定向的操作步骤。首先,根据HTTP协议,在客户端向服务器发...

NAS外网到底安全吗?一文看懂HTTP/HTTPS和SSL证书

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:可爱的小cherry搭好了NAS,但是不懂做好网络加密,那么隐私泄露也会随时发生!大家好,这里是Cherry,喜爱折腾、玩数码,热衷于分享数...

ForwardEmail免费、开源、加密的邮件转发服务

ForwardEmail是一款免费、加密和开源的邮件转发服务,设置简单只需4步即可正常使用,通过测试来看也要比ImprovMX好得多,转发近乎秒到且未进入垃圾箱(仅以Mailbox.org发送、Out...

使用CloudFlare进行域名重定向

当网站变更域名的时候,经常会使用域名重定向的方式,将老域名指向到新域名,这通常叫做:URL转发(URLFORWARDING),善于使用URL转发,对SEO来说非常有用,因为用这种方式能明确告知搜索引...

要将端口5002和5003通过Nginx代理到一个域名上的操作笔记

要将端口5002和5003通过Nginx代理到域名www.4rvi.cn的不同路径下,请按照以下步骤配置Nginx:步骤说明创建或编辑Nginx配置文件通常配置文件位于/etc/nginx/sites...

SEO浅谈:网站域名重定向的三种方式

在大多数情况下,我们输入网站访问网站的时候,很难发现www.***.com和***.com的区别,因为一般的网站主,都会把这两个域名指向到同一网站。但是对于网站运营和优化来说,www.***.com和...

花生壳出现诊断域名与转发服务器ip不一致的解决办法

出现诊断域名与转发服务器ip不一致您可以:1、更改客户端所处主机的drs为223.5.5.5备用dns为119.29.29.29;2、在windows上进入命令提示符输入ipconfig/flush...

涨知识了!带你认识什么是域名

1、什么是域名从技术角度来看,域名是在Internet上解决IP地址对应的一种方法。一个完整的域名由两个或两个以上部分组成,各部分之间用英文的句号“.”来分隔。如“abc.com”。其中“com”称...

域名被跳转到其他网站是怎么回事

当你输入域名时被跳转到另一个网站,这可能是由几种原因造成的:一、域名可能配置了域名转发服务。无论何时有人访问域名,比如.com、.top等,都会自动重定向到另一个指定的URL,这通常是在域名注册商设...

取消回复欢迎 发表评论: