Tomcat 七源码学习笔记 - 2 (socket接入后的处理)
Tomcat 7源码学习笔记 - 2 (socket接入后的处理)
前一篇文章写到SocketProcessor的run方法,这次继续说明后续的处理流程。
1.在之前的Http11Protocol构造方法中,创建JIoEndpoint对象以后,接着指定了handler,就是Http11ConnectionHandler对象。
2.所以SocketProcessor的run方法中,直接调用了handler.process(socket,status)。这个process方法在Http11ConnectionHandler的父类AbstractConnectionHandler中定义。
3.接着,在process方法中回调Http11ConnectionHandler中的createProcessor()方法,createProcessor()方法会创建一个Http11Processor对象并返回。然后process方法中会继续调用Http11Processor对象的process(SocketWrapper<S> socketWrapper)方法。
4.process(SocketWrapper<S> socketWrapper)方法定义在Http11Processor的父类AbstractHttp11Processor中,从这个process方法开始,才正式进入了对request请求的处理。
5.process方法的大致处理如下
a.从socket中获得inputstream和outputstream,分别设置到Http11Processor类中的InternalInputBuffer和InternalOutputBuffer中
InternalInputBuffer类里面的inputStream成员变量保存从socket中获得的inputstream,父类AbstractInputBuffer中有request成员变量Request request
InternalOutputBuffer类里面的outputStream成员变量保存从socket中获得的outputstream,父类AbstractOutputBuffer中有response成员变量Response response
b.调用InternalInputBuffer类的parseRequestLine方法,该方法内部从inputStream里面读取http请求头header信息,进行分析后把header中的信息设置到request中,如:
method,requestURI,protocol。
c.调用prepareRequest方法,对该请求的filter进行设置。
在前面的3.中,构造Http11Processor对象的时候,会调用initializeFilters方法向
InternalInputBuffer和InternalOutputBuffer中添加标准的filter
d.prepareRequest方法中调用addInputFilter方法,根据请求header中的transfer-encoding的值来选择要添加的filter。
transfer-encoding:
identity的时候,不添加filter
chunked的时候,添加ChunkedInputFilter
buffered的时候,添加BufferedInputFilter
void的时候,添加VoidInputFilter
如果header中没有transfer-encoding,那么从header中取content-length,如果content-length >= 0,那么添加IdentityInputFilter。否则,添加VoidInputFilter。
e.调用CoyoteAdapter类中的service(request, response)方法来处理请求。
f.请求处理完以后,调用endRequest()方法结束请求,向客户端返回响应。
6.请求处理完以后,当前的请求处理线程结束。2.中的SocketProcessor的run方法结束。
关于e.中的service(request, response)方法的处理细节,下回继续分解。
前一篇文章写到SocketProcessor的run方法,这次继续说明后续的处理流程。
1.在之前的Http11Protocol构造方法中,创建JIoEndpoint对象以后,接着指定了handler,就是Http11ConnectionHandler对象。
public Http11Protocol() { endpoint = new JIoEndpoint(); cHandler = new Http11ConnectionHandler(this); ((JIoEndpoint) endpoint).setHandler(cHandler); setSoLinger(Constants.DEFAULT_CONNECTION_LINGER); setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT); setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY); }
2.所以SocketProcessor的run方法中,直接调用了handler.process(socket,status)。这个process方法在Http11ConnectionHandler的父类AbstractConnectionHandler中定义。
3.接着,在process方法中回调Http11ConnectionHandler中的createProcessor()方法,createProcessor()方法会创建一个Http11Processor对象并返回。然后process方法中会继续调用Http11Processor对象的process(SocketWrapper<S> socketWrapper)方法。
4.process(SocketWrapper<S> socketWrapper)方法定义在Http11Processor的父类AbstractHttp11Processor中,从这个process方法开始,才正式进入了对request请求的处理。
5.process方法的大致处理如下
a.从socket中获得inputstream和outputstream,分别设置到Http11Processor类中的InternalInputBuffer和InternalOutputBuffer中
InternalInputBuffer类里面的inputStream成员变量保存从socket中获得的inputstream,父类AbstractInputBuffer中有request成员变量Request request
InternalOutputBuffer类里面的outputStream成员变量保存从socket中获得的outputstream,父类AbstractOutputBuffer中有response成员变量Response response
// Setting up the I/O setSocketWrapper(socketWrapper); getInputBuffer().init(socketWrapper, endpoint); getOutputBuffer().init(socketWrapper, endpoint);
b.调用InternalInputBuffer类的parseRequestLine方法,该方法内部从inputStream里面读取http请求头header信息,进行分析后把header中的信息设置到request中,如:
method,requestURI,protocol。
c.调用prepareRequest方法,对该请求的filter进行设置。
在前面的3.中,构造Http11Processor对象的时候,会调用initializeFilters方法向
InternalInputBuffer和InternalOutputBuffer中添加标准的filter
/** * Initialize standard input and output filters. */ protected void initializeFilters(int maxTrailerSize) { // Create and add the identity filters. getInputBuffer().addFilter(new IdentityInputFilter()); getOutputBuffer().addFilter(new IdentityOutputFilter()); // Create and add the chunked filters. getInputBuffer().addFilter(new ChunkedInputFilter(maxTrailerSize)); getOutputBuffer().addFilter(new ChunkedOutputFilter()); // Create and add the void filters. getInputBuffer().addFilter(new VoidInputFilter()); getOutputBuffer().addFilter(new VoidOutputFilter()); // Create and add buffered input filter getInputBuffer().addFilter(new BufferedInputFilter()); // Create and add the chunked filters. //getInputBuffer().addFilter(new GzipInputFilter()); getOutputBuffer().addFilter(new GzipOutputFilter()); pluggableFilterIndex = getInputBuffer().getFilters().length; }
d.prepareRequest方法中调用addInputFilter方法,根据请求header中的transfer-encoding的值来选择要添加的filter。
transfer-encoding:
identity的时候,不添加filter
chunked的时候,添加ChunkedInputFilter
buffered的时候,添加BufferedInputFilter
void的时候,添加VoidInputFilter
如果header中没有transfer-encoding,那么从header中取content-length,如果content-length >= 0,那么添加IdentityInputFilter。否则,添加VoidInputFilter。
e.调用CoyoteAdapter类中的service(request, response)方法来处理请求。
f.请求处理完以后,调用endRequest()方法结束请求,向客户端返回响应。
getInputBuffer().endRequest(); getOutputBuffer().endRequest();
6.请求处理完以后,当前的请求处理线程结束。2.中的SocketProcessor的run方法结束。
关于e.中的service(request, response)方法的处理细节,下回继续分解。