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; } }
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; }
终于看到真正处理请求的方法了。。。。
阅读全文
0 0
- tomcat请求处理流程
- tomcat处理请求流程
- tomcat处理请求
- Tomcat请求处理流程
- Tomcat处理请求过程
- tomcat 处理请求过程
- Tomcat请求处理过程
- tomcat 请求处理模型
- tomcat处理请求
- Tomcat请求处理(三) -- coyote请求处理
- Tomcat请求处理(二) -- 请求处理框架
- Tomcat - 处理HTTP请求过程
- Tomcat请求处理控制结构
- tomcat处理请求的过程
- tomcat请求处理(续)
- tomcat处理客户端请求原理
- tomcat处理请求的过程
- Tomcat如何处理一个请求
- 指针和运算符优先级
- 用户行为日志-js埋点(一)实现整体流程
- PHP写注册登录界面有关表单的低级错误
- intelij破解方法
- 回到顶部
- tomcat处理请求
- 测试博客
- Requst相关属性
- HTML标题处有一个小图片
- 组件属性
- wr720n v4 折腾笔记(四):安装inode客户端njitclient
- 拒绝纸上谈兵--萌新开发手册(踩坑分享之封装)
- webService 初解
- C# ListView 简单的搜索功能