📄 contextmanager.java
字号:
}
/** 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("");
if(ctx == null){
// The request didn't map into any context so send a 404 error.
try{
handleContextNotFound(req, res);
}catch(IOException e){
}
return;
}
// 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 ( statusLoop( ctx, req, code ) ){
log( "Error loop for " + req + " error code " + code);
return;
}
if( errorServlet==null ) {
if( code == 404 )
errorServlet=ctx.getServletByName( "tomcat.notFoundHandler");
else
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 = -1;
if ( !((UnavailableException)t).isPermanent() ) {
unavailableTime = ((UnavailableException)t).getUnavailableSeconds();
// if unavailable time not known, use 1 second
if ( unavailableTime <= 0 )
unavailableTime = 1;
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());
req.setAttribute("javax.servlet.error.message", t.getMessage());
req.setAttribute("javax.servlet.jsp.jspException", t);
req.setAttribute("tomcat.servlet.error.throwable", t);
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
}
}
public ServletWrapper getHandlerForPath( Context ctx, String path ) {
if( ! path.startsWith( "/" ) ) {
return ctx.getServletByName( path );
}
RequestImpl req1=new RequestImpl();
ResponseImpl res1=new ResponseImpl();
initRequest( req1, res1 );
req1.setServerName( ctx.getHost() );
req1.setRequestURI( ctx.getPath() + path );
processRequest( req1 );
return req1.getWrapper();
}
/** Handle the case of error handler generating an error or special status
*/
private boolean errorLoop( Context ctx, Request req ) {
if( req.getAttribute("javax.servlet.error.status_code") != null
|| req.getAttribute("javax.servlet.error.exception_type")!=null) {
if( ctx.getDebug() > 0 )
ctx.log( "Error: exception inside exception servlet " +
req.getAttribute("javax.servlet.error.status_code") +
" " + req.
getAttribute("javax.servlet.error.exception_type"));
return true;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -