From 0f510e6753a0b90f6b1279397976dfb279548fa0 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Sun, 29 Mar 2009 02:15:22 +0000 Subject: [PATCH] This commit takes jetty-7 back to the 2.5 servlet API, but leaves much of the 3.0 asynchronous machinery available. Introduces a new improved Continuation API that is an evolution of the original Continuation API, while taking some good ideas from the 3.0 spec. The intention is that this API will simplify the use of the 3.0 API, while making it available in jetty-7 (scalably) and in all other 2.5 containers with the ContinuationFilter. git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@27 7e9141cc-0065-0410-87d8-b60c137991c4 --- jetty-annotations/pom.xml | 5 - .../annotations/AnnotationProcessor.java | 125 +---- .../org/eclipse/jetty/annotations/ClassC.java | 11 - .../annotations/ServletAnnotationTest.java | 155 ------- jetty-continuation/pom.xml | 83 ++++ .../jetty/continuation/Continuation.java | 207 +++++++++ .../jetty/continuation/ContinuationEvent.java | 10 + .../continuation/ContinuationFilter.java | 433 ++++++++++++++++++ .../continuation/ContinuationListener.java | 11 + .../continuation}/ContinuationSupport.java | 14 +- .../jetty/security/MappedLoginService.java | 2 +- .../jetty/security/SecurityHandler.java | 2 +- jetty-server/pom.xml | 5 + .../eclipse/jetty/server/AsyncContext.java | 27 ++ .../eclipse/jetty/server/AsyncRequest.java | 166 +++++-- .../org/eclipse/jetty/server/Dispatcher.java | 3 - .../eclipse/jetty/server/DispatcherType.java | 11 + .../eclipse/jetty/server/HttpConnection.java | 1 - .../org/eclipse/jetty/server/Request.java | 92 +--- .../java/org/eclipse/jetty/server/Server.java | 1 - .../jetty/server/Servlet3Continuation.java | 115 ----- .../jetty/server/handler/ContextHandler.java | 137 +----- .../server/handler/RequestLogHandler.java | 2 +- .../server/nio/SelectChannelConnector.java | 2 +- .../jetty/server/session/SessionHandler.java | 5 +- .../jetty/server/AsyncContextTest.java | 14 +- .../org/eclipse/jetty/server/DumpHandler.java | 9 +- .../org/eclipse/jetty/testing/HttpTester.java | 2 +- .../eclipse/jetty/servlet/FilterHolder.java | 46 +- .../eclipse/jetty/servlet/FilterMapping.java | 2 +- .../org/eclipse/jetty/servlet/Holder.java | 80 +--- .../jetty/servlet/ServletContextHandler.java | 150 +----- .../eclipse/jetty/servlet/ServletHandler.java | 2 +- .../eclipse/jetty/servlet/ServletHolder.java | 29 -- .../jetty/servlet/SessionTestServer.java | 3 +- jetty-servlets/pom.xml | 5 + .../jetty/servlets/AsyncProxyServlet.java | 352 -------------- .../eclipse/jetty/servlets/GzipFilter.java | 15 +- .../eclipse/jetty/servlets/ProxyServlet.java | 355 +++++++------- .../org/eclipse/jetty/servlets/QoSFilter.java | 19 +- jetty-test-webapp/pom.xml | 8 +- .../src/main/java/com/acme/ChatServlet.java | 110 ++--- .../src/main/java/com/acme/CometServlet.java | 85 ---- .../src/main/java/com/acme/Date2Tag.java | 48 -- .../src/main/java/com/acme/DateTag.java | 65 --- .../src/main/java/com/acme/Dump.java | 123 ++--- .../src/main/java/com/acme/TagListener.java | 135 ------ .../src/main/java/com/acme/TestListener.java | 9 +- .../src/main/webapp/WEB-INF/web.xml | 38 +- .../src/main/webapp/error404.html | 4 + jetty-test-webapp/src/main/webapp/index.html | 2 - .../src/main/webapp/jsp/bean1.jsp | 15 - .../src/main/webapp/jsp/bean2.jsp | 15 - .../src/main/webapp/jsp/dump.jsp | 23 - .../src/main/webapp/jsp/expr.jsp | 23 - .../src/main/webapp/jsp/index.html | 15 - jetty-test-webapp/src/main/webapp/jsp/tag.jsp | 16 - .../src/main/webapp/jsp/tag2.jsp | 19 - .../src/main/webapp/jsp/tagfile.jsp | 37 -- jetty-test-webapp/src/main/webapp/snoop.jsp | 201 -------- .../eclipse/jetty/util/ajax/Continuation.java | 117 ----- .../jetty/util/ajax/WaitingContinuation.java | 153 ------- .../eclipse/jetty/util/thread/Timeout.java | 6 +- .../eclipse/jetty/webapp/WebAppContext.java | 29 +- .../eclipse/jetty/xml/XmlConfiguration.java | 7 + pom.xml | 9 +- 66 files changed, 1308 insertions(+), 2712 deletions(-) delete mode 100644 jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletAnnotationTest.java create mode 100644 jetty-continuation/pom.xml create mode 100644 jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java create mode 100644 jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationEvent.java create mode 100644 jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationFilter.java create mode 100644 jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationListener.java rename {jetty-util/src/main/java/org/eclipse/jetty/util/ajax => jetty-continuation/src/main/java/org/eclipse/jetty/continuation}/ContinuationSupport.java (72%) create mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContext.java create mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/DispatcherType.java delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/Servlet3Continuation.java delete mode 100644 jetty-servlets/src/main/java/org/eclipse/jetty/servlets/AsyncProxyServlet.java delete mode 100644 jetty-test-webapp/src/main/java/com/acme/CometServlet.java delete mode 100644 jetty-test-webapp/src/main/java/com/acme/Date2Tag.java delete mode 100644 jetty-test-webapp/src/main/java/com/acme/DateTag.java delete mode 100644 jetty-test-webapp/src/main/java/com/acme/TagListener.java create mode 100644 jetty-test-webapp/src/main/webapp/error404.html delete mode 100644 jetty-test-webapp/src/main/webapp/jsp/bean1.jsp delete mode 100644 jetty-test-webapp/src/main/webapp/jsp/bean2.jsp delete mode 100644 jetty-test-webapp/src/main/webapp/jsp/dump.jsp delete mode 100644 jetty-test-webapp/src/main/webapp/jsp/expr.jsp delete mode 100644 jetty-test-webapp/src/main/webapp/jsp/index.html delete mode 100644 jetty-test-webapp/src/main/webapp/jsp/tag.jsp delete mode 100644 jetty-test-webapp/src/main/webapp/jsp/tag2.jsp delete mode 100644 jetty-test-webapp/src/main/webapp/jsp/tagfile.jsp delete mode 100644 jetty-test-webapp/src/main/webapp/snoop.jsp delete mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/ajax/Continuation.java delete mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/ajax/WaitingContinuation.java diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 0c5c725cdda..01f62be1905 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -50,11 +50,6 @@ junit test - - org.mortbay.jetty - servlet-annotation-spec - 3.0.pre0 - org.eclipse.jetty jetty-jndi diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationProcessor.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationProcessor.java index 652e69b2188..073b22b20e9 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationProcessor.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationProcessor.java @@ -16,7 +16,6 @@ package org.eclipse.jetty.annotations; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -29,29 +28,14 @@ import javax.annotation.security.RunAs; import javax.naming.InitialContext; import javax.naming.NameNotFoundException; import javax.naming.NamingException; -import javax.servlet.DispatcherType; -import javax.servlet.http.annotation.InitParam; -import javax.servlet.http.annotation.jaxrs.DELETE; -import javax.servlet.http.annotation.jaxrs.GET; -import javax.servlet.http.annotation.jaxrs.HEAD; -import javax.servlet.http.annotation.jaxrs.POST; -import javax.servlet.http.annotation.jaxrs.PUT; import org.eclipse.jetty.plus.annotation.Injection; import org.eclipse.jetty.plus.annotation.InjectionCollection; import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection; -import org.eclipse.jetty.plus.annotation.PojoContextListener; -import org.eclipse.jetty.plus.annotation.PojoFilter; -import org.eclipse.jetty.plus.annotation.PojoServlet; import org.eclipse.jetty.plus.annotation.PostConstructCallback; import org.eclipse.jetty.plus.annotation.PreDestroyCallback; import org.eclipse.jetty.plus.annotation.RunAsCollection; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.FilterMapping; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.servlet.ServletMapping; import org.eclipse.jetty.util.IntrospectionUtil; -import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.webapp.WebAppContext; @@ -111,112 +95,11 @@ public class AnnotationProcessor public void processServlets () throws Exception { - //@Servlet(urlMappings=String[], description=String, icon=String, loadOnStartup=int, name=String, initParams=InitParams[]) - for (Class clazz:_finder.getClassesForAnnotation(javax.servlet.http.annotation.Servlet.class)) - { - javax.servlet.http.annotation.Servlet annotation = (javax.servlet.http.annotation.Servlet)clazz.getAnnotation(javax.servlet.http.annotation.Servlet.class); - PojoServlet servlet = new PojoServlet(getPojoInstanceFor(clazz)); - - List methods = _finder.getMethodsForAnnotation(GET.class); - if (methods.size() > 1) - throw new IllegalStateException ("More than one GET annotation on "+clazz.getName()); - else if (methods.size() == 1) - servlet.setGetMethodName(methods.get(0).getName()); - - methods = _finder.getMethodsForAnnotation(POST.class); - if (methods.size() > 1) - throw new IllegalStateException ("More than one POST annotation on "+clazz.getName()); - else if (methods.size() == 1) - servlet.setPostMethodName(methods.get(0).getName()); - - methods = _finder.getMethodsForAnnotation(PUT.class); - if (methods.size() > 1) - throw new IllegalStateException ("More than one PUT annotation on "+clazz.getName()); - else if (methods.size() == 1) - servlet.setPutMethodName(methods.get(0).getName()); - - methods = _finder.getMethodsForAnnotation(DELETE.class); - if (methods.size() > 1) - throw new IllegalStateException ("More than one DELETE annotation on "+clazz.getName()); - else if (methods.size() == 1) - servlet.setDeleteMethodName(methods.get(0).getName()); - - methods = _finder.getMethodsForAnnotation(HEAD.class); - if (methods.size() > 1) - throw new IllegalStateException ("More than one HEAD annotation on "+clazz.getName()); - else if (methods.size() == 1) - servlet.setHeadMethodName(methods.get(0).getName()); - - ServletHolder holder = new ServletHolder(servlet); - holder.setName((annotation.name().equals("")?clazz.getName():annotation.name())); - holder.setInitOrder(annotation.loadOnStartup()); - LazyList.add(_servlets, holder); - - for (InitParam ip:annotation.initParams()) - { - holder.setInitParameter(ip.name(), ip.value()); - } - - if (annotation.urlMappings().length > 0) - { - ArrayList paths = new ArrayList(); - ServletMapping mapping = new ServletMapping(); - mapping.setServletName(holder.getName()); - for (String s:annotation.urlMappings()) - { - paths.add(normalizePattern(s)); - } - mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()])); - LazyList.add(_servletMappings,mapping); - } - } } public void processFilters () throws Exception - { - //@ServletFilter(description=String, filterName=String, displayName=String, icon=String,initParams=InitParam[], filterMapping=FilterMapping) - for (Class clazz:_finder.getClassesForAnnotation(javax.servlet.http.annotation.ServletFilter.class)) - { - javax.servlet.http.annotation.ServletFilter annotation = (javax.servlet.http.annotation.ServletFilter)clazz.getAnnotation(javax.servlet.http.annotation.ServletFilter.class); - PojoFilter filter = new PojoFilter(getPojoInstanceFor(clazz)); - - FilterHolder holder = new FilterHolder(filter); - holder.setName((annotation.filterName().equals("")?clazz.getName():annotation.filterName())); - holder.setDisplayName(annotation.displayName()); - LazyList.add(_filters, holder); - - for (InitParam ip:annotation.initParams()) - { - holder.setInitParameter(ip.name(), ip.value()); - } - - if (annotation.filterMapping() != null) - { - FilterMapping mapping = new FilterMapping(); - mapping.setFilterName(holder.getName()); - ArrayList paths = new ArrayList(); - for (String s:annotation.filterMapping().urlPattern()) - { - paths.add(normalizePattern(s)); - } - mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()])); - ArrayList names = new ArrayList(); - for (String s:annotation.filterMapping().servletNames()) - { - names.add(s); - } - mapping.setServletNames((String[])names.toArray(new String[names.size()])); - - int dispatcher=FilterMapping.DEFAULT; - for (DispatcherType d:annotation.filterMapping().dispatcherTypes()) - { - dispatcher = dispatcher|FilterMapping.dispatch(d); - } - mapping.setDispatches(dispatcher); - LazyList.add(_filterMappings,mapping); - } - } + { } @@ -224,12 +107,6 @@ public class AnnotationProcessor public void processListeners () throws Exception { - //@ServletContextListener(description=String) - for (Class clazz:_finder.getClassesForAnnotation(javax.servlet.http.annotation.ServletContextListener.class)) - { - PojoContextListener listener = new PojoContextListener(getPojoInstanceFor(clazz)); - LazyList.add(_listeners, listener); - } } diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassC.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassC.java index f3828a0a89f..0fdb380720e 100644 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassC.java +++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ClassC.java @@ -18,22 +18,13 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.annotation.security.RunAs; -import javax.servlet.DispatcherType; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import javax.servlet.http.annotation.FilterMapping; -import javax.servlet.http.annotation.InitParam; -import javax.servlet.http.annotation.Servlet; -import javax.servlet.http.annotation.ServletFilter; -import javax.servlet.http.annotation.jaxrs.GET; -import javax.servlet.http.annotation.jaxrs.POST; -@Servlet(urlMappings = { "/foo/*", "/bah/*" }, name="CServlet", initParams={@InitParam(name="x", value="y")}) -@ServletFilter(filterName="CFilter", filterMapping=@FilterMapping(dispatcherTypes={DispatcherType.REQUEST}, urlPattern = {"/*"}), initParams={@InitParam(name="a", value="99")}) @RunAs("admin") public class ClassC { @@ -52,8 +43,6 @@ public class ClassC } - @GET() - @POST() public void anything (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletAnnotationTest.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletAnnotationTest.java deleted file mode 100644 index 3d251b5887e..00000000000 --- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/ServletAnnotationTest.java +++ /dev/null @@ -1,155 +0,0 @@ -// ======================================================================== -// Copyright (c) 2008-2009 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.annotations; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NameNotFoundException; - -import junit.framework.TestCase; - -import org.eclipse.jetty.plus.annotation.Injection; -import org.eclipse.jetty.plus.annotation.InjectionCollection; -import org.eclipse.jetty.plus.annotation.LifeCycleCallback; -import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection; -import org.eclipse.jetty.plus.annotation.PojoFilter; -import org.eclipse.jetty.plus.annotation.PojoServlet; -import org.eclipse.jetty.plus.annotation.RunAs; -import org.eclipse.jetty.plus.annotation.RunAsCollection; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.FilterMapping; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.servlet.ServletMapping; -import org.eclipse.jetty.webapp.WebAppContext; - -public class ServletAnnotationTest extends TestCase -{ - - public void tearDown() - throws Exception - { - InitialContext ic = new InitialContext(); - Context comp = (Context)ic.lookup("java:comp"); - comp.destroySubcontext("env"); - } - - public void testAnnotations() throws Exception - { - Server server = new Server(); - WebAppContext wac = new WebAppContext(); - wac.setServer(server); - - InitialContext ic = new InitialContext(); - Context comp = (Context)ic.lookup("java:comp"); - Context env = null; - try - { - env = (Context)comp.lookup("env"); - } - catch (NameNotFoundException e) - { - env = comp.createSubcontext("env"); - } - - org.eclipse.jetty.plus.jndi.EnvEntry foo = new org.eclipse.jetty.plus.jndi.EnvEntry("foo", new Double(1000.00), false); - List servlets = new ArrayList(); - List filters = new ArrayList(); - List listeners = new ArrayList(); - List servletMappings = new ArrayList(); - List filterMappings = new ArrayList(); - - List classes = new ArrayList(); - classes.add("org.eclipse.jetty.annotations.ClassC"); - - AnnotationFinder finder = new AnnotationFinder(); - finder.find (classes, - new ClassNameResolver() - { - - public boolean isExcluded(String name) - { - return false; - } - - public boolean shouldOverride(String name) - { - return true; - } - - }); - - - RunAsCollection runAs = new RunAsCollection(); - InjectionCollection injections = new InjectionCollection(); - LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection(); - - AnnotationProcessor processor = new AnnotationProcessor (wac, finder, runAs, injections, callbacks, - servlets, filters, listeners, servletMappings, filterMappings); - processor.process(); - - - assertEquals(1, servlets.size()); - ServletHolder sholder = (ServletHolder)servlets.get(0); - assertEquals("CServlet", sholder.getName()); - assertTrue(sholder.getServlet() instanceof PojoServlet); - PojoServlet ps = (PojoServlet)sholder.getServlet(); - assertEquals("anything", ps.getGetMethodName()); - assertEquals("anything", ps.getPostMethodName()); - Map sinitparams = sholder.getInitParameters(); - assertEquals(1, sinitparams.size()); - assertTrue(sinitparams.containsKey("x")); - assertTrue(sinitparams.containsValue("y")); - assertEquals(1, filters.size()); - FilterHolder fholder = (FilterHolder)filters.get(0); - assertTrue(fholder.getFilter() instanceof PojoFilter); - - Map finitparams = fholder.getInitParameters(); - assertEquals(1, finitparams.size()); - assertTrue(finitparams.containsKey("a")); - assertTrue(finitparams.containsValue("99")); - assertEquals(1, servletMappings.size()); - ServletMapping smap = (ServletMapping)servletMappings.get(0); - assertEquals("CServlet", smap.getServletName()); - assertEquals(2, smap.getPathSpecs().length); - assertEquals(1, filterMappings.size()); - FilterMapping fmap = (FilterMapping)filterMappings.get(0); - assertEquals("CFilter", fmap.getFilterName()); - assertEquals(1, fmap.getPathSpecs().length); - - List fieldInjections = injections.getFieldInjections(ClassC.class); - assertNotNull(fieldInjections); - assertEquals(1, fieldInjections.size()); - - RunAs ra = runAs.getRunAs(sholder); - assertNotNull(ra); - assertEquals("admin", ra.getRoleName()); - - List predestroys = callbacks.getPreDestroyCallbacks(sholder.getServlet()); - assertNotNull(predestroys); - assertEquals(1, predestroys.size()); - LifeCycleCallback cb = (LifeCycleCallback)predestroys.get(0); - assertTrue(cb.getTarget().equals(ClassC.class.getDeclaredMethod("pre", new Class[]{}))); - - List postconstructs = callbacks.getPostConstructCallbacks(sholder.getServlet()); - assertNotNull(postconstructs); - assertEquals(1, postconstructs.size()); - cb = (LifeCycleCallback)postconstructs.get(0); - assertTrue(cb.getTarget().equals(ClassC.class.getDeclaredMethod("post", new Class[]{}))); - } - -} diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml new file mode 100644 index 00000000000..8f6c35ea8fa --- /dev/null +++ b/jetty-continuation/pom.xml @@ -0,0 +1,83 @@ + + + org.eclipse.jetty + jetty-project + 7.0.0.incubation0-SNAPSHOT + + 4.0.0 + jetty-continuation + Jetty :: Continuation + Asynchronous API + + + + org.apache.felix + maven-bundle-plugin + 1.4.2 + true + + + + manifest + + + + org.eclipse.jetty.continuation + J2SE-1.5 + http://jetty.eclipse.org + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + artifact-jar + + jar + + + + test-jar + + test-jar + + + + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + + + junit + junit + test + + + org.mortbay.jetty + servlet-api + + + diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java new file mode 100644 index 00000000000..f4043ef23b4 --- /dev/null +++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/Continuation.java @@ -0,0 +1,207 @@ +// ======================================================================== +// Copyright (c) 2004-2009 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.continuation; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.Servlet; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +/* ------------------------------------------------------------ */ +/** + * Continuation. + * + * A continuation is a mechanism by which a HTTP Request can be suspended and + * restarted after a timeout or an asynchronous event has occurred. + * + */ +public interface Continuation +{ + public final static String ATTRIBUTE = "org.eclipse.jetty.continuation"; + + /** + * Set the continuation timeout + * + * @param timeoutMs + * The time in milliseconds to wait before expiring this + * continuation. + */ + void setTimeout(long timeoutMs); + + /** + * Suspend the processing of the request and associated + * {@link ServletResponse}. + * + *

+ * After this method has been called, the lifecycle of the request will be + * extended beyond the return to the container from the + * {@link Servlet#service(ServletRequest, ServletResponse)} method and + * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)} + * calls. If a request is suspended, then the container will not commit the + * associated response when the call to the filter chain and/or servlet + * service method returns to the container. Any exceptions thrown to the + * container by a filter chain and/or servlet for a suspended requests are + * silently ignored. + *

+ * + *

+ * When the thread calling the filter chain and/or servlet has returned to + * the container with a suspended request, the thread is freed for other + * tasks and the request is held pending either: + *

    + *
  • a call to {@link ServletRequest#resume()}.
  • + *
  • a call to {@link ServletRequest#complete()}.
  • + *
  • the passed or default timeout expires.
  • + *
  • there is IO activity on the connection that received the request, + * such as the close of the connection or the receipt of a pipelined + * request. + *
+ *

+ * After any of the events listed above, the suspended request will be + * redispatched via the filter and servlet processing. + *

+ * + *

+ * Suspend may only be called by a thread that is within the service calling + * stack of + * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)} + * and/or {@link Servlet#service(ServletRequest, ServletResponse)}. A + * request that has been dispatched for error handling may not be suspended. + *

+ * + * @see {@link #resume()} + * @see {@link #complete()} + * + * @exception IllegalStateException + * If the calling thread is not within the calling stack of + * {@link Filter#doFilter(ServletRequest, ServletResponse, FilterChain)} + * and/or + * {@link Servlet#service(ServletRequest, ServletResponse)} + * or if the request has been dispatched for error handling. + */ + void suspend(); + + /** + * Resume a suspended request. + * + *

+ * This method can be called by any thread that has been passed a reference + * to a suspended request. When called the request is redispatched to the + * normal filter chain and servlet processing. + *

+ * + *

+ * If resume is called before a suspended request is returned to the + * container (ie the thread that called {@link #suspend(long)} is still + * within the filter chain and/or servlet service method), then the resume + * does not take effect until the call to the filter chain and/or servlet + * returns to the container. In this case both {@link #isSuspended()} and + * {@link isResumed()} return true. + *

+ * + *

+ * Multiple calls to resume are ignored + *

+ * + * @see {@link #suspend()} + * @exception IllegalStateException + * if the request is not suspended. + * + */ + void resume(); + + /** + * Complete a suspended request. + * + *

+ * This method can be called by any thread that has been passed a reference + * to a suspended request. When a request is completed, the associated + * response object commited and flushed. The request is not redispatched. + *

+ * + *

+ * If complete is called before a suspended request is returned to the + * container (ie the thread that called {@link #suspend(long)} is still + * within the filter chain and/or servlet service method), then the complete + * does not take effect until the call to the filter chain and/or servlet + * returns to the container. In this case both {@link #isSuspended()} and + * {@link isResumed()} return true. + *

+ * + *

+ * Once complete has been called and any thread calling the filter chain + * and/or servlet chain has returned to the container, the request lifecycle + * is complete. The container is able to recycle request objects, so it is + * not valid hold a request reference after the end of the life cycle or to + * call any request methods. + * + * @see {@link #suspend()} + * @exception IllegalStateException + * if the request is not suspended. + * + */ + void complete(); + + /** + * @return true after {@link #suspend(long)} has been called and before the + * request has been redispatched due to being resumed, completed or + * timed out. + */ + boolean isSuspended(); + + /** + * @return true if the request has been redispatched by a call to + * {@link #resume()}. Returns false after any subsequent call to + * suspend + */ + boolean isResumed(); + + /** + * @return true after a request has been redispatched as the result of a + * timeout. Returns false after any subsequent call to suspend. + */ + boolean isExpired(); + + /** + * @return true while the request is within the initial dispatch to the + * filter chain and/or servlet. Will return false once the calling + * thread has returned to the container after suspend has been + * called and during any subsequent redispatch. + */ + boolean isInitial(); + + + /* ------------------------------------------------------------ */ + /** + * Call to signal that the suspending filter/servlet has kept a + * reference to any passed requests wrappers, and that these should + * not be finalized until a onComplete event has been seen. + */ + void keepWrappers(); + + /** + * @return True if {@link #keepWrappers()} has been called. + */ + boolean wrappersKept(); + + /* ------------------------------------------------------------ */ + /** + * @param listener + */ + void addContinuationListener(ContinuationListener listener); + +} diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationEvent.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationEvent.java new file mode 100644 index 00000000000..ab49733b9a5 --- /dev/null +++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationEvent.java @@ -0,0 +1,10 @@ +package org.eclipse.jetty.continuation; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +public interface ContinuationEvent +{ + public ServletRequest getRequest(); + public ServletResponse getResponse(); +} diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationFilter.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationFilter.java new file mode 100644 index 00000000000..230a3865364 --- /dev/null +++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationFilter.java @@ -0,0 +1,433 @@ +package org.eclipse.jetty.continuation; + +import java.io.IOException; +import java.util.ArrayList; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +public class ContinuationFilter implements Filter +{ + final boolean _jetty=true; + ServletContext _context; + + public void init(FilterConfig filterConfig) throws ServletException + { + _context = filterConfig.getServletContext(); + } + + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException + { + if (_jetty) + chain.doFilter(request,response); + else + { + final FauxContinuation fc = new FauxContinuation(); + request.setAttribute(Continuation.ATTRIBUTE,fc); + boolean complete=false; + + while (!complete) + { + try + { + chain.doFilter(request,response); + } + catch(IOException e) + { + _context.log("OpenServletFilter caught ",e); + } + catch(ServletException e) + { + _context.log("OpenServletFilter caught ",e); + } + finally + { + complete=fc.handleSuspension(); + } + } + } + } + + public void destroy() + { + } + + + + private class FauxContinuation implements Continuation + { + private static final int __HANDLING=1; // Request dispatched to filter/servlet + private static final int __SUSPENDING=2; // Suspend called, but not yet returned to container + private static final int __RESUMING=3; // resumed while suspending + private static final int __COMPLETING=4; // resumed while suspending or suspended + private static final int __SUSPENDED=5; // Suspended and parked + private static final int __UNSUSPENDING=6; + private static final int __COMPLETE=7; + + private int _state=__HANDLING; + private boolean _initial=true; + private boolean _resumed=false; + private boolean _timeout=false; + private boolean _keepWrappers=false; + + private long _timeoutMs=30000; // TODO configure + + private ArrayList _listeners; + + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.continuation.Continuation#keepWrappers() + */ + public void keepWrappers() + { + _keepWrappers=true; + } + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.continuation.Continuation#wrappersKept() + */ + public boolean wrappersKept() + { + return _keepWrappers; + } + + /* ------------------------------------------------------------ */ + public boolean isInitial() + { + synchronized(this) + { + return _initial; + } + } + + public boolean isResumed() + { + synchronized(this) + { + return _resumed; + } + } + + public boolean isSuspended() + { + synchronized(this) + { + switch(_state) + { + case __HANDLING: + return false; + case __SUSPENDING: + case __RESUMING: + case __COMPLETING: + case __SUSPENDED: + return true; + case __UNSUSPENDING: + default: + return false; + } + } + } + + public boolean isExpired() + { + synchronized(this) + { + return _timeout; + } + } + + public void setTimeout(long timeoutMs) + { + _timeoutMs = timeoutMs; + } + + public void suspend() + { + synchronized (this) + { + switch(_state) + { + case __HANDLING: + _timeout=false; + _resumed=false; + _state=__SUSPENDING; + return; + + case __SUSPENDING: + case __RESUMING: + return; + + case __COMPLETING: + case __SUSPENDED: + case __UNSUSPENDING: + throw new IllegalStateException(this.getStatusString()); + + default: + throw new IllegalStateException(""+_state); + } + + } + } + + + /* ------------------------------------------------------------ */ + /* (non-Javadoc) + * @see org.mortbay.jetty.Suspendor#resume() + */ + public void resume() + { + synchronized (this) + { + switch(_state) + { + case __HANDLING: + _resumed=true; + return; + + case __SUSPENDING: + _resumed=true; + _state=__RESUMING; + return; + + case __RESUMING: + case __COMPLETING: + return; + + case __SUSPENDED: + fauxResume(); + _resumed=true; + _state=__UNSUSPENDING; + break; + + case __UNSUSPENDING: + _resumed=true; + return; + + default: + throw new IllegalStateException(this.getStatusString()); + } + } + + } + + + public void complete() + { + // just like resume, except don't set _resumed=true; + synchronized (this) + { + switch(_state) + { + case __HANDLING: + throw new IllegalStateException(this.getStatusString()); + + case __SUSPENDING: + _state=__COMPLETING; + break; + + case __RESUMING: + break; + + case __COMPLETING: + return; + + case __SUSPENDED: + _state=__COMPLETING; + fauxResume(); + break; + + case __UNSUSPENDING: + return; + + default: + throw new IllegalStateException(this.getStatusString()); + } + } + + } + + + + + void handling() + { + synchronized (this) + { + _keepWrappers=false; + switch(_state) + { + case __HANDLING: + throw new IllegalStateException(this.getStatusString()); + + case __SUSPENDING: + case __RESUMING: + throw new IllegalStateException(this.getStatusString()); + + case __COMPLETING: + return; + + case __SUSPENDED: + fauxResume(); + case __UNSUSPENDING: + _state=__HANDLING; + return; + + default: + throw new IllegalStateException(""+_state); + } + + } + } + + /* ------------------------------------------------------------ */ + /** + * @return true if handling is complete + */ + public boolean handleSuspension() + { + synchronized (this) + { + switch(_state) + { + case __HANDLING: + _state=__COMPLETE; + return true; + + case __SUSPENDING: + _initial=false; + _state=__SUSPENDED; + fauxSuspend(); // could block and change state. + if (_state==__SUSPENDED || _state==__COMPLETING) + return true; + + _initial=false; + _state=__HANDLING; + return false; + + case __RESUMING: + _initial=false; + _state=__HANDLING; + return false; + + case __COMPLETING: + _initial=false; + _state=__COMPLETE; + return true; + + case __SUSPENDED: + case __UNSUSPENDING: + default: + throw new IllegalStateException(this.getStatusString()); + } + } + } + + /* ------------------------------------------------------------ */ + protected void expire() + { + // just like resume, except don't set _resumed=true; + + synchronized (this) + { + switch(_state) + { + case __HANDLING: + return; + + case __SUSPENDING: + _timeout=true; + _state=__RESUMING; + fauxResume(); + return; + + case __RESUMING: + return; + + case __COMPLETING: + return; + + case __SUSPENDED: + _timeout=true; + _state=__UNSUSPENDING; + break; + + case __UNSUSPENDING: + _timeout=true; + return; + + default: + throw new IllegalStateException(this.getStatusString()); + } + } + } + + private void fauxSuspend() + { + long expire_at = System.currentTimeMillis()+_timeoutMs; + long wait=_timeoutMs; + while (_timeoutMs>0 && wait>0) + { + try + { + this.wait(wait); + } + catch (InterruptedException e) + { + _context.log("OpenServletFilter caught ",e); + } + wait=expire_at-System.currentTimeMillis(); + } + + if (_timeoutMs>0 && wait<=0) + expire(); + } + + private void fauxResume() + { + _timeoutMs=0; + this.notifyAll(); + } + + public String toString() + { + return getStatusString(); + } + + String getStatusString() + { + synchronized (this) + { + return + ((_state==__HANDLING)?"HANDLING": + (_state==__SUSPENDING)?"SUSPENDING": + (_state==__SUSPENDED)?"SUSPENDED": + (_state==__RESUMING)?"RESUMING": + (_state==__UNSUSPENDING)?"UNSUSPENDING": + (_state==__COMPLETING)?"COMPLETING": + ("???"+_state))+ + (_initial?",initial":"")+ + (_resumed?",resumed":"")+ + (_timeout?",timeout":""); + } + } + + + public void addContinuationListener(ContinuationListener listener) + { + if (_listeners==null) + _listeners=new ArrayList(); + _listeners.add(listener); + + // TODO Call the listeners + } + + + } +} diff --git a/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationListener.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationListener.java new file mode 100644 index 00000000000..cf4e926d787 --- /dev/null +++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationListener.java @@ -0,0 +1,11 @@ + +package org.eclipse.jetty.continuation; + +import java.io.IOException; +import java.util.EventListener; + +public interface ContinuationListener extends EventListener +{ + public void onComplete(ContinuationEvent event) throws IOException; + public void onTimeout(ContinuationEvent event) throws IOException; +} diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/ContinuationSupport.java b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java similarity index 72% rename from jetty-util/src/main/java/org/eclipse/jetty/util/ajax/ContinuationSupport.java rename to jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java index 07b23807efe..22faf15a4f4 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/ContinuationSupport.java +++ b/jetty-continuation/src/main/java/org/eclipse/jetty/continuation/ContinuationSupport.java @@ -11,25 +11,21 @@ // You may elect to redistribute this code under either of these licenses. // ======================================================================== -package org.eclipse.jetty.util.ajax; +package org.eclipse.jetty.continuation; -import javax.servlet.http.HttpServletRequest; +import javax.servlet.ServletRequest; /* ------------------------------------------------------------ */ /** ContinuationSupport. - * Conveniance class to avoid classloading visibility issues. * - * */ public class ContinuationSupport { - public static Continuation getContinuation(HttpServletRequest request, Object mutex) + public static Continuation getContinuation(ServletRequest request) { - Continuation continuation = (Continuation) request.getAttribute("org.eclipse.jetty.ajax.Continuation"); + Continuation continuation = (Continuation) request.getAttribute(Continuation.ATTRIBUTE); if (continuation==null) - continuation=new WaitingContinuation(mutex); - else - continuation.setMutex(mutex); + throw new IllegalStateException("!Jetty && !ContinuationFilter installed"); return continuation; } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java index d4e88b3814d..f63c257029c 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java @@ -164,7 +164,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo * @param roles * @return UserIdentity */ - protected synchronized UserIdentity putUser(String userName, Credential credential, String[] roles) + public synchronized UserIdentity putUser(String userName, Credential credential, String[] roles) { Principal userPrincipal = new KnownUser(userName,credential); Subject subject = new Subject(); diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index f550d235631..23644067cf8 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -260,7 +260,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti List list = getServer().getBeans(LoginService.class); for (LoginService service : list) - if (service.getName().equals(getRealmName())) + if (service.getName()!=null && service.getName().equals(getRealmName())) return service; if (list.size()>0) return list.get(0); diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index 329e7373804..6e018ed5fe1 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -97,6 +97,11 @@ org.mortbay.jetty servlet-api + + org.eclipse.jetty + jetty-continuation + ${project.version} + org.eclipse.jetty jetty-http diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContext.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContext.java new file mode 100644 index 00000000000..7fbccda845a --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContext.java @@ -0,0 +1,27 @@ + +package org.eclipse.jetty.server; + +import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +/* temporary interface in anticipation of servlet 3.0 */ +public interface AsyncContext +{ + static final String ASYNC_REQUEST_URI = "javax.servlet.async.request_uri"; + static final String ASYNC_CONTEXT_PATH = "javax.servlet.async.context_path"; + static final String ASYNC_PATH_INFO = "javax.servlet.async.path_info"; + static final String ASYNC_SERVLET_PATH = "javax.servlet.async.servlet_path"; + static final String ASYNC_QUERY_STRING = "javax.servlet.async.query_string"; + + public ServletRequest getRequest(); + public ServletResponse getResponse(); + public boolean hasOriginalRequestAndResponse(); + public void dispatch(); + public void dispatch(String path); + public void dispatch(ServletContext context, String path); + public void complete(); + public void start(Runnable run); +} + + diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequest.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequest.java index 4bb375d48d3..f7005cfe813 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequest.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequest.java @@ -13,13 +13,13 @@ package org.eclipse.jetty.server; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import org.eclipse.jetty.continuation.ContinuationEvent; +import org.eclipse.jetty.continuation.ContinuationListener; +import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.io.AsyncEndPoint; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.server.handler.ContextHandler; @@ -31,10 +31,8 @@ import org.eclipse.jetty.util.thread.Timeout; /* ------------------------------------------------------------ */ /** Asyncrhonous Request. * - * - * */ -public class AsyncRequest implements AsyncContext +public class AsyncRequest implements AsyncContext, Continuation { // STATES: private static final int __IDLE=0; // Idle request @@ -62,11 +60,14 @@ public class AsyncRequest implements AsyncContext /* ------------------------------------------------------------ */ protected HttpConnection _connection; - protected Object _listeners; + private Object _listeners; /* ------------------------------------------------------------ */ private int _state; private boolean _initial; + private boolean _resumed; + private boolean _expired; + private boolean _keepWrappers; private long _timeoutMs; private AsyncEventState _event; @@ -76,14 +77,6 @@ public class AsyncRequest implements AsyncContext _state=__IDLE; _initial=true; } - - /* ------------------------------------------------------------ */ - protected AsyncRequest(final HttpConnection connection) - { - this(); - if (connection!=null) - setConnection(connection); - } /* ------------------------------------------------------------ */ protected void setConnection(final HttpConnection connection) @@ -91,6 +84,12 @@ public class AsyncRequest implements AsyncContext _connection=connection; } + /* ------------------------------------------------------------ */ + public void addContinuationListener(ContinuationListener listener) + { + _listeners=LazyList.add(_listeners,listener); + } + /* ------------------------------------------------------------ */ public void setAsyncTimeout(long ms) { @@ -109,6 +108,24 @@ public class AsyncRequest implements AsyncContext return _event; } + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.continuation.Continuation#keepWrappers() + */ + public void keepWrappers() + { + _keepWrappers=true; + } + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.continuation.Continuation#wrappersKept() + */ + public boolean wrappersKept() + { + return _keepWrappers; + } + /* ------------------------------------------------------------ */ /* (non-Javadoc) * @see javax.servlet.ServletRequest#isInitial() @@ -178,6 +195,8 @@ public class AsyncRequest implements AsyncContext { synchronized (this) { + _keepWrappers=false; + switch(_state) { case __DISPATCHED: @@ -220,7 +239,16 @@ public class AsyncRequest implements AsyncContext { synchronized (this) { - _event=new AsyncEventState(context,request,response); + _resumed=false; + _expired=false; + + if (_event==null || request!=_event.getRequest() || response != _event.getResponse() || context != _event.getServletContext()) + _event=new AsyncEventState(context,request,response); + else + { + _event._dispatchContext=null; + _event._path=null; + } switch(_state) { @@ -322,11 +350,13 @@ public class AsyncRequest implements AsyncContext case __SUSPENDING: _state=__REDISPATCHING; + _resumed=true; return; case __SUSPENDED: dispatch=true; _state=__UNSUSPENDING; + _resumed=true; break; case __UNSUSPENDING: @@ -357,6 +387,7 @@ public class AsyncRequest implements AsyncContext default: return; } + _expired=true; } if (_listeners!=null) @@ -365,7 +396,7 @@ public class AsyncRequest implements AsyncContext { try { - AsyncListener listener=((AsyncListener)LazyList.get(_listeners,i)); + ContinuationListener listener=((ContinuationListener)LazyList.get(_listeners,i)); listener.onTimeout(_event); } catch(Exception e) @@ -461,7 +492,7 @@ public class AsyncRequest implements AsyncContext { try { - ((AsyncListener)LazyList.get(_listeners,i)).onComplete(_event); + ((ContinuationListener)LazyList.get(_listeners,i)).onComplete(_event); } catch(Exception e) { @@ -485,8 +516,10 @@ public class AsyncRequest implements AsyncContext _state=__IDLE; } _initial = true; + _resumed=false; + _expired=false; + _keepWrappers=false; cancelTimeout(); - _event=null; _timeoutMs=60000L; // TODO configure _listeners=null; } @@ -500,7 +533,6 @@ public class AsyncRequest implements AsyncContext _state=__COMPLETE; _initial = false; cancelTimeout(); - _event=null; _listeners=null; } } @@ -558,8 +590,12 @@ public class AsyncRequest implements AsyncContext this.notifyAll(); } } - else if (_event!=null) - _connection.cancelTimeout(_event._timeout); + else + { + final AsyncEventState event=_event; + if (event!=null) + _connection.cancelTimeout(event._timeout); + } } /* ------------------------------------------------------------ */ @@ -662,27 +698,77 @@ public class AsyncRequest implements AsyncContext return ((Context)_event.getServletContext()).getContextHandler(); return null; } - + + /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - public class AsyncEventState extends AsyncEvent + /** + * @see Continuation#isResumed() + */ + public boolean isResumed() { - final Timeout.Task _timeout; - final ServletContext _suspendedContext; + return _resumed; + } + /* ------------------------------------------------------------ */ + /** + * @see Continuation#isExpired() + */ + public boolean isExpired() + { + return _expired; + } + + /* ------------------------------------------------------------ */ + /** + * @see Continuation#resume() + */ + public void resume() + { + dispatch(); + } + + /* ------------------------------------------------------------ */ + /** + * @see Continuation#suspend(long) + */ + public void setTimeout(long timeoutMs) + { + setAsyncTimeout(timeoutMs); + } + + /* ------------------------------------------------------------ */ + /** + * @see Continuation#suspend() + */ + public void suspend() + { + // TODO simplify? + AsyncRequest.this.suspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse()); + } + + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + public class AsyncEventState implements ContinuationEvent + { + private final ServletContext _suspendedContext; + private final ServletRequest _request; + private final ServletResponse _response; + ServletContext _dispatchContext; + String _path; + final Timeout.Task _timeout = new Timeout.Task() + { + public void expired() + { + AsyncRequest.this.expired(); + } + }; public AsyncEventState(ServletContext context, ServletRequest request, ServletResponse response) { - super(request,response); _suspendedContext=context; - _timeout= new Timeout.Task() - { - public void expired() - { - AsyncRequest.this.expired(); - } - }; + _request=request; + _response=response; } public ServletContext getSuspendedContext() @@ -699,6 +785,16 @@ public class AsyncRequest implements AsyncContext { return _dispatchContext==null?_suspendedContext:_dispatchContext; } + + public ServletRequest getRequest() + { + return _request; + } + + public ServletResponse getResponse() + { + return _response; + } public String getPath() { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java index 5fe63fcb7e0..6afa257cf73 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Dispatcher.java @@ -20,7 +20,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Map; -import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -41,7 +40,6 @@ import org.eclipse.jetty.util.UrlEncoded; */ public class Dispatcher implements RequestDispatcher { - /* public static final String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri"; public static final String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path"; public static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info"; @@ -59,7 +57,6 @@ public class Dispatcher implements RequestDispatcher public static final String ERROR_REQUEST_URI = "javax.servlet.error.request_uri"; public static final String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name"; public static final String ERROR_STATUS_CODE = "javax.servlet.error.status_code"; - */ /** Dispatch include attribute names */ public final static String __INCLUDE_PREFIX="javax.servlet.include."; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/DispatcherType.java b/jetty-server/src/main/java/org/eclipse/jetty/server/DispatcherType.java new file mode 100644 index 00000000000..02da5df6b9f --- /dev/null +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/DispatcherType.java @@ -0,0 +1,11 @@ + +package org.eclipse.jetty.server; + +public enum DispatcherType +{ + FORWARD, + INCLUDE, + REQUEST, + ASYNC, + ERROR +} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java index 3d3584d5268..3e97d202dbe 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnection.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; -import javax.servlet.DispatcherType; import javax.servlet.ServletInputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 341e5cbdd52..212214384c1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -32,10 +32,6 @@ import java.util.Locale; import java.util.Map; import javax.security.auth.login.LoginException; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletInputStream; @@ -49,6 +45,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.eclipse.jetty.continuation.ContinuationEvent; +import org.eclipse.jetty.continuation.ContinuationListener; +import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.http.HttpCookie; import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeaders; @@ -72,7 +71,6 @@ import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.UrlEncoded; -import org.eclipse.jetty.util.ajax.Continuation; import org.eclipse.jetty.util.log.Log; /* ------------------------------------------------------------ */ @@ -181,28 +179,9 @@ public class Request implements HttpServletRequest } /* ------------------------------------------------------------ */ - public void addAsyncListener(AsyncListener listener) + public void addAsyncListener(ContinuationListener listener) { - _async._listeners=LazyList.add(_async._listeners,listener); - } - - /* ------------------------------------------------------------ */ - public void addAsyncListener(final AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse) - { - final AsyncEvent event = new AsyncEvent(servletRequest,servletResponse); - - _async._listeners=LazyList.add(_async._listeners,new AsyncListener() - { - public void onComplete(AsyncEvent ev) throws IOException - { - listener.onComplete(event); - } - - public void onTimeout(AsyncEvent ev) throws IOException - { - listener.onComplete(event); - } - }); + _async.addContinuationListener((ContinuationListener)listener); } /* ------------------------------------------------------------ */ @@ -210,6 +189,9 @@ public class Request implements HttpServletRequest { if (listener instanceof ServletRequestAttributeListener) _requestAttributeListeners= LazyList.add(_requestAttributeListeners, listener); + if (listener instanceof ContinuationListener) + _async.addContinuationListener((ContinuationListener)listener); + } /* ------------------------------------------------------------ */ @@ -336,18 +318,8 @@ public class Request implements HttpServletRequest */ public Object getAttribute(String name) { - if ("org.eclipse.jetty.util.ajax.Continuation".equals(name)) - return getContinuation(true); - - if (DispatcherType.ASYNC.equals(_dispatcherType)) - { - // TODO handle forwards(path!) - if (name.equals(Dispatcher.FORWARD_PATH_INFO)) return getPathInfo(); - if (name.equals(Dispatcher.FORWARD_REQUEST_URI)) return getRequestURI(); - if (name.equals(Dispatcher.FORWARD_SERVLET_PATH)) return getServletPath(); - if (name.equals(Dispatcher.FORWARD_CONTEXT_PATH)) return getContextPath(); - if (name.equals(Dispatcher.FORWARD_QUERY_STRING)) return getQueryString(); - } + if (Continuation.ATTRIBUTE.equals(name)) + return _async; if (_attributes==null) return null; @@ -362,6 +334,7 @@ public class Request implements HttpServletRequest { if (_attributes==null) return Collections.enumeration(Collections.EMPTY_LIST); + return AttributesMap.getAttributeNamesCopy(_attributes); } @@ -456,17 +429,6 @@ public class Request implements HttpServletRequest return _continuation; } - /* ------------------------------------------------------------ */ - /** - * @deprecated - */ - public Continuation getContinuation(boolean create) - { - if (_continuation==null && create) - _continuation=new Servlet3Continuation(this); - return _continuation; - } - /* ------------------------------------------------------------ */ /* @@ -1355,8 +1317,6 @@ public class Request implements HttpServletRequest if (_savedNewSessions!=null) _savedNewSessions.clear(); _savedNewSessions=null; - if (_continuation!=null && _continuation.isPending()) - _continuation.reset(); } /* ------------------------------------------------------------ */ @@ -1833,35 +1793,5 @@ public class Request implements HttpServletRequest return (_handled?"[":"(")+getMethod()+" "+_uri+(_handled?"]@":")@")+hashCode()+" "+super.toString(); } - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.http.HttpServletRequest#login(javax.servlet.http.HttpServletResponse) - */ - public boolean login(HttpServletResponse response) throws IOException, LoginException - { - // TODO Auto-generated method stub - return false; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.http.HttpServletRequest#login(java.lang.String, java.lang.String) - */ - public void login(String username, String password) throws LoginException - { - // TODO Auto-generated method stub - - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.http.HttpServletRequest#logout() - */ - public void logout() throws LoginException - { - // TODO Auto-generated method stub - - } - } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 2deaf4be132..d1eca01cedb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -22,7 +22,6 @@ import java.util.Iterator; import java.util.List; import java.util.ListIterator; -import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Servlet3Continuation.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Servlet3Continuation.java deleted file mode 100644 index 08703c229d3..00000000000 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Servlet3Continuation.java +++ /dev/null @@ -1,115 +0,0 @@ -// ======================================================================== -// Copyright (c) 2004-2009 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; - -import java.io.IOException; - -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; - -import org.eclipse.jetty.util.ajax.Continuation; - -public class Servlet3Continuation implements Continuation, AsyncListener -{ - AsyncContext _asyncContext; - Request _request; - Object _object; - RetryRequest _retry; - boolean _resumed=false; - boolean _timeout=false; - - Servlet3Continuation(Request request) - { - _request=request; - } - - public Object getObject() - { - return _object; - } - - public boolean isExpired() - { - return _asyncContext!=null && _timeout; - } - - public boolean isNew() - { - return _retry==null; - } - - public boolean isPending() - { - return _asyncContext!=null && (_request.getAsyncRequest().isSuspended() || !_request.getAsyncRequest().isInitial()); - } - - public boolean isResumed() - { - return _asyncContext!=null && _resumed; - } - - public void reset() - { - _resumed=false; - _timeout=false; - } - - public void resume() - { - if (_asyncContext==null) - throw new IllegalStateException(); - _resumed=true; - _asyncContext.dispatch(); - } - - public void setMutex(Object mutex) - { - } - - public void setObject(Object o) - { - _object=o; - } - - public boolean suspend(long timeout) - { - _asyncContext=_request.startAsync();; - if (!_request.getAsyncRequest().isInitial()||_resumed||_timeout) - { - _resumed=false; - _timeout=false; - return _resumed; - } - - _request.setAsyncTimeout(timeout); - _request.addAsyncListener(this); - if (_retry==null) - _retry=new RetryRequest(); - throw _retry; - - } - - public void onComplete(AsyncEvent event) throws IOException - { - - } - - public void onTimeout(AsyncEvent event) throws IOException - { - _timeout=true; - _request.getAsyncRequest().dispatch(); - } - -} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index f159721be1c..ee0acddad4a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -30,9 +30,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; -import javax.servlet.DispatcherType; import javax.servlet.Filter; -import javax.servlet.FilterRegistration; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletContext; @@ -41,12 +39,9 @@ import javax.servlet.ServletContextAttributeListener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -54,6 +49,7 @@ import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.Buffer; import org.eclipse.jetty.io.HttpException; import org.eclipse.jetty.server.Dispatcher; +import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HandlerContainer; import org.eclipse.jetty.server.HttpConnection; @@ -1766,137 +1762,6 @@ public class ContextHandler extends HandlerWrapper implements Attributes, Server ContextHandler.this.getInitParams().put(name,value); return true; } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addFilter(java.lang.String, java.lang.Class) - */ - public FilterRegistration addFilter(String filterName, Class filterClass) - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addFilter(java.lang.String, java.lang.String) - */ - public FilterRegistration addFilter(String filterName, String className) - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addServlet(java.lang.String, java.lang.Class) - */ - public ServletRegistration addServlet(String servletName, Class servletClass) - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addServlet(java.lang.String, java.lang.String) - */ - public ServletRegistration addServlet(String servletName, String className) - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#findFilterRegistration(java.lang.String) - */ - public FilterRegistration findFilterRegistration(String filterName) - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#findServletRegistration(java.lang.String) - */ - public ServletRegistration findServletRegistration(String servletName) - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#getDefaultSessionTrackingModes() - */ - public EnumSet getDefaultSessionTrackingModes() - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#getEffectiveSessionTrackingModes() - */ - public EnumSet getEffectiveSessionTrackingModes() - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#getSessionCookieConfig() - */ - public SessionCookieConfig getSessionCookieConfig() - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#setSessionTrackingModes(java.util.EnumSet) - */ - public void setSessionTrackingModes(EnumSet sessionTrackingModes) - { - Log.warn("Use servlet Context"); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addFilter(java.lang.String, javax.servlet.Filter) - */ - public FilterRegistration addFilter(String filterName, Filter filter) - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addServlet(java.lang.String, javax.servlet.Servlet) - */ - public ServletRegistration addServlet(String servletName, Servlet servlet) - { - Log.warn("Use servlet Context"); - return null; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#setSessionTrackingModes(java.util.Set) - */ - public void setSessionTrackingModes(Set sessionTrackingModes) - { - // TODO Auto-generated method stub - Log.warn("Not implemented"); - - } - } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java index b03c42cc23a..da175c48bdd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/RequestLogHandler.java @@ -15,11 +15,11 @@ package org.eclipse.jetty.server.handler; import java.io.IOException; -import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.HttpConnection; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.RequestLog; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java index 14ad86adee8..ba050c99181 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/nio/SelectChannelConnector.java @@ -43,7 +43,7 @@ import org.eclipse.jetty.util.thread.Timeout.Task; * This connector is best used when there are a many connections that have idle periods. *

*

- * When used with {@link org.eclipse.jetty.util.ajax.Continuation}, threadless waits are supported. When + * When used with {@link org.eclipse.jetty.continuation.Continuation}, threadless waits are supported. When * a filter or servlet calls getEvent on a Continuation, a {@link org.eclipse.jetty.server.RetryRequest} * runtime exception is thrown to allow the thread to exit the current request handling. Jetty will * catch this exception and will not send a response to the client. Instead the thread is released diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java index 5bfec3cace7..0f1d58eae97 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionHandler.java @@ -17,15 +17,14 @@ import java.io.IOException; import java.util.EnumSet; import java.util.EventListener; -import javax.servlet.DispatcherType; import javax.servlet.ServletException; -import javax.servlet.SessionTrackingMode; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.eclipse.jetty.http.HttpCookie; +import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.HttpConnection; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.RetryRequest; @@ -42,8 +41,6 @@ import org.eclipse.jetty.util.log.Log; */ public class SessionHandler extends HandlerWrapper { - public final static EnumSet DEFAULT_TRACKING = EnumSet.of(SessionTrackingMode.COOKIE,SessionTrackingMode.URL); - /* -------------------------------------------------------------- */ private SessionManager _sessionManager; diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java index a9efc64abdc..ed2bdd00d59 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/AsyncContextTest.java @@ -16,16 +16,14 @@ package org.eclipse.jetty.server; import java.io.IOException; import java.io.InputStream; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; -import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import junit.framework.TestCase; +import org.eclipse.jetty.continuation.ContinuationEvent; +import org.eclipse.jetty.continuation.ContinuationListener; import org.eclipse.jetty.server.handler.HandlerWrapper; public class AsyncContextTest extends TestCase @@ -277,14 +275,14 @@ public class AsyncContextTest extends TestCase } - private static AsyncListener __asyncListener = - new AsyncListener() + private static ContinuationListener __asyncListener = + new ContinuationListener() { - public void onComplete(AsyncEvent event) throws IOException + public void onComplete(ContinuationEvent event) throws IOException { } - public void onTimeout(AsyncEvent event) throws IOException + public void onTimeout(ContinuationEvent event) throws IOException { event.getRequest().setAttribute("TIMEOUT",Boolean.TRUE); ((Request)event.getRequest()).getAsyncContext().dispatch(); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java b/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java index 758215872ec..7b173aeda99 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/DumpHandler.java @@ -26,12 +26,12 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.continuation.Continuation; +import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.ajax.Continuation; -import org.eclipse.jetty.util.ajax.ContinuationSupport; import org.eclipse.jetty.util.log.Log; /* ------------------------------------------------------------ */ @@ -68,8 +68,9 @@ public class DumpHandler extends AbstractHandler if (request.getParameter("continue")!=null) { - Continuation continuation = ContinuationSupport.getContinuation(request, null); - continuation.suspend(Long.parseLong(request.getParameter("continue"))); + Continuation continuation = ContinuationSupport.getContinuation(request); + continuation.setTimeout(Long.parseLong(request.getParameter("continue"))); + continuation.suspend(); } base_request.setHandled(true); diff --git a/jetty-servlet-tester/src/main/java/org/eclipse/jetty/testing/HttpTester.java b/jetty-servlet-tester/src/main/java/org/eclipse/jetty/testing/HttpTester.java index 94fbd9c1805..fb4975b76ab 100644 --- a/jetty-servlet-tester/src/main/java/org/eclipse/jetty/testing/HttpTester.java +++ b/jetty-servlet-tester/src/main/java/org/eclipse/jetty/testing/HttpTester.java @@ -326,7 +326,7 @@ public class HttpTester cookie.getMaxAge(), cookie.getComment(), cookie.getSecure(), - cookie.isHttpOnly(), + false, cookie.getVersion()); } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java index b8557634102..4d07a15b7c4 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java @@ -15,11 +15,10 @@ package org.eclipse.jetty.servlet; import java.util.EnumSet; -import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterConfig; -import javax.servlet.FilterRegistration; +import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.util.log.Log; /* --------------------------------------------------------------------- */ @@ -132,49 +131,6 @@ public class FilterHolder extends Holder return getName(); } - - public FilterRegistration getRegistration() - { - return new Registration(); - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - protected class Registration extends HolderRegistration implements FilterRegistration - { - /* ------------------------------------------------------------ */ - public boolean addMappingForServletNames(EnumSet dispatcherTypes, boolean isMatchAfter, String... servletNames) - { - illegalStateIfContextStarted(); - FilterMapping mapping = new FilterMapping(); - mapping.setFilterHolder(FilterHolder.this); - mapping.setServletNames(servletNames); - mapping.setDispatcherTypes(dispatcherTypes); - if (isMatchAfter) - _servletHandler.addFilterMapping(mapping); - else - _servletHandler.prependFilterMapping(mapping); - - return true; - } - - public boolean addMappingForUrlPatterns(EnumSet dispatcherTypes, boolean isMatchAfter, String... urlPatterns) - { - illegalStateIfContextStarted(); - FilterMapping mapping = new FilterMapping(); - mapping.setFilterHolder(FilterHolder.this); - mapping.setPathSpecs(urlPatterns); - mapping.setDispatcherTypes(dispatcherTypes); - if (isMatchAfter) - _servletHandler.addFilterMapping(mapping); - else - _servletHandler.prependFilterMapping(mapping); - return true; - } - - } - /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java index 169067353dd..0467bb2d369 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterMapping.java @@ -16,9 +16,9 @@ package org.eclipse.jetty.servlet; import java.util.Arrays; import java.util.EnumSet; -import javax.servlet.DispatcherType; import org.eclipse.jetty.http.PathMap; +import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.Handler; diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java index b63267baf8a..9a37a6dd5e3 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Holder.java @@ -33,14 +33,14 @@ import org.eclipse.jetty.util.log.Log; /** * */ -public class Holder extends AbstractLifeCycle implements Serializable +public class Holder extends AbstractLifeCycle { - protected transient Class _class; + protected transient Class _class; protected String _className; protected String _displayName; protected Map _initParams; protected boolean _extInstance; - protected boolean _asyncSupported; + protected boolean _asyncSupported=true; protected AttributesMap _initAttributes; /* ---------------------------------------------------------------- */ @@ -296,80 +296,6 @@ public class Holder extends AbstractLifeCycle implements Serializable return Holder.this._initAttributes.keySet(); return Collections.emptySet(); } - - } - - /* -------------------------------------------------------- */ - /* -------------------------------------------------------- */ - /* -------------------------------------------------------- */ - protected class HolderRegistration - { - public boolean setAsyncSupported(boolean isAsyncSupported) - { - illegalStateIfContextStarted(); - Holder.this.setAsyncSupported(isAsyncSupported); - return true; - } - - public boolean setDescription(String description) - { - return true; - } - - public boolean setInitParameter(String name, String value) - { - illegalStateIfContextStarted(); - if (Holder.this.getInitParameter(name)!=null) - return false; - Holder.this.setInitParameter(name,value); - return true; - } - - public boolean setInitParameters(Map initParameters) - { - illegalStateIfContextStarted(); - for (String name : initParameters.keySet()) - if (Holder.this.getInitParameter(name)!=null) - return false; - Holder.this.setInitParameters(initParameters); - return true; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletRegistration#setInitAttribute(java.lang.String, java.lang.Object) - */ - public boolean setInitAttribute(String name, Object value) - { - illegalStateIfContextStarted(); - if (_initAttributes==null) - _initAttributes=new AttributesMap(); - else if (_initAttributes.getAttribute(name)!=null) - return false; - _initAttributes.setAttribute(name,value); - return true; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletRegistration#setInitAttributes(java.util.Map) - */ - public boolean setInitAttributes(Map initAttributes) - { - illegalStateIfContextStarted(); - if (_initAttributes==null) - _initAttributes=new AttributesMap(); - else - { - for (String name : initAttributes.keySet()) - if (_initAttributes.getAttribute(name)!=null) - return false; - } - for (String name : initAttributes.keySet()) - _initAttributes.setAttribute(name,initAttributes.get(name)); - - return true; - }; } } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java index 3b10330cd12..470ab707e8f 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java @@ -15,23 +15,19 @@ package org.eclipse.jetty.servlet; import java.util.EnumSet; -import javax.servlet.DispatcherType; import javax.servlet.Filter; -import javax.servlet.FilterRegistration; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletContext; -import javax.servlet.ServletRegistration; -import javax.servlet.SessionTrackingMode; import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.server.Dispatcher; +import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HandlerContainer; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.session.SessionHandler; -import org.eclipse.jetty.util.log.Log; /* ------------------------------------------------------------ */ @@ -352,150 +348,6 @@ public class ServletContextHandler extends ContextHandler handler.addServlet(holder); } - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addFilter(java.lang.String, java.lang.Class) - */ - public FilterRegistration addFilter(String filterName, Class filterClass) - { - if (isStarted()) - throw new IllegalStateException(); - - final ServletHandler handler = ServletContextHandler.this.getServletHandler(); - final FilterHolder holder= handler.newFilterHolder(); - holder.setName(filterName); - holder.setHeldClass(filterClass); - handler.addFilter(holder); - return holder.getRegistration(); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addFilter(java.lang.String, java.lang.String) - */ - public FilterRegistration addFilter(String filterName, String className) - { - if (isStarted()) - throw new IllegalStateException(); - - final ServletHandler handler = ServletContextHandler.this.getServletHandler(); - final FilterHolder holder= handler.newFilterHolder(); - holder.setName(filterName); - holder.setClassName(className); - handler.addFilter(holder); - return holder.getRegistration(); - } - - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addFilter(java.lang.String, javax.servlet.Filter) - */ - public FilterRegistration addFilter(String filterName, Filter filter) - { - if (isStarted()) - throw new IllegalStateException(); - - final ServletHandler handler = ServletContextHandler.this.getServletHandler(); - final FilterHolder holder= handler.newFilterHolder(); - holder.setName(filterName); - holder.setFilter(filter); - handler.addFilter(holder); - return holder.getRegistration(); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addServlet(java.lang.String, java.lang.Class) - */ - public ServletRegistration addServlet(String servletName, Class servletClass) - { - if (!isStarting()) - throw new IllegalStateException(); - - final ServletHandler handler = ServletContextHandler.this.getServletHandler(); - final ServletHolder holder= handler.newServletHolder(); - holder.setName(servletName); - holder.setHeldClass(servletClass); - handler.addServlet(holder); - return holder.getRegistration(); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addServlet(java.lang.String, java.lang.String) - */ - public ServletRegistration addServlet(String servletName, String className) - { - if (!isStarting()) - throw new IllegalStateException(); - - final ServletHandler handler = ServletContextHandler.this.getServletHandler(); - final ServletHolder holder= handler.newServletHolder(); - holder.setName(servletName); - holder.setClassName(className); - handler.addServlet(holder); - return holder.getRegistration(); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#addServlet(java.lang.String, javax.servlet.Servlet) - */ - public ServletRegistration addServlet(String servletName, Servlet servlet) - { - if (!isStarting()) - throw new IllegalStateException(); - - final ServletHandler handler = ServletContextHandler.this.getServletHandler(); - final ServletHolder holder= handler.newServletHolder(); - holder.setName(servletName); - holder.setServlet(servlet); - handler.addServlet(holder); - return holder.getRegistration(); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#findFilterRegistration(java.lang.String) - */ - public FilterRegistration findFilterRegistration(String filterName) - { - final ServletHandler handler = ServletContextHandler.this.getServletHandler(); - final FilterHolder holder=handler.getFilter(filterName); - return (holder==null)?null:holder.getRegistration(); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#findServletRegistration(java.lang.String) - */ - public ServletRegistration findServletRegistration(String servletName) - { - final ServletHandler handler = ServletContextHandler.this.getServletHandler(); - final ServletHolder holder=handler.getServlet(servletName); - return (holder==null)?null:holder.getRegistration(); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#getDefaultSessionTrackingModes() - */ - public EnumSet getDefaultSessionTrackingModes() - { - return SessionHandler.DEFAULT_TRACKING; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.servlet.ServletContext#getEffectiveSessionTrackingModes() - */ - public EnumSet getEffectiveSessionTrackingModes() - { - Log.warn("Not Implemented"); - return null; - } - } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java index c02d9361277..8f4d003f660 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.RequestDispatcher; @@ -42,6 +41,7 @@ import org.eclipse.jetty.io.HttpException; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.server.Dispatcher; +import org.eclipse.jetty.server.DispatcherType; import org.eclipse.jetty.server.HttpConnection; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.RetryRequest; diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java index d37504fe4fe..9ef1fa6ddd2 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java @@ -22,7 +22,6 @@ import java.util.Stack; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.SingleThreadModel; @@ -554,34 +553,6 @@ public class ServletHolder extends Holder implements UserIdentity.Scope, Compara } - /* -------------------------------------------------------- */ - /* -------------------------------------------------------- */ - /* -------------------------------------------------------- */ - protected class Registration extends HolderRegistration implements ServletRegistration - { - public boolean addMapping(String... urlPatterns) - { - illegalStateIfContextStarted(); - ServletMapping mapping = new ServletMapping(); - mapping.setServletName(ServletHolder.this.getName()); - mapping.setPathSpecs(urlPatterns); - _servletHandler.addServletMapping(mapping); - return true; - } - - public boolean setLoadOnStartup(int loadOnStartup) - { - illegalStateIfContextStarted(); - ServletHolder.this.setInitOrder(loadOnStartup); - return false; - } - } - - public ServletRegistration getRegistration() - { - return new Registration(); - } - /* -------------------------------------------------------- */ /* -------------------------------------------------------- */ /* -------------------------------------------------------- */ diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SessionTestServer.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SessionTestServer.java index 2288d5b7b50..73f5a43265c 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SessionTestServer.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SessionTestServer.java @@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.SessionIdManager; import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.server.handler.ContextHandlerCollection; @@ -76,7 +77,7 @@ public abstract class SessionTestServer extends Server pathInfo = pathInfo.substring(8); String cpath = pathInfo.substring(0, pathInfo.indexOf('/', 1)); pathInfo = pathInfo.substring(cpath.length()); - ServletContext context = request.getServletContext().getContext(cpath); + ServletContext context = ((Request)request).getServletContext().getContext(cpath); RequestDispatcher dispatcher = context.getRequestDispatcher(pathInfo); dispatcher.forward(request, response); } diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 747c0aec0d8..6838444de9d 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -52,6 +52,11 @@ junit test + + org.eclipse.jetty + jetty-continuation + ${project.version} + org.eclipse.jetty jetty-webapp diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/AsyncProxyServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/AsyncProxyServlet.java deleted file mode 100644 index a25fb62fe93..00000000000 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/AsyncProxyServlet.java +++ /dev/null @@ -1,352 +0,0 @@ -// ======================================================================== -// Copyright (c) 2006-2009 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.servlets; - - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.Socket; -import java.util.Enumeration; -import java.util.HashSet; - -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.HttpExchange; -import org.eclipse.jetty.http.HttpHeaders; -import org.eclipse.jetty.http.HttpSchemes; -import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.EofException; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; - - - -/** - * EXPERIMENTAL Proxy servlet. - * - * - */ -public class AsyncProxyServlet implements Servlet -{ - HttpClient _client; - - protected HashSet _DontProxyHeaders = new HashSet(); - { - _DontProxyHeaders.add("proxy-connection"); - _DontProxyHeaders.add("connection"); - _DontProxyHeaders.add("keep-alive"); - _DontProxyHeaders.add("transfer-encoding"); - _DontProxyHeaders.add("te"); - _DontProxyHeaders.add("trailer"); - _DontProxyHeaders.add("proxy-authorization"); - _DontProxyHeaders.add("proxy-authenticate"); - _DontProxyHeaders.add("upgrade"); - } - - private ServletConfig config; - private ServletContext context; - - /* (non-Javadoc) - * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) - */ - public void init(ServletConfig config) throws ServletException - { - this.config=config; - this.context=config.getServletContext(); - - _client=new HttpClient(); - //_client.setConnectorType(HttpClient.CONNECTOR_SOCKET); - _client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL); - try - { - _client.start(); - } - catch (Exception e) - { - throw new ServletException(e); - } - } - - /* (non-Javadoc) - * @see javax.servlet.Servlet#getServletConfig() - */ - public ServletConfig getServletConfig() - { - return config; - } - - /* (non-Javadoc) - * @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) - */ - public void service(ServletRequest req, ServletResponse res) throws ServletException, - IOException - { - final HttpServletRequest request = (HttpServletRequest)req; - final HttpServletResponse response = (HttpServletResponse)res; - if ("CONNECT".equalsIgnoreCase(request.getMethod())) - { - handleConnect(request,response); - } - else - { - final InputStream in=request.getInputStream(); - final OutputStream out=response.getOutputStream(); - - if (request.getDispatcherType()!=DispatcherType.ASYNC) - { - String uri=request.getRequestURI(); - if (request.getQueryString()!=null) - uri+="?"+request.getQueryString(); - - HttpURI url=proxyHttpURI(request.getScheme(), - request.getServerName(), - request.getServerPort(), - uri); - if (url==null) - { - response.sendError(HttpServletResponse.SC_FORBIDDEN); - return; - } - - final AsyncContext async=request.startAsync(request,response); - - HttpExchange exchange = new HttpExchange() - { - protected void onRequestCommitted() throws IOException - { - } - - protected void onRequestComplete() throws IOException - { - } - - protected void onResponseComplete() throws IOException - { - async.complete(); - } - - protected void onResponseContent(Buffer content) throws IOException - { - content.writeTo(out); - } - - protected void onResponseHeaderComplete() throws IOException - { - } - - protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException - { - if (reason!=null && reason.length()>0) - response.setStatus(status,reason.toString()); - else - response.setStatus(status); - } - - protected void onResponseHeader(Buffer name, Buffer value) throws IOException - { - String s = name.toString().toLowerCase(); - if (!_DontProxyHeaders.contains(s)) - response.addHeader(name.toString(),value.toString()); - } - - protected void onConnectionFailed(Throwable ex) - { - onException(ex); - } - - protected void onException(Throwable ex) - { - if (ex instanceof EofException) - { - Log.ignore(ex); - return; - } - Log.warn(ex.toString()); - Log.debug(ex); - if (!response.isCommitted()) - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - async.complete(); - } - - protected void onExpire() - { - if (!response.isCommitted()) - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - async.complete(); - } - - }; - - exchange.setScheme(HttpSchemes.HTTPS.equals(request.getScheme())?HttpSchemes.HTTPS_BUFFER:HttpSchemes.HTTP_BUFFER); - exchange.setMethod(request.getMethod()); - exchange.setURL(url.toString()); - exchange.setVersion(request.getProtocol()); - - if (Log.isDebugEnabled()) - Log.debug("PROXY TO "+url); - - // check connection header - String connectionHdr = request.getHeader("Connection"); - if (connectionHdr!=null) - { - connectionHdr=connectionHdr.toLowerCase(); - if (connectionHdr.indexOf("keep-alive")<0 && - connectionHdr.indexOf("close")<0) - connectionHdr=null; - } - - // copy headers - boolean xForwardedFor=false; - boolean hasContent=false; - long contentLength=-1; - Enumeration enm = request.getHeaderNames(); - while (enm.hasMoreElements()) - { - // TODO could be better than this! - String hdr=(String)enm.nextElement(); - String lhdr=hdr.toLowerCase(); - - if (_DontProxyHeaders.contains(lhdr)) - continue; - if (connectionHdr!=null && connectionHdr.indexOf(lhdr)>=0) - continue; - - if ("content-type".equals(lhdr)) - hasContent=true; - if ("content-length".equals(lhdr)) - { - contentLength=request.getContentLength(); - exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(contentLength)); - if (contentLength>0) - hasContent=true; - } - - Enumeration vals = request.getHeaders(hdr); - while (vals.hasMoreElements()) - { - String val = (String)vals.nextElement(); - if (val!=null) - { - exchange.setRequestHeader(lhdr,val); - xForwardedFor|="X-Forwarded-For".equalsIgnoreCase(hdr); - } - } - } - - // Proxy headers - exchange.setRequestHeader("Via","1.1 (jetty)"); - if (!xForwardedFor) - exchange.addRequestHeader("X-Forwarded-For", - request.getRemoteAddr()); - - if (hasContent) - exchange.setRequestContentSource(in); - - _client.send(exchange); - - } - } - } - - - /* ------------------------------------------------------------ */ - public void handleConnect(HttpServletRequest request, - HttpServletResponse response) - throws IOException - { - String uri = request.getRequestURI(); - - context.log("CONNECT: "+uri); - - String port = ""; - String host = ""; - - int c = uri.indexOf(':'); - if (c>=0) - { - port = uri.substring(c+1); - host = uri.substring(0,c); - if (host.indexOf('/')>0) - host = host.substring(host.indexOf('/')+1); - } - - // TODO - make this async! - - - InetSocketAddress inetAddress = new InetSocketAddress (host, Integer.parseInt(port)); - - //if (isForbidden(HttpMessage.__SSL_SCHEME,addrPort.getHost(),addrPort.getPort(),false)) - //{ - // sendForbid(request,response,uri); - //} - //else - { - InputStream in=request.getInputStream(); - OutputStream out=response.getOutputStream(); - - Socket socket = new Socket(inetAddress.getAddress(),inetAddress.getPort()); - context.log("Socket: "+socket); - - response.setStatus(200); - response.setHeader("Connection","close"); - response.flushBuffer(); - // TODO prevent real close! - - context.log("out<-in"); - IO.copyThread(socket.getInputStream(),out); - context.log("in->out"); - IO.copy(in,socket.getOutputStream()); - } - } - - /* ------------------------------------------------------------ */ - protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) - throws MalformedURLException - { - return new HttpURI(scheme+"://"+serverName+":"+serverPort+uri); - } - - - /* (non-Javadoc) - * @see javax.servlet.Servlet#getServletInfo() - */ - public String getServletInfo() - { - return "Proxy Servlet"; - } - - /* (non-Javadoc) - * @see javax.servlet.Servlet#destroy() - */ - public void destroy() - { - - } - -} diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java index 8f961634d64..d59e4c6adf3 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java @@ -21,8 +21,6 @@ import java.util.Set; import java.util.StringTokenizer; import java.util.zip.GZIPOutputStream; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; @@ -33,6 +31,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; +import org.eclipse.jetty.continuation.Continuation; +import org.eclipse.jetty.continuation.ContinuationEvent; +import org.eclipse.jetty.continuation.ContinuationListener; +import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.util.ByteArrayOutputStream2; import org.eclipse.jetty.util.StringUtil; @@ -132,16 +134,17 @@ public class GzipFilter extends UserAgentFilter } finally { - if (request.isAsyncStarted() && !req.getAsyncContext().hasOriginalRequestAndResponse()) + Continuation continuation = ContinuationSupport.getContinuation(request); + if (continuation.isSuspended() && continuation.wrappersKept()) { - request.addAsyncListener(new AsyncListener() + continuation.addContinuationListener(new ContinuationListener() { - public void onComplete(AsyncEvent event) throws IOException + public void onComplete(ContinuationEvent event) throws IOException { wrappedResponse.finish(); } - public void onTimeout(AsyncEvent event) throws IOException + public void onTimeout(ContinuationEvent event) throws IOException {} }); } diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java index 5d439e4ba1c..72f03a5ad9b 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java @@ -1,5 +1,5 @@ // ======================================================================== -// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 2006-2009 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 @@ -13,14 +13,13 @@ package org.eclipse.jetty.servlets; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.HttpURLConnection; import java.net.InetSocketAddress; +import java.net.MalformedURLException; import java.net.Socket; -import java.net.URL; -import java.net.URLConnection; import java.util.Enumeration; import java.util.HashSet; @@ -33,7 +32,18 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.HttpExchange; +import org.eclipse.jetty.continuation.Continuation; +import org.eclipse.jetty.continuation.ContinuationSupport; +import org.eclipse.jetty.http.HttpHeaders; +import org.eclipse.jetty.http.HttpSchemes; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.io.Buffer; +import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.log.Log; @@ -44,9 +54,9 @@ import org.eclipse.jetty.util.IO; */ public class ProxyServlet implements Servlet { - private int _tunnelTimeoutMs=300000; - - protected final HashSet _DontProxyHeaders = new HashSet(); + HttpClient _client; + + protected HashSet _DontProxyHeaders = new HashSet(); { _DontProxyHeaders.add("proxy-connection"); _DontProxyHeaders.add("connection"); @@ -58,10 +68,10 @@ public class ProxyServlet implements Servlet _DontProxyHeaders.add("proxy-authenticate"); _DontProxyHeaders.add("upgrade"); } - + private ServletConfig config; private ServletContext context; - + /* (non-Javadoc) * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) */ @@ -69,6 +79,18 @@ public class ProxyServlet implements Servlet { this.config=config; this.context=config.getServletContext(); + + _client=new HttpClient(); + //_client.setConnectorType(HttpClient.CONNECTOR_SOCKET); + _client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL); + try + { + _client.start(); + } + catch (Exception e) + { + throw new ServletException(e); + } } /* (non-Javadoc) @@ -85,161 +107,175 @@ public class ProxyServlet implements Servlet public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { - HttpServletRequest request = (HttpServletRequest)req; - HttpServletResponse response = (HttpServletResponse)res; + final HttpServletRequest request = (HttpServletRequest)req; + final HttpServletResponse response = (HttpServletResponse)res; if ("CONNECT".equalsIgnoreCase(request.getMethod())) { handleConnect(request,response); } else { - String uri=request.getRequestURI(); - if (request.getQueryString()!=null) - uri+="?"+request.getQueryString(); - URL url = new URL(request.getScheme(), - request.getServerName(), - request.getServerPort(), - uri); + final InputStream in=request.getInputStream(); + final OutputStream out=response.getOutputStream(); + + final Continuation continuation = ContinuationSupport.getContinuation(request); - context.log("URL="+url); - - URLConnection connection = url.openConnection(); - connection.setAllowUserInteraction(false); - - // Set method - HttpURLConnection http = null; - if (connection instanceof HttpURLConnection) + if (!continuation.isInitial()) + response.sendError(HttpServletResponse.SC_GATEWAY_TIMEOUT); // Need better test that isInitial + else { - http = (HttpURLConnection)connection; - http.setRequestMethod(request.getMethod()); - http.setInstanceFollowRedirects(false); - } + String uri=request.getRequestURI(); + if (request.getQueryString()!=null) + uri+="?"+request.getQueryString(); - // check connection header - String connectionHdr = request.getHeader("Connection"); - if (connectionHdr!=null) - { - connectionHdr=connectionHdr.toLowerCase(); - if (connectionHdr.equals("keep-alive")|| - connectionHdr.equals("close")) - connectionHdr=null; - } - - // copy headers - boolean xForwardedFor=false; - boolean hasContent=false; - Enumeration enm = request.getHeaderNames(); - while (enm.hasMoreElements()) - { - // TODO could be better than this! - String hdr=(String)enm.nextElement(); - String lhdr=hdr.toLowerCase(); + HttpURI url=proxyHttpURI(request.getScheme(), + request.getServerName(), + request.getServerPort(), + uri); + if (url==null) + { + response.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } - if (_DontProxyHeaders.contains(lhdr)) - continue; - if (connectionHdr!=null && connectionHdr.indexOf(lhdr)>=0) - continue; - if ("content-type".equals(lhdr)) - hasContent=true; - - Enumeration vals = request.getHeaders(hdr); - while (vals.hasMoreElements()) + HttpExchange exchange = new HttpExchange() { - String val = (String)vals.nextElement(); - if (val!=null) + protected void onRequestCommitted() throws IOException { - connection.addRequestProperty(hdr,val); - context.log("req "+hdr+": "+val); - xForwardedFor|="X-Forwarded-For".equalsIgnoreCase(hdr); + } + + protected void onRequestComplete() throws IOException + { + } + + protected void onResponseComplete() throws IOException + { + continuation.complete(); + } + + protected void onResponseContent(Buffer content) throws IOException + { + content.writeTo(out); + } + + protected void onResponseHeaderComplete() throws IOException + { + } + + protected void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException + { + if (reason!=null && reason.length()>0) + response.setStatus(status,reason.toString()); + else + response.setStatus(status); + } + + protected void onResponseHeader(Buffer name, Buffer value) throws IOException + { + String s = name.toString().toLowerCase(); + if (!_DontProxyHeaders.contains(s)) + response.addHeader(name.toString(),value.toString()); + } + + protected void onConnectionFailed(Throwable ex) + { + onException(ex); + } + + protected void onException(Throwable ex) + { + if (ex instanceof EofException) + { + Log.ignore(ex); + return; + } + Log.warn(ex.toString()); + Log.debug(ex); + if (!response.isCommitted()) + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + continuation.complete(); + } + + protected void onExpire() + { + if (!response.isCommitted()) + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + continuation.complete(); + } + + }; + + exchange.setScheme(HttpSchemes.HTTPS.equals(request.getScheme())?HttpSchemes.HTTPS_BUFFER:HttpSchemes.HTTP_BUFFER); + exchange.setMethod(request.getMethod()); + exchange.setURL(url.toString()); + exchange.setVersion(request.getProtocol()); + + if (Log.isDebugEnabled()) + Log.debug("PROXY TO "+url); + + // check connection header + String connectionHdr = request.getHeader("Connection"); + if (connectionHdr!=null) + { + connectionHdr=connectionHdr.toLowerCase(); + if (connectionHdr.indexOf("keep-alive")<0 && + connectionHdr.indexOf("close")<0) + connectionHdr=null; + } + + // copy headers + boolean xForwardedFor=false; + boolean hasContent=false; + long contentLength=-1; + Enumeration enm = request.getHeaderNames(); + while (enm.hasMoreElements()) + { + // TODO could be better than this! + String hdr=(String)enm.nextElement(); + String lhdr=hdr.toLowerCase(); + + if (_DontProxyHeaders.contains(lhdr)) + continue; + if (connectionHdr!=null && connectionHdr.indexOf(lhdr)>=0) + continue; + + if ("content-type".equals(lhdr)) + hasContent=true; + if ("content-length".equals(lhdr)) + { + contentLength=request.getContentLength(); + exchange.setRequestHeader(HttpHeaders.CONTENT_LENGTH,TypeUtil.toString(contentLength)); + if (contentLength>0) + hasContent=true; + } + + Enumeration vals = request.getHeaders(hdr); + while (vals.hasMoreElements()) + { + String val = (String)vals.nextElement(); + if (val!=null) + { + exchange.setRequestHeader(lhdr,val); + xForwardedFor|="X-Forwarded-For".equalsIgnoreCase(hdr); + } } } - } - // Proxy headers - connection.setRequestProperty("Via","1.1 (jetty)"); - if (!xForwardedFor) - connection.addRequestProperty("X-Forwarded-For", - request.getRemoteAddr()); + // Proxy headers + exchange.setRequestHeader("Via","1.1 (jetty)"); + if (!xForwardedFor) + exchange.addRequestHeader("X-Forwarded-For", + request.getRemoteAddr()); - // a little bit of cache control - String cache_control = request.getHeader("Cache-Control"); - if (cache_control!=null && - (cache_control.indexOf("no-cache")>=0 || - cache_control.indexOf("no-store")>=0)) - connection.setUseCaches(false); - - // customize Connection - - try - { - connection.setDoInput(true); - - // do input thang! - InputStream in=request.getInputStream(); if (hasContent) - { - connection.setDoOutput(true); - IO.copy(in,connection.getOutputStream()); - } - - // Connect - connection.connect(); - } - catch (Exception e) - { - context.log("proxy",e); - } - - InputStream proxy_in = null; + exchange.setRequestContentSource(in); - // handler status codes etc. - int code=500; - if (http!=null) - { - proxy_in = http.getErrorStream(); - - code=http.getResponseCode(); - response.setStatus(code, http.getResponseMessage()); - context.log("response = "+http.getResponseCode()); - } - - if (proxy_in==null) - { - try {proxy_in=connection.getInputStream();} - catch (Exception e) - { - context.log("stream",e); - proxy_in = http.getErrorStream(); - } - } - - // clear response defaults. - response.setHeader("Date",null); - response.setHeader("Server",null); - - // set response headers - int h=0; - String hdr=connection.getHeaderFieldKey(h); - String val=connection.getHeaderField(h); - while(hdr!=null || val!=null) - { - String lhdr = hdr!=null?hdr.toLowerCase():null; - if (hdr!=null && val!=null && !_DontProxyHeaders.contains(lhdr)) - response.addHeader(hdr,val); + continuation.suspend(); + continuation.keepWrappers(); + _client.send(exchange); - context.log("res "+hdr+": "+val); - - h++; - hdr=connection.getHeaderFieldKey(h); - val=connection.getHeaderField(h); } - response.addHeader("Via","1.1 (jetty)"); - - // Handle - if (proxy_in!=null) - IO.copy(proxy_in,response.getOutputStream()); - } } @@ -250,12 +286,12 @@ public class ProxyServlet implements Servlet throws IOException { String uri = request.getRequestURI(); - + context.log("CONNECT: "+uri); - + String port = ""; String host = ""; - + int c = uri.indexOf(':'); if (c>=0) { @@ -265,11 +301,11 @@ public class ProxyServlet implements Servlet host = host.substring(host.indexOf('/')+1); } - - + // TODO - make this async! + InetSocketAddress inetAddress = new InetSocketAddress (host, Integer.parseInt(port)); - + //if (isForbidden(HttpMessage.__SSL_SCHEME,addrPort.getHost(),addrPort.getPort(),false)) //{ // sendForbid(request,response,uri); @@ -278,15 +314,14 @@ public class ProxyServlet implements Servlet { InputStream in=request.getInputStream(); OutputStream out=response.getOutputStream(); - + Socket socket = new Socket(inetAddress.getAddress(),inetAddress.getPort()); context.log("Socket: "+socket); - + response.setStatus(200); response.setHeader("Connection","close"); response.flushBuffer(); - - + // TODO prevent real close! context.log("out<-in"); IO.copyThread(socket.getInputStream(),out); @@ -294,10 +329,15 @@ public class ProxyServlet implements Servlet IO.copy(in,socket.getOutputStream()); } } - - - - + + /* ------------------------------------------------------------ */ + protected HttpURI proxyHttpURI(String scheme, String serverName, int serverPort, String uri) + throws MalformedURLException + { + return new HttpURI(scheme+"://"+serverName+":"+serverPort+uri); + } + + /* (non-Javadoc) * @see javax.servlet.Servlet#getServletInfo() */ @@ -313,4 +353,5 @@ public class ProxyServlet implements Servlet { } + } diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java index a7c92b269c9..861b81247c8 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java @@ -29,6 +29,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.eclipse.jetty.continuation.Continuation; +import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.util.ArrayQueue; /** @@ -77,7 +79,7 @@ public class QoSFilter implements Filter long _waitMs; long _suspendMs; Semaphore _passes; - Queue[] _queue; + Queue[] _queue; String _suspended="QoSFilter@"+this.hashCode(); public void init(FilterConfig filterConfig) @@ -89,7 +91,7 @@ public class QoSFilter implements Filter max_priority=Integer.parseInt(filterConfig.getInitParameter(MAX_PRIORITY_INIT_PARAM)); _queue=new Queue[max_priority+1]; for (int p=0;p<_queue.length;p++) - _queue[p]=new ArrayQueue(); + _queue[p]=new ArrayQueue(); int passes=__DEFAULT_PASSES; if (filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM)!=null) @@ -123,12 +125,13 @@ public class QoSFilter implements Filter else { request.setAttribute(_suspended,Boolean.TRUE); + Continuation continuation = ContinuationSupport.getContinuation(request); if (_suspendMs>0) - request.setAsyncTimeout(_suspendMs); - request.startAsync(); + continuation.setTimeout(_suspendMs); + continuation.suspend(); int priority = getPriority(request); - _queue[priority].add(request); + _queue[priority].add(continuation); return; } } @@ -182,10 +185,10 @@ public class QoSFilter implements Filter { for (int p=_queue.length;p-->0;) { - ServletRequest r=_queue[p].poll(); - if (r!=null) + Continuation continutaion=_queue[p].poll(); + if (continutaion!=null) { - r.getAsyncContext().dispatch(); + continutaion.resume(); break; } } diff --git a/jetty-test-webapp/pom.xml b/jetty-test-webapp/pom.xml index 10696ffcd75..c7bdb292e69 100644 --- a/jetty-test-webapp/pom.xml +++ b/jetty-test-webapp/pom.xml @@ -118,10 +118,10 @@ provided - org.mortbay.jetty - jsp-api-2.1-glassfish - 9.1.02.B04.p0 - provided + org.eclipse.jetty + jetty-webapp + ${project.version} + test junit diff --git a/jetty-test-webapp/src/main/java/com/acme/ChatServlet.java b/jetty-test-webapp/src/main/java/com/acme/ChatServlet.java index 0fc8bf5e0f9..6e81517701d 100644 --- a/jetty-test-webapp/src/main/java/com/acme/ChatServlet.java +++ b/jetty-test-webapp/src/main/java/com/acme/ChatServlet.java @@ -19,14 +19,14 @@ import java.util.LinkedList; import java.util.Map; import java.util.Queue; -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.continuation.Continuation; +import org.eclipse.jetty.continuation.ContinuationSupport; + // Simple asynchronous Chat room. @@ -34,22 +34,12 @@ import javax.servlet.http.HttpServletResponse; // Some code is duplicated for clarity. public class ChatServlet extends HttpServlet { - AsyncListener _asyncListener = new AsyncListener() - { - public void onComplete(AsyncEvent event) throws IOException - {} - - public void onTimeout(AsyncEvent event) throws IOException - { - event.getRequest().getAsyncContext().dispatch(); - } - }; // inner class to hold message queue for each chat room member class Member { String _name; - AsyncContext _asyncContext; + Continuation _continuation; Queue _queue = new LinkedList(); } @@ -105,43 +95,50 @@ public class ChatServlet extends HttpServlet return; } - if (member._queue.size()>0) + synchronized(member) { - // Send one chat message - response.setContentType("text/json;charset=utf-8"); - StringBuilder buf=new StringBuilder(); - - buf.append("{\"action\":\"poll\","); - buf.append("\"from\":\""); - buf.append(member._queue.poll()); - buf.append("\","); - - String message = member._queue.poll(); - int quote=message.indexOf('"'); - while (quote>=0) + if (member._queue.size()>0) { - message=message.substring(0,quote)+'\\'+message.substring(quote); - quote=message.indexOf('"',quote+2); + // Send one chat message + response.setContentType("text/json;charset=utf-8"); + StringBuilder buf=new StringBuilder(); + + buf.append("{\"action\":\"poll\","); + buf.append("\"from\":\""); + buf.append(member._queue.poll()); + buf.append("\","); + + String message = member._queue.poll(); + int quote=message.indexOf('"'); + while (quote>=0) + { + message=message.substring(0,quote)+'\\'+message.substring(quote); + quote=message.indexOf('"',quote+2); + } + buf.append("\"chat\":\""); + buf.append(message); + buf.append("\"}"); + byte[] bytes = buf.toString().getBytes("utf-8"); + response.setContentLength(bytes.length); + response.getOutputStream().write(bytes); + } + else + { + Continuation continuation = ContinuationSupport.getContinuation(request); + if (continuation.isInitial()) + { + // No chat in queue, so suspend and wait for timeout or chat + continuation.suspend(); + member._continuation=continuation; + } + else + { + // Timeout so send empty response + response.setContentType("text/json;charset=utf-8"); + PrintWriter out=response.getWriter(); + out.print("{action:\"poll\"}"); + } } - buf.append("\"chat\":\""); - buf.append(message); - buf.append("\"}"); - byte[] bytes = buf.toString().getBytes("utf-8"); - response.setContentLength(bytes.length); - response.getOutputStream().write(bytes); - } - else if (request.isAsyncStarted()) - { - // Timeout so send empty response - response.setContentType("text/json;charset=utf-8"); - PrintWriter out=response.getWriter(); - out.print("{action:\"poll\"}"); - } - else - { - // No chat in queue, so suspend and wait for timeout or chat - request.addAsyncListener(_asyncListener); - member._asyncContext=request.startAsync(); } } @@ -152,14 +149,17 @@ public class ChatServlet extends HttpServlet // Post chat to all members for (Member m:room.values()) { - m._queue.add(username); // from - m._queue.add(message); // chat - - // wakeup member if polling - if (m._asyncContext!=null) + synchronized (m) { - m._asyncContext.dispatch(); - m._asyncContext=null; + m._queue.add(username); // from + m._queue.add(message); // chat + + // wakeup member if polling + if (m._continuation!=null) + { + m._continuation.resume(); + m._continuation=null; + } } } diff --git a/jetty-test-webapp/src/main/java/com/acme/CometServlet.java b/jetty-test-webapp/src/main/java/com/acme/CometServlet.java deleted file mode 100644 index 2f063bb82d1..00000000000 --- a/jetty-test-webapp/src/main/java/com/acme/CometServlet.java +++ /dev/null @@ -1,85 +0,0 @@ -// ======================================================================== -// Copyright (c) 2004-2009 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 com.acme; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.util.ajax.Continuation; -import org.eclipse.jetty.util.ajax.ContinuationSupport; - -/** CometServlet - * This servlet implements the Comet API from tc6.x with the exception of the read method. - * - * - * - */ -public class CometServlet extends HttpServlet -{ - public void begin(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - request.setAttribute("org.apache.tomcat.comet",Boolean.TRUE); - } - - public void end(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - synchronized(request) - { - request.removeAttribute("org.apache.tomcat.comet"); - - Continuation continuation=ContinuationSupport.getContinuation(request,request); - if (continuation.isPending()) - continuation.resume(); - } - } - - public void error(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - end(request,response); - } - - public boolean read(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - throw new UnsupportedOperationException(); - } - - protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - synchronized(request) - { - // TODO: wrap response so we can reset timeout on writes. - - Continuation continuation=ContinuationSupport.getContinuation(request,request); - - if (!continuation.isPending()) - begin(request,response); - - Integer timeout=(Integer)request.getAttribute("org.apache.tomcat.comet.timeout"); - boolean resumed=continuation.suspend(timeout==null?60000:timeout.intValue()); - - if (!resumed) - error(request,response); - } - } - - public void setTimeout(HttpServletRequest request, HttpServletResponse response, int timeout) throws IOException, ServletException, - UnsupportedOperationException - { - request.setAttribute("org.apache.tomcat.comet.timeout",new Integer(timeout)); - } -} diff --git a/jetty-test-webapp/src/main/java/com/acme/Date2Tag.java b/jetty-test-webapp/src/main/java/com/acme/Date2Tag.java deleted file mode 100644 index d120f49f594..00000000000 --- a/jetty-test-webapp/src/main/java/com/acme/Date2Tag.java +++ /dev/null @@ -1,48 +0,0 @@ -// ======================================================================== -// Copyright (c) 2004-2009 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 com.acme; - -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.StringTokenizer; - -import javax.servlet.jsp.JspContext; -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.JspFragment; -import javax.servlet.jsp.tagext.SimpleTagSupport; - -public class Date2Tag extends SimpleTagSupport -{ - String format; - - public void setFormat(String value) { - this.format = value; - } - - public void doTag() throws JspException, IOException { - String formatted = - new SimpleDateFormat("long".equals(format)?"EEE 'the' d:MMM:yyyy":"d:MM:yy") - .format(new Date()); - StringTokenizer tok = new StringTokenizer(formatted,":"); - JspContext context = getJspContext(); - context.setAttribute("day", tok.nextToken() ); - context.setAttribute("month", tok.nextToken() ); - context.setAttribute("year", tok.nextToken() ); - - JspFragment fragment = getJspBody(); - fragment.invoke(null); - } -} - diff --git a/jetty-test-webapp/src/main/java/com/acme/DateTag.java b/jetty-test-webapp/src/main/java/com/acme/DateTag.java deleted file mode 100644 index 978a8676e97..00000000000 --- a/jetty-test-webapp/src/main/java/com/acme/DateTag.java +++ /dev/null @@ -1,65 +0,0 @@ -// ======================================================================== -// Copyright (c) 2004-2009 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 com.acme; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; - -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.JspTagException; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.tagext.BodyContent; -import javax.servlet.jsp.tagext.BodyTagSupport; -import javax.servlet.jsp.tagext.Tag; - -public class DateTag extends BodyTagSupport -{ - Tag parent; - BodyContent body; - String tz="GMT"; - - public void setParent(Tag parent) {this.parent=parent;} - public Tag getParent() {return parent;} - public void setBodyContent(BodyContent content) {body=content;} - public void setPageContext(PageContext pageContext) {} - - public void setTz(String value) {tz=value;} - - public int doStartTag() throws JspException {return EVAL_BODY_TAG;} - - public int doEndTag() throws JspException {return EVAL_PAGE;} - - public void doInitBody() throws JspException {} - - public int doAfterBody() throws JspException { - try - { - SimpleDateFormat format = new SimpleDateFormat(body.getString()); - format.setTimeZone(TimeZone.getTimeZone(tz)); - body.getEnclosingWriter().write(format.format(new Date())); - return SKIP_BODY; - } - catch (Exception ex) { - ex.printStackTrace(); - throw new JspTagException(ex.toString()); - } - } - - public void release() - { - body=null; - } -} - diff --git a/jetty-test-webapp/src/main/java/com/acme/Dump.java b/jetty-test-webapp/src/main/java/com/acme/Dump.java index 9dab8d17748..957b6128c2b 100644 --- a/jetty-test-webapp/src/main/java/com/acme/Dump.java +++ b/jetty-test-webapp/src/main/java/com/acme/Dump.java @@ -23,8 +23,6 @@ import java.lang.reflect.Field; import java.util.Enumeration; import java.util.Locale; -import javax.servlet.AsyncEvent; -import javax.servlet.AsyncListener; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -39,10 +37,10 @@ import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; +import org.eclipse.jetty.continuation.Continuation; +import org.eclipse.jetty.continuation.ContinuationSupport; import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.ajax.Continuation; -import org.eclipse.jetty.util.ajax.ContinuationSupport; @@ -73,7 +71,7 @@ public class Dump extends HttpServlet } /* ------------------------------------------------------------ */ - public void doGet(final HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { if(request.getPathInfo()!=null && request.getPathInfo().toLowerCase().indexOf("script")!=-1) { @@ -131,19 +129,20 @@ public class Dump extends HttpServlet { e.printStackTrace(); } - Continuation continuation = ContinuationSupport.getContinuation(request, null); + Continuation continuation = ContinuationSupport.getContinuation(request); continuation.resume(); } }).start(); } - if (request.getParameter("continue")!=null) + if (request.getParameter("suspend")!=null) { try { - Continuation continuation = ContinuationSupport.getContinuation(request, null); - continuation.suspend(Long.parseLong(request.getParameter("continue"))); + Continuation continuation = ContinuationSupport.getContinuation(request); + continuation.setTimeout(Long.parseLong(request.getParameter("suspend"))); + continuation.suspend(); } catch(Exception e) { @@ -151,84 +150,37 @@ public class Dump extends HttpServlet } } - if (request.getAttribute("ASYNC")==null) + if (request.getParameter("complete")!=null) { - request.setAttribute("ASYNC",Boolean.TRUE); - - if (request.getParameter("dispatch")!=null) + final long complete=Long.parseLong(request.getParameter("complete")); + new Thread(new Runnable() { - final long resume=Long.parseLong(request.getParameter("dispatch")); - final String path=request.getParameter("dispatchPath"); - new Thread(new Runnable() + public void run() { - public void run() + try { - try - { - Thread.sleep(resume); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - if (path!=null) - request.getAsyncContext().dispatch(path); - else - request.getAsyncContext().dispatch(); - + Thread.sleep(complete); } - - }).start(); - } - - if (request.getParameter("complete")!=null) - { - final long complete=Long.parseLong(request.getParameter("complete")); - new Thread(new Runnable() - { - public void run() + catch (InterruptedException e) { - try - { - Thread.sleep(complete); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - try - { - HttpServletResponse response = (HttpServletResponse) request.getAsyncContext().getResponse(); - response.setContentType("text/html"); - response.getOutputStream().println("

COMPLETED

"); - request.getAsyncContext().complete(); - } - catch (IOException e) - { - e.printStackTrace(); - } + e.printStackTrace(); } - - }).start(); - } - - if (request.getParameter("async")!=null) - { - final long async=Long.parseLong(request.getParameter("async")); - request.addAsyncListener(new AsyncListener(){ - public void onComplete(AsyncEvent event) throws IOException + try { + response.setContentType("text/html"); + response.getOutputStream().println("

COMPLETED

"); + Continuation continuation = ContinuationSupport.getContinuation(request); + continuation.complete(); } - public void onTimeout(AsyncEvent event) throws IOException + catch (IOException e) { - event.getRequest().getAsyncContext().dispatch(); + e.printStackTrace(); } - }); - request.setAsyncTimeout(async); - request.startAsync(); - return; - } + } + + }).start(); } + request.setAttribute("Dump", this); getServletContext().setAttribute("Dump",this); @@ -442,10 +394,6 @@ public class Dump extends HttpServlet pout.write("

Dump Servlet

\n"); pout.write(""); pout.write("\n"); - pout.write(""); - pout.write(""); - pout.write("\n"); - pout.write("\n"); pout.write(""); pout.write(""); pout.write("\n"); @@ -476,13 +424,6 @@ public class Dump extends HttpServlet pout.write(""); pout.write(""); pout.write("\n"); - - pout.write(""); - pout.write(""); - pout.write("\n"); - pout.write(""); - pout.write(""); - pout.write("\n"); pout.write(""); pout.write(""); @@ -772,22 +713,12 @@ public class Dump extends HttpServlet pout.write("resource:
\n"); pout.write(""); pout.write("\n"); - - } catch (Exception e) { getServletContext().log("dump", e); } - - if (request.getParameter("stream")!=null) - { - pout.flush(); - Continuation continuation = ContinuationSupport.getContinuation(request, null); - continuation.suspend(Long.parseLong(request.getParameter("stream"))); - } - String lines= request.getParameter("lines"); if (lines!=null) { diff --git a/jetty-test-webapp/src/main/java/com/acme/TagListener.java b/jetty-test-webapp/src/main/java/com/acme/TagListener.java deleted file mode 100644 index bbafdeaca41..00000000000 --- a/jetty-test-webapp/src/main/java/com/acme/TagListener.java +++ /dev/null @@ -1,135 +0,0 @@ -// ======================================================================== -// Copyright (c) 2004-2009 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 com.acme; - -import javax.servlet.ServletContextAttributeEvent; -import javax.servlet.ServletContextAttributeListener; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRequestAttributeEvent; -import javax.servlet.ServletRequestAttributeListener; -import javax.servlet.ServletRequestEvent; -import javax.servlet.ServletRequestListener; -import javax.servlet.http.HttpSessionActivationListener; -import javax.servlet.http.HttpSessionAttributeListener; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - -public class TagListener implements HttpSessionListener, HttpSessionAttributeListener, HttpSessionActivationListener, ServletContextListener, ServletContextAttributeListener, ServletRequestListener, ServletRequestAttributeListener -{ - public void attributeAdded(HttpSessionBindingEvent se) - { - //System.err.println("tagListener: attributedAdded "+se); - } - - public void attributeRemoved(HttpSessionBindingEvent se) - { - //System.err.println("tagListener: attributeRemoved "+se); - } - - public void attributeReplaced(HttpSessionBindingEvent se) - { - //System.err.println("tagListener: attributeReplaced "+se); - } - - public void sessionWillPassivate(HttpSessionEvent se) - { - //System.err.println("tagListener: sessionWillPassivate "+se); - } - - public void sessionDidActivate(HttpSessionEvent se) - { - //System.err.println("tagListener: sessionDidActivate "+se); - } - - public void contextInitialized(ServletContextEvent sce) - { - //System.err.println("tagListener: contextInitialized "+sce); - } - - public void contextDestroyed(ServletContextEvent sce) - { - //System.err.println("tagListener: contextDestroyed "+sce); - } - - public void attributeAdded(ServletContextAttributeEvent scab) - { - //System.err.println("tagListener: attributeAdded "+scab); - } - - public void attributeRemoved(ServletContextAttributeEvent scab) - { - //System.err.println("tagListener: attributeRemoved "+scab); - } - - public void attributeReplaced(ServletContextAttributeEvent scab) - { - //System.err.println("tagListener: attributeReplaced "+scab); - } - - public void requestDestroyed(ServletRequestEvent sre) - { - //System.err.println("tagListener: requestDestroyed "+sre); - } - - public void requestInitialized(ServletRequestEvent sre) - { - //System.err.println("tagListener: requestInitialized "+sre); - } - - public void attributeAdded(ServletRequestAttributeEvent srae) - { - //System.err.println("tagListener: attributeAdded "+srae); - } - - public void attributeRemoved(ServletRequestAttributeEvent srae) - { - //System.err.println("tagListener: attributeRemoved "+srae); - } - - public void attributeReplaced(ServletRequestAttributeEvent srae) - { - //System.err.println("tagListener: attributeReplaced "+srae); - } - - public void sessionCreated(HttpSessionEvent se) - { - //System.err.println("tagListener: sessionCreated "+se); - } - - public void sessionDestroyed(HttpSessionEvent se) - { - //System.err.println("tagListener: sessionDestroyed "+se); - } - - public void requestCompleted(ServletRequestEvent rre) - { - // TODO Auto-generated method stub - - } - - public void requestResumed(ServletRequestEvent rre) - { - // TODO Auto-generated method stub - - } - - public void requestSuspended(ServletRequestEvent rre) - { - // TODO Auto-generated method stub - - } - -} diff --git a/jetty-test-webapp/src/main/java/com/acme/TestListener.java b/jetty-test-webapp/src/main/java/com/acme/TestListener.java index b0427086b1a..bc5d48b05e6 100644 --- a/jetty-test-webapp/src/main/java/com/acme/TestListener.java +++ b/jetty-test-webapp/src/main/java/com/acme/TestListener.java @@ -13,10 +13,6 @@ package com.acme; -import java.util.EnumSet; - -import javax.servlet.DispatcherType; -import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; @@ -64,13 +60,16 @@ public class TestListener implements HttpSessionListener, HttpSessionAttributeL { ServletContext context=sce.getServletContext(); - FilterRegistration registration=context.addFilter("TestFilter",TestFilter.class.getName()); + /* TODO for servlet 3.0 + * FilterRegistration registration=context.addFilter("TestFilter",TestFilter.class.getName()); + registration.setAsyncSupported(true); registration.addMappingForUrlPatterns( EnumSet.of(DispatcherType.ERROR,DispatcherType.ASYNC,DispatcherType.FORWARD,DispatcherType.INCLUDE,DispatcherType.REQUEST), true, new String[]{"/dump/*","/dispatch/*","*.dump"}); + */ } public void contextDestroyed(ServletContextEvent sce) diff --git a/jetty-test-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-test-webapp/src/main/webapp/WEB-INF/web.xml index b6192c710b4..e93511e3642 100644 --- a/jetty-test-webapp/src/main/webapp/WEB-INF/web.xml +++ b/jetty-test-webapp/src/main/webapp/WEB-INF/web.xml @@ -150,17 +150,6 @@ /dispatch/* - - JspSnoop - /snoop.jsp - 1 - - - - JspSnoop - /jspsnoop/* - - CGI org.eclipse.jetty.servlets.CGI @@ -186,12 +175,7 @@ 404 - /jspsnoop/ERROR/404 - - - - java.io.IOException - /jspsnoop/IOException + /error404.html @@ -266,26 +250,6 @@ /logonError.html?param=test - - - - - http://www.acme.com/taglib - - - /WEB-INF/acme-taglib.tld - - - - - - http://www.acme.com/taglib2 - - - /WEB-INF/acme-taglib2.tld - - - 5 diff --git a/jetty-test-webapp/src/main/webapp/error404.html b/jetty-test-webapp/src/main/webapp/error404.html new file mode 100644 index 00000000000..0dd635b22bc --- /dev/null +++ b/jetty-test-webapp/src/main/webapp/error404.html @@ -0,0 +1,4 @@ + +

Not Found ERROR

+custom 404 page + \ No newline at end of file diff --git a/jetty-test-webapp/src/main/webapp/index.html b/jetty-test-webapp/src/main/webapp/index.html index 069421c19ac..3e7641f1ceb 100644 --- a/jetty-test-webapp/src/main/webapp/index.html +++ b/jetty-test-webapp/src/main/webapp/index.html @@ -28,8 +28,6 @@ This is a test context that serves:
  • a Request Dump Servlet
  • a Session Dump Servlet
  • a Cookie Dump Servlet
  • -
  • a Request Dump JSP
  • -
  • a Other JSP Tests
  • a Dispatcher Servlet
  • a CGI script(unix only)
  • diff --git a/jetty-test-webapp/src/main/webapp/jsp/bean1.jsp b/jetty-test-webapp/src/main/webapp/jsp/bean1.jsp deleted file mode 100644 index 0c15da2ca4e..00000000000 --- a/jetty-test-webapp/src/main/webapp/jsp/bean1.jsp +++ /dev/null @@ -1,15 +0,0 @@ - -<%@ page session="true"%> - - - -

    JSP1.2 Beans: 1

    - -Counter accessed times.
    -Counter last accessed by
    - - -Goto bean2.jsp - - - diff --git a/jetty-test-webapp/src/main/webapp/jsp/bean2.jsp b/jetty-test-webapp/src/main/webapp/jsp/bean2.jsp deleted file mode 100644 index 624dc2e59d4..00000000000 --- a/jetty-test-webapp/src/main/webapp/jsp/bean2.jsp +++ /dev/null @@ -1,15 +0,0 @@ - -<%@ page session="true"%> - - - -

    JSP1.2 Beans: 2

    - -Counter accessed times.
    -Counter last accessed by
    - - -Goto bean1.jsp - - - diff --git a/jetty-test-webapp/src/main/webapp/jsp/dump.jsp b/jetty-test-webapp/src/main/webapp/jsp/dump.jsp deleted file mode 100644 index fb73b0b0002..00000000000 --- a/jetty-test-webapp/src/main/webapp/jsp/dump.jsp +++ /dev/null @@ -1,23 +0,0 @@ - -<%@ page import="java.util.Enumeration" %> - -

    JSP Dump

    - -
    getDispatcherTYpe: " + request.getDispatcherType()+"
    getMethod: " + notag(request.getMethod())+"
    getQueryString: "+notag(request.getQueryString())+"
    isAsyncSupported: "+request.isAsyncSupported()+"
    isAsyncStarted: "+request.isAsyncStarted()+"
    getProtocol: "+request.getProtocol()+"
    - - - - -<% - Enumeration e =request.getParameterNames(); - while(e.hasMoreElements()) - { - String name = (String)e.nextElement(); -%> - - - -<% } %> - -
    Request URI:<%= request.getRequestURI() %>
    ServletPath:<%= request.getServletPath() %>
    PathInfo:<%= request.getPathInfo() %>
    getParameter("<%= name %>")<%= request.getParameter(name) %>
    - diff --git a/jetty-test-webapp/src/main/webapp/jsp/expr.jsp b/jetty-test-webapp/src/main/webapp/jsp/expr.jsp deleted file mode 100644 index e0b25e20203..00000000000 --- a/jetty-test-webapp/src/main/webapp/jsp/expr.jsp +++ /dev/null @@ -1,23 +0,0 @@ - -

    JSP2.0 Expressions

    - - - - - - - - - - - - - - - - - - - -
    ExpressionResult
    \${param["A"]}${param["A"]} 
    \${header["host"]}${header["host"]}
    \${header["user-agent"]}${header["user-agent"]}
    \${1+1}${1+1}
    \${param["A"] * 2}${param["A"] * 2} 
    - diff --git a/jetty-test-webapp/src/main/webapp/jsp/index.html b/jetty-test-webapp/src/main/webapp/jsp/index.html deleted file mode 100644 index 3b3af3c00df..00000000000 --- a/jetty-test-webapp/src/main/webapp/jsp/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - -

    Day2

    - -JSP 1.2 embedded java
    -JSP 1.2 Bean demo
    -JSP 1.2 BodyTag demo
    -JSP 2.0 SimpleTag demo
    -JSP 2.0 Tag File demo
    -JSP 2.0 Tag Expression
    - - - - diff --git a/jetty-test-webapp/src/main/webapp/jsp/tag.jsp b/jetty-test-webapp/src/main/webapp/jsp/tag.jsp deleted file mode 100644 index 069d8c67b17..00000000000 --- a/jetty-test-webapp/src/main/webapp/jsp/tag.jsp +++ /dev/null @@ -1,16 +0,0 @@ - - - -<%@ taglib uri="http://www.acme.com/taglib" prefix="acme" %> - -<acme:date tz="GMT">EEE, dd/MMM/yyyy HH:mm:ss ZZZ</acme:date> -==> -EEE, dd/MMM/yyyy HH:mm:ss ZZZ -
    -<acme:date tz="EST">EEE, dd-MMM-yyyy HH:mm:ss ZZZ</acme:date> -==> -EEE, dd-MMM-yyyy HH:mm:ss ZZZ -
    - - - diff --git a/jetty-test-webapp/src/main/webapp/jsp/tag2.jsp b/jetty-test-webapp/src/main/webapp/jsp/tag2.jsp deleted file mode 100644 index 8071927562a..00000000000 --- a/jetty-test-webapp/src/main/webapp/jsp/tag2.jsp +++ /dev/null @@ -1,19 +0,0 @@ - - - -<%@ taglib uri="http://www.acme.com/taglib2" prefix="acme" %> - - - On ${day} of ${month} in the year ${year} - - -
    - - - ${day} - ${month} - ${year} - - -
    - - - diff --git a/jetty-test-webapp/src/main/webapp/jsp/tagfile.jsp b/jetty-test-webapp/src/main/webapp/jsp/tagfile.jsp deleted file mode 100644 index 67299f0229c..00000000000 --- a/jetty-test-webapp/src/main/webapp/jsp/tagfile.jsp +++ /dev/null @@ -1,37 +0,0 @@ -<%@ taglib prefix="acme" tagdir="/WEB-INF/tags" %> - - - - -

    JSP 2.0 Tag File Example

    -
    -

    Panel tag created from JSP fragment file in WEB-INF/tags -


    - - - - - - -
    - - First panel.
    -
    -
    - - Second panel.
    - Second panel.
    - Second panel.
    - Second panel.
    -
    -
    - - Third panel.
    - - A panel in a panel. - - Third panel.
    -
    -
    - - diff --git a/jetty-test-webapp/src/main/webapp/snoop.jsp b/jetty-test-webapp/src/main/webapp/snoop.jsp deleted file mode 100644 index bc51540b9ce..00000000000 --- a/jetty-test-webapp/src/main/webapp/snoop.jsp +++ /dev/null @@ -1,201 +0,0 @@ - - - JSP snoop page - <%@ page import="javax.servlet.http.HttpUtils,java.util.Enumeration" %> - - - -

    WebApp JSP Snoop page

    - -

    Request information

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Requested URL:<%= HttpUtils.getRequestURL(request) %>
    Request method:<%= request.getMethod() %>
    Request URI:<%= request.getRequestURI() %>
    Request protocol:<%= request.getProtocol() %>
    Servlet path:<%= request.getServletPath() %>
    Path info:<%= request.getPathInfo() %>
    Path translated:<%= request.getPathTranslated() %>
    Query string:<% if(request.getQueryString()!=null) out.write(request.getQueryString().replaceAll("<", "<").replaceAll(">",">")); %>
    Content length:<%= request.getContentLength() %>
    Content type:<%= request.getContentType() %>
    Server name:<%= request.getServerName() %>
    Server port:<%= request.getServerPort() %>
    Remote user:<%= request.getRemoteUser() %>
    Remote address:<%= request.getRemoteAddr() %>
    Remote host:<%= request.getRemoteHost() %>
    Authorization scheme:<%= request.getAuthType() %>
    - -<% - Enumeration e = request.getHeaderNames(); - if(e != null && e.hasMoreElements()) { -%> -

    Request headers

    - - - - - - -<% - while(e.hasMoreElements()) { - String k = (String) e.nextElement(); -%> - - - - -<% - } -%> -
    Header:Value:
    <%= k %><%= request.getHeader(k) %>
    -<% - } -%> - - -<% - e = request.getParameterNames(); - if(e != null && e.hasMoreElements()) { -%> -

    Request parameters

    - - - - - - -<% - while(e.hasMoreElements()) { - String k = (String) e.nextElement(); - String val = request.getParameter(k); - String vals[] = request.getParameterValues(k); -%> - - - - - -<% - } -%> -
    Parameter:Value:Multiple values:
    <%= k.replaceAll("<", "<").replaceAll(">",">") %><%= val.replaceAll("<", "<").replaceAll(">",">") %><% - for(int i = 0; i < vals.length; i++) { - if(i > 0) - out.print("
    "); - out.print(vals[i].replaceAll("<", "<").replaceAll(">",">")); - } - %>
    -<% - } -%> - - -<% - e = request.getAttributeNames(); - if(e != null && e.hasMoreElements()) { -%> -

    Request Attributes

    - - - - - -<% - while(e.hasMoreElements()) { - String k = (String) e.nextElement(); - Object val = request.getAttribute(k); -%> - - - - -<% - } -%> -
    Attribute:Value:
    <%= k.replaceAll("<", "<").replaceAll(">",">") %><%= val.toString().replaceAll("<", "<").replaceAll(">",">") %>
    -<% - } -%> - - -<% - e = getServletConfig().getInitParameterNames(); - if(e != null && e.hasMoreElements()) { -%> -

    Init parameters

    - - - - - -<% - while(e.hasMoreElements()) { - String k = (String) e.nextElement(); - String val = getServletConfig().getInitParameter(k); -%> - - - - -<% - } -%> -
    Parameter:Value:
    <%= k %><%= val %>
    -<% - } -%> - - - - diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/Continuation.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/Continuation.java deleted file mode 100644 index 16ca3aad89a..00000000000 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/Continuation.java +++ /dev/null @@ -1,117 +0,0 @@ -// ======================================================================== -// Copyright (c) 2004-2009 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.util.ajax; - -import javax.servlet.ServletRequest; - - -/* ------------------------------------------------------------ */ -/** Continuation. - * - * A continuation is a mechanism by which a HTTP Request can be - * suspended and restarted after a timeout or an asynchronous event - * has occured. - * Blocking continuations will block the process of the request during a - * call to {@link #suspend(long)}. - * Non-blocking continuation can abort the current request and arrange for it - * to be retried when {@link #resume()} is called or the timeout expires. - * - * In order to supprt non-blocking continuations, it is important that - * all actions taken by a filter or servlet before a call to - * {@link #suspend(long)} are either idempotent (can be retried) or - * are made conditional on {@link #isPending} so they are not performed on - * retried requests. - * - * With the appropriate HTTP Connector, this allows threadless waiting - * for events (see {@link org.eclipse.jetty.nio.SelectChannelConnector}). - * - * - * @deprecated use {@link ServletRequest#suspend()} - * - */ -public interface Continuation -{ - - /* ------------------------------------------------------------ */ - /** Suspend handling. - * This method will suspend the request for the timeout or until resume is - * called. - * @param timeout. A timeout of < 0 will cause an immediate return. I timeout of 0 will wait indefinitely. - * @return True if resume called or false if timeout. - */ - public boolean suspend(long timeout); - - /* ------------------------------------------------------------ */ - /** Resume the request. - * Resume a suspended request. The passed event will be returned in the getObject method. - */ - public void resume(); - - - /* ------------------------------------------------------------ */ - /** Reset the continuation. - * Cancel any pending status of the continuation. - */ - public void reset(); - - /* ------------------------------------------------------------ */ - /** Is this a newly created Continuation. - *

    - * A newly created continuation has not had {@link #getEvent(long)} called on it. - *

    - * @return True if the continuation has just been created and has not yet suspended the request. - */ - public boolean isNew(); - - /* ------------------------------------------------------------ */ - /** Get the pending status? - * A continuation is pending while the handling of a call to suspend has not completed. - * For blocking continuations, pending is true only during the call to {@link #suspend(long)}. - * For non-blocking continuations, pending is true until a second call to {@link #suspend(long)} or - * a call to {@link #reset()}, thus this method can be used to determine if a request is being - * retried. - * @return True if the continuation is handling a call to suspend. - */ - public boolean isPending(); - - /* ------------------------------------------------------------ */ - /** Get the resumed status? - * @return True if the continuation is has been resumed. - */ - public boolean isResumed(); - - /* ------------------------------------------------------------ */ - /** Get the resumed status? - * @return True if the continuation is has been expired. - */ - public boolean isExpired(); - - /* ------------------------------------------------------------ */ - /** Arbitrary object associated with the continuation for context. - * @return An arbitrary object associated with the continuation - */ - public Object getObject(); - - /* ------------------------------------------------------------ */ - /** Arbitrary object associated with the continuation for context. - * @param o An arbitrary object to associate with the continuation - */ - public void setObject(Object o); - - /* ------------------------------------------------------------ */ - /** - */ - public void setMutex(Object mutex); - -} diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/WaitingContinuation.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/WaitingContinuation.java deleted file mode 100644 index 98ba86e1e38..00000000000 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ajax/WaitingContinuation.java +++ /dev/null @@ -1,153 +0,0 @@ -// ======================================================================== -// Copyright (c) 2004-2009 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.util.ajax; - -import org.eclipse.jetty.util.log.Log; - -public class WaitingContinuation implements org.eclipse.jetty.util.ajax.Continuation -{ - Object _mutex; - Object _object; - boolean _new=true; - boolean _resumed=false; - boolean _pending=false; - boolean _expired=false; - - public WaitingContinuation() - { - _mutex=this; - } - - public WaitingContinuation(Object mutex) - { - _mutex=mutex==null?this:mutex; - } - - public void resume() - { - synchronized (_mutex) - { - _resumed=true; - _mutex.notify(); - } - } - - public void reset() - { - synchronized (_mutex) - { - _resumed=false; - _pending=false; - _expired=false; - _mutex.notify(); - } - } - - public boolean isNew() - { - return _new; - } - - public boolean suspend(long timeout) - { - synchronized (_mutex) - { - _new=false; - _pending=true; - boolean result; - try - { - if (!_resumed && timeout>=0) - { - if (timeout==0) - _mutex.wait(); - else if (timeout>0) - _mutex.wait(timeout); - - } - } - catch (InterruptedException e) - { - _expired=true; - Log.ignore(e); - } - finally - { - result=_resumed; - _resumed=false; - _pending=false; - } - - return result; - } - } - - public boolean isPending() - { - synchronized (_mutex) - { - return _pending; - } - } - - public boolean isResumed() - { - synchronized (_mutex) - { - return _resumed; - } - } - - public boolean isExpired() - { - synchronized (_mutex) - { - return _expired; - } - } - - public Object getObject() - { - return _object; - } - - public void setObject(Object object) - { - _object = object; - } - - public Object getMutex() - { - return _mutex; - } - - public void setMutex(Object mutex) - { - if (_pending && mutex!=_mutex) - throw new IllegalStateException(); - _mutex = mutex==null ? this : mutex; - } - - public String toString() - { - synchronized (this) - { - return "WaitingContinuation@"+hashCode()+ - (_new?",new":"")+ - (_pending?",pending":"")+ - (_resumed?",resumed":"")+ - (_expired?",expired":""); - } - } -} diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java index 993e8cfac7b..f1e2d11add5 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Timeout.java @@ -271,7 +271,7 @@ public class Timeout boolean _expired=false; /* ------------------------------------------------------------ */ - public Task() + protected Task() { _next=_prev=this; } @@ -372,7 +372,7 @@ public class Timeout * the {@link #isExpired()} state to true. * @see #expired() For an unsynchronized callback. */ - public void expire(){} + protected void expire(){} /* ------------------------------------------------------------ */ /** Expire task. @@ -380,7 +380,7 @@ public class Timeout * outside of any synchronization scope and may be delayed. * */ - public void expired(){} + protected void expired(){} } diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java index 5dbafa6f2db..626f0ec4a4f 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java @@ -65,6 +65,7 @@ import org.eclipse.jetty.util.resource.Resource; */ public class WebAppContext extends ServletContextHandler { + public static final String TEMPDIR = "javax.servlet.context.tempdir"; public final static String WEB_DEFAULTS_XML="org/eclipse/jetty/webapp/webdefault.xml"; public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page"; @@ -94,16 +95,16 @@ public class WebAppContext extends ServletContextHandler "org.w3c.", "org.apache.commons.logging.", "org.apache.log4j.", - "org.eclipse.jetty.servlet.", // webapp cannot change default servlets - "org.eclipse.util.ajax.", // webapp cannot change continuation classes - "org.eclipse.naming." // webapp cannot change naming classes + "org.eclipse.jetty.servlet.", // webapp cannot change default servlets + "org.eclipse.jetty.continuation.", // webapp cannot change continuation classes + "org.eclipse.jetty.naming." // webapp cannot change naming classes }; private String[] _serverClasses = { - "-org.eclipse.naming.", // don't hide naming classes - "-org.eclipse.util.ajax.", // don't hide continuation classes - "-org.eclipse.jetty.plus.jaas.", //don't hide jaas modules - "org.eclipse.", // hide rest of eclipse classes - "org.slf4j." // hide slf4j + "-org.eclipse.jetty.naming.", // don't hide naming classes + "-org.eclipse.jetty.continuation.", // don't hide continuation classes + "-org.eclipse.jetty.plus.jaas.", // don't hide jaas modules + "org.eclipse.jetty.", // hide rest of jetty classes + "org.slf4j." // hide slf4j }; private File _tmpDir; private boolean _isExistingTmpDir; @@ -602,7 +603,7 @@ public class WebAppContext extends ServletContextHandler // // I'm afraid that this is very much black magic. // but if you can think of better.... - Object t = getAttribute(ServletContext.TEMPDIR); + Object t = getAttribute(TEMPDIR); if (t!=null && (t instanceof File)) { @@ -620,7 +621,7 @@ public class WebAppContext extends ServletContextHandler if (_tmpDir.isDirectory() && _tmpDir.canWrite()) { if(Log.isDebugEnabled())Log.debug("Converted to File "+_tmpDir+" for "+this); - setAttribute(ServletContext.TEMPDIR,_tmpDir); + setAttribute(TEMPDIR,_tmpDir); return _tmpDir; } } @@ -715,7 +716,7 @@ public class WebAppContext extends ServletContextHandler } } - setAttribute(ServletContext.TEMPDIR,_tmpDir); + setAttribute(TEMPDIR,_tmpDir); return _tmpDir; } @@ -1134,7 +1135,7 @@ public class WebAppContext extends ServletContextHandler throw new IllegalArgumentException("Bad temp directory: "+dir); _tmpDir=dir; - setAttribute(ServletContext.TEMPDIR,_tmpDir); + setAttribute(TEMPDIR,_tmpDir); } /* ------------------------------------------------------------ */ @@ -1203,8 +1204,8 @@ public class WebAppContext extends ServletContextHandler && work.isDirectory() && work.getFile() != null && work.getFile().canWrite() - && getAttribute(ServletContext.TEMPDIR) == null) - setAttribute(ServletContext.TEMPDIR, work.getFile()); + && getAttribute(TEMPDIR) == null) + setAttribute(TEMPDIR, work.getFile()); } // Configure webapp diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java index e38aac0b909..c955458d570 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java @@ -72,8 +72,15 @@ public class XmlConfiguration { URL configURL = Loader.getResource(XmlConfiguration.class, "org/eclipse/jetty/xml/configure_6_0.dtd", true); __parser.redirectEntity("configure.dtd", configURL); + __parser.redirectEntity("configure_1_0.dtd", configURL); + __parser.redirectEntity("configure_1_1.dtd", configURL); + __parser.redirectEntity("configure_1_2.dtd", configURL); __parser.redirectEntity("configure_1_3.dtd", configURL); + __parser.redirectEntity("configure_6_0.dtd", configURL); + + __parser.redirectEntity("http://jetty.mortbay.org/configure.dtd", configURL); __parser.redirectEntity("http://jetty.eclipse.org/configure.dtd", configURL); + __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN", configURL); __parser.redirectEntity("http://jetty.eclipse.org/configure_1_3.dtd", configURL); __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.3//EN", configURL); diff --git a/pom.xml b/pom.xml index 96165083e62..d8aa15a4a72 100644 --- a/pom.xml +++ b/pom.xml @@ -13,8 +13,7 @@ pom - - 3.0-SNAPSHOT + 2.5-20081211 1.1 1.6.5 1.1.1 @@ -98,12 +97,10 @@ - jetty-util jetty-io jetty-http + jetty-continuation jetty-server jetty-client jetty-xml @@ -113,9 +110,9 @@ jetty-servlets jetty-deploy jetty-ajp - jetty-annotations jetty-jmx jetty-jndi + jetty-annotations jetty-plus jetty-rewrite jetty-servlet-tester