Tomcat基于Coyote的HTTP 1.1协议连接器
来源:互联网 发布:单片机程序100例 编辑:程序博客网 时间:2024/06/05 21:50
1. 模块架构
org.apache.coyote.http11包支持http1.1协议,内部分为三类:ARP、NIO、普通http,这里只对最基本的普通http(使用java的IO流,而非NIO流)作简单研究。
这个包主要有以下几个类:
- Http11Protocol,实现了ProtocolHandler接口
- Http11Processor,实现了ActionHook接口
- InternalInputBuffer,实现了InputBuffer接口
- InternalOutputBuffer,实现了OutputBuffer接口
- InputFilter和OutputFilter接口,具体的实现类在 org.apache.coyote.http11.filters 中。
架构图如下所示(转自王程斯的博客):
处理流程:
- JIOEndpoint起到一个连接池的作用,可以启动多个socket监听,一旦收到浏览器发来的请求后,把对应的socket对象通过process方法,传递给Http11ConnectionHandler,再交给Http11Processor
- Http11Processor内部有个InternalInputBuffer(图上未画出),InternalInputBuffer是真正对socket中包含的字节流进行处理的,它将字节转换为Request
- Request流经过滤器filters,最后到达实现了Adapter接口的容器,模块的工作就到此为止,回头继续处理下一个socket
2. 代码研究
- Http11Protocol
该类是http1.1协议的ProtocolHandler实现,主要包含了内部类Http11ConnectionHandler和Http11ConnectionHandler的实例对象,它的初始化代码和过程如下:
public Http11Protocol() { endpoint = new JIoEndpoint(); //新建endpoint,启动若干socket server,监听服务器端口 cHandler = new Http11ConnectionHandler(this); //协议连接处理对象,用于对socket连接的处理 ((JIoEndpoint) endpoint).setHandler(cHandler); //一旦endpoint接收到请求,会将对应socket实例传给cHandler.process方法进行处理 setSoLinger(Constants.DEFAULT_CONNECTION_LINGER); setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT); setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY); }
Http11ConnectionHandler内部类则继承了AbstractConnectionHandler,它主要实现了createProcessor方法,用于将Http11Processor应用于连接处理流程中。函数内新建了一个Http11Processor实例,并将该实例绑定到ConnectionHandler上。ConnectionHandler一旦接收到从endpoint发来的处理请求,使用对应的Processor对接收到的数据进行处理,形成Request对象。
2. Http11Processor
这个类的作用就是生成Request(当然本质上还是InternalInputBuffer完成的),交给实现了Adapter接口的容器。它有adapter、request、response、inputbuffer、outputbuffer等几个关键字段,还有很多和http 1.1协议有关的字段和方法,用于协议的解析(这里就不对解析过程进行分析了)。
这个类对socket对象依次做如下的处理:
1) 把socket的inputstream和outputstream分别与inputbuffer和outputbuffer关联起来
2) 通过inputBuffer.parseRequestLine() 和 inputBuffer.parseHeaders() 方法,解析socket字节流中的头字段,写到request中
3) 通过prepareRequest方法组装filter,用于处理http消息体
4) adapter.service(request, response) 把生成的request和response交给容器处理
5) 如果一切顺利,开始处理socket中的下一个请求(因为http1.1是支持持续连接的,所以一个socket中可能包含多个请求),循环回到第一步
6) 如果出错,则设置response的响应码,并终止循环
其中的prepareRequest方法,是用于准备inputbuffer的filter,主要包括一下几个过程:
1) 根据之前对http头字段的解析,分别检查protocol、method、expect、user-agent和MIMEheaders,此外还检查URI的格式
2) 准备加载filter
3) 如果有transfer-encoding这个头字段,则分别设置不同编码的filter
4) 校验content-length头字段
3. InternalInputBuffer
这个类的主要功能是:从socket中获取字节流,将字节读入一个缓冲区buf,然后从缓冲区逐个解析http请求头以及内容。
主要的字段有:
request:Request对象,从缓冲区中解析出的信息会写入request中
buf:缓冲区,从socket的inputstream读取的字节放入此缓冲区中
headers : MimeHeaders,保存以键值对出现的报头,也就是除去请求报文第一行之后的所有头部
主要的方法有:
parseRequestLine()
解析请求报头的第一行,形如:GET http://class/download.microtool.de:80/somedata.exe,包括请求方法(GET or POST)、协议(http)、URI。解析后,放入request中
parseHeader()
解析刚才parseRequestLine()之后的报头,由于RequestLine之后的报头都是以“:”分隔的键值对,因此每执行一次本方法,则在headers 中加入一个键值对,如果格式错误则返回false
endRequest()
结束一个request的处理,把多余的字节清空
nextRequest()
准备下一个request的处理,这个方法主要用来对所有的标记位和指针进行复位
fill()
从socket的inputstream中读出一定数量的字节,填充buf,在很多方法中都有用到。例如解析报头时,当发现buf已经读取完了,就调用fill重新填充buf,如果inputstream已经读完了,fill返回false。
4. InternalOutputBuffer
这个类是用来从response中读取信息,然后写入socket的outputstream中,返回给客户端的。里面的很多方法和InternalInputBuffer基本相似,有两个是专门用于处理Response的:nextRequest()和endRequest()。这两个函数的功能主要是在当前Request处理完并发出Response之后,跳转到下一个Request的处理或者结束处理。
3. org.apache.coyote.http11.upgrade
Apache在基于coyote的HTTP 1.1连接器实现模块中还实现了能够供基于HTTP 1.1的一些协议和在HTTP 1.1基础上进行操作的接口和实现,方便进行扩展。它主要有以下几个类:
- UpgradeInbound接口
接口定义了基于socket数据流处理需要实现的一些接口,主要功能是当连接器从socket中读取出数据后,会通知UpgradeInbound实现类进行数据解析,即onData函数。
2. UpgradeProcessor类
这个类是基于HTTP 1.1连接器的upgrade连接器Processor的模板类,定义了一个标准的UpgradeProcessor必须要重写的读写处理函数:
// Output methods public abstract void flush() throws IOException; public abstract void write(int b) throws IOException;public abstract void write(byte[] b, int off, int len) throws IOException;// Input methods public abstract int read() throws IOException; public abstract int read(boolean block, byte[] bytes, int off, int len) throws IOException;
3. UpgradeOutbound类
该类继承了OutputStream类,重写了write函数。这个类是一个功能封装类,在类初始化的时候传入用于解析数据的UpgradeProcessor,而在重写的write函数中则直接调用Processor的处理函数,使得数据能够被写到Upgraded的数据流中。
- Tomcat基于Coyote的HTTP 1.1协议连接器
- Tomcat基于Coyote的HTTP 1.1协议连接器
- Tomcat基于Coyote的连接器源码分析
- Tomcat基于Coyote的连接器源码分析
- Tomcat连接器:Coyote框架
- Tomcat连接器:Coyote框架
- Tomcat连接器:Coyote框架
- Tomcat连接器:Coyote框架
- [Tomcat] Coyote连接器框架源码分析
- 浅析Tomcat之Coyote连接器架构分析
- 浅析Tomcat之Coyote连接器架构分析
- [Tomcat] Coyote连接器框架源码分析
- Tomcat网络连接器组件-Coyote框架
- Tomcat的HTTP和AJP连接器
- Tomcat6 Coyote连接器分析
- mvn tomcat:run启动tomcat插件一直停在Starting Coyote HTTP/1.1 on http-8080
- Tomcat的默认连接器
- Tomcat 7.0.50 Coyote 连接器类结构和架构设计简析
- 排序方法
- Postfix服务操作
- STM32学习笔记(2):外部中断的使用
- 白话经典算法系列之七 堆与堆排序
- 来学习的第一周
- Tomcat基于Coyote的HTTP 1.1协议连接器
- STM32学习笔记(3):系统时钟和SysTick定时器
- 最小生成树之prim算法
- SQL 2005 try catch
- 白话经典算法系列之一 冒泡排序的三种实现
- 三马之马明哲个人简历
- STM32学习笔记(4):通用定时器基本定时功能
- Oracle11g Memory & Storage Overview
- U-BOOT移植过程详解: 开题