`
wu_quanyin
  • 浏览: 208113 次
  • 性别: Icon_minigender_1
  • 来自: 福建省
社区版块
存档分类
最新评论

Tomcat源码---请求处理二

阅读更多

一,经过以上文章(JIoEndpoint$Worker#run)执行,就成功把socket交给tomcat中的coyote包执行

org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler#process(Socket socket)

 

 public boolean process(Socket socket) {
            Http11Processor processor = recycledProcessors.poll();
            try {

                if (processor == null) {
                    //创建Http11Processor
                    processor = createProcessor();
                }

                if (processor instanceof ActionHook) {
                         //标记process started为ture意为开始处理
                	((ActionHook) processor).action(ActionCode.ACTION_START, null);
                }

                if (proto.secure && (proto.sslImplementation != null)) {
                     //支持ssl
                    processor.setSSLSupport
                        (proto.sslImplementation.getSSLSupport(socket));
                } else {
                    processor.setSSLSupport(null);
                }
                //继续往下处理
                processor.process(socket);
                return false;

            } catch(java.net.SocketException e) {
                // SocketExceptions are normal
                Http11Protocol.log.debug
                    (sm.getString
                     ("http11protocol.proto.socketexception.debug"), e);
            } catch (java.io.IOException e) {
                // IOExceptions are normal
                Http11Protocol.log.debug
                    (sm.getString
                     ("http11protocol.proto.ioexception.debug"), e);
            }
            // Future developers: if you discover any other
            // rare-but-nonfatal exceptions, catch them here, and log as
            // above.
            catch (Throwable e) {
                // any other exception or error is odd. Here we log it
                // with "ERROR" level, so it will show up even on
                // less-than-verbose logs.
                Http11Protocol.log.error
                    (sm.getString("http11protocol.proto.error"), e);
            } finally {
                //       if(proto.adapter != null) proto.adapter.recycle();
                //                processor.recycle();

                if (processor instanceof ActionHook) {//设置started为false表示处理完毕
                    ((ActionHook) processor).action(ActionCode.ACTION_STOP, null);
                }
                recycledProcessors.offer(processor);
            }
            return false;
        }

  在创建Http11Processor的时候,进行了一系列的对象的初始化如下:

 

ublic Http11Processor(int headerBufferSize, JIoEndpoint endpoint) {  
  
      this.endpoint = endpoint;  
      //org.apache.coyote.Request  
      request = new Request();  
     //输入流  
      inputBuffer = new InternalInputBuffer(request, headerBufferSize);  
      request.setInputBuffer(inputBuffer);  
  
     //org.apache.coyote.Response  
      response = new Response();  
      response.setHook(this);  
      //输出流  
      outputBuffer = new InternalOutputBuffer(response, headerBufferSize);  
      response.setOutputBuffer(outputBuffer);  
      request.setResponse(response);  
  
      initializeFilters();  
  
      // Cause loading of HexUtils  
      int foo = HexUtils.DEC[0];  
  
  }  

    Http11Processor#process(Socket socket)

 

public void process(Socket socket)
        throws IOException {
        RequestInfo rp = request.getRequestProcessor();
        rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);

        // Set the remote address
        remoteAddr = null;
        remoteHost = null;
        localAddr = null;
        localName = null;
        remotePort = -1;
        localPort = -1;

        // Setting up the I/O
        this.socket = socket;
        //对scoket流进行设置处理
        inputBuffer.setInputStream(socket.getInputStream());
        outputBuffer.setOutputStream(socket.getOutputStream());
      
        // Error flag
        error = false;
        keepAlive = true;
        
  

	// 连接的计数器 
        int keepAliveLeft = maxKeepAliveRequests;
        //超时设置
        int soTimeout = socket.getSoTimeout();
        int oldSoTimeout = soTimeout;

	// 当前JIoEndpoint中的已经使用的Worker与总Worker的比例  
        int threadRatio = (endpoint.getCurrentThreadsBusy() * 100)
                / endpoint.getMaxThreads();
	// 如果使用中的Worker比例高于75%,只保持连接1次  
        if (threadRatio > 75) {
            keepAliveLeft = 1;
        }
        
        if (soTimeout != oldSoTimeout) {
            try {
                //设置进超时时限
                socket.setSoTimeout(soTimeout);
            } catch (Throwable t) {
                log.debug(sm.getString("http11processor.socket.timeout"), t);
                error = true;
            }
        }
	//是否被保持着连接
        boolean keptAlive = false;

        while (started && !error && keepAlive) {

            // Parsing the request header
            try {
                if (keptAlive) {
                    if (keepAliveTimeout > 0) {
                        socket.setSoTimeout(keepAliveTimeout);
                    }
                    else if (soTimeout > 0) {
                        socket.setSoTimeout(soTimeout);
                    }
                }
  		//读取请求行
                inputBuffer.parseRequestLine();
 		//设置请求开始时间
                request.setStartTime(System.currentTimeMillis());
                keptAlive = true;
                if (!disableUploadTimeout) {
                    socket.setSoTimeout(timeout);
                }
                //解析头部文件
                inputBuffer.parseHeaders();
            } catch (IOException e) {
                error = true;
                break;
            } catch (Throwable t) {
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("http11processor.header.parse"), t);
                }
                // 400 - Bad Request
                response.setStatus(400);
                error = true;
            }

            if (!error) {
                // Setting up filters, and parse some request headers
                rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
                try {
                    //开始准备请求,就是在里面把需要的信息设置进需要处理的对象inputbuffer outputbuffer,request,response等
                    prepareRequest();
                } catch (Throwable t) {
                    if (log.isDebugEnabled()) {
                        log.debug(sm.getString("http11processor.request.prepare"), t);
                    }
                    // 400 - Internal Server Error
                    response.setStatus(400);
                    error = true;
                }
            }

            if (maxKeepAliveRequests > 0 && --keepAliveLeft == 0)
                keepAlive = false;

            // Process the request in the adapter
            if (!error) {
                try {
                    rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                     // adapter是 org.apache.catalina.connector.CoyoteAdapter类的对象  
                     //这里面还对coyote.Request/Response转换成                     //org.apache.catalina.connector.Request/Response
                     //这一步是请求的下一步执行
                    adapter.service(request, response);
                    // Handle when the response was committed before a serious
                    // error occurred.  Throwing a ServletException should both
                    // set the status to 500 and set the errorException.
                    // If we fail here, then the response is likely already
                    // committed, so we can't try and set headers.
                    if(keepAlive && !error) { // Avoid checking twice.
                        error = response.getErrorException() != null ||
                                statusDropsConnection(response.getStatus());
                    }

                } catch (InterruptedIOException e) {
                    error = true;
                } catch (Throwable t) {
                    log.error(sm.getString("http11processor.request.process"), t);
                    // 500 - Internal Server Error
                    response.setStatus(500);
                    error = true;
                }
            }

            // Finish the handling of the request
            try {
                rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);
                // If we know we are closing the connection, don't drain input.
                // This way uploading a 100GB file doesn't tie up the thread 
                // if the servlet has rejected it.
                if(error)
                    inputBuffer.setSwallowInput(false);
                //结束请求
                inputBuffer.endRequest();
            } catch (IOException e) {
                error = true;
            } catch (Throwable t) {
                log.error(sm.getString("http11processor.request.finish"), t);
                // 500 - Internal Server Error
                response.setStatus(500);
                error = true;
            }
            try {
                rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);
                outputBuffer.endRequest();
            } catch (IOException e) {
                error = true;
            } catch (Throwable t) {
                log.error(sm.getString("http11processor.response.finish"), t);
                error = true;
            }

            // If there was an error, make sure the request is counted as
            // and error, and update the statistics counter
            if (error) {
                response.setStatus(500);
            }
            request.updateCounters();

            rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);

            // Don't reset the param - we'll see it as ended. Next request
            // will reset it
            // thrA.setParam(null);
            // Next request
            inputBuffer.nextRequest();
            outputBuffer.nextRequest();

        }

        rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);

        // Recycle
         //对流进行回收
        inputBuffer.recycle();
        outputBuffer.recycle();
        this.socket = null;
        // Recycle ssl info
        sslSupport = null;
    }

  接下去对这一步进行详解adapter.service(request, response);

 org.apache.catalina.connector.CoyoteAdapter#service对org.apache.coyote.Request/org.apache.coyote.Response进行封装成org.apache.catalina.connector.Request/Response

 

    /**
     * Service method.
     */
    public void service(org.apache.coyote.Request req, 
    	                org.apache.coyote.Response res)
        throws Exception {

        Request request = (Request) req.getNote(ADAPTER_NOTES);
        Response response = (Response) res.getNote(ADAPTER_NOTES);

        if (request == null) {
             进行封装成connector的reqeust..
            // Create objects
            request = (Request) connector.createRequest();
            request.setCoyoteRequest(req);
            response = (Response) connector.createResponse();
            response.setCoyoteResponse(res);

            // Link objects
            request.setResponse(response);
            response.setRequest(request);

            // Set as notes
            req.setNote(ADAPTER_NOTES, request);
            res.setNote(ADAPTER_NOTES, response);

            // Set query string encoding
            req.getParameters().setQueryStringEncoding
                (connector.getURIEncoding());

        }

        if (connector.getXpoweredBy()) {
            response.addHeader("X-Powered-By", "Servlet/2.5");
        }

        boolean comet = false;
        
        try {

            // Parse and set Catalina and configuration specific 
            // request parameters
            req.getRequestProcessor().setWorkerThreadName(Thread.currentThread().getName());
            //这里面有对sessionid的处理,以后详解
            if (postParseRequest(req, request, res, response)) {
                // Calling the container
                //运用pipeline以及valve,使request/response在容器间处理,,,重点详解这一步
                connector.getContainer().getPipeline().getFirst().invoke(request, response);

                if (request.isComet()) {
                    if (!response.isClosed() && !response.isError()) {
                        if (request.getAvailable() || (request.getContentLength() > 0 && (!request.isParametersParsed()))) {
                            // Invoke a read event right away if there are available bytes
                            if (event(req, res, SocketStatus.OPEN)) {
                                comet = true;
                                res.action(ActionCode.ACTION_COMET_BEGIN, null);
                            }
                        } else {
                            comet = true;
                            res.action(ActionCode.ACTION_COMET_BEGIN, null);
                        }
                    } else {
                        // Clear the filter chain, as otherwise it will not be reset elsewhere
                        // since this is a Comet request
                        request.setFilterChain(null);
                    }
                }

            }

            if (!comet) {
                response.finishResponse();//执行响应操作,返回给客户端
                req.action(ActionCode.ACTION_POST_REQUEST , null);
            }

        } catch (IOException e) {
            ;
        } catch (Throwable t) {
            log.error(sm.getString("coyoteAdapter.service"), t);
        } finally {
            req.getRequestProcessor().setWorkerThreadName(null);
            // Recycle the wrapper request and response
            if (!comet) {
                request.recycle();
                response.recycle();
            } else {
                // Clear converters so that the minimum amount of memory 
                // is used by this processor
                request.clearEncoders();
                response.clearEncoders();
            }
        }

    }
 

 

 

分享到:
评论

相关推荐

    apache-tomcat-7.0.81-src 源码免费下载

    9. **错误处理与日志系统**:Tomcat使用自定义的日志框架,源码中`logging`目录下的类定义了如何记录和处理错误信息。 10. **网络编程**:Tomcat底层使用NIO(非阻塞I/O)和BIO(阻塞I/O)模型,这在`java/org/...

    apache-tomcat-9.0.8-src源码资源

    通过对`apache-tomcat-9.0.8-src`源码的深入研究,我们可以了解到Tomcat如何处理网络请求,怎样管理Web应用,以及如何实现各种高级特性。这对于开发者来说是一份宝贵的学习资料,可以帮助他们更好地优化应用程序,...

    tomcat-connectors-1.2.48-src

    `mod_jk`负责在HTTPD服务器端接收请求,然后将这些请求转发到Tomcat,而`jk`则在Tomcat端处理这些请求,并返回响应给`mod_jk`,再由`mod_jk`转发给客户端。 2. **版本兼容性** `tomcat-connectors-1.2.48-src`特别...

    apache-tomcat-源码-lib包

    2. **HTTP链接**:Tomcat作为HTTP服务器,处理HTTP请求和响应。它通过解析HTTP协议来与客户端进行通信。lib目录下的httpcore.jar和httpclient.jar包含Apache HttpClient库,提供了高效的HTTP协议处理能力,使得...

    apache-tomcat-7.0.62-src和apache-tomcat-6.0.39-src的源码

    这个压缩包包含了两个版本的Tomcat源码:apache-tomcat-7.0.62-src和apache-tomcat-6.0.39-src,这两个版本分别代表了Tomcat在不同时间点的开发状态和技术特性。 首先,让我们从Apache Tomcat 6.0.39源码开始分析。...

    Tomcat源码apache-tomcat-8.5.47-src.zip

    2. ** Coyote**:负责处理HTTP请求和响应。Coyote是Tomcat的网络连接器,它包含一个或多个处理器,如`Http11Processor`,这些处理器处理HTTP协议细节。`org.apache.coyote`包下的类与网络通信密切相关。 3. ** ...

    tomcat6-server-and-src

    通过分析源码,开发者可以学习到如何遵循Servlet和JSP规范进行服务器端开发,理解Tomcat如何处理请求、管理会话、调度线程等。此外,源码还便于开发者修复已知问题,优化性能,或添加特定的功能。 总之,`tomcat6-...

    Tomcat 6.0 -- 9.0 及其源码

    深入研究Tomcat源码有助于开发者理解Web应用服务器的内部运作机制,提升系统设计和优化能力,同时也有助于自定义扩展和调试,实现更高效、安全的Web服务。 总之,从Tomcat 6.0到9.0,每个版本都带来了技术的进步和...

    apache-tomcat-6.0.29.zip

    7. **线程池**:Tomcat使用线程池模型处理并发请求,提高性能和响应速度。线程池大小可以在`server.xml`中调整。 8. **安全管理**:Tomcat支持角色基础的访问控制(RBAC),可以设置不同用户的访问权限,通过`...

    3-5Tomcat响应请求源码与nio处理请求源码实现.mp4

    3-5Tomcat响应请求源码与nio处理请求源码实现.mp4

    apache-tomcat-7.0.59,apache-tomcat-7.0.69 源码

    在源码分析中,开发者可以深入了解Tomcat如何处理请求、响应,以及它如何管理Web应用程序的生命周期。此外,对于性能优化、自定义行为或解决特定问题,源码阅读也是非常有价值的。 7.0.59和7.0.69之间的差异可能...

    apache-tomcat-9.0.14-src源码

    对于初次接触Tomcat源码的开发者,可以从阅读`src/main/java`目录下的源码开始,重点关注`org.apache.catalina`包下的类,以及`org.apache.coyote`和`org.apache.jasper`等包。同时,`conf/server.xml`是配置整个...

    tomcat7.0.42源码,eclipse直接使用

    Eclipse是一个广泛使用的Java集成开发环境(IDE),它支持直接导入和管理Tomcat源码。在Eclipse中,开发者可以通过导入“Existing Projects into Workspace”来加载Tomcat源码。然后,可以利用Eclipse的强大功能,如...

    apache-tomcat-6.0.37

    Tomcat作为Servlet和JSP容器,负责处理HTTP请求,解析请求到相应的Servlet或JSP页面,执行其中的Java代码,并将结果返回给客户端。 Apache Tomcat 6.0.37 版本是在2013年发布的一个稳定版本,支持Java EE 5规范。这...

    tomcat-7.0.42-src源码爱好者(已编译导入直接可用)

    通过研究Tomcat源码,开发者可以了解到HTTP请求的处理流程、Servlet容器的工作方式、以及如何高效地管理Web应用。此外,了解Tomcat源码还可以帮助开发者借鉴其设计模式和架构,以便在日常开发中构建更稳定、高效的...

    apache-tomcat-7.0.39-src

    在Tomcat中,Servlet用于处理HTTP请求并返回响应。 - **JSP**:JavaServer Pages是Java平台上的动态网页技术,允许开发者将HTML代码与Java代码混合编写,以实现动态内容的生成。 2. **Tomcat的结构**: - **conf*...

    tomcat源码+文档pdf+源码解析

    源码解析部分则是对Tomcat源码的深度剖析,涵盖了关键类和方法的作用、设计模式的运用以及性能优化技巧。这有助于开发者理解Tomcat内部的工作流程,例如,如何处理HTTP请求的生命周期,以及线程池是如何调度和管理的...

    tomcat8源码-eclipse工程

    7. **Eclipse集成**:在Eclipse中导入Tomcat源码,可以方便地进行调试、代码分析和自定义修改。这需要配置Tomcat插件,设置源代码路径,以及正确配置项目的构建路径。 8. **部署与调试**:在Eclipse中如何部署Web...

    jakarta-tomcat-connectors-1.2.15-src.tar.gz

    深入学习jakarta-tomcat-connectors-1.2.15-src源码,可以提升对Tomcat工作流程的理解,包括请求的接收、处理、响应过程,以及如何通过连接器优化服务器性能。这对于进行性能调优、定制化开发或者排查系统问题都至关...

    tomcat源码

    Apache Tomcat源码分析 Apache Tomcat是一款广泛应用的开源Java Servlet容器,它是Java EE Web应用程序的标准实现。Tomcat源码的深入理解对于Java Web开发者来说是至关重要的,它可以帮助我们了解HTTP服务器的工作...

Global site tag (gtag.js) - Google Analytics