📄 contextmanager.java
字号:
// wront request - parsing error int status=res.getStatus(); if( status >= 400 ) { if( debug > 0) log( "Error reading request " + req + " " + status); handleStatus( req, res, status ); return; } status= processRequest( req ); if( status != 0 ) { if( debug > 0) log("Error mapping the request " + req + " " + status); handleStatus( req, res, status ); return; } if( req.getWrapper() == null ) { status=404; if( debug > 0) log("No handler for request " + req + " " + status); handleStatus( req, res, status ); return; } String roles[]=req.getRequiredRoles(); if(roles != null ) status=doAuthorize( req, res, roles ); if( status > 200 ) { if( debug > 0) log("Authorize error " + req + " " + status); handleStatus( req, res, status ); return; } req.getWrapper().service(req, res); } catch (Throwable t) { handleError( req, res, t ); } } /** Will find the ServletWrapper for a servlet, assuming we already have * the Context. This is also used by Dispatcher and getResource - * where the Context is already known. */ public int processRequest( Request req ) { if(debug>9) logInt("ProcessRequest: "+req.toString()); int status=0; for( int i=0; i< requestInterceptors.size(); i++ ) { status=((RequestInterceptor)requestInterceptors.elementAt(i)). contextMap( req ); if( status!=0 ) return status; } for( int i=0; i< requestInterceptors.size(); i++ ) { status=((RequestInterceptor)requestInterceptors.elementAt(i)). requestMap( req ); if( status!=0 ) return status; } if(debug>9) logInt("After processing: "+req.toString()); return 0; } /** Call all authentication callbacks. If any of them is able to identify the user it will set the principal in req. */ public int doAuthenticate( Request req, Response res ) { int status=0; RequestInterceptor reqI[]= getRequestInterceptors(req); for( int i=0; i< reqI.length; i++ ) { status=reqI[i].authenticate( req, res ); if ( status != 0 ) { if( debug>0) logInt( "Authenticate status " + status ); return status; } } return 0; } /** Call all authorization callbacks. The "require valid user" attributes are probably set during the mapping stage ( for efficiency), but it can be done here too. */ public int doAuthorize( Request req, Response res, String roles[] ) { int status=0; RequestInterceptor reqI[]= getRequestInterceptors(req); for( int i=0; i< reqI.length; i++ ) { status = reqI[i].authorize( req, res, roles ); if ( status != 0 ) { if( debug>0) logInt( "Authorize status " + status ); return status; } } return 0; } /** Call beforeBody callbacks. Before body allows you do do various actions before the first byte of the response is sent. After all those callbacks are called tomcat may send the status and headers */ int doBeforeBody( Request req, Response res ) { RequestInterceptor reqI[]= getRequestInterceptors(req); for( int i=0; i< reqI.length; i++ ) { reqI[i].beforeBody( req, res ); } return 0; } /** Call beforeCommit callbacks. This allows interceptors to manipulate the buffer before it gets sent. XXX Add a standard way to access the body. The method was not used too much, we need a review and maybe change in parameters. */ int doBeforeCommit( Request req, Response res ) { RequestInterceptor reqI[]= getRequestInterceptors(req); for( int i=0; i< reqI.length; i++ ) { reqI[i].beforeCommit( req, res ); } return 0; } int doPreService( Request req, Response res ) { RequestInterceptor reqI[]= getRequestInterceptors(req); for( int i=0; i< reqI.length; i++ ) { reqI[i].preService( req, res ); } return 0; } int doPostService( Request req, Response res ) { RequestInterceptor reqI[]= getRequestInterceptors(req); for( int i=0; i< reqI.length; i++ ) { reqI[i].postService( req, res ); } return 0; } int doNewSessionRequest( Request req, Response res ) { RequestInterceptor reqI[]= getRequestInterceptors(req); for( int i=0; i< reqI.length; i++ ) { reqI[i].newSessionRequest( req, res ); } return 0; } /** Call afterBody callbacks. It is called after the servlet finished sending the response ( either closeing the stream or ending ). You can deal with connection reuse or do other actions */ int doAfterBody( Request req, Response res ) { RequestInterceptor reqI[]= getRequestInterceptors(req); for( int i=0; i< reqI.length; i++ ) { reqI[i].afterBody( req, res ); } return 0; } // -------------------- Sub-Request mechanism -------------------- /** Create a new sub-request in a given context, set the context "hint" * This is a particular case of sub-request that can't get out of * a context ( and we know the context before - so no need to compute it * again) * * Note that session and all stuff will still be computed. */ public Request createRequest( Context ctx, String urlPath ) { // assert urlPath!=null // deal with paths with parameters in it String contextPath=ctx.getPath(); String origPath=urlPath; // append context path if( !"".equals(contextPath) && !"/".equals(contextPath)) { if( urlPath.startsWith("/" ) ) urlPath=contextPath + urlPath; else urlPath=contextPath + "/" + urlPath; } else { // root context if( !urlPath.startsWith("/" ) ) urlPath= "/" + urlPath; } if( debug >4 ) logInt("createRequest " + origPath + " " + urlPath ); Request req= createRequest( urlPath ); String host=ctx.getHost(); if( host != null) req.setServerName( host ); return req; } /** Create a new sub-request, deal with query string */ public Request createRequest( String urlPath ) { String queryString=null; int i = urlPath.indexOf("?"); int len=urlPath.length(); if (i>-1) { if(i<len) queryString =urlPath.substring(i + 1, urlPath.length()); urlPath = urlPath.substring(0, i); } /** Creates an "internal" request */ RequestImpl lr = new RequestImpl(); // RequestAdapterImpl reqA=new RequestAdapterImpl(); //lr.setRequestAdapter( reqA); lr.setRequestURI( urlPath ); lr.setQueryString( queryString ); // lr.processQueryString(); // lr.setContext( ctx ); // XXX set query string too return lr; } // -------------------- Error handling -------------------- public void saveErrorURI( Request req, Response res ) { if (res.getErrorURI() == null) res.setErrorURI( (String)req.getAttribute("javax.servlet.include.request_uri")); } /** Called for error-codes */ public void handleStatus( Request req, Response res, int code ) { String errorPath=null; Handler errorServlet=null; try { res.resetBuffer(); } catch (Exception e) { } if( code==0 ) code=res.getStatus(); else res.setStatus(code); Context ctx = req.getContext(); if(ctx==null) ctx=getContext(""); // don't log normal cases ( redirect and need_auth ), they are not // error // XXX this log was intended to debug the status code generation. // it can be removed for all cases. if( code != 302 && code != 401 ) ctx.log( code + " " + req + " " + req.getAttribute("javax.servlet.error.message")); errorPath = ctx.getErrorPage( code ); if( errorPath != null ) { errorServlet=getHandlerForPath( ctx, errorPath ); // if not an internal handler if (errorPath.indexOf("tomcat.") != 0) { // Make sure Jsps will work req.setAttribute( "javax.servlet.include.request_uri", ctx.getPath() + "/" + errorPath ); req.setAttribute( "javax.servlet.include.servlet_path", errorPath ); } } if( debug>0 ) ctx.log( "Handler " + errorServlet + " " + errorPath); if( errorServlet==null ) errorServlet=ctx.getServletByName( "tomcat.statusHandler"); req.setAttribute("javax.servlet.error.status_code",new Integer( code)); req.setAttribute("tomcat.servlet.error.request", req); try { errorServlet.service( req, res ); } catch( IOException e ) { ; // ASSERT: Only thrown by included servlets } catch( ServletException e ) { ; // ASSERT: Only thrown by included servlets } } // XXX XXX Security - we should log the message, but nothing // should show up to the user - it gives up information // about the internal system ! // Developers can/should use the logs !!! /** General error handling mechanism. It will try to find an error handler * or use the default handler. */ void handleError( Request req, Response res , Throwable t ) { Context ctx = req.getContext(); if(ctx==null) { ctx=getContext(""); } /** The exception must be available to the user. Note that it is _WRONG_ to send the trace back to the client. AFAIK the trace is the _best_ debugger. */ if (t instanceof UnavailableException) { int unavailableTime = ((UnavailableException)t).getUnavailableSeconds(); if( unavailableTime > 0 ) { res.setHeader("Retry-After", Integer.toString(unavailableTime)); } String msg=t.getMessage(); ctx.log( "UnavailableException in: " + req + ", time remaining " + unavailableTime + " seconds : " + msg, t); req.setAttribute("javax.servlet.error.message", msg ); req.setAttribute("tomcat.servlet.error.unavailableTime", new Integer(unavailableTime)); res.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE); // 503 handleStatus( req, res, HttpServletResponse.SC_SERVICE_UNAVAILABLE ); return; } else if( t instanceof IllegalStateException ) { ctx.log("IllegalStateException in: " + req + " " + t.getMessage() ); } else if( t instanceof org.apache.jasper.JasperException ) { ctx.log("JasperException: " + req + " " + t.getMessage()); } else if( t instanceof IOException ) { if ( "Broken pipe".equals(t.getMessage())) return; ctx.log("IOException in: " + req + " " + t.getMessage()); } else { ctx.log("Exception in: " + req , t ); } if(null!=req.getAttribute("tomcat.servlet.error.defaultHandler")){ // we are in handleRequest for the "default" error handler System.out.println("ERROR: can't find default error handler "+ "or error in default error page"); t.printStackTrace(); } String errorPath=null; Handler errorServlet=null; // Scan the exception's inheritance tree looking for a rule // that this type of exception should be forwarded Class clazz = t.getClass(); while (errorPath == null && clazz != null) { String name = clazz.getName(); errorPath = ctx.getErrorPage(name); clazz = clazz.getSuperclass(); } if( errorPath != null ) { errorServlet=getHandlerForPath( ctx, errorPath ); // Make sure Jsps will work req.setAttribute( "javax.servlet.include.request_uri", ctx.getPath() + "/" + errorPath ); req.setAttribute( "javax.servlet.include.servlet_path", errorPath ); } if( errorLoop( ctx, req ) || errorServlet==null) errorServlet = ctx.getServletByName("tomcat.exceptionHandler"); else { // reset buffer only if using a non-default handler, ignore exception try { res.resetBuffer(); } catch (Exception e) { } } req.setAttribute("javax.servlet.error.exception_type", t.getClass());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -