从零手写实现 nginx-22-modules 模块配置加载

前言

大家好,我是老马。很高兴遇到你。

我们为 java 开发者实现了 java 版本的 nginx

https://github.com/houbb/nginx4j

如果你想知道 servlet 如何处理的,可以参考我的另一个项目:

手写从零实现简易版 tomcat minicat

手写 nginx 系列

如果你对 nginx 原理感兴趣,可以阅读:

从零手写实现 nginx-01-为什么不能有 java 版本的 nginx?

从零手写实现 nginx-02-nginx 的核心能力

从零手写实现 nginx-03-nginx 基于 Netty 实现

从零手写实现 nginx-04-基于 netty http 出入参优化处理

从零手写实现 nginx-05-MIME类型(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)

从零手写实现 nginx-06-文件夹自动索引

从零手写实现 nginx-07-大文件下载

从零手写实现 nginx-08-范围查询

从零手写实现 nginx-09-文件压缩

从零手写实现 nginx-10-sendfile 零拷贝

从零手写实现 nginx-11-file+range 合并

从零手写实现 nginx-12-keep-alive 连接复用

从零手写实现 nginx-13-nginx.conf 配置文件介绍

从零手写实现 nginx-14-nginx.conf 和 hocon 格式有关系吗?

从零手写实现 nginx-15-nginx.conf 如何通过 java 解析处理?

从零手写实现 nginx-16-nginx 支持配置多个 server

从零手写实现 nginx-17-nginx 默认配置优化

从零手写实现 nginx-18-nginx 请求头+响应头操作

从零手写实现 nginx-19-nginx cors

从零手写实现 nginx-20-nginx 占位符 placeholder

从零手写实现 nginx-21-nginx modules 模块信息概览

从零手写实现 nginx-22-nginx modules 分模块加载优化

从零手写实现 nginx-23-nginx cookie 的操作处理

从零手写实现 nginx-24-nginx IF 指令

前言

大家好,我是老马。

这一节我们将配置的加载,拆分为不同的模块加载处理,便于后续拓展。

核心实现

/*** 细化为不同的组件读取** @since 0.18.0* @author 老马啸西风*/
public  class NginxUserConfigLoaderConfigComponentFile extends AbstractNginxUserConfigLoader {private final String filePath;public NginxUserConfigLoaderConfigComponentFile(String filePath) {this.filePath = filePath;}@Overrideprotected NginxUserConfig doLoad() {NgxConfig conf = null;try {conf = NgxConfig.read(filePath);NginxUserConfigBs configBs = NginxUserConfigBs.newInstance();//1. basicINginxUserMainConfigLoad mainConfigLoad = new NginxUserMainConfigLoadFile(conf);NginxUserMainConfig mainConfig = mainConfigLoad.load();configBs.mainConfig(mainConfig);//2. eventsINginxUserEventsConfigLoad eventsConfigLoad = new NginxUserEventsConfigLoadFile(conf);NginxUserEventsConfig eventsConfig = new NginxUserEventsConfig();configBs.eventsConfig(eventsConfig);//3. server 信息// 首先获取 blockList<NgxEntry> servers = conf.findAll(NgxConfig.BLOCK, "http", "server"); // 示例3if(CollectionUtil.isNotEmpty(servers)) {for (NgxEntry entry : servers) {// 每一个 server 的处理NgxBlock ngxBlock = (NgxBlock) entry;final INginxUserServerConfigLoad serverConfigLoad = new NginxUserServerConfigLoadFile(conf, ngxBlock);NginxUserServerConfig serverConfig = serverConfigLoad.load();configBs.addServerConfig(serverConfig);}}// 返回return configBs.build();} catch (IOException e) {throw new RuntimeException(e);}}}

然后每一个模块,都有对应的子实现。

我们以 server 为例。

NginxUserServerConfigLoadFile

package com.github.houbb.nginx4j.config.load.component.impl;import com.github.houbb.heaven.util.lang.StringUtil;
import com.github.houbb.heaven.util.util.CollectionUtil;
import com.github.houbb.nginx4j.bs.NginxUserServerConfigBs;
import com.github.houbb.nginx4j.config.NginxCommonConfigParam;
import com.github.houbb.nginx4j.config.NginxUserServerConfig;
import com.github.houbb.nginx4j.config.NginxUserServerLocationConfig;
import com.github.houbb.nginx4j.config.load.component.INginxUserServerConfigLoad;
import com.github.houbb.nginx4j.config.load.component.INginxUserServerLocationConfigLoad;
import com.github.houbb.nginx4j.constant.NginxLocationPathTypeEnum;
import com.github.houbb.nginx4j.constant.NginxUserServerConfigDefaultConst;
import com.github.odiszapc.nginxparser.NgxBlock;
import com.github.odiszapc.nginxparser.NgxConfig;
import com.github.odiszapc.nginxparser.NgxEntry;
import com.github.odiszapc.nginxparser.NgxParam;import java.util.*;/*** @since 0.18.0*/
public class NginxUserServerConfigLoadFile implements INginxUserServerConfigLoad {private final NgxConfig conf;private final NgxBlock serverBlock;public NginxUserServerConfigLoadFile(NgxConfig conf, NgxBlock serverBlock) {this.conf = conf;this.serverBlock = serverBlock;}@Overridepublic NginxUserServerConfig load() {NginxUserServerConfigBs serverConfigBs = NginxUserServerConfigBs.newInstance();String name = serverBlock.getName();int httpServerPort = getHttpServerListen(conf, serverBlock);String httpServerName = getHttpServerName(conf, serverBlock);String httpServerRoot = getHttpServerRoot(conf, serverBlock);List<String> httpIndexList = getHttpServerIndexList(conf, serverBlock);// sendfile on;String sendFile = getHttpServerSendFile(conf, serverBlock);//gzipString gzip = getHttpServerGzip(conf, serverBlock);long gzipMinLen = getHttpServerGzipMinLen(conf, serverBlock);List<String> gzipTypes = getHttpServerGzipTypes(conf, serverBlock);// 添加 locationList<NginxUserServerLocationConfig> locationConfigList = getHttpServerLocationList(conf, serverBlock);NginxUserServerLocationConfig defaultLocationConfig = getDefaultLocationConfig(locationConfigList);serverConfigBs.httpServerName(httpServerName).httpServerListen(httpServerPort).httpServerRoot(httpServerRoot).httpServerIndexList(httpIndexList).sendFile(sendFile).gzip(gzip).gzipMinLength(gzipMinLen).gzipTypes(gzipTypes).locationConfigList(locationConfigList).defaultLocationConfig(defaultLocationConfig);return serverConfigBs.build();}// 各种实现private List<NginxUserServerLocationConfig> getHttpServerLocationList(final NgxConfig conf, final NgxBlock serverBlock) {List<NginxUserServerLocationConfig> resultList = new ArrayList<>();// valueList<NgxEntry> entryList = serverBlock.findAll(NgxBlock.class, "location");if(CollectionUtil.isNotEmpty(entryList)) {for(NgxEntry entry : entryList) {NgxBlock ngxBlock = (NgxBlock) entry;// 参数// location 的处理final INginxUserServerLocationConfigLoad locationConfigLoad = new NginxUserServerLocationConfigLoadFile(conf, ngxBlock);NginxUserServerLocationConfig locationConfig = locationConfigLoad.load();resultList.add(locationConfig);}}// 排序。按照匹配的优先级,从高到底排序if(CollectionUtil.isNotEmpty(resultList)) {Collections.sort(resultList, new Comparator<NginxUserServerLocationConfig>() {@Overridepublic int compare(NginxUserServerLocationConfig o1, NginxUserServerLocationConfig o2) {return o1.getTypeEnum().getOrder() - o2.getTypeEnum().getOrder();}});}return resultList;}}

因为 server 中,又涉及到 location 子模块,这里继续让 NginxUserServerLocationConfigLoadFile 来处理具体的逻辑。

小结

模块的加载拆分为不同的模块加载后,我们暂时实现了其中的部分。

后续有时间再实现更多的配置信息。

我是老马,期待与你的下次重逢。

开源地址

为了便于大家学习,已经将 nginx 开源

https://github.com/houbb/nginx4j

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/27106.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DETR实现目标检测(二)-利用自己训练的模型进行预测

1、图片预测&#xff08;CPU&#xff09; 关于DETR模型训练自己的数据集参考上篇文章&#xff1a; DETR实现目标检测(一)-训练自己的数据集-CSDN博客 训练完成后的模型文件保存位置如下&#xff1a; 准备好要预测的图片&#xff1a; 然后直接调用模型进行预测&#xff0c;并设…

linux部署运维3——centos7.9离线安装部署配置涛思taos2.6时序数据库TDengine以及java项目链接问题处理(二)

上一篇讲了centos7.9如何安装涛思taos2.6时序数据库的操作步骤和方案&#xff0c;本篇主要讲解taos数据库的初始化&#xff0c;相关配置说明&#xff0c;数据库和表的创建问题以及java项目连接问题。 centos7.9如何离线安装taos2.6&#xff0c;请点击下方链接详细查看&#xf…

React的@reduxjs/toolkit的异步方法处理和实现

一、使用异步方法,需要 createAsyncThunk 函数 1.首先在特定的ts文件中建立异步 const fetchArticles=createAsyncThunk(searchArticle/fetchArticles,async({SearchKey,type},thunkAPI)=>{const params = {Filter: SearchKey,PageSize: 10,PageNum: 1,ArticleType: &quo…

YOLOv5改进 | Head | 将yolov5的检测头替换为ASFF_Detect

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 在目标检测中&#xff0c;为了解决尺度变化的问题&#xff0c;通常采用金字塔特征表示。然而&#xff0c;对于基于特征金字塔的单次检测器来…

Python中的pass语句

在Python编程语言中&#xff0c;pass是一个特殊的语句&#xff0c;它并不执行任何操作&#xff0c;仅仅用作占位符。当我们在编写代码时&#xff0c;有时需要定义一个空的代码块或函数&#xff0c;但又不想立即实现它&#xff0c;这时候pass语句就派上了用场。pass语句可以帮助…

h5页面上传图片安卓手机无法调用摄像头

<input type”file”> 在ios中&#xff0c;会 而安卓中&#xff0c;没有这些选项 解决方法&#xff1a; 给input 加上accept属性 <input type”file” accept”image/*” /> //调用相机 &#xff0c;图片或者相册 &#xff08;两者都行&#xff09; 加上了cap…

MYSQL 查看SQL执行计划

一、explain explain select id,db,user,host,command,time,state,info from information_schema.processlist order by time desc; id: 查询的标记&#xff0c;可以查看不同查询的执行顺序。 select_type: 查询的类型&#xff0c;如SIMPLE、SUBQUERY、PRIMARY等。 table: …

本地Zabbix开源监控系统安装内网穿透实现远程访问详细教程

文章目录 前言1. Linux 局域网访问Zabbix2. Linux 安装cpolar3. 配置Zabbix公网访问地址4. 公网远程访问Zabbix5. 固定Zabbix公网地址 &#x1f4a1;推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【…

web前端按值传递:深入剖析与探索

web前端按值传递&#xff1a;深入剖析与探索 在Web前端开发中&#xff0c;按值传递是一种重要的参数传递方式。然而&#xff0c;其背后的机制、影响以及在实际应用中的使用技巧&#xff0c;往往让开发者感到困惑。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;…

Ollama在windows上的设置

下载 Download Ollama on macOS 安装&#xff1a;是不可以选择安装路径&#xff0c;系统自动运行&#xff0c;不启动模型不占用GPU 参数设置&#xff1a;windows添加环境变量&#xff08;需要重启ollama&#xff09; 修改模型位置&#xff1a;添加 OLLAMA_MODELS D:\LLM\Oll…

【必会面试题】TCP协议的粘包拆包

目录 TCP数据报文结构粘包拆包如何处理粘包和拆包 TCP协议的粘包和拆包是数据传输过程中常见的现象&#xff0c;它们不是TCP协议本身的设计目的&#xff0c;而是基于TCP协议的特性自然产生的结果。 TCP数据报文结构 字段名English Name长度&#xff08;比特&#xff09;描述源…

军用FPGA软件 Verilog语言的编码准测之时钟

军用FPGA软件 Verilog语言的编码准测之时钟 语言 &#xff1a;Verilg HDL EDA工具&#xff1a;ISE、Vivado、Quartus II 军用FPGA软件 Verilog语言的编码准测之时钟一、引言二、基本编程规范之时钟强制准则1----禁止将寄存器的输出直接连接到其他寄存器的时钟管脚。强制准则2--…

ADOQuery中使用Resync解决读取lookup数据不正确的问题

在使用 Delphi2007 的ADOQuery时&#xff0c;遇到一个看到的数据与读取 lookup 数据不一样的问题。 使用 MSSQL数据。有一个存储过程。使用ADOQuery&#xff08;QTY1)获取返回的数据。 如&#xff1a; ID NAME MACHINE QTY 1 JOE XL75…

算法day28

第一题 295. 数据流的中位数 本题我们是求解给定数组的中位数。且由于需要随时给数组添加元素&#xff0c;所以我们要求解该动态数组的中位数&#xff0c;所以本题最关键的就是维护数组在添加元素之后保持有序的排序&#xff0c;这样就能很快的求解中位数&#xff1b; 解法&am…

广州酒吧安全管理:蓝牙可燃气体报警器的实践与检定

随着现代都市生活的丰富多样&#xff0c;酒吧已成为人们休闲娱乐的重要场所。然而&#xff0c;酒吧内大量使用的燃气设备也带来了不小的安全隐患。 如何在确保顾客享受愉悦时光的同时&#xff0c;保障他们的生命财产安全&#xff0c;成为广州各大酒吧经营者亟待解决的问题。 …

通过语言大模型来学习tensorflow框架训练模型(三)

一、模型训练5步骤走 1.数据获取&#xff0c;2&#xff0c;数据处理&#xff0c;3.模型创建与训练&#xff0c;4 模型测试与评估&#xff0c;5.模型预测 二、tensorflow数据获取 在TensorFlow中&#xff0c;数据获取和预处理是构建深度学习模型的重要步骤。TensorFlow提供了多…

Linux之history历史指令查看

Linux之history历史指令查看 history命令用来查看曾经输出过的命令。 命令格式 history [选项]选项 n 显示最近条记录 -c 清除历史记录&#xff0c;但是此项清除只是清除当前shell&#xff0c;从新连接还是有历史记录显示命令时间设置 命令history显示时间戳。此命令只是临…

每日一练:攻防世界:北京地铁

首先是找图片隐写 在这里可以看到一串类似base64格式的字符串 再结合题目&#xff0c;这应该就是明文了&#xff0c;要AES解密&#xff0c;还需要密钥&#xff0c;提示要看图片本身&#xff0c;那密钥可能藏在里面&#xff0c;找了半天没找到&#xff0c;参考师傅的wp&#x…

外盘黄金期货需要注意什么?

为大家整理了关于黄金做单的五大原则&#xff0c;相信对于新手投资者来说肯定会产生一定的帮助。  1、看多空&#xff1a;主要有两种方法&#xff0c;基本面判断和技术面判断&#xff0c;基本面判断&#xff0c;主要是借助基本信息面&#xff0c;如政策。供需&#xff0c;产量…

idea远程调试docker容器内正在运行的线上项目

1.重新编写Dockerfile文件 在原本的Dockerfile上新增参数 就是 运行jar包增加调试参数 增加调试暴漏的端口号 -agentlib:jdwptransportdt_socket,servery,suspendn,address*:50052.在运行docker容器的时候增加暴漏端口5005 3.打开idea就是正在运行的项目 4.选择远程配置 5.配…