public void reset() { if (DEBUG) log.debug("reset {}", this); // reset state if (_state == State.CLOSE || _state == State.CLOSED) return; setState(State.START); _endOfContent = EndOfContent.UNKNOWN_CONTENT; _contentLength = -1; _contentPosition = 0; _responseStatus = 0; _contentChunk = null; _headerBytes = 0; _host = false; }
@Override public void dispatcher(HttpServletRequest request, HttpServletResponse response) { String encoding = webContext.getEncoding(); try { request.setCharacterEncoding(encoding); } catch (Throwable t) { log.error("dispatcher error", t); } response.setCharacterEncoding(encoding); String uri = request.getRequestURI(); String prePath = request.getContextPath() + request.getServletPath(); String invokeUri = uri.substring(prePath.length()); String key = request.getMethod() + "@" + invokeUri; String beforeIntercept = "b#" + invokeUri; String afterIntercept = "a#" + invokeUri; Set<MvcMetaInfo> beforeSet = webContext.getBean(beforeIntercept); Set<MvcMetaInfo> afterSet = webContext.getBean(afterIntercept); log.debug("uri map [{}]", key); MvcMetaInfo mvcMetaInfo = webContext.getBean(key); if (mvcMetaInfo != null) { Object ret = null; Object beforeRet = null; // 前置拦截器的返回值 MvcMetaInfo lastBefore = null; // 最后得到的前置拦截器 Object afterRet = null; // 后置拦截器的返回值 MvcMetaInfo lastAfter = null; // 最后得到的后置拦截器 // 前置拦截栈调用 if (beforeSet != null) { for (MvcMetaInfo before : beforeSet) { Object[] beforeP = getParams(request, response, before, null); beforeRet = before.invoke(beforeP); if (beforeRet != null) { lastBefore = before; break; } } } if (beforeRet == null) { // controller调用 Object[] p = getParams(request, response, mvcMetaInfo, null); ret = mvcMetaInfo.invoke(p); // 后置拦截栈调用 if (afterSet != null) { for (MvcMetaInfo after : afterSet) { Object[] afterP = getParams(request, response, after, ret); afterRet = after.invoke(afterP); if (afterRet != null) { lastAfter = after; break; } } } } // 视图渲染 try { if (afterRet != null) { lastAfter.getViewHandle().render(request, response, afterRet); } else if (beforeRet != null) { lastBefore.getViewHandle().render(request, response, beforeRet); } else { mvcMetaInfo.getViewHandle().render(request, response, ret); } } catch (Throwable t) { log.error("dispatcher error", t); } } else { String msg = request.getRequestURI() + " not register"; SystemHtmlPage.responseSystemPage( request, response, webContext.getEncoding(), HttpServletResponse.SC_NOT_FOUND, msg); } }
protected void setState(State state) { if (DEBUG) log.debug("{} --> {}", _state, state); _state = state; }
/** Request that the associated data source be closed */ public void close() { if (DEBUG) log.debug("close {}", this); setState(State.CLOSE); }
/** Signal that the associated data source is at EOF */ public void atEOF() { if (DEBUG) log.debug("atEOF {}", this); _eof = true; }
/** * Parse until next Event. * * @param buffer the buffer to parse * @return True if an {@link RequestHandler} method was called and it returned true; */ public boolean parseNext(ByteBuffer buffer) { if (DEBUG) log.debug("parseNext s={} {}", _state, BufferUtils.toDetailString(buffer)); try { // Start a request/response if (_state == State.START) { _version = null; _method = null; _methodString = null; _endOfContent = EndOfContent.UNKNOWN_CONTENT; _header = null; if (quickStart(buffer)) return true; } // Request/response line if (_state.ordinal() >= State.START.ordinal() && _state.ordinal() < State.HEADER.ordinal()) { if (parseLine(buffer)) return true; } // parse headers if (_state.ordinal() >= State.HEADER.ordinal() && _state.ordinal() < State.CONTENT.ordinal()) { if (parseHeaders(buffer)) return true; } // parse content if (_state.ordinal() >= State.CONTENT.ordinal() && _state.ordinal() < State.END.ordinal()) { // Handle HEAD response if (_responseStatus > 0 && _headResponse) { setState(State.END); return _handler.messageComplete(); } else { if (parseContent(buffer)) return true; } } // handle end states if (_state == State.END) { // eat white space while (buffer.remaining() > 0 && buffer.get(buffer.position()) <= HttpTokens.SPACE) buffer.get(); } else if (_state == State.CLOSE) { // Seeking EOF if (BufferUtils.hasContent(buffer)) { // Just ignore data when closed _headerBytes += buffer.remaining(); BufferUtils.clear(buffer); if (_maxHeaderBytes > 0 && _headerBytes > _maxHeaderBytes) { // Don't want to waste time reading data of a closed // request throw new IllegalStateException("too much data seeking EOF"); } } } else if (_state == State.CLOSED) { BufferUtils.clear(buffer); } // Handle EOF if (_eof && !buffer.hasRemaining()) { switch (_state) { case CLOSED: break; case START: setState(State.CLOSED); _handler.earlyEOF(); break; case END: case CLOSE: setState(State.CLOSED); break; case EOF_CONTENT: setState(State.CLOSED); return _handler.messageComplete(); case CONTENT: case CHUNKED_CONTENT: case CHUNK_SIZE: case CHUNK_PARAMS: case CHUNK: setState(State.CLOSED); _handler.earlyEOF(); break; default: if (DEBUG) log.debug("{} EOF in {}", this, _state); setState(State.CLOSED); _handler.badMessage(400, null); break; } } } catch (BadMessageException e) { BufferUtils.clear(buffer); Throwable cause = e.getCause(); boolean stack = log.isDebugEnable() || (!(cause instanceof NumberFormatException) && (cause instanceof RuntimeException || cause instanceof Error)); if (stack) log.warn( "bad HTTP parsed: " + e._code + (e.getReason() != null ? " " + e.getReason() : "") + " for " + _handler, e); else log.warn( "bad HTTP parsed: " + e._code + (e.getReason() != null ? " " + e.getReason() : "") + " for " + _handler); setState(State.CLOSE); _handler.badMessage(e.getCode(), e.getReason()); } catch (NumberFormatException | IllegalStateException e) { BufferUtils.clear(buffer); log.warn("parse exception: {} in {} for {}", e.toString(), _state, _handler); if (DEBUG) log.debug("parse exception", e); switch (_state) { case CLOSED: break; case CLOSE: _handler.earlyEOF(); break; default: setState(State.CLOSE); _handler.badMessage(400, null); } } catch (Exception | Error e) { BufferUtils.clear(buffer); log.warn("parse exception: " + e.toString() + " for " + _handler, e); switch (_state) { case CLOSED: break; case CLOSE: _handler.earlyEOF(); break; default: setState(State.CLOSE); _handler.badMessage(400, null); } } return false; }