zoukankan      html  css  js  c++  java
  • tomcat源码阅读_代码篇11

    Http11Processor类,该类用于处理接受到得HTTP请求。在该类中主要需要注意的是process方法,如下:

        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;
            inputBuffer.setInputStream(socket.getInputStream());
            outputBuffer.setOutputStream(socket.getOutputStream());

            // Error flag
            error = false;
            keepAlive = true;

            int keepAliveLeft = maxKeepAliveRequests;
            int soTimeout = socket.getSoTimeout();
            int oldSoTimeout = soTimeout;

            int threadRatio = (endpoint.getCurrentThreadsBusy() * 100)
                    / endpoint.getMaxThreads();
            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 {
                        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.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;
        }

    在该方法中,主要就是完成协议解析,服务,响应等工作。

    1:解析

    inputBuffer.parseRequestLine();

    inputBuffer.parseHeaders();
    prepareRequest();

    2:服务响应

    adapter.service(request, response);

    在上面的语句中使用到了org.apache.catalina.connector.CoyoteAdapter类,该类实现了Adapter接口,用于处理用户请求。

    service方法如下:

        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) {

                // 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());
                if (postParseRequest(req, request, res, response)) {
                    // Calling the container
                    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();
                }
            }

        }

    在后边的内容中主要学习

    connector.getContainer().getPipeline().getFirst().invoke(request, response);

    是如何工作的

  • 相关阅读:
    Leetcode 50.Pow(x,n) By Python
    Leetcode 347.前K个高频元素 By Python
    Leetcode 414.Fizz Buzz By Python
    Leetcode 237.删除链表中的节点 By Python
    Leetcode 20.有效的括号 By Python
    Leetcode 70.爬楼梯 By Python
    Leetcode 190.颠倒二进制位 By Python
    团体程序设计天梯赛 L1-034. 点赞
    Wannafly挑战赛9 C-列一列
    TZOJ Start
  • 原文地址:https://www.cnblogs.com/macula7/p/1960473.html
Copyright © 2011-2022 走看看