Tomcat 7源码学习笔记 - 2 (socket接入后的处理)

前一篇文章写到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)方法的处理细节,下回继续分解。

猜你喜欢

转载自blogzhoubo.iteye.com/blog/1707067