Class ConditionalHandler
- All Implemented Interfaces:
Handler, Handler.Container, Handler.Singleton, Request.Handler, Container, Destroyable, Dumpable, Dumpable.DumpableContainer, LifeCycle, Invocable
- Direct Known Subclasses:
ConditionalHandler.Abstract, ConditionalHandler.ElseNext
Handler.Wrapper that conditionally handles a Request.
The conditions are implemented by IncludeExcludes of:
- A HTTP method name, which can be efficiently matched
- A
PathSpecor string representation, which can be efficiently matched. - An arbitrary
Predicatetaking theRequest, which is matched in a linear test of all predicates.
If the conditions are met, the abstract onConditionsMet(Request, Response, Callback) method will be invoked,
otherwise the onConditionsNotMet(Request, Response, Callback) method will be invoked. Implementations may call
the nextHandler(Request, Response, Callback) method to call the wrapped handler.
A typical usage is to extend the ConditionalHandler.Abstract sub class and provide an implementation of
onConditionsMet(Request, Response, Callback) and onConditionsNotMet(Request, Response, Callback):
public class MyOptionalHandler extends ConditionalHandler.Abstract
{
@Override
public boolean onConditionsMet(Request request, Response response, Callback callback)
{
response.getHeaders().add("Test", "My Optional Handling");
return nextHandle(request, response, callback);
}
@Override
public boolean onConditionsNoMet(Request request, Response response, Callback callback)
{
return false;
}
}
If the conditions added to MyOptionalHandler are met, then the onConditionsMet(Request, Response, Callback)
method is called and a response header added before invoking nextHandler(Request, Response, Callback), otherwise
the onConditionsNotMet(Request, Response, Callback) is called, which returns false to indicate no more handling.
Alternatively, one of the concrete subclasses may be used. These implementations conditionally provide a specific
action in their onConditionsMet(Request, Response, Callback) methods:
ConditionalHandler.DontHandle- If the conditions are met, terminate further handling by returningfalseConditionalHandler.Reject- If the conditions are met, reject the request with aHttpStatus.FORBIDDEN_403(or other status code) response.ConditionalHandler.SkipNext- If the conditions are met, then thenext handleris skipped and thefollowing handerinvoked instead.
Otherwise, if their conditions are not met, these subclasses are all extension of the abstract ConditionalHandler.ElseNext subclass,
that implements onConditionsNotMet(Request, Response, Callback) to call nextHandler(Request, Response, Callback).
Thus their specific behaviour is not applied and the handling continues with the next handler.
These concrete handlers are ideal for retrofitting conditional behavior. For example, if an application handler was
found to not correctly handle the OPTIONS method for the path "/secret/*", it could be protected as follows:
Server server = new Server();
ApplicationHandler application = new ApplicationHandler();
server.setHandler(application);
ConditionalHandler reject = new ConditionalHandler.Reject(403); // or DontHandle
reject.includeMethod("OPTIONS");
reject.includePath("/secret/*");
server.insertHandler(reject);
Another example, in an application comprised of several handlers, one of which is a wrapping handler whose behavior needs to be skipped for "POST" requests, then it could be achieved as follows:
Server server = new Server();
ApplicationWrappingHandler wrappingHandler = new ApplicationWrappingHandler();
ApplicationHandler applicationHandler = new ApplicationHandler();
server.setHandler(wrappingHandler);
filter.setHandler(applicationHandler);
ConditionalHandler skipNext = new ConditionalHandler.SkipNext();
skipNext.includeMethod("POST");
skipNext.setHandler(wrappingHandler);
server.setHandler(skipNext);
Note that a better solution, if possible, would be for the ApplicationFilterHandler and/or
ApplicationHandler handlers to extend ConditionalHandler.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classAn AbstractConditionalHandler.static classAPredicateoverRequestthat tests thenameof theconnectorobtained fromRequest.getConnectionMetaData()static classAn implementation ofConditionalHandlerthat, if conditions are met, will not do any further handling by returningfalsefromConditionalHandler.DontHandle.onConditionsMet(Request, Response, Callback).static classAn abstract implementation ofConditionalHandlerthat, if conditions are not met, will call thenextHandler(Request, Response, Callback)fromConditionalHandler.ElseNext.onConditionsNotMet(Request, Response, Callback).static classAPredicateoverRequestthat tests anInetAddressPatternagainst thegetRemoteSocketAddress()ofRequest.getConnectionMetaData().static classstatic classstatic classstatic classAn implementation ofConditionalHandlerthat, if conditions are met, will reject the request by sending a response (by default aHttpStatus.FORBIDDEN_403).static classAn implementation ofConditionalHandlerthat, if conditions are met, will skip the nextHandlerby invoking itsnext Handler.Nested classes/interfaces inherited from class Handler.Abstract
Handler.Abstract.NonBlockingNested classes/interfaces inherited from class AbstractLifeCycle
AbstractLifeCycle.AbstractLifeCycleListener, AbstractLifeCycle.StopExceptionNested classes/interfaces inherited from interface Container
Container.InheritedListener, Container.ListenerNested classes/interfaces inherited from interface Dumpable
Dumpable.DumpableContainerNested classes/interfaces inherited from interface Handler
Handler.AbstractContainer, Handler.Collection, Handler.Container, Handler.Sequence, Handler.Singleton, Handler.WrapperNested classes/interfaces inherited from interface Invocable
Invocable.Callable, Invocable.InvocationType, Invocable.ReadyTask, Invocable.TaskNested classes/interfaces inherited from interface LifeCycle
LifeCycle.ListenerNested classes/interfaces inherited from interface Request.Handler
Request.Handler.AbortException -
Field Summary
Fields inherited from interface Invocable
__nonBlocking, NOOP -
Method Summary
Modifier and TypeMethodDescriptionvoidclear()Clear all inclusions and exclusions.protected voiddoStart()Starts the managed lifecycle beans in the order they were added.voiddump(Appendable out, String indent) Dump this object (and children) into an Appendable using the provided indent after any new lines.final voidvoidExcludePathSpecs in the conditions to be metvoidexclude(InetAddressPattern... patterns) ExcludeInetAddressPatterns in the conditions to be metvoidexcludeInetAddressPattern(String... patterns) ExcludeInetAddressPatternin the conditions to be metvoidexcludeMethod(String... methods) Excludemethods in the conditions to be metvoidexcludePath(String... paths) ExcludePathSpecin the conditions to be metCreate aPredicateoverRequestbuilt from theandof one or more of:ConditionalHandler.ConnectorPredicateConditionalHandler.InetAddressPatternPredicateConditionalHandler.MethodPredicateConditionalHandler.PathSpecPredicatefrom(String connectorName, InetAddressPattern inetAddressPattern, String method, PathSpec pathSpec) Create aPredicateoverRequestbuilt from theandof one or more of:TypeUtil.truePredicate()ConditionalHandler.ConnectorPredicateConditionalHandler.InetAddressPatternPredicateConditionalHandler.MethodPredicateConditionalHandler.PathSpecPredicatefinal booleanInvoked to handle the passed HTTP request and response.final voidvoidIncludePathSpecs in the conditions to be metvoidinclude(InetAddressPattern... patterns) IncludeInetAddressPatterns in the conditions to be metvoidincludeInetAddressPattern(String... patterns) IncludeInetAddressPatterns in the conditions to be metvoidincludeMethod(String... methods) Includemethods in the conditions to be metvoidincludePath(String... paths) IncludePathSpecs in the conditions to be metprotected booleannextHandler(Request request, Response response, Callback callback) Handle a request by invoking thehandle(Request, Response, Callback)method of thenext Handler.protected abstract booleanonConditionsMet(Request request, Response response, Callback callback) Handle a request that has met the conditions.protected abstract booleanonConditionsNotMet(Request request, Response response, Callback callback) This method is called when the request has not met the conditions and is not to be handled by this handler.Methods inherited from class Handler.Wrapper
getHandler, getInvocationType, setHandlerMethods inherited from class Handler.AbstractContainer
findContainerOf, getDescendant, getDescendants, isDynamic, setDynamic, setServerMethods inherited from class Handler.Abstract
destroy, doStop, getServerMethods inherited from class ContainerLifeCycle
addBean, addBean, addEventListener, addManaged, contains, dump, dump, dumpObjects, dumpStdErr, getBean, getBeans, getBeans, getContainedBeans, getContainedBeans, installBean, installBean, isAuto, isManaged, isUnmanaged, manage, removeBean, removeBeans, removeEventListener, setBeans, start, stop, unmanage, updateBean, updateBean, updateBeans, updateBeansMethods inherited from class AbstractLifeCycle
getEventListeners, getState, getState, isFailed, isRunning, isStarted, isStarting, isStopped, isStopping, setEventListeners, start, stop, toStringMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface Container
getCachedBeans, getEventListenersMethods inherited from interface Destroyable
destroyMethods inherited from interface Dumpable.DumpableContainer
isDumpableMethods inherited from interface Handler.Container
getContainer, getDescendant, getDescendants, getDescendantsMethods inherited from interface Handler.Singleton
getHandlers, getTail, insertHandler, setHandlerMethods inherited from interface LifeCycle
addEventListener, isFailed, isRunning, isStarted, isStarting, isStopped, isStopping, removeEventListener, start, stop
-
Method Details
-
clear
public void clear()Clear all inclusions and exclusions. -
includeMethod
-
excludeMethod
-
include
IncludePathSpecs in the conditions to be met- Parameters:
paths- ThePathSpecs that are tested against thepathInContext.
-
exclude
ExcludePathSpecs in the conditions to be met- Parameters:
paths- ThePathSpecs that are tested against thepathInContext.
-
includePath
IncludePathSpecs in the conditions to be met- Parameters:
paths- String representations ofPathSpecs that are tested against thepathInContext.
-
excludePath
ExcludePathSpecin the conditions to be met- Parameters:
paths- String representations ofPathSpecs that are tested against thepathInContext.
-
include
IncludeInetAddressPatterns in the conditions to be met- Parameters:
patterns-InetAddressPatterns that are tested against thegetRemoteSocketAddress()ofRequest.getConnectionMetaData().
-
includeInetAddressPattern
IncludeInetAddressPatterns in the conditions to be met- Parameters:
patterns- String representations ofInetAddressPatterns that are tested against thegetRemoteSocketAddress()ofRequest.getConnectionMetaData().
-
exclude
ExcludeInetAddressPatterns in the conditions to be met- Parameters:
patterns-InetAddressPatterns that are tested against thegetRemoteSocketAddress()ofRequest.getConnectionMetaData().
-
excludeInetAddressPattern
ExcludeInetAddressPatternin the conditions to be met- Parameters:
patterns- String representations ofInetAddressPatterns that are tested against thegetRemoteSocketAddress()ofRequest.getConnectionMetaData().
-
include
- Parameters:
predicates-Predicates that are tested against theRequest. This method is optimized so that a passedConditionalHandler.MethodPredicateorConditionalHandler.PathSpecPredicateis converted to a more efficientincludeMethod(String...)orinclude(PathSpec...)respectively.
-
exclude
- Parameters:
predicates-Predicates that are tested against theRequest. This method is optimized so that a passedConditionalHandler.MethodPredicateorConditionalHandler.PathSpecPredicateis converted to a more efficientexcludeMethod(String...)orexclude(PathSpec...)respectively.
-
doStart
Description copied from class:ContainerLifeCycleStarts the managed lifecycle beans in the order they were added.- Overrides:
doStartin classHandler.Abstract- Throws:
Exception- If there was a problem starting. Will cause a transition to FAILED state
-
handle
Description copied from interface:Request.HandlerInvoked to handle the passed HTTP request and response.
The request is accepted by returning true, then handling must be concluded by completing the passed callback. The handling may be asynchronous, i.e. this method may return true and complete the given callback later, possibly from a different thread. If this method returns false, then the callback must not be invoked and any mutation on the response reversed.
Exceptions thrown by this method may be subsequently handled by an error
Request.Handler, if present, otherwise a default HTTP 500 error is generated and the callback completed while writing the error response.The simplest implementation is:
public boolean handle(Request request, Response response, Callback callback) { callback.succeeded(); return true; }A HelloWorld implementation is:
public boolean handle(Request request, Response response, Callback callback) { response.write(true, ByteBuffer.wrap("Hello World\n".getBytes(StandardCharsets.UTF_8)), callback); return true; }- Specified by:
handlein interfaceRequest.Handler- Overrides:
handlein classHandler.Wrapper- Parameters:
request- the HTTP request to handleresponse- the HTTP response to handlecallback- the callback to complete when the handling is complete- Returns:
- True if and only if the request will be handled, a response generated and the callback eventually called. This may occur within the scope of the call to this method, or asynchronously some time later. If false is returned, then this method must not generate a response, nor complete the callback.
- Throws:
Exception- if there is a failure during the handling. Catchers cannot assume that the callback will be called and thus should attempt to complete the request as if a false had been returned.- See Also:
-
onConditionsMet
protected abstract boolean onConditionsMet(Request request, Response response, Callback callback) throws Exception Handle a request that has met the conditions. Typically, the implementation will provide optional handling and then call thenextHandler(Request, Response, Callback)method to continue handling.- Parameters:
request- The request to handleresponse- The response to generatecallback- The callback for completion- Returns:
- True if this handler will complete the callback
- Throws:
Exception- If there is a problem handling- See Also:
-
onConditionsNotMet
protected abstract boolean onConditionsNotMet(Request request, Response response, Callback callback) throws Exception This method is called when the request has not met the conditions and is not to be handled by this handler. Implementations may return false; send an error response; or handle the request differently.- Parameters:
request- The request to handleresponse- The response to generatecallback- The callback for completion- Returns:
- True if this handler will complete the callback
- Throws:
Exception- If there is a problem handling- See Also:
-
nextHandler
protected boolean nextHandler(Request request, Response response, Callback callback) throws Exception Handle a request by invoking thehandle(Request, Response, Callback)method of thenext Handler.- Parameters:
request- The request to handleresponse- The response to generatecallback- The callback for completion- Returns:
- True if this handler will complete the callback
- Throws:
Exception- If there is a problem handling- See Also:
-
dump
Description copied from interface:DumpableDump this object (and children) into an Appendable using the provided indent after any new lines. The indent should not be applied to the first object dumped.- Specified by:
dumpin interfaceDumpable- Overrides:
dumpin classContainerLifeCycle- Parameters:
out- The appendable to dump toindent- The indent to apply after any new lines.- Throws:
IOException- if unable to write to Appendable
-
from
public static Predicate<Request> from(String connectorName, String inetAddressPattern, String method, String pathSpec) - Parameters:
connectorName- The connector name ornullinetAddressPattern- AnInetAddressPatternstring ornullmethod- AHttpMethodname ornullpathSpec- APathSpecstring ornull- Returns:
- the combined
PredicateoverRequest
-
from
public static Predicate<Request> from(String connectorName, InetAddressPattern inetAddressPattern, String method, PathSpec pathSpec) - Parameters:
connectorName- The connector name ornullinetAddressPattern- AnInetAddressPatternornullmethod- AHttpMethodname ornullpathSpec- APathSpecornull- Returns:
- the combined
PredicateoverRequest
-