前言
Connector是Tomcat的连接器,其主要任务是负责处理浏览器发送过来的请求,并创建一个Request和Response的对象用于和浏览器交换数据,然后产生一个线程用于处理请求,Connector会把Request和Response对象传递给该线程,该线程的具体的处理过程是Container容器的事了。执行过程分为以下几个步骤
- 实例化Connector,构造一个Connector对象
- 调用Connector的initIntenal方法,初始化Connetor
- 调用ProtocolHanlder的init方法,完成ProtocolHanlder的初始化。这个过程包括了创建线程池并创建一个线程处理浏览器请求
- 调用Connector的startIntenal方法,启动Connector
- 调用ProtocolHandler的start方法,启动Protocolhanlder
- 调用MapperListener的start方法,启动监听器程序
为了对Connector的执行过程有一个大概的印象,可以参考下面的序列图:
注意:由于Tomcat还支持AJP协议,但为了简化,我画的这个序列图是基于Http协议的,这也是我们在Web开发中接触最多的协议了。
在深入Connector之前我们先看看Connector类的结构:
既然是处理浏览器请求,那么需要支持http协议,在Tomcat中有两种协议处理器:HTTP/1.1与AJP/1.3协议处理器。在server.xml中已经指明tomcat所支持的两种协议:
代码清单3-1:
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">Connector</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">port</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8080"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">protocol</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"HTTP/1.1"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">connectionTimeout</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"20000"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">redirectPort</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8443"</span> /></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">Connector</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">port</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8009"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">protocol</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"AJP/1.3"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">redirectPort</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"8443"</span> /></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
在tomcat中是怎么样分别处理这两种协议的呢,我们可以ProtocolHanlder类中找到答案:
图中被选中的就是Tomcat默认使用协议处理器,其实现过程与Java标准Socket编程是一样的,在tomcat中可以使用Connetor类的setProtocol方法,看看源码就知道了:
代码清单3-2:
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> setProtocol(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span> protocol) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (AprLifecycleListener<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>isAprAvailable()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"HTTP/1.1"</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">equals</span>(protocol)) { setProtocolHandlerClassName (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.http11.Http11AprProtocol"</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AJP/1.3"</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">equals</span>(protocol)) { setProtocolHandlerClassName (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.ajp.AjpAprProtocol"</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (protocol <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) { setProtocolHandlerClassName(protocol); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { setProtocolHandlerClassName (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.http11.Http11AprProtocol"</span>); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"HTTP/1.1"</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">equals</span>(protocol)) { setProtocolHandlerClassName (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.http11.Http11Protocol"</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AJP/1.3"</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">equals</span>(protocol)) { setProtocolHandlerClassName (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org.apache.coyote.ajp.AjpProtocol"</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (protocol <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) { setProtocolHandlerClassName(protocol); } } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>
从第2个if子句的最后一个else可以知道tomcat默认使用的是http1.1协议。
我们再看看Connector的初始化过程:
代码清单3-3:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">initInternal</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> LifecycleException { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.initInternal(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Initialize adapter</span> adapter = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> CoyoteAdapter(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>); protocolHandler.setAdapter(adapter); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Make sure parseBodyMethodsSet has a default</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>( <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == parseBodyMethodsSet ) { setParseBodyMethods(getParseBodyMethods()); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (protocolHandler.isAprRequired() && !AprLifecycleListener.isAprAvailable()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LifecycleException( sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"coyoteConnector.protocolHandlerNoApr"</span>, getProtocolHandlerClassName())); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { protocolHandler.init(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LifecycleException (sm.getString (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"coyoteConnector.protocolHandlerInitializationFailed"</span>), e); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Initialize mapper listener</span> mapperListener.init(); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>
从这段代码中可以看到:首先调用父类org.apache.catalina.util.LifecycleMBeanBase的初始化方法,然后创建一个Adapter,然后设置protocolHanlder(协议处理器)的Adapter,同时判断传过来的请求的请求方法(比如get或者post),如果没有指明请求方法,默认使用post处理,然后调用protocolHanlder的初始化方法,最后调用mapperListener的初始化方法,而mapperListener的初始化方法调用的是org.apache.catalina.util.LifecycleBase的init方法,我们重点关注protocolHanlder的初始化方法,具体是实现在AbstractProtocol抽象类中,其直接子类有AbstractAjpProtocol和AbstractHttp11Protocol,分别对应的是两种不同的处理协议,所以协议处理器的初始化方法是在其子抽象类(实现ProtocolHanlder接口的抽象类)来实现的,这里看看AbstractHttp11Protocol的初始化方法:
代码清单3-4:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getLog().isInfoEnabled()) getLog().info(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.init"</span>, getName())); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (oname == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Component not pre-registered so register it</span> oname = createObjectName(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (oname != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { Registry.getRegistry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>).registerComponent(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, oname, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.domain != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { tpOname = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ObjectName(domain + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">":"</span> + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"type=ThreadPool,name="</span> + getName()); Registry.getRegistry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>).registerComponent(endpoint, tpOname, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) { getLog().error(sm.getString( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.mbeanRegistrationFailed"</span>, tpOname, getName()), e); } rgOname=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ObjectName(domain + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">":type=GlobalRequestProcessor,name="</span> + getName()); Registry.getRegistry(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>).registerComponent( getHandler().getGlobal(), rgOname, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ); } String endpointName = getName(); endpoint.setName(endpointName.substring(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, endpointName.length()-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { endpoint.init(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception ex) { getLog().error(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.initError"</span>, getName()), ex); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> ex; } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li></ul>
打断点调试可以知道oname的值是Tomcat:type=ProtocolHandler,port=auto-1,address="127.0.0.1"
,tpOname是Tomcat:type=ProtocolHandler,port=auto-1,address="127.0.0.1"
,rOname是Tomcat:type=GlobalRequestProcessor,name="http-bio-127.0.0.1-auto-1"
,我们重点关注endpoint的init方法,主要完成以下几个过程:
- 设置线程接收数和最大连接数
- 创建线程池,启动监听的线程监听用户请求
- 启动一个线程处理请求
初始化完成Connector就可以启动了,启动阶段调用startInternal方法:
代码清单3-5:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startInternal</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> LifecycleException { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Validate settings before starting</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getPort() < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LifecycleException(sm.getString( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"coyoteConnector.invalidPort"</span>, Integer.valueOf(getPort()))); } setState(LifecycleState.STARTING); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { protocolHandler.start(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) { String errPrefix = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.service != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { errPrefix += <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"service.getName(): \""</span> + <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.service.getName() + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\"; "</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LifecycleException (errPrefix + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" "</span> + sm.getString (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"coyoteConnector.protocolHandlerStartFailed"</span>), e); } mapperListener.start(); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>
可以看出Connector调用protocolHandler.start()
方法,继续看看这个方法的源码:
代码清单3-6:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">start</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getLog().isInfoEnabled()) getLog().info(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.start"</span>, getName())); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { endpoint.start(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception ex) { getLog().error(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abstractProtocolHandler.startError"</span>, getName()), ex); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> ex; } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
这个方法又调用了endpoint.start()
方法:
代码清单3-7:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">start</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (bindState == BindState.UNBOUND) { bind(); bindState = BindState.BOUND_ON_START; } startInternal(); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
然后又调用了org.apache.tomcat.util.net.AbstractEndpoint.startInternal()方法:
代码清单3-8:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startInternal</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!running) { running = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; paused = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Create worker collection</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getExecutor() == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { createExecutor(); } initializeConnectionLatch(); startAcceptorThreads(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Start async timeout thread</span> Thread timeoutThread = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Thread(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> AsyncTimeout(), getName() + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"-AsyncTimeout"</span>); timeoutThread.setPriority(threadPriority); timeoutThread.setDaemon(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); timeoutThread.start(); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>
- 设置线程接收数和最大连接数
- 创建线程池,启动监听的线程监听用户请求
- 启动一个线程处理异步请求
这里启动了一个异步线程处理请求,这个异步线程是如何执行的呢?
代码清单3-9:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * Async timeout thread */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AsyncTimeout</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Runnable</span> {</span> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * The background thread that checks async requests and fires the * timeout if there has been no activity. */</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Loop until we receive a shutdown command</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (running) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { Thread.sleep(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InterruptedException e) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Ignore</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> now = System.currentTimeMillis(); Iterator<SocketWrapper<Socket>> sockets = waitingRequests.iterator(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (sockets.hasNext()) { SocketWrapper<Socket> socket = sockets.next(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> access = socket.getLastAccess(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (socket.getTimeout() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && (now-access)>socket.getTimeout()) { processSocketAsync(socket,SocketStatus.TIMEOUT); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Loop if endpoint is paused</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (paused && running) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { Thread.sleep(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InterruptedException e) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Ignore</span> } } } } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//processSocket</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">processSocketAsync</span>(SocketWrapper<Socket> socket, SocketStatus status) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> (socket) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (waitingRequests.remove(socket)) { SocketProcessor proc = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SocketProcessor(socket,status); ClassLoader loader = Thread.currentThread().getContextClassLoader(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//threads should not be created by the webapp classloader</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (Constants.IS_SECURITY_ENABLED) { PrivilegedAction<Void> pa = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> PrivilegedSetTccl( getClass().getClassLoader()); AccessController.doPrivileged(pa); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { Thread.currentThread().setContextClassLoader( getClass().getClassLoader()); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// During shutdown, executor may be null - avoid NPE</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!running) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } getExecutor().execute(proc); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//TODO gotta catch RejectedExecutionException and properly handle it</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (Constants.IS_SECURITY_ENABLED) { PrivilegedAction<Void> pa = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> PrivilegedSetTccl(loader); AccessController.doPrivileged(pa); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { Thread.currentThread().setContextClassLoader(loader); } } } } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Throwable t) { ExceptionUtils.handleThrowable(t); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// This means we got an OOM or similar creating a thread, or that</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// the pool and its queue are full</span> log.error(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"endpoint.process.fail"</span>), t); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li></ul>
org.apache.tomcat.util.net.JIoEndpoint.SocketProcessor的职责是把具体的请求处理过程委派给org.apache.tomcat.util.net.JIoEndpoint.Handler,然后根据handler返回的不同SocketState,来决定是否关闭连接或者进行下一轮处理。
代码清单3-10:
<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">public void run() { boolean launch = false; synchronized (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>) { try { SocketState <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> = SocketState.OPEN; try { <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> SSL handshake serverSocketFactory.handshake(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.getSocket()); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.isDebugEnabled()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.debug(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"endpoint.err.handshake"</span>), t); } // Tell to <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">close</span> the <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> = SocketState.CLOSED; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> != SocketState.CLOSED)) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (status == null) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> = handler.process(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>, SocketStatus.OPEN_READ); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> = handler.process(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>,status); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.CLOSED) { <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> Close <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.isTraceEnabled()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.trace(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Closing socket:"</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>); } countDownConnection(); try { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.getSocket().<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">close</span>(); } catch (IOException e) { <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> Ignore } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.OPEN || <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.UPGRADING || <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.UPGRADING_TOMCAT || <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.UPGRADED){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.setKeptAlive(true); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.access(); launch = true; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">state</span> == SocketState.LONG) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>.access(); waitingRequests.add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>); } } finally { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (launch) { try { getExecutor().execute(new SocketProcessor(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>, SocketStatus.OPEN_READ)); } catch (RejectedExecutionException <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">x</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">warn</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Socket reprocessing request was rejected for:"</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">x</span>); try { <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//unable</span> to handle connection at this <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">time</span> handler.process(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span>, SocketStatus.DISCONNECT); } finally { countDownConnection(); } } catch (NullPointerException npe) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (running) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">log</span>.error(sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"endpoint.launch.fail"</span>), npe); } } } } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">socket</span> = null; <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> Finish up this request } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li></ul>
其中的process方法主要完成对request的解析,包括请求头、请求行和请求体
代码清单3-11:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//process method of org.apache.coyote.http11.AbstractHttp11Processor<S>.HttpProcessor extends org.apache.coyote.http11.AbstractHttp11Processor<S></span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> SocketState <span class="hljs-title" style="box-sizing: border-box;">process</span>(SocketWrapper<S> socketWrapper) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> IOException { RequestInfo rp = request.getRequestProcessor(); rp.setStage(org.apache.coyote.Constants.STAGE_PARSE); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Setting up the I/O</span> setSocketWrapper(socketWrapper); getInputBuffer().init(socketWrapper, endpoint); getOutputBuffer().init(socketWrapper, endpoint); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Flags</span> error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; keepAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; comet = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; openSocket = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; sendfileInProgress = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; readComplete = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (endpoint.getUsePolling()) { keptAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { keptAlive = socketWrapper.isKeptAlive(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (disableKeepAlive()) { socketWrapper.setKeepAliveLeft(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (!error && keepAlive && !comet && !isAsync() && upgradeInbound == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && httpUpgradeHandler == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && !endpoint.isPaused()) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Parsing the request header</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { setRequestLineReadTimeout(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!getInputBuffer().parseRequestLine(keptAlive)) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (handleIncompleteRequestLineRead()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (endpoint.isPaused()) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 503 - Service unavailable</span> response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">503</span>); error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Make sure that connectors that are non-blocking during</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// header processing (NIO) only set the start time the first</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// time a request is processed.</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (request.getStartTime() < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { request.setStartTime(System.currentTimeMillis()); } keptAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Set this every time in case limit has been changed via JMX</span> request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount()); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Currently only NIO will ever return false here</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!getInputBuffer().parseHeaders()) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// We've read part of the request, don't recycle it</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// instead associate it with the socket</span> openSocket = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; readComplete = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!disableUploadTimeout) { setSocketTimeout(connectionUploadTimeout); } } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IOException e) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getLog().isDebugEnabled()) { getLog().debug( sm.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.header.parse"</span>), e); } error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Throwable t) { ExceptionUtils.handleThrowable(t); UserDataHelper.Mode logMode = userDataHelper.getNextMode(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (logMode != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { String message = sm.getString( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.header.parse"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (logMode) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> INFO_THEN_DEBUG: message += sm.getString( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.fallToDebug"</span>); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//$FALL-THROUGH$</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> INFO: getLog().info(message); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> DEBUG: getLog().debug(message); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 400 - Bad Request</span> response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">400</span>); adapter.log(request, response, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!error) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Setting up filters, and parse some request headers</span> rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { prepareRequest(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Throwable t) { ExceptionUtils.handleThrowable(t); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (getLog().isDebugEnabled()) { getLog().debug(sm.getString( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.request.prepare"</span>), t); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 400 - Internal Server Error</span> response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">400</span>); adapter.log(request, response, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (maxKeepAliveRequests == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { keepAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (maxKeepAliveRequests > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && socketWrapper.decrementKeepAlive() <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { keepAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Process the request in the adapter</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!error) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE); adapter.service(request, response); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(keepAlive && !error) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Avoid checking twice.</span> error = response.getErrorException() != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> || (!isAsync() && statusDropsConnection(response.getStatus())); } setCometTimeouts(socketWrapper); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InterruptedIOException e) { error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (HeadersTooLargeException e) { error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// The response should not have been committed but check it</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// anyway to be safe</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!response.isCommitted()) { response.reset(); response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">500</span>); response.setHeader(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Connection"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"close"</span>); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Throwable t) { ExceptionUtils.handleThrowable(t); getLog().error(sm.getString( <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http11processor.request.process"</span>), t); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 500 - Internal Server Error</span> response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">500</span>); adapter.log(request, response, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); error = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Finish the handling of the request</span> rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!isAsync() && !comet) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (error) { getInputBuffer().setSwallowInput(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (response.getStatus() < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span> || response.getStatus() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">299</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (expectation) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Client sent Expect: 100-continue but received a</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// non-2xx response. Disable keep-alive (if enabled) to</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// ensure the connection is closed. Some clients may</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// still send the body, some may send the next request.</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// No way to differentiate, so close the connection to</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// force the client to send the next request.</span> getInputBuffer().setSwallowInput(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>); keepAlive = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } } endRequest(); } rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// If there was an error, make sure the request is counted as</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// and error, and update the statistics counter</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (error) { response.setStatus(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">500</span>); } request.updateCounters(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!isAsync() && !comet || error) { getInputBuffer().nextRequest(); getOutputBuffer().nextRequest(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!disableUploadTimeout) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(endpoint.getSoTimeout() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { setSocketTimeout(endpoint.getSoTimeout()); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { setSocketTimeout(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); } } rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (breakKeepAliveLoop(socketWrapper)) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; } } rp.setStage(org.apache.coyote.Constants.STAGE_ENDED); } } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li><li style="box-sizing: border-box; padding: 0px 5px;">128</li><li style="box-sizing: border-box; padding: 0px 5px;">129</li><li style="box-sizing: border-box; padding: 0px 5px;">130</li><li style="box-sizing: border-box; padding: 0px 5px;">131</li><li style="box-sizing: border-box; padding: 0px 5px;">132</li><li style="box-sizing: border-box; padding: 0px 5px;">133</li><li style="box-sizing: border-box; padding: 0px 5px;">134</li><li style="box-sizing: border-box; padding: 0px 5px;">135</li><li style="box-sizing: border-box; padding: 0px 5px;">136</li><li style="box-sizing: border-box; padding: 0px 5px;">137</li><li style="box-sizing: border-box; padding: 0px 5px;">138</li><li style="box-sizing: border-box; padding: 0px 5px;">139</li><li style="box-sizing: border-box; padding: 0px 5px;">140</li><li style="box-sizing: border-box; padding: 0px 5px;">141</li><li style="box-sizing: border-box; padding: 0px 5px;">142</li><li style="box-sizing: border-box; padding: 0px 5px;">143</li><li style="box-sizing: border-box; padding: 0px 5px;">144</li><li style="box-sizing: border-box; padding: 0px 5px;">145</li><li style="box-sizing: border-box; padding: 0px 5px;">146</li><li style="box-sizing: border-box; padding: 0px 5px;">147</li><li style="box-sizing: border-box; padding: 0px 5px;">148</li><li style="box-sizing: border-box; padding: 0px 5px;">149</li><li style="box-sizing: border-box; padding: 0px 5px;">150</li><li style="box-sizing: border-box; padding: 0px 5px;">151</li><li style="box-sizing: border-box; padding: 0px 5px;">152</li><li style="box-sizing: border-box; padding: 0px 5px;">153</li><li style="box-sizing: border-box; padding: 0px 5px;">154</li><li style="box-sizing: border-box; padding: 0px 5px;">155</li><li style="box-sizing: border-box; padding: 0px 5px;">156</li><li style="box-sizing: border-box; padding: 0px 5px;">157</li><li style="box-sizing: border-box; padding: 0px 5px;">158</li><li style="box-sizing: border-box; padding: 0px 5px;">159</li><li style="box-sizing: border-box; padding: 0px 5px;">160</li><li style="box-sizing: border-box; padding: 0px 5px;">161</li><li style="box-sizing: border-box; padding: 0px 5px;">162</li><li style="box-sizing: border-box; padding: 0px 5px;">163</li><li style="box-sizing: border-box; padding: 0px 5px;">164</li><li style="box-sizing: border-box; padding: 0px 5px;">165</li><li style="box-sizing: border-box; padding: 0px 5px;">166</li><li style="box-sizing: border-box; padding: 0px 5px;">167</li><li style="box-sizing: border-box; padding: 0px 5px;">168</li><li style="box-sizing: border-box; padding: 0px 5px;">169</li><li style="box-sizing: border-box; padding: 0px 5px;">170</li><li style="box-sizing: border-box; padding: 0px 5px;">171</li><li style="box-sizing: border-box; padding: 0px 5px;">172</li><li style="box-sizing: border-box; padding: 0px 5px;">173</li><li style="box-sizing: border-box; padding: 0px 5px;">174</li><li style="box-sizing: border-box; padding: 0px 5px;">175</li><li style="box-sizing: border-box; padding: 0px 5px;">176</li><li style="box-sizing: border-box; padding: 0px 5px;">177</li><li style="box-sizing: border-box; padding: 0px 5px;">178</li><li style="box-sizing: border-box; padding: 0px 5px;">179</li><li style="box-sizing: border-box; padding: 0px 5px;">180</li><li style="box-sizing: border-box; padding: 0px 5px;">181</li><li style="box-sizing: border-box; padding: 0px 5px;">182</li><li style="box-sizing: border-box; padding: 0px 5px;">183</li><li style="box-sizing: border-box; padding: 0px 5px;">184</li><li style="box-sizing: border-box; padding: 0px 5px;">185</li><li style="box-sizing: border-box; padding: 0px 5px;">186</li><li style="box-sizing: border-box; padding: 0px 5px;">187</li><li style="box-sizing: border-box; padding: 0px 5px;">188</li><li style="box-sizing: border-box; padding: 0px 5px;">189</li><li style="box-sizing: border-box; padding: 0px 5px;">190</li><li style="box-sizing: border-box; padding: 0px 5px;">191</li><li style="box-sizing: border-box; padding: 0px 5px;">192</li><li style="box-sizing: border-box; padding: 0px 5px;">193</li><li style="box-sizing: border-box; padding: 0px 5px;">194</li><li style="box-sizing: border-box; padding: 0px 5px;">195</li><li style="box-sizing: border-box; padding: 0px 5px;">196</li></ul>
首先在Http11Processor的process方法里,会先从socket里读取http请求数据,并解析请求头,构造Request对象和Response对象,然后调用Adapter.service()方法。Adapter.service()完成请求行以及请求体的解析,并把解析出来的信息封装到Request和Response对象中,Adapter(确切说是org.apache.catalina.connector.CoyoteAdapter)是connector和container的桥梁,经过这一步,请求就从connector传递到container里了,Adapter.service()方法之后便将封装了Request以及Response对象的Socket传给Container容器了。
要注意的是:最先处理请求的Request是org.apache.coyote.Request类型,这是一个Tomcat中一个轻量级对象,完成基本的请求处理后很容易被JVM回收,那为什么不直接交给Connector.Request对象处理呢?由于后者是Servlet容器真正传递的对象其完成的职责比前者复杂,这里使用org.apache.coyote.Request主要减轻后者的任务负担,出于性能考虑才这么设计。
具体service方法清单如下:
代码清单3-12:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">@Override public void service(org<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.apache</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.coyote</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Request</span> req, org<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.apache</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.coyote</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Response</span> res) throws Exception { Request request = (Request) req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getNote</span>(ADAPTER_NOTES)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> Response response = (Response) res<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getNote</span>(ADAPTER_NOTES)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> if (request == null) { // Create objects request = connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.createRequest</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCoyoteRequest</span>(req)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> response = connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.createResponse</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setCoyoteResponse</span>(res)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> // Link objects request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setResponse</span>(response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setRequest</span>(request)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Set</span> as notes req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setNote</span>(ADAPTER_NOTES, request)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> res<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setNote</span>(ADAPTER_NOTES, response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> // <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Set</span> query string encoding req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getParameters</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setQueryStringEncoding</span> (connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getURIEncoding</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } if (connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getXpoweredBy</span>()) { response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addHeader</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"X-Powered-By"</span>, POWERED_BY)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } boolean comet = false<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> boolean async = false<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> try { // Parse <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span> Catalina <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> configuration //specific // request parameters req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getRequestProcessor</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setWorkerThreadName</span>(Thread<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.currentThread</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> //postParseRequest方法把CoyoteRequest转换为Connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Request</span>对象 //后一类型的对象才是在Tomcat容器流转时真正传递的对象 boolean postParseSuccess = postParseRequest(req, request, res, response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> if (postParseSuccess) { //check valves if we support async request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setAsyncSupported</span>(connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getService</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getContainer</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getPipeline</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isAsyncSupported</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> // 调用Container容器的invoke方法,把请求交给Container容器 connector<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getService</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getContainer</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getPipeline</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getFirst</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.invoke</span>(request, response)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> if (request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isComet</span>()) { if (!response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isClosed</span>() && !response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isError</span>()) { if (request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAvailable</span>() || (request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getContentLength</span>() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && (!request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.isParametersParsed</span>()))) { // Invoke a read event right away if there are available bytes if (event(req, res, SocketStatus<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.OPEN</span>_READ)) { comet = true<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> res<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.action</span>(ActionCode<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.COMET</span>_BEGIN, null)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } } else { comet = true<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> res<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.action</span>(ActionCode<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.COMET</span>_BEGIN, null)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } } else { // Clear the filter chain, as otherwise it will not be reset elsewhere // since this is a Comet request request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setFilterChain</span>(null)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } } } AsyncContextImpl asyncConImpl = (AsyncContextImpl)request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAsyncContext</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> if (asyncConImpl != null) { async = true<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } else if (!comet) { request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.finishRequest</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> response<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.finishResponse</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> if (postParseSuccess && request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getMappingData</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.context</span> != null) { ((Context) request<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getMappingData</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.context</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.logAccess</span>( request, response, System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.currentTimeMillis</span>() - req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getStartTime</span>(), false)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } req<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.action</span>(ActionCode<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.POST</span>_REQUEST , null)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> } } catch (IOException e) { // Ignore } finally { //ignore } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li></ul>
从connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
这句代码中可以知道下一步的处理需要交给Container容器了。
经过上面一系列复杂的操作流程,Tomcat的Connector已经完成了protocol.start()方法,返回Connector的startIntenal方法,还有一个步骤要完成就是mapperListener.start()
的方法了,整个执行过程比较简单,有两步:
- 执行Connector的startIntenal方法
- 执行MapperListener的startIntenal方法
代码清单3-14:
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startInternal</span>() <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> LifecycleException { setState(LifecycleState.STARTING); findDefaultHost(); Engine engine = (Engine) connector.getService().getContainer(); addListeners(engine); Container[] conHosts = engine.findChildren(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (Container conHost : conHosts) { Host host = (Host) conHost; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!LifecycleState.NEW.equals(host.getState())) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Registering the host will register the context and wrappers</span> registerHost(host); } } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>
首先注册已初始化的组件,然后为这些组件添加监听器,最后添加容器之间的映射关系。这样经过上面两个大步骤以及N个小步骤,我们的Connector才算启动完毕,可谓是路途艰辛啊!