tomcat处理请求

来源:互联网 发布:activiti 源码分析 编辑:程序博客网 时间:2024/06/13 11:42

参考资料:Tomcat7.0源码分析——请求原理分析(中)


客户端和服务器之间的链接建立了,那接下来就要接受数据,处理请求,我们来看看是怎样实现的。


1、我们之前创建了Acceptor线程类接受连接,成功连接以后就要进行处理socket了。

    protected class Acceptor extends AbstractEndpoint.Acceptor {        @Override        public void run() {            int errorDelay = 0;            while (running) {                while (paused && running) {                    state = AcceptorState.PAUSED;                    try {                        Thread.sleep(50);                    } catch (InterruptedException e) {                    }                }                if (!running) {                    break;                }                state = AcceptorState.RUNNING;                try {                    countUpOrAwaitConnection();                    Socket socket = null;                    try {                        socket = serverSocketFactory.acceptSocket(serverSocket);                    } catch (IOException ioe) {                        errorDelay = handleExceptionWithDelay(errorDelay);                        throw ioe;                    }                    errorDelay = 0;                    if (running && !paused && setSocketOptions(socket)) {                        // 在这里处理请求                        if (!processSocket(socket)) {                            closeSocket(socket);                        }                    } else {                        closeSocket(socket);                    }                } catch (IOException x) {                    if (running) {                        log.error(sm.getString("endpoint.accept.fail"), x);                    }                } catch (NullPointerException npe) {                    if (running) {                        log.error(sm.getString("endpoint.accept.fail"), npe);                    }                } catch (Throwable t) {                    ExceptionUtils.handleThrowable(t);                    log.error(sm.getString("endpoint.accept.fail"), t);                }            }            state = AcceptorState.ENDED;        }    }



2、进入processSocket方法,我们可以看到处理socket请求的是另一个线程类SocketProcessor。


    protected class SocketProcessor implements Runnable {        // 包装socket        protected SocketWrapper<Socket> socket = null;        protected SocketStatus status = null;        public SocketProcessor(SocketWrapper<Socket> socket) {            if (socket == null) throw new NullPointerException();            this.socket = socket;        }        public SocketProcessor(SocketWrapper<Socket> socket, SocketStatus status) {            this(socket);            this.status = status;        }        @Override        public void run() {            boolean launch = false;            synchronized (socket) {                try {                    SocketState state = SocketState.OPEN;                    try {                        serverSocketFactory.handshake(socket.getSocket());                    } catch (Throwable t) {                        ExceptionUtils.handleThrowable(t);                        if (log.isDebugEnabled()) {                            log.debug(sm.getString("endpoint.err.handshake"), t);                        }                        state = SocketState.CLOSED;                    }                    if ((state != SocketState.CLOSED)) {                        if (status == null) {                            // 处理请求的方法                            state = handler.process(socket, SocketStatus.OPEN);                        } else {                            state = handler.process(socket, status);                        }                    }                    if (state == SocketState.CLOSED) {                        if (log.isTraceEnabled()) {                            log.trace("Closing socket:" + socket);                        }                        countDownConnection();                        try {                            socket.getSocket().close();                        } catch (IOException e) {                        }                    } else if (state == SocketState.OPEN) {                        socket.setKeptAlive(true);                        socket.access();                        launch = true;                    } else if (state == SocketState.LONG) {                        socket.access();                        waitingRequests.add(socket);                    }                } finally {                    if (launch) {                        try {                            getExecutor().execute(new SocketProcessor(socket, SocketStatus.OPEN));                        } catch (NullPointerException npe) {                            if (running) {                                log.error(sm.getString("endpoint.launch.fail"), npe);                            }                        }                    }                }            }            socket = null;        }    }




3、进入process方法

public SocketState process(SocketWrapper<S> socket, SocketStatus status) {            P processor = connections.remove(socket.getSocket());            if (getLog().isDebugEnabled()) {                getLog().debug("process() entry " +                        "Socket: [" + logHashcode(socket.getSocket()) + "], " +                        "Processor [" + logHashcode(processor) + "]");            }            socket.setAsync(false);            try {                if (processor == null) {                    processor = recycledProcessors.poll();                }                if (processor == null) {                    // 创建Http请求处理器                    processor = createProcessor();                }                if (getLog().isDebugEnabled()) {                    getLog().debug("process() gotProcessor " +                            "Socket: [" + logHashcode(socket.getSocket()) + "], " +                            "Processor [" + logHashcode(processor) + "]");                }                initSsl(socket, processor);                SocketState state = SocketState.CLOSED;                do {                    if (processor.isAsync() || state == SocketState.ASYNC_END) {                        state = processor.asyncDispatch(status);                        if (getLog().isDebugEnabled()) {                            getLog().debug("process() asyncDispatch " +                                    "Socket: [" + logHashcode(socket.getSocket()) + "], " +                                    "Processor: [" + logHashcode(processor) + "], " +                                    "State: [" + state.toString() + "]");                        }                    } else if (processor.isComet()) {                        state = processor.event(status);                        if (getLog().isDebugEnabled()) {                            getLog().debug("process() event " +                                    "Socket: [" + logHashcode(socket.getSocket()) + "], " +                                    "Processor: [" + logHashcode(processor) + "], " +                                    "State: [" + state.toString() + "]");                        }                    } else {                        // 同步处理socket                        state = processor.process(socket);                        if (getLog().isDebugEnabled()) {                            getLog().debug("process() process " +                                    "Socket: [" + logHashcode(socket.getSocket()) + "], " +                                    "Processor: [" + logHashcode(processor) + "], " +                                    "State: [" + state.toString() + "]");                        }                    }                    if (state != SocketState.CLOSED && processor.isAsync()) {                        state = processor.asyncPostProcess();                        if (getLog().isDebugEnabled()) {                            getLog().debug("process() asyncPostProcess " +                                    "Socket: [" + logHashcode(socket.getSocket()) + "], " +                                    "Processor: [" + logHashcode(processor) + "], " +                                    "State: [" + state.toString() + "]");                        }                    }                } while (state == SocketState.ASYNC_END);                if (state == SocketState.LONG) {                    longPoll(socket, processor);                } else if (state == SocketState.OPEN) {                    release(socket, processor, false, true);                } else if (state == SocketState.SENDFILE) {                    release(socket, processor, false, false);                } else {                    release(socket, processor, true, false);                }                return state;            } catch (java.net.SocketException e) {                getLog().debug(sm.getString("ajpprotocol.proto.socketexception.debug"), e);            } catch (java.io.IOException e) {                getLog().debug(sm.getString("ajpprotocol.proto.ioexception.debug"), e);            }            catch (Throwable e) {                ExceptionUtils.handleThrowable(e);                getLog().error(sm.getString("ajpprotocol.proto.error"), e);            }            release(socket, processor, true, false);            return SocketState.CLOSED;        }


4、在process方法中,解析成Request对象,交给CoyoteAdapter 进行处理

    @Override    public SocketState process(SocketWrapper<S> socketWrapper) throws IOException {        RequestInfo rp = request.getRequestProcessor();        rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);        setSocketWrapper(socketWrapper);        getInputBuffer().init(socketWrapper, endpoint);        getOutputBuffer().init(socketWrapper, endpoint);        error = false;        keepAlive = true;        comet = false;        openSocket = false;        sendfileInProgress = false;        readComplete = true;        if (endpoint.getUsePolling()) {            keptAlive = false;        } else {            keptAlive = socketWrapper.isKeptAlive();        }        if (disableKeepAlive()) {            socketWrapper.setKeepAliveLeft(0);        }        while (!error && keepAlive && !comet && !isAsync() &&                !endpoint.isPaused()) {            try {                setRequestLineReadTimeout();                if (!getInputBuffer().parseRequestLine(keptAlive)) {                    if (handleIncompleteRequestLineRead()) {                        break;                    }                }                if (endpoint.isPaused()) {                    response.setStatus(503);                    error = true;                } else {                    request.setStartTime(System.currentTimeMillis());                    keptAlive = true;                    if (!getInputBuffer().parseHeaders()) {                        openSocket = true;                        readComplete = false;                        break;                    }                    if (!disableUploadTimeout) {                        setSocketTimeout(connectionUploadTimeout);                    }                }            } catch (IOException e) {                if (getLog().isDebugEnabled()) {                    getLog().debug(sm.getString("http11processor.header.parse"), e);                }                error = true;                break;            } catch (Throwable t) {                ExceptionUtils.handleThrowable(t);                if (getLog().isDebugEnabled()) {                    getLog().debug(sm.getString("http11processor.header.parse"), t);                }                response.setStatus(400);                adapter.log(request, response, 0);                error = true;            }            if (!error) {                rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);                try {                    prepareRequest();                } catch (Throwable t) {                    ExceptionUtils.handleThrowable(t);                    if (getLog().isDebugEnabled()) {                        getLog().debug(sm.getString("http11processor.request.prepare"), t);                    }                    response.setStatus(400);                    adapter.log(request, response, 0);                    error = true;                }            }            if (maxKeepAliveRequests == 1) {                keepAlive = false;            } else if (maxKeepAliveRequests > 0 &&                    socketWrapper.decrementKeepAlive() <= 0) {                keepAlive = false;            }            if (!error) {                try {                    rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);                    // 把请求交给CoyoteAdapter 来处理                    adapter.service(request, response);                    if (keepAlive && !error) {                        error = response.getErrorException() != null || (!isAsync() && statusDropsConnection(response.getStatus()));                    }                    setCometTimeouts(socketWrapper);                } catch (InterruptedIOException e) {                    error = true;                } catch (Throwable t) {                    ExceptionUtils.handleThrowable(t);                    getLog().error(sm.getString("http11processor.request.process"), t);                    response.setStatus(500);                    adapter.log(request, response, 0);                    error = true;                }            }            rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);            if (!isAsync() && !comet) {                if (error) {                   getInputBuffer().setSwallowInput(false);                }                endRequest();            }            rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);            if (error) {                response.setStatus(500);            }            request.updateCounters();            if (!isAsync() && !comet || error) {                getInputBuffer().nextRequest();                getOutputBuffer().nextRequest();            }            if (!disableUploadTimeout) {                setSocketTimeout(endpoint.getSoTimeout());            }            rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);            if (breakKeepAliveLoop(socketWrapper)) {                break;            }        }        rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);        if (error || endpoint.isPaused()) {            return SocketState.CLOSED;        } else if (isAsync() || comet) {            return SocketState.LONG;        } else {            if (sendfileInProgress) {                return SocketState.SENDFILE;            } else {                if (openSocket) {                    if (readComplete) {                        return SocketState.OPEN;                    } else {                        return SocketState.LONG;                    }                } else {                    return SocketState.CLOSED;                }            }        }    }


5、CoyoteAdapter 的service方法继续解析请求

@Override    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) {            request = connector.createRequest();            request.setCoyoteRequest(req);            response = connector.createResponse();            response.setCoyoteResponse(res);            request.setResponse(response);            response.setRequest(request);            req.setNote(ADAPTER_NOTES, request);            res.setNote(ADAPTER_NOTES, response);            req.getParameters().setQueryStringEncoding                    (connector.getURIEncoding());        }        if (connector.getXpoweredBy()) {            response.addHeader("X-Powered-By", POWERED_BY);        }        boolean comet = false;        boolean async = false;        try {            req.getRequestProcessor().setWorkerThreadName(Thread.currentThread().getName());            // 解析请求            boolean postParseSuccess = postParseRequest(req, request, res, response);            if (postParseSuccess) {                request.setAsyncSupported(connector.getService().getContainer().getPipeline().isAsyncSupported());                // 处理请求                connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);                if (request.isComet()) {                    if (!response.isClosed() && !response.isError()) {                        if (request.getAvailable() || (request.getContentLength() > 0 && (!request.isParametersParsed()))) {                            if (event(req, res, SocketStatus.OPEN)) {                                comet = true;                                res.action(ActionCode.COMET_BEGIN, null);                            }                        } else {                            comet = true;                            res.action(ActionCode.COMET_BEGIN, null);                        }                    } else {                        request.setFilterChain(null);                    }                }            }            AsyncContextImpl asyncConImpl = (AsyncContextImpl) request.getAsyncContext();            if (asyncConImpl != null) {                async = true;            } else if (!comet) {                request.finishRequest();                response.finishResponse();                if (postParseSuccess && request.getMappingData().context != null) {                    ((Context) request.getMappingData().context).logAccess(request, response, System.currentTimeMillis() - req.getStartTime(), false);                }                req.action(ActionCode.POST_REQUEST, null);            }        } catch (IOException e) {        } finally {            req.getRequestProcessor().setWorkerThreadName(null);            if (!comet && !async) {                request.recycle();                response.recycle();            } else {                request.clearEncoders();                response.clearEncoders();            }        }    }


    protected boolean postParseRequest(org.apache.coyote.Request req, Request request, org.apache.coyote.Response res, Response response) throws Exception {        if (!req.scheme().isNull()) {            request.setSecure(req.scheme().equals("https"));        } else {            req.scheme().setString(connector.getScheme());            request.setSecure(connector.getSecure());        }        String proxyName = connector.getProxyName();        int proxyPort = connector.getProxyPort();        if (proxyPort != 0) {            req.setServerPort(proxyPort);        }        if (proxyName != null) {            req.serverName().setString(proxyName);        }        MessageBytes decodedURI = req.decodedURI();        decodedURI.duplicate(req.requestURI());        parsePathParameters(req, request);        try {            req.getURLDecoder().convert(decodedURI, false);        } catch (IOException ioe) {            res.setStatus(400);            res.setMessage("Invalid URI: " + ioe.getMessage());            connector.getService().getContainer().logAccess(request, response, 0, true);            return false;        }        if (!normalize(req.decodedURI())) {            res.setStatus(400);            res.setMessage("Invalid URI");            connector.getService().getContainer().logAccess(request, response, 0, true);            return false;        }        convertURI(decodedURI, request);        if (!checkNormalize(req.decodedURI())) {            res.setStatus(400);            res.setMessage("Invalid URI character encoding");            connector.getService().getContainer().logAccess(request, response, 0, true);            return false;        }        String principal = req.getRemoteUser().toString();        if (principal != null) {            request.setUserPrincipal(new CoyotePrincipal(principal));        }        String authtype = req.getAuthType().toString();        if (authtype != null) {            request.setAuthType(authtype);        }        MessageBytes serverName;        if (connector.getUseIPVHosts()) {            serverName = req.localName();            if (serverName.isNull()) {                res.action(ActionCode.REQ_LOCAL_NAME_ATTRIBUTE, null);            }        } else {            serverName = req.serverName();        }        if (request.isAsyncStarted()) {            request.getMappingData().recycle();        }        boolean mapRequired = true;        String version = null;        while (mapRequired) {            if (version != null) {                mapRequired = false;            }            connector.getMapper().map(serverName, decodedURI, version,                    request.getMappingData());            request.setContext((Context) request.getMappingData().context);            request.setWrapper((Wrapper) request.getMappingData().wrapper);            if (request.getMappingData().contexts == null) {                mapRequired = false;            }            if (request.getContext() == null) {                res.setStatus(404);                res.setMessage("Not found");                Host host = request.getHost();                if (host != null) {                    host.logAccess(request, response, 0, true);                }                return false;            }            String sessionID = null;            if (request.getServletContext().getEffectiveSessionTrackingModes()                    .contains(SessionTrackingMode.URL)) {                sessionID = request.getPathParameter(                        SessionConfig.getSessionUriParamName(                                request.getContext()));                if (sessionID != null) {                    request.setRequestedSessionId(sessionID);                    request.setRequestedSessionURL(true);                }            }            parseSessionCookiesId(req, request);            parseSessionSslId(request);            sessionID = request.getRequestedSessionId();            if (mapRequired) {                if (sessionID == null) {                    mapRequired = false;                } else {                    Object[] objs = request.getMappingData().contexts;                    for (int i = (objs.length); i > 0; i--) {                        Context ctxt = (Context) objs[i - 1];                        if (ctxt.getManager().findSession(sessionID) != null) {                            if (ctxt.equals(request.getMappingData().context)) {                                mapRequired = false;                            } else {                                version = ctxt.getWebappVersion();                                request.getMappingData().recycle();                                break;                            }                        }                    }                    if (version == null) {                        mapRequired = false;                    }                }            }        }        MessageBytes redirectPathMB = request.getMappingData().redirectPath;        if (!redirectPathMB.isNull()) {            String redirectPath = urlEncoder.encode(redirectPathMB.toString());            String query = request.getQueryString();            if (request.isRequestedSessionIdFromURL()) {                redirectPath = redirectPath + ";" +                        SessionConfig.getSessionUriParamName(                                request.getContext()) +                        "=" + request.getRequestedSessionId();            }            if (query != null) {                redirectPath = redirectPath + "?" + query;            }            response.sendRedirect(redirectPath);            request.getContext().logAccess(request, response, 0, true);            return false;        }        if (!connector.getAllowTrace()                && req.method().equalsIgnoreCase("TRACE")) {            Wrapper wrapper = request.getWrapper();            String header = null;            if (wrapper != null) {                String[] methods = wrapper.getServletMethods();                if (methods != null) {                    for (int i = 0; i < methods.length; i++) {                        if ("TRACE".equals(methods[i])) {                            continue;                        }                        if (header == null) {                            header = methods[i];                        } else {                            header += ", " + methods[i];                        }                    }                }            }            res.setStatus(405);            res.addHeader("Allow", header);            res.setMessage("TRACE method is not allowed");            request.getContext().logAccess(request, response, 0, true);            return false;        }        return true;    }


终于看到真正处理请求的方法了。。。。


原创粉丝点击