apache编程思想--挂钩(HOOK)

      如果让你自己编写一个web服务器你会怎么设计,我曾经使用java语言实现了一个最简单的web服务器,我的做法是应用一个socket类启用去监听一个特定的端口,并根据http协议标准去解析这样一个长串:POST /reg.jsp HTTP/ (CRLF) ,我所做的只是将/reg.jsp截取下来,然后在本地的机器上找到这个文件,并根据“状态行、消息报头、响应正文”的响应报文格式返回给浏览器, 当然,一个真正的web服务器还要去解析Accept、HOST、Content-Length、Connection等字段,在这我们不去讨论这方面内容,我们继续来研究web服务器最主要的功能--解析请求串POST /reg.jsp HTTP/ (CRLF),当时我还沾沾自喜认为一个服务器原来有这么简单(设计思想上的简单,只需要加一些逻辑判断来适应复杂的http请求),可是当我看到了apache的源代码,并花了很长的时间研究了它的原理,我才发现我的程序是多么地单薄。
      继续我上面的例子,如果我想改变web服务器的端口,我肯定不能去修改源代码,因为这样拓展性就太差了,这时就要用到配置文件来动态地设置端口号,一般的web服务器都会有十几二十个配置文件,应用配置文件就会在启动服务器之前来定制我想要的功能,当然,这也不是我想要说的主要问题。
      应用配置文件后我的服务器的扩展性大大增强了,可是又一个需求来了,就是如果一个从浏览器发送过来的请求是加密的话,我要根据他传过来的密钥进行解密。这就需要我们在服务器接受请求时增加一段代码(类或函数)来处理这一过程,具体加密解密在这我们也不讨论,我们只讨论如何通过配置文件来调用这一过程。
      一般地,我们会在配置文件中添加诸如ssl_engine = true(名字可以自己起)这样的信息点来告诉服务器,服务器加载配置文件时就会知道要不要启动这一功能,好了需求说完了,可是我们要怎么设计呢,一个想法就是在主程序读取配置文件后通过if-else语句来判断,如果是true则在if()内执行解密代码,当然,这是一种非常糟糕的实现,拓展性极差而且执行效率会很低,如果一个配置文件有几百个信息点,如何实现主程序真是无法想象。

      作为世界使用排名第一的Web服务器软件,让我们看看apache是如何实现的,apache引入了挂钩的概念,什么是挂钩呢,从大的方面来看,Apache对HTTP的请求可以分为连接、处理和断开连接三个阶段;从小的方面而言,每个阶段又可以分为更多的子阶段。比如对HTTP的请求,我们可以进一步划分为客户身份验证、客户权限认证、请求校验等阶段,每一个阶段调用相应的函数进行处理。在Apache中,这些子阶段可以用术语“挂钩(HOOK)”来描述。也就是说你就可以把挂钩理解为一个处理过程,在上面的例子中,你完全可以把解密过程看做是一个挂钩的实现。
      按照apache的设计思想,我把我的web服务器细化为三大部分,第一部分是处理请求前挂钩,第二部分是处理请求挂钩,第三部分是后续挂钩,其中的每一个部分挂钩可以看做是抽象的,他们本身并不会完成什么功能,但在每一个部分挂钩中我们都维护一个类似于List的数据结构,在这个List中则是真正地各种挂钩的实现。我可以把上面的解密过程注册(对于java程序就是在List或队列中进行接口回调)到第一部分挂钩中,当主程序运行到这个挂钩时,就会遍历这个List,找到注册在里面的解密代码,就可以进行相应地处理了。
      这就是apache的精髓之一,整个服务器程序的扩展性极高,每一个模块和每一个特殊功能都可以独立出来并通过挂钩再整合到服务器上。   

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值