nginx学习笔记——http module分析
////// nginx/src/http/ngx_http.c //////// static ngx_int_t ngx_http_init_phases(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf) { if (ngx_array_init(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers, cf->pool, 1, sizeof(ngx_http_handler_pt)) != NGX_OK) { return NGX_ERROR; } ..... ..... if (ngx_array_init(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers, cf->pool, 1, sizeof(ngx_http_handler_pt)) != NGX_OK) { return NGX_ERROR; } return NGX_OK; } ///// nginx/src/http/modules/ngx_http_rewrite_module.c ///// static ngx_int_t ngx_http_rewrite_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); //在&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers指向的数组中申请一个函数指针空间 h = ngx_array_push(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers); if (h == NULL) { return NGX_ERROR; } //将函数添加到数组中新申请的元素中 *h = ngx_http_rewrite_handler; h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); if (h == NULL) { return NGX_ERROR; } *h = ngx_http_rewrite_handler; return NGX_OK; } ////// nginx/src/http/ngx_http.c //////// static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf) { cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1; cmcf->phase_engine.location_rewrite_index = (ngx_uint_t) -1; find_config_index = 0; use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0; use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0; n = use_rewrite + use_access + cmcf->try_files + 1 /* find config phase */; for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) { n += cmcf->phases[i].handlers.nelts; } //为phase ph = ngx_pcalloc(cf->pool, n * sizeof(ngx_http_phase_handler_t) + sizeof(void *)); if (ph == NULL) { return NGX_ERROR; } cmcf->phase_engine.handlers = ph; n = 0; for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) { h = cmcf->phases[i].handlers.elts; switch (i) { case NGX_HTTP_SERVER_REWRITE_PHASE: if (cmcf->phase_engine.server_rewrite_index == (ngx_uint_t) -1) { cmcf->phase_engine.server_rewrite_index = n; } //根据phase阶段确定每个阶段对应的checker checker = ngx_http_core_rewrite_phase; break; ..... ..... case NGX_HTTP_CONTENT_PHASE: checker = ngx_http_core_content_phase; break; default: checker = ngx_http_core_generic_phase; } n += cmcf->phases[i].handlers.nelts; //遍历各个phase handlers数组中的注册函数并统一添加到cmcf->phase_engine.handlers中 for (j = cmcf->phases[i].handlers.nelts - 1; j >=0; j--) { ph->checker = checker; ph->handler = h[j]; ph->next = n; ph++; } } return NGX_OK; } ///// nginx/src/http/ngx_http_core_module.c //////// void ngx_http_core_run_phases(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_phase_handler_t *ph; ngx_http_core_main_conf_t *cmcf; cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); ph = cmcf->phase_engine.handlers; while (ph[r->phase_handler].checker) { //根据请求中的phase索引确定执行的checker函数 //checker函数根据处理结果来决定是结束处理还是继续下一个phase rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]); if (rc == NGX_OK) { return; } } }
///// nginx/src/http/ngx_http_core_module.c /////// ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in) { ..... //通过链表接口来一次遍历各个filter模块进行处理 rc = ngx_http_top_body_filter(r, in); ..... return rc; } ///// nginx/src/http/ngx_http_copy_filter_module.c ////////// static ngx_int_t ngx_http_copy_filter_init(ngx_conf_t *cf) { ngx_http_next_body_filter = ngx_http_top_body_filter; ngx_http_top_body_filter = ngx_http_copy_filter; return NGX_OK; } static ngx_int_t ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in) { ..... ..... ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); if (ctx == NULL) { ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_copy_filter_module); //记录下一个要执行的filter ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_body_filter; ctx->filter_ctx = r; .... .... if (in && in->buf && ngx_buf_size(in->buf)) { r->request_output = 1; } } ..... rc = ngx_output_chain(ctx, in); ..... return rc; }
nginx学习笔记——http module分析的更多相关文章
- Nginx学习笔记4 源码分析
Nginx学习笔记(四) 源码分析 源码分析 在茫茫的源码中,看到了几个好像挺熟悉的名字(socket/UDP/shmem).那就来看看这个文件吧!从简单的开始~~~ src/os/unix/Ngx_ ...
- python学习笔记之module && package
个人总结: import module,module就是文件名,导入那个python文件 import package,package就是一个文件夹,导入的文件夹下有一个__init__.py的文件, ...
- UML和模式应用学习笔记-1(面向对象分析和设计)
UML和模式应用学习笔记-1(面向对象分析和设计) 而只是对情节的记录:此处的用例场景为:游戏者请求掷骰子.系统展示结果:如果骰子的总点数是7,则游戏者赢得游戏,否则为输 (2)定义领域模型:在领域模 ...
- Nginx学习笔记~目录索引
回到占占推荐博客索引 前几天整理了<Docker的学习笔记索引>,受到了很多朋友的关注,今天把Nginx的文章也整理一下,以后将永久更新,像大叔之前的<EF文章系列>,< ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- ArcGIS案例学习笔记4_2_水文分析批处理地理建模
ArcGIS案例学习笔记4_2_水文分析批处理地理建模 联系方式:谢老师,135_4855_4328,xiexiaokui#139.com 概述 计划时间:第4天下午 目的:自动化,批量化,批处理,提 ...
- ArcGIS案例学习笔记4_1_水文分析
ArcGIS案例学习笔记4_1_水文分析 联系方式:谢老师,135_4855_4328,xiexiaokui#139.com 概述 计划时间:第4天上午 教程: pdf page478 数据:实验数据 ...
- nginx 学习笔记(2) nginx新手入门
这篇手册简单介绍了nginx,并提供了一些可以操作的简单的工作.前提是nginx已经被安装到你的服务器上.如果没有安装,请阅读上篇:nginx 学习笔记(1) nginx安装.这篇手册主要内容:1. ...
- Nginx学习笔记之加强篇
在上一篇文章Nginx学习笔记之应用篇中,我们已经可以正式运行自己的网站了.但是在使用Nginx服务器时还需要注意几个问题: 1.Nginx服务器上配置的单个站点的并发量不超过1024 2.Nginx ...
随机推荐
- requireJS的配置心得
1.html页面中如果同时存在data-main和require()和配置(config中的baseUrl),那么定义根路径 baseUrl > data-main > index.htm ...
- SEO-关键词密度与友情链接交换技巧
关键词密度 关键词密度 关键词密度与关键词频率所阐述的实质上是同一个概念,用来量度关键词在网页上出现的总次数与其他文字的比例,一般用百分比表示.相对于页面总字数而言,关键词出现的频率越高,关键词密度也 ...
- PHP无锁内存nosql---Yac的实战
无锁内存nosql---Yac的实战 最近在工作使用了yac,所以比较了下Memcache和Yac的高并发读写性能测试,发现Yac要比Memcache快很多(这里没有比较Yac和Apc的性能情况, 不 ...
- Rabbitmq 性能测试
背景: 线上环境,出了一起事故,初步定位是rabbitmq server. 通过抓包发现,是有多个应用使用同一台rabbitmq server.并且多个应用使用rabbitmq的方式也不一样.发现有以 ...
- Angular企业级开发(9)-前后端分离之后添加验证码
1.背景介绍 团队开发的项目,前端基于Bootstrap+AngularJS,后端Spring MVC以RESTful接口给前端调用.开发和部署都是前后端分离.项目简单部署图如下,因为后台同时采用微服 ...
- require和include的区别及自动加载的定义
//引入文件//require与include的区别://include主要是指引入,如果引入的文件出现错误,则程序停止运行//require主要是指请求,如果请求的文件出现错误,则程序不受影响,继续 ...
- H5 Canvas vs. SVG
HTML 5 Canvas vs. SVG HTML5 SVG HTML5 地理定位 Canvas 和 SVG 都允许您在浏览器中创建图形,但是它们在根本上是不同的. SVG SVG 是一种使用 XM ...
- Mac下tomcat配置ssl
最近在搞单点登录CAS,第一步就是需要给tomcat配置证书.但是,第一次配置就遇到了个问题排插了一下午.下面来存一份文档,以备以后遇到. 一.首先准备好环境 java环境:配置好环境变量,找到jdk ...
- quartz笔记
首先网络上的很多教程经常有错(信息过载了),其主要原因是版本发生了变化,例如quartz1和2之间还是有不少差别的,导致查找资料的人浪费了不少时间.所以无论教程如何写,都建议读者首先学习官网的教程,如 ...
- iOS开发之视频播放
1.如何播放视频 iOS提供了MPMoviePlayerController.MPMoviePlayerViewController两个类,可以用来轻松播放视频和网络流媒体\网络音频. 提示:网络音频 ...