From 627ba945f1680fad5f77dccd29f02cef5c31a40a Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 23 Oct 2014 09:11:27 +1100 Subject: [PATCH] Added AsyncDelayHandler example --- examples/embedded/pom.xml | 10 ++ .../eclipse/jetty/embedded/LikeJettyXml.java | 9 +- .../server/handler/AsyncDelayHandler.java | 153 ++++++++++++++++++ 3 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/handler/AsyncDelayHandler.java diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index c5de80dcef1..453aad9fb9e 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -76,6 +76,16 @@ jetty-proxy ${project.version} + + org.eclipse.jetty + jetty-jaas + ${project.version} + + + org.eclipse.jetty + jetty-plus + ${project.version} + org.eclipse.jetty apache-jsp diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java index b53f55cfc81..eb4d6223ba0 100644 --- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java +++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.server.handler.AsyncDelayHandler; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerCollection; @@ -42,6 +43,7 @@ import org.eclipse.jetty.server.handler.StatisticsHandler; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; +import org.eclipse.jetty.webapp.Configuration; public class LikeJettyXml { @@ -142,7 +144,11 @@ public class LikeJettyXml deployer.addAppProvider(webapp_provider); server.addBean(deployer); - + + // === setup jetty plus == + Configuration.ClassList.setServerDefault(server) + .addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", + "org.eclipse.jetty.plus.webapp.EnvConfiguration","org.eclipse.jetty.plus.webapp.PlusConfiguration"); // === jetty-stats.xml === StatisticsHandler stats = new StatisticsHandler(); @@ -182,7 +188,6 @@ public class LikeJettyXml login.setRefreshInterval(0); server.addBean(login); - // Start the server server.start(); server.join(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AsyncDelayHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AsyncDelayHandler.java new file mode 100644 index 00000000000..82ad9142e1b --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AsyncDelayHandler.java @@ -0,0 +1,153 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.server.handler; + +import java.io.IOException; + +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.server.Request; + + +/* ------------------------------------------------------------ */ +/** A handler wrapper that provides the framework to asynchronously + * delay the handling of a request. While it uses standard servlet + * API for asynchronous servlets, it adjusts the dispatch type of the + * request so that it does not appear to be asynchronous during the + * delayed dispatch. + * + */ +public class AsyncDelayHandler extends HandlerWrapper +{ + public final static String AHW_ATTR = "o.e.j.s.h.AsyncHandlerWrapper"; + + /* ------------------------------------------------------------ */ + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + if (!isStarted() || _handler==null) + return; + + // Get the dispatcher types + DispatcherType ctype = baseRequest.getDispatcherType(); + DispatcherType dtype = (DispatcherType)baseRequest.getAttribute(AHW_ATTR); + Object async_context_path=null; + Object async_path_info=null; + Object async_query_string=null; + Object async_request_uri=null; + Object async_servlet_path=null; + + // Is this request a restarted one? + boolean restart=false; + if (dtype!=null) + { + // fake the dispatch type to the original + baseRequest.setAttribute(AHW_ATTR,null); + baseRequest.setDispatcherType(dtype); + restart=true; + + async_context_path=baseRequest.getAttribute(AsyncContext.ASYNC_CONTEXT_PATH); + baseRequest.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,null); + async_path_info=baseRequest.getAttribute(AsyncContext.ASYNC_PATH_INFO); + baseRequest.setAttribute(AsyncContext.ASYNC_PATH_INFO,null); + async_query_string=baseRequest.getAttribute(AsyncContext.ASYNC_QUERY_STRING); + baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING,null); + async_request_uri=baseRequest.getAttribute(AsyncContext.ASYNC_REQUEST_URI); + baseRequest.setAttribute(AsyncContext.ASYNC_REQUEST_URI,null); + async_servlet_path=baseRequest.getAttribute(AsyncContext.ASYNC_SERVLET_PATH); + baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,null); + } + + // Should we handle this request now? + if (!startHandling(baseRequest,restart)) + { + // No, so go async and remember dispatch type + AsyncContext context = baseRequest.startAsync(); + baseRequest.setAttribute(AHW_ATTR,ctype); + + delayHandling(baseRequest, context); + return; + } + + // Handle the request + try + { + _handler.handle(target,baseRequest, request, response); + } + finally + { + if(restart) + { + // reset the request + baseRequest.setDispatcherType(ctype); + baseRequest.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,async_context_path); + baseRequest.setAttribute(AsyncContext.ASYNC_PATH_INFO,async_path_info); + baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING,async_query_string); + baseRequest.setAttribute(AsyncContext.ASYNC_REQUEST_URI,async_request_uri); + baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,async_servlet_path); + } + + // signal the request is leaving the handler + endHandling(baseRequest); + } + + } + + /* ------------------------------------------------------------ */ + /** Called to indicate that a request has been presented for handling + * @param request The request to handle + * @param restart True if this request is being restarted after a delay + * @return True if the request should be handled now + */ + protected boolean startHandling(Request request, boolean restart) + { + return true; + } + + /* ------------------------------------------------------------ */ + /** Called to indicate that a requests handling is being delayed/ + * The implementation should arrange for context.dispatch() to be + * called when the request should be handled. It may also set + * timeouts on the context. + * + * @param request The request to be delayed + * @param context The AsyncContext of the delayed request + */ + protected void delayHandling(Request request,AsyncContext context) + { + context.dispatch(); + } + + /* ------------------------------------------------------------ */ + /** Called to indicated the handling of the request is ending. + * This is only the end of the current dispatch of the request and + * if the request is asynchronous, it may be handled again. + * @param request The request + */ + protected void endHandling(Request request) + { + + } + + +}