现在请求到了Protocol(Http11NioProtocol)的#process()方法了,由于方法较长,很多代码没有列出:
public SocketState process(NioChannel socket) {
// 得到Processor
Http11NioProcessor processor = connections.remove(socket);
try {
if (processor == null) {
processor = recycledProcessors.poll();
}
if (processor == null) {
processor = createProcessor();
}
// 配置processor是否SSL:略
......
// 重要:调用Processor的#process()方法
SocketState state = processor.process(socket);
// 对长连接的支持:略
if (state == SocketState.LONG) {
......
}
if (state == SocketState.LONG || state == SocketState.ASYNC_END) {
// Already done all we need to do.
} else if (state == SocketState.OPEN) {// 一般的keep-alive的请求都回到这里
// 开始回收Processor
release(socket);
// 如果keep-alive,那么将SocketChannel继续加到Poller中等待
socket.getPoller().add(socket);
} else {
// 回收Processor
release(socket);
}
return state;
} catch(XXXException){
// 略过异常处理
......
}
// 做一些回收工作
connections.remove(socket);
processor.recycle();
recycledProcessors.offer(processor);
return SocketState.CLOSED;
}
这里很明显,最重要的是对Processor的#process()的调用,直接上代码,当然,方法太长也略过了很多部分。另外对请求的byte[]的解析就不上代码了,太长了,主要的方式就是byte[]循环的方式,这也是为了提高效率的考虑,毕竟使用字符串和byte相比还是要慢的。
public SocketState process(NioChannel socket) throws IOException {
RequestInfo rp = request.getRequestProcessor();
rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
// Setting up the socket
this.socket = socket;
inputBuffer.setSocket(socket);
outputBuffer.setSocket(socket);
inputBuffer.setSelectorPool(endpoint.getSelectorPool());
outputBuffer.setSelectorPool(endpoint.getSelectorPool());
// Error flag
error = false;
keepAlive = true;
comet = false;
long soTimeout = endpoint.getSoTimeout();
int keepAliveTimeout = endpoint.getKeepAliveTimeout();
boolean keptAlive = false;
boolean openSocket = false;
boolean recycle = true;
final KeyAttachment ka = (KeyAttachment) socket.getAttachment(false);
while (!error && keepAlive && !comet && !isAsync() && !endpoint.isPaused()) {
// always default to our soTimeout
ka.setTimeout(soTimeout);
// Parsing the request header
try {
if (!disableUploadTimeout && keptAlive && soTimeout > 0) {
socket.getIOChannel().socket().setSoTimeout((int) soTimeout);
}
// 这里将Socket的数据读入到读缓冲区,nRead = socket.read(socket.getBufHandler().getReadBuffer());
// 并且将协议和请求的URI解析出来
if (!inputBuffer.parseRequestLine(keptAlive)) {
// 略过非正常情况的处理
}
keptAlive = true;
// 这一步是解析请求的Header,Tomcat的解析是直接基于byte[]去逐个循环的,可以好好学下
if (!inputBuffer.parseHeaders()) {
// 略过非正常情况的处理
}
request.setStartTime(System.currentTimeMillis());
if (!disableUploadTimeout) {
socket.getIOChannel().socket().setSoTimeout(timeout);
}
} catch(XXXException){
// 略过异常处理
......
}
if (!error) {
rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
try {
// 设定请求处理的一些Filters
prepareRequest();
} catch(XXXException){
// 略过异常处理
......
}
}
if (maxKeepAliveRequests == 1)
keepAlive = false;
if (maxKeepAliveRequests > 0 && ka.decrementKeepAlive() <= 0)
keepAlive = false;
// Process the request in the adapter
if (!error) {
try {
rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
// 这里就是调用CoyoteAdapter去继续请求了,此时请求会脱离Connctor层进入Engine层了
// 进入Tomcat请求处理PipeLine的下一段管道了
adapter.service(request, response);
if (keepAlive && !error) { // Avoid checking twice.
error = response.getErrorException() != null
|| statusDropsConnection(response.getStatus());
}
// 长连接的支持:略
......
} catch(XXXException){
// 略过异常处理
......
}
}
// 收尾和回收工作:略
}// while
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
if (error || endpoint.isPaused()) {
recycle();
return SocketState.CLOSED;
} else if (comet || isAsync()) {
return SocketState.LONG;
} else {
if (recycle) {
recycle();
}
// return (openSocket) ? (SocketState.OPEN) : SocketState.CLOSED;
return (openSocket) ? (recycle ? SocketState.OPEN : SocketState.LONG) : SocketState.CLOSED;
}
}
这段代码有分4个部分需要关注下。
(1) 对inputBuffer的#parseRequestLine()的调用,这里主要就是读入Socket的数据并且解析出请求的URI;
(2) 对inputBuffer的#parseHeaders()的调用,这里就是读取请求中的请求头了;
(3) #prepareRequest()的调用,这里主要是对前两步得到的数据进行分析使用,构建处理请求的上下文属性,并且如果请求的transfer-encoding域有值,需要配置相应的Filter去处理。默认有IdentityInputFilter,ChunkedInputFilter,VoidInputFilter,BufferedInputFilter四种;
(4) 对CoyoteAdapter的#service()的调用,这里就准备进入PipeLine的下一段管道了。
全文完。
分享到:
相关推荐
赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.4.Final-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....
赠送源代码:xnio-nio-3.8.0.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.0.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.0.Final-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.jboss.xnio:...
赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.4.Final-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.jboss.xnio:...
赠送源代码:xnio-nio-3.8.0.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.0.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.0.Final-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....
赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:httpcore-nio,...
本文将深入探讨Tomcat 8的源代码,帮助读者理解其工作原理,以便更好地优化和定制自己的服务器环境。 1. **目录结构** Apache Tomcat 8的源代码目录结构清晰,主要分为以下几个部分: - `conf`:存放服务器配置...
赠送源代码:httpcore-nio-4.4.6-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.6-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:httpcore-nio,...
Apache Tomcat 8.5是Java Servlet和JavaServer Pages(JSP)的开源Web应用程序服务器,由Apache软件基金会开发和维护。它是一个轻量级应用服务器,特别适用于部署Java EE Web应用程序。在这个“apache-tomcat-8.5.64...
Apache Tomcat 6是一款广泛应用的开源Java Servlet容器...通过深入学习和研究Tomcat6的源代码,开发者不仅可以掌握Servlet容器的工作原理,还能提升解决实际问题的能力,为构建高效、稳定的Java Web应用打下坚实基础。
在本文中,我们将深入探讨`apache-tomcat-7.0.88-src.tar`这个源代码包,了解其核心组件、工作原理以及如何通过源代码学习和定制Tomcat。 首先,`apache-tomcat-7.0.88-src.tar`是一个包含Apache Tomcat 7.0.88版本...
Apache Tomcat 是一个开源软件应用服务器,主要用于部署和运行Java Servlet和JavaServer Pages(JSP)应用程序。这个压缩包文件 "apache-tomcat-8.5.97-windows-x.zip" 包含了Apache Tomcat 8.5.97 版本在Windows...
赠送源代码:httpcore-nio-4.4.10-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.10.pom; 包含翻译后的API文档:httpcore-nio-4.4.10-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....
《深入剖析Tomcat7源代码》 Tomcat7是一款广泛使用的开源Java Servlet容器,它实现了Java EE中的Web应用规范,包括Servlet、JSP和EL(Expression Language)等。本资源包含Tomcat7的源代码以及运行所需的jar包,...
赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:...
"tomcat-native-1.2.25-src-build" 指的是该扩展的源代码版本1.2.25,用于编译生成适用于不同操作系统的本地库文件。 【编译过程】:下载的源码包"tomcat-native-1.2.25-src-build"需要经过编译才能生成适用于目标...
Apache Tomcat是一款开源的Java应用服务器,主要用于运行Java Servlet和JavaServer Pages(JSP)技术。这个最新的版本,即apache-tomcat-9.0.54,是针对Windows操作系统设计的64位版本,提供了在Windows环境下部署和...
Apache Tomcat 9.0.74 是一个广泛使用的开源软件,它是一个实现了Java Servlet、JavaServer Pages(JSP)和Java EE的Web应用程序容器。这个版本是专门为Windows x64平台设计的,确保在64位操作系统上高效运行。在...
赠送源代码:httpcore-nio-4.4.10-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.10.pom; 包含翻译后的API文档:httpcore-nio-4.4.10-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache....
源代码分析对于理解Tomcat的工作原理、优化性能或进行自定义扩展非常有价值。这里的“简单实用”可能是指通过研究源码,开发者可以更直观地了解Web服务器内部机制,从而更好地应用在实际项目中。 **Tomcat 8源代码...
在手写Tomcat NIO时,我们需要创建并管理这些SocketChannel,以接收和响应客户端请求。 2. **选择器(Selector)**:选择器是NIO的核心组件,它允许我们监控多个通道的事件(如连接就绪、数据可读或可写等)。通过...