Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2E34017E52 for ; Fri, 15 May 2015 16:43:45 +0000 (UTC) Received: (qmail 69649 invoked by uid 500); 15 May 2015 16:43:45 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 69627 invoked by uid 500); 15 May 2015 16:43:44 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 69618 invoked by uid 99); 15 May 2015 16:43:44 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 15 May 2015 16:43:44 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id C0A73AC0A56 for ; Fri, 15 May 2015 16:43:44 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1679603 - in /felix/trunk/http/base/src: main/java/org/apache/felix/http/base/internal/ main/java/org/apache/felix/http/base/internal/console/ main/java/org/apache/felix/http/base/internal/dispatch/ main/java/org/apache/felix/http/base/int... Date: Fri, 15 May 2015 16:43:44 -0000 To: commits@felix.apache.org From: cziegeler@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150515164344.C0A73AC0A56@hades.apache.org> Author: cziegeler Date: Fri May 15 16:43:43 2015 New Revision: 1679603 URL: http://svn.apache.org/r1679603 Log: FELIX-4888 : ServletHandler's are not sorted by longest matching path Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java - copied, changed from r1678786, felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java Removed: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/console/HttpServicePlugin.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/InfoServletContextHelperRuntime.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/SimpleServletHandlerTest.java Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java Fri May 15 16:43:43 2015 @@ -24,7 +24,6 @@ import javax.servlet.http.HttpSessionEve import javax.servlet.http.HttpSessionIdListener; import javax.servlet.http.HttpSessionListener; -import org.apache.felix.http.base.internal.console.HttpServicePlugin; import org.apache.felix.http.base.internal.dispatch.Dispatcher; import org.apache.felix.http.base.internal.handler.HandlerRegistry; import org.apache.felix.http.base.internal.handler.HttpSessionWrapper; @@ -38,7 +37,6 @@ public final class HttpServiceController private final BundleContext bundleContext; private final HandlerRegistry registry; private final Dispatcher dispatcher; - private final HttpServicePlugin plugin; private final HttpServiceFactory httpServiceFactory; private final WhiteboardManager whiteboardManager; @@ -49,7 +47,6 @@ public final class HttpServiceController this.bundleContext = bundleContext; this.registry = new HandlerRegistry(); this.dispatcher = new Dispatcher(this.registry); - this.plugin = new HttpServicePlugin(bundleContext, registry); this.httpServiceFactory = new HttpServiceFactory(this.bundleContext, this.registry); this.whiteboardManager = new WhiteboardManager(bundleContext, this.httpServiceFactory, this.registry); } @@ -113,8 +110,6 @@ public final class HttpServiceController { this.registry.init(); - this.plugin.register(); - this.httpServiceFactory.start(servletContext); this.whiteboardManager.start(servletContext); @@ -123,8 +118,6 @@ public final class HttpServiceController public void unregister() { - this.plugin.unregister(); - this.dispatcher.setWhiteboardManager(null); if ( this.whiteboardManager != null ) Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/console/HttpServicePlugin.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/console/HttpServicePlugin.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/console/HttpServicePlugin.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/console/HttpServicePlugin.java Fri May 15 16:43:43 2015 @@ -24,6 +24,7 @@ import java.io.PrintWriter; import java.util.Arrays; import java.util.Dictionary; import java.util.Hashtable; +import java.util.Map; import javax.servlet.Servlet; import javax.servlet.http.HttpServlet; @@ -31,26 +32,33 @@ import javax.servlet.http.HttpServletReq import javax.servlet.http.HttpServletResponse; import org.apache.felix.http.base.internal.handler.FilterHandler; -import org.apache.felix.http.base.internal.handler.HandlerRegistry; import org.apache.felix.http.base.internal.handler.ServletHandler; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceRegistration; - +import org.osgi.framework.dto.ServiceReferenceDTO; +import org.osgi.service.http.runtime.HttpServiceRuntime; +import org.osgi.service.http.runtime.dto.RuntimeDTO; +import org.osgi.service.http.runtime.dto.ServletContextDTO; +import org.osgi.service.http.runtime.dto.ServletDTO; + +/** + * This is a web console plugin. + */ @SuppressWarnings("serial") public class HttpServicePlugin extends HttpServlet { - private final HandlerRegistry registry; + private final HttpServiceRuntime runtime; private final BundleContext context; - private ServiceRegistration serviceReg; + private volatile ServiceRegistration serviceReg; - public HttpServicePlugin(BundleContext context, HandlerRegistry registry) + public HttpServicePlugin(final BundleContext context, final HttpServiceRuntime runtime) { - this.registry = registry; + this.runtime = runtime; this.context = context; } @@ -62,7 +70,7 @@ public class HttpServicePlugin extends H props.put("felix.webconsole.label", "httpservice"); props.put("felix.webconsole.title", "HTTP Service"); props.put("felix.webconsole.configprinter.modes", "always"); - this.serviceReg = context.registerService(Servlet.class.getName(), this, props); + this.serviceReg = context.registerService(Servlet.class, this, props); } @Override @@ -71,18 +79,118 @@ public class HttpServicePlugin extends H getHtml(resp); } - private void getHtml(HttpServletResponse resp) throws IOException + private void getHtml(final HttpServletResponse resp) throws IOException { + final RuntimeDTO dto = this.runtime.getRuntimeDTO(); + final PrintWriter pw = resp.getWriter(); - printServletDetails(pw); - printFilterDetails(pw); + printRuntimeDetails(pw, dto.serviceDTO); + for(final ServletContextDTO ctxDto : dto.servletContextDTOs ) + { + printContextDetails(pw, ctxDto); + } + } + + private String getValueAsString(final Object value) + { + if ( value.getClass().isArray() ) + { + if (value instanceof long[]) + { + return Arrays.toString((long[])value); + } + else if (value instanceof int[]) + { + return Arrays.toString((int[])value); + } + else if (value instanceof double[]) + { + return Arrays.toString((double[])value); + } + else if (value instanceof byte[]) + { + return Arrays.toString((byte[])value); + } + else if (value instanceof float[]) + { + return Arrays.toString((float[])value); + } + else if (value instanceof short[]) + { + return Arrays.toString((short[])value); + } + else if (value instanceof boolean[]) + { + return Arrays.toString((boolean[])value); + } + else if (value instanceof char[]) + { + return Arrays.toString((char[])value); + } + else + { + return Arrays.toString((Object[])value); + } + } + return value.toString(); + } + + private void printRuntimeDetails(final PrintWriter pw, final ServiceReferenceDTO dto) + { + pw.println("

${Runtime Properties}

"); + pw.println(""); + pw.println(""); + pw.println(""); + pw.println(""); + pw.println(""); + boolean odd = true; + for(final Map.Entry prop : dto.properties.entrySet()) + { + odd = printRow(pw, odd, prop.getKey(), getValueAsString(prop.getValue())); + } + pw.println("
${Name}${Value}
"); + } + + private boolean printRow(final PrintWriter pw, final boolean odd, final String...columns) + { + pw.print(""); + + for(final String val : columns) + { + pw.print(""); + pw.print(val); + pw.println(""); + } + + pw.println(""); + return !odd; + } + + private void printContextDetails(final PrintWriter pw, final ServletContextDTO dto) + { + pw.print("

${Servlet Context} '"); + pw.print(dto.name); + pw.println("'

"); + + pw.println(""); + + boolean odd = true; + odd = printRow(pw, odd, "${Path}", dto.contextPath); + odd = printRow(pw, odd, "${service.id}", String.valueOf(dto.serviceId)); + pw.println("
"); + printServletDetails(pw, dto); + printFilterDetails(pw, dto); } - private void printFilterDetails(PrintWriter pw) + private void printFilterDetails(final PrintWriter pw, final ServletContextDTO dto) { - pw.println("

${Registered Filter Services}

"); + pw.print("

${Servlet Context} '"); + pw.print(dto.name); + pw.println("' ${Registered Filter Services}

"); pw.println(""); pw.println(""); @@ -114,37 +222,26 @@ public class HttpServicePlugin extends H pw.println("
"); } - private void printServletDetails(PrintWriter pw) + private void printServletDetails(final PrintWriter pw, final ServletContextDTO dto) { - pw.println("

${Registered Servlet Services}

"); + pw.print("

${Servlet Context} '"); + pw.print(dto.name); + pw.println("' ${Registered Servlet Services}

"); pw.println(""); pw.println(""); - pw.println(""); - pw.println(""); - pw.println(""); + pw.println(""); + pw.println(""); + pw.println(""); pw.println(""); - ServletHandler[] servlets = new ServletHandler[0]; // XXX was: registry.getServlets(); - String rowClass = "odd"; - for (ServletHandler servlet : servlets) + boolean odd = true; + for (ServletDTO servlet : dto.servletDTOs) { + final StringBuilder sb = new StringBuilder(); + sb.append("${service.id} : ").append(String.valueOf(servlet.serviceId)).append("\n"); - pw.println(""); -// pw.println(""); // XXX -// pw.println(""); - - printBundleDetails(pw, servlet.getServlet().getClass()); - - pw.println(""); - if (rowClass.equals("odd")) - { - rowClass = "even"; - } - else - { - rowClass = "odd"; - } + odd = printRow(pw, odd, getValueAsString(servlet.patterns), servlet.name, sb.toString()); } pw.println("
${Alias}${Servlet}${Bundle}${Path}${Name}${Info}
" + Arrays.toString(servlet.getPatternStrings()) + "" + servlet.getServlet().getClass().getName() + "
"); } Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java Fri May 15 16:43:43 2015 @@ -541,11 +541,6 @@ public final class Dispatcher implements } } - /** - * Catch-all filter chain that simple finishes all requests with a "404 Not Found" error. - */ - private static final FilterChain DEFAULT_CHAIN = new NotFoundFilterChain(); - private final HandlerRegistry handlerRegistry; private WhiteboardManager whiteboardManager; @@ -570,7 +565,7 @@ public final class Dispatcher implements */ public void dispatch(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException { - // invalid sessions first + // check for invalidating session(s) first final HttpSession session = req.getSession(false); if ( session != null ) { @@ -600,7 +595,7 @@ public final class Dispatcher implements String pathInfo = UriUtils.compactPath(UriUtils.relativePath(servletPath, requestURI)); String queryString = null; // XXX - ExtServletContext servletContext = (servletHandler != null) ? servletHandler.getContext() : null; + final ExtServletContext servletContext = servletHandler.getContext(); final RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, queryString); final HttpServletRequest wrappedRequest = new ServletRequestWrapper(req, servletContext, requestInfo, servletHandler.getContextServiceId(), @@ -707,7 +702,7 @@ public final class Dispatcher implements private void invokeChain(FilterHandler[] filterHandlers, ServletHandler servletHandler, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - FilterChain filterChain = new InvocationFilterChain(servletHandler, filterHandlers, DEFAULT_CHAIN); + final FilterChain filterChain = new InvocationChain(servletHandler, filterHandlers); filterChain.doFilter(request, response); } } Copied: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java (from r1678786, felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java) URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java?p2=felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java&p1=felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java&r1=1678786&r2=1679603&rev=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java Fri May 15 16:43:43 2015 @@ -16,59 +16,67 @@ */ package org.apache.felix.http.base.internal.dispatch; +import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; import static javax.servlet.http.HttpServletResponse.SC_OK; import java.io.IOException; +import javax.annotation.Nonnull; import javax.servlet.FilterChain; import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.felix.http.base.internal.handler.FilterHandler; import org.apache.felix.http.base.internal.handler.ServletHandler; -class InvocationFilterChain extends HttpFilterChain +public class InvocationChain implements FilterChain { private final ServletHandler servletHandler; private final FilterHandler[] filterHandlers; - private final FilterChain defaultChain; private int index = -1; - public InvocationFilterChain(ServletHandler servletHandler, FilterHandler[] filterHandlers, FilterChain defaultChain) + public InvocationChain(@Nonnull final ServletHandler servletHandler, @Nonnull final FilterHandler[] filterHandlers) { this.filterHandlers = filterHandlers; this.servletHandler = servletHandler; - this.defaultChain = defaultChain; } @Override - protected void doFilter(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException + public final void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException { - this.index++; - - if (this.index < this.filterHandlers.length) + if ( this.index == -1 ) { - if (this.filterHandlers[this.index].handle(req, res, this)) + final HttpServletRequest hReq = (HttpServletRequest) req; + final HttpServletResponse hRes = (HttpServletResponse) res; + + // invoke security + if ( !servletHandler.getContext().handleSecurity(hReq, hRes)) { - // We're done... + // FELIX-3988: If the response is not yet committed and still has the default + // status, we're going to override this and send an error instead. + if (!res.isCommitted() && (hRes.getStatus() == SC_OK || hRes.getStatus() == 0)) + { + hRes.sendError(SC_FORBIDDEN); + } + + // we're done return; } } + this.index++; - // Last entry in the chain... - if (this.servletHandler != null && this.servletHandler.handle(req, res)) + if (this.index < this.filterHandlers.length) { - // We're done... - return; + this.filterHandlers[this.index].handle(req, res, this); } - - // FELIX-3988: If the response is not yet committed and still has the default - // status, we're going to override this and send an error instead. - if (!res.isCommitted() && res.getStatus() == SC_OK) + else { - this.defaultChain.doFilter(req, res); + // Last entry in the chain... + this.servletHandler.handle(req, res); } } } Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java Fri May 15 16:43:43 2015 @@ -16,9 +16,6 @@ */ package org.apache.felix.http.base.internal.handler; -import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; -import static javax.servlet.http.HttpServletResponse.SC_OK; - import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -27,8 +24,8 @@ import java.util.regex.Pattern; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; import org.apache.felix.http.base.internal.context.ExtServletContext; import org.apache.felix.http.base.internal.runtime.FilterInfo; @@ -84,6 +81,7 @@ public final class FilterHandler extends return this.filter; } + @Override public FilterInfo getFilterInfo() { return this.filterInfo; @@ -94,23 +92,9 @@ public final class FilterHandler extends return filterInfo.getRanking(); } - public boolean handle(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException + public void handle(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException { - if (getContext().handleSecurity(req, res)) - { - this.filter.doFilter(req, res, chain); - - return true; - } - - // FELIX-3988: If the response is not yet committed and still has the default - // status, we're going to override this and send an error instead. - if (!res.isCommitted() && (res.getStatus() == SC_OK || res.getStatus() == 0)) - { - res.sendError(SC_FORBIDDEN); - } - - return false; + this.filter.doFilter(req, res, chain); } @Override @@ -150,6 +134,7 @@ public final class FilterHandler extends return this.patterns; } + @Override public long getContextServiceId() { return this.contextServiceId; Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java Fri May 15 16:43:43 2015 @@ -37,8 +37,6 @@ import org.apache.felix.http.base.intern import org.apache.felix.http.base.internal.runtime.dto.ContextRuntime; import org.apache.felix.http.base.internal.runtime.dto.FailureRuntime; import org.apache.felix.http.base.internal.runtime.dto.HandlerRegistryRuntime; -import org.apache.felix.http.base.internal.runtime.dto.InfoServletContextHelperRuntime; -import org.apache.felix.http.base.internal.runtime.dto.ServletContextHelperRuntime; import org.apache.felix.http.base.internal.runtime.dto.ServletRegistryRuntime; import org.apache.felix.http.base.internal.whiteboard.RegistrationFailureException; @@ -50,8 +48,6 @@ import org.apache.felix.http.base.intern */ public final class HandlerRegistry { - private static final String HTTP_SERVICE_CONTEXT_NAME = "Http service context"; - private static FilterHandler[] EMPTY_FILTER_HANDLER = new FilterHandler[0]; /** Current list of context registrations. */ @@ -252,12 +248,6 @@ public final class HandlerRegistry return EMPTY_FILTER_HANDLER; } - public ServletContextHelperRuntime getHttpServiceContextRuntime() - { - ServletContextHelperInfo info = new ServletContextHelperInfo(Integer.MAX_VALUE, 0, HTTP_SERVICE_CONTEXT_NAME, "/", null); - return new InfoServletContextHelperRuntime(info); - } - public synchronized void addServlet(ServletHandler handler) throws RegistrationFailureException { Pattern[] patterns = handler.getPatterns(); Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java Fri May 15 16:43:43 2015 @@ -16,16 +16,13 @@ */ package org.apache.felix.http.base.internal.handler; -import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; -import static javax.servlet.http.HttpServletResponse.SC_OK; - import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; import org.apache.felix.http.base.internal.context.ExtServletContext; import org.apache.felix.http.base.internal.runtime.ServletInfo; @@ -69,23 +66,9 @@ public abstract class ServletHandler ext return this.servletInfo.compareTo(other.servletInfo); } - public boolean handle(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException + public void handle(ServletRequest req, ServletResponse res) throws ServletException, IOException { - if (getContext().handleSecurity(req, res)) - { - getServlet().service(req, res); - - return true; - } - - // FELIX-3988: If the response is not yet committed and still has the default - // status, we're going to override this and send an error instead. - if (!res.isCommitted() && (res.getStatus() == SC_OK || res.getStatus() == 0)) - { - res.sendError(SC_FORBIDDEN); - } - - return false; + getServlet().service(req, res); } public String determineServletPath(String uri) @@ -114,6 +97,7 @@ public abstract class ServletHandler ext return this.patterns; } + @Override public ServletInfo getServletInfo() { return this.servletInfo; Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/InfoServletContextHelperRuntime.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/InfoServletContextHelperRuntime.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/InfoServletContextHelperRuntime.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/InfoServletContextHelperRuntime.java Fri May 15 16:43:43 2015 @@ -26,15 +26,23 @@ public class InfoServletContextHelperRun { private final ServletContextHelperInfo info; - public InfoServletContextHelperRuntime(ServletContextHelperInfo info) + private final ServletContext servletContext; + + public InfoServletContextHelperRuntime(final ServletContextHelperInfo info) + { + this(info, null); + } + + public InfoServletContextHelperRuntime(final ServletContextHelperInfo info, final ServletContext ctx) { this.info = info; + this.servletContext = ctx; } @Override public ServletContext getSharedContext() { - return null; + return this.servletContext; } @Override @@ -44,7 +52,7 @@ public class InfoServletContextHelperRun } @Override - public int compareTo(InfoServletContextHelperRuntime other) + public int compareTo(final InfoServletContextHelperRuntime other) { return info.compareTo(other.info); } Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java Fri May 15 16:43:43 2015 @@ -86,12 +86,12 @@ final class ServletContextDTOBuilder ServletContextDTO build() { - ServletContext context = contextRuntime.getSharedContext(); - ServletContextHelperInfo contextInfo = contextRuntime.getContextInfo(); - long contextId = contextInfo.getServiceId(); + final ServletContext context = contextRuntime.getSharedContext(); + final ServletContextHelperInfo contextInfo = contextRuntime.getContextInfo(); + final long contextId = contextInfo.getServiceId(); contextDTO.attributes = getAttributes(context); - contextDTO.contextPath = context == null ? contextInfo.getPath() : context.getContextPath(); + contextDTO.contextPath = context != null ? context.getContextPath() : contextInfo.getPath(); contextDTO.errorPageDTOs = errorPageDTOs; contextDTO.filterDTOs = filterDTOs; contextDTO.initParams = contextInfo.getInitParameters(); Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java (original) +++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java Fri May 15 16:43:43 2015 @@ -41,6 +41,7 @@ import javax.servlet.ServletContextListe import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; +import org.apache.felix.http.base.internal.console.HttpServicePlugin; import org.apache.felix.http.base.internal.context.ExtServletContext; import org.apache.felix.http.base.internal.handler.HandlerRegistry; import org.apache.felix.http.base.internal.handler.HttpSessionWrapper; @@ -60,6 +61,7 @@ import org.apache.felix.http.base.intern import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo; import org.apache.felix.http.base.internal.runtime.dto.FailureRuntime; import org.apache.felix.http.base.internal.runtime.dto.HandlerRegistryRuntime; +import org.apache.felix.http.base.internal.runtime.dto.InfoServletContextHelperRuntime; import org.apache.felix.http.base.internal.runtime.dto.RegistryRuntime; import org.apache.felix.http.base.internal.runtime.dto.ServletContextHelperRuntime; import org.apache.felix.http.base.internal.service.HttpServiceFactory; @@ -115,6 +117,8 @@ public final class WhiteboardManager private volatile ServiceRegistration runtimeServiceReg; + private final HttpServicePlugin plugin; + /** * Create a new whiteboard http manager * @param bundleContext @@ -129,6 +133,7 @@ public final class WhiteboardManager this.httpServiceFactory = httpServiceFactory; this.httpService = new WhiteboardHttpService(this.bundleContext, registry); this.serviceRuntime = new HttpServiceRuntimeImpl(registry, this); + this.plugin = new HttpServicePlugin(bundleContext, this.serviceRuntime); } public void start(final ServletContext context) @@ -191,6 +196,7 @@ public final class WhiteboardManager addTracker(new ServletRequestListenerTracker(this.bundleContext, this)); addTracker(new ServletRequestAttributeListenerTracker(this.bundleContext, this)); + this.plugin.register(); } private void addTracker(ServiceTracker tracker) @@ -204,6 +210,7 @@ public final class WhiteboardManager */ public void stop() { + this.plugin.unregister(); for(final ServiceTracker t : this.trackers) { t.close(); @@ -740,6 +747,8 @@ public final class WhiteboardManager return handlers; } + private static final String HTTP_SERVICE_CONTEXT_NAME = "Http Service context"; + public RegistryRuntime getRuntime(HandlerRegistry registry) { final Collection contextRuntimes = new TreeSet(ServletContextHelperRuntime.COMPARATOR); @@ -759,7 +768,10 @@ public final class WhiteboardManager listenerRuntimes.put(serviceId, handler.getListenerRegistry().getRuntime()); } } - contextRuntimes.add(registry.getHttpServiceContextRuntime()); + // TODO - this is the wrong place, it adds the context for the http service + final ServletContextHelperInfo info = new ServletContextHelperInfo(Integer.MAX_VALUE, 0, HTTP_SERVICE_CONTEXT_NAME, "/", null); + contextRuntimes.add(new InfoServletContextHelperRuntime(info, this.webContext)); + handlerRuntimes = registry.getRuntime(failureRuntime); failureRuntime.add(serviceFailures); } Modified: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java (original) +++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java Fri May 15 16:43:43 2015 @@ -36,6 +36,7 @@ import javax.servlet.FilterConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.felix.http.base.internal.dispatch.InvocationChain; import org.apache.felix.http.base.internal.runtime.FilterInfo; import org.junit.Before; import org.junit.Test; @@ -116,9 +117,11 @@ public class FilterHandlerTest extends A public void testHandleFoundForbidden() throws Exception { FilterHandler h1 = createHandler(0, "/a"); + final ServletHandler sc = mock(ServletHandler.class); + when(sc.getContext()).thenReturn(this.context); + final InvocationChain ic = new InvocationChain(sc, new FilterHandler[] {h1}); HttpServletRequest req = createServletRequest(); HttpServletResponse res = createServletResponse(); - FilterChain chain = mock(FilterChain.class); when(req.getRequestURI()).thenReturn("/a"); // Default behaviour: uncomitted response and default status code... @@ -127,10 +130,9 @@ public class FilterHandlerTest extends A when(this.context.handleSecurity(req, res)).thenReturn(false); - h1.handle(req, res, chain); + ic.doFilter(req, res); - verify(this.filter, never()).doFilter(req, res, chain); - verify(chain, never()).doFilter(req, res); + verify(this.filter, never()).doFilter(req, res, ic); verify(res).sendError(SC_FORBIDDEN); } @@ -141,9 +143,11 @@ public class FilterHandlerTest extends A public void testHandleFoundForbiddenCommittedOwnResponse() throws Exception { FilterHandler h1 = createHandler(0, "/a"); + final ServletHandler sc = mock(ServletHandler.class); + when(sc.getContext()).thenReturn(this.context); + final InvocationChain ic = new InvocationChain(sc, new FilterHandler[] {h1}); HttpServletRequest req = createServletRequest(); HttpServletResponse res = createServletResponse(); - FilterChain chain = mock(FilterChain.class); when(req.getRequestURI()).thenReturn("/a"); // Simulate an already committed response... @@ -152,10 +156,9 @@ public class FilterHandlerTest extends A when(this.context.handleSecurity(req, res)).thenReturn(false); - h1.handle(req, res, chain); + ic.doFilter(req, res); - verify(this.filter, never()).doFilter(req, res, chain); - verify(chain, never()).doFilter(req, res); + verify(this.filter, never()).doFilter(req, res, ic); // Should not be called from our handler... verify(res, never()).sendError(SC_FORBIDDEN); } @@ -167,9 +170,11 @@ public class FilterHandlerTest extends A public void testHandleFoundForbiddenCustomStatusCode() throws Exception { FilterHandler h1 = createHandler(0, "/a"); + final ServletHandler sc = mock(ServletHandler.class); + when(sc.getContext()).thenReturn(this.context); + final InvocationChain ic = new InvocationChain(sc, new FilterHandler[] {h1}); HttpServletRequest req = createServletRequest(); HttpServletResponse res = createServletResponse(); - FilterChain chain = mock(FilterChain.class); when(req.getRequestURI()).thenReturn("/a"); // Simulate an uncommitted response with a non-default status code... @@ -178,10 +183,9 @@ public class FilterHandlerTest extends A when(this.context.handleSecurity(req, res)).thenReturn(false); - h1.handle(req, res, chain); + ic.doFilter(req, res); - verify(this.filter, never()).doFilter(req, res, chain); - verify(chain, never()).doFilter(req, res); + verify(this.filter, never()).doFilter(req, res, ic); // Should not be called from our handler... verify(res, never()).sendError(SC_FORBIDDEN); } @@ -190,30 +194,32 @@ public class FilterHandlerTest extends A public void testHandleNotFound() throws Exception { FilterHandler h1 = createHandler(0, "/a"); + final ServletHandler sc = mock(ServletHandler.class); + when(sc.getContext()).thenReturn(this.context); + final InvocationChain ic = new InvocationChain(sc, new FilterHandler[] {h1}); HttpServletRequest req = createServletRequest(); HttpServletResponse res = createServletResponse(); - FilterChain chain = mock(FilterChain.class); when(req.getRequestURI()).thenReturn("/"); - h1.handle(req, res, chain); + ic.doFilter(req, res); - verify(this.filter, never()).doFilter(req, res, chain); - verify(chain, never()).doFilter(req, res); + verify(this.filter, never()).doFilter(req, res, ic); } @Test public void testHandleNotFoundContextRoot() throws Exception { FilterHandler h1 = createHandler(0, "/a"); + final ServletHandler sc = mock(ServletHandler.class); + when(sc.getContext()).thenReturn(this.context); + final InvocationChain ic = new InvocationChain(sc, new FilterHandler[] {h1}); HttpServletRequest req = createServletRequest(); HttpServletResponse res = createServletResponse(); - FilterChain chain = mock(FilterChain.class); when(req.getRequestURI()).thenReturn(null); - h1.handle(req, res, chain); + ic.doFilter(req, res); - verify(this.filter, never()).doFilter(req, res, chain); - verify(chain, never()).doFilter(req, res); + verify(this.filter, never()).doFilter(req, res, ic); } @Test Modified: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/SimpleServletHandlerTest.java URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/SimpleServletHandlerTest.java?rev=1679603&r1=1679602&r2=1679603&view=diff ============================================================================== --- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/SimpleServletHandlerTest.java (original) +++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/SimpleServletHandlerTest.java Fri May 15 16:43:43 2015 @@ -19,8 +19,7 @@ package org.apache.felix.http.base.inter import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; import static javax.servlet.http.HttpServletResponse.SC_OK; import static javax.servlet.http.HttpServletResponse.SC_PAYMENT_REQUIRED; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -35,6 +34,7 @@ import javax.servlet.ServletConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.felix.http.base.internal.dispatch.InvocationChain; import org.apache.felix.http.base.internal.runtime.ServletInfo; import org.junit.Before; import org.junit.Test; @@ -63,14 +63,15 @@ public class SimpleServletHandlerTest ex public void testHandleFound() throws Exception { ServletHandler h1 = createHandler("/a"); + final InvocationChain ic = new InvocationChain(h1, new FilterHandler[0]); HttpServletRequest req = mock(HttpServletRequest.class); HttpServletResponse res = mock(HttpServletResponse.class); when(this.context.handleSecurity(req, res)).thenReturn(true); when(req.getPathInfo()).thenReturn("/a/b"); - boolean result = h1.handle(req, res); + ic.doFilter(req, res); - assertTrue(result); + assertEquals(0, res.getStatus()); verify(this.servlet).service(any(HttpServletRequest.class), any(HttpServletResponse.class)); } @@ -78,14 +79,15 @@ public class SimpleServletHandlerTest ex public void testHandleFoundContextRoot() throws Exception { ServletHandler h1 = createHandler("/"); + final InvocationChain ic = new InvocationChain(h1, new FilterHandler[0]); HttpServletRequest req = mock(HttpServletRequest.class); HttpServletResponse res = mock(HttpServletResponse.class); when(this.context.handleSecurity(req, res)).thenReturn(true); when(req.getPathInfo()).thenReturn(null); - boolean result = h1.handle(req, res); + ic.doFilter(req, res); - assertTrue(result); + assertEquals(0, res.getStatus()); verify(this.servlet).service(any(HttpServletRequest.class), any(HttpServletResponse.class)); } @@ -96,6 +98,7 @@ public class SimpleServletHandlerTest ex public void testHandleFoundForbidden() throws Exception { ServletHandler h1 = createHandler("/a"); + final InvocationChain ic = new InvocationChain(h1, new FilterHandler[0]); HttpServletRequest req = mock(HttpServletRequest.class); HttpServletResponse res = mock(HttpServletResponse.class); @@ -107,9 +110,9 @@ public class SimpleServletHandlerTest ex when(this.context.handleSecurity(req, res)).thenReturn(false); when(req.getPathInfo()).thenReturn("/a/b"); - boolean result = h1.handle(req, res); + ic.doFilter(req, res); - assertFalse(result); + assertEquals(SC_OK, res.getStatus()); verify(this.servlet, never()).service(req, res); verify(res).sendError(SC_FORBIDDEN); } @@ -121,6 +124,7 @@ public class SimpleServletHandlerTest ex public void testHandleFoundForbiddenCommittedOwnResponse() throws Exception { ServletHandler h1 = createHandler("/a"); + final InvocationChain ic = new InvocationChain(h1, new FilterHandler[0]); HttpServletRequest req = mock(HttpServletRequest.class); HttpServletResponse res = mock(HttpServletResponse.class); @@ -132,9 +136,9 @@ public class SimpleServletHandlerTest ex when(this.context.handleSecurity(req, res)).thenReturn(false); when(req.getPathInfo()).thenReturn("/a/b"); - boolean result = h1.handle(req, res); + ic.doFilter(req, res); - assertFalse(result); + assertEquals(SC_OK, res.getStatus()); verify(this.servlet, never()).service(req, res); verify(res, never()).sendError(SC_FORBIDDEN); } @@ -146,6 +150,7 @@ public class SimpleServletHandlerTest ex public void testHandleFoundForbiddenCustomStatusCode() throws Exception { ServletHandler h1 = createHandler("/a"); + final InvocationChain ic = new InvocationChain(h1, new FilterHandler[0]); HttpServletRequest req = mock(HttpServletRequest.class); HttpServletResponse res = mock(HttpServletResponse.class); @@ -157,9 +162,9 @@ public class SimpleServletHandlerTest ex when(this.context.handleSecurity(req, res)).thenReturn(false); when(req.getPathInfo()).thenReturn("/a/b"); - boolean result = h1.handle(req, res); + ic.doFilter(req, res); - assertFalse(result); + assertEquals(SC_PAYMENT_REQUIRED, res.getStatus()); verify(this.servlet, never()).service(req, res); verify(res, never()).sendError(SC_FORBIDDEN); } @@ -168,13 +173,13 @@ public class SimpleServletHandlerTest ex public void testHandleNotFound() throws Exception { ServletHandler h1 = createHandler("/a"); + final InvocationChain ic = new InvocationChain(h1, new FilterHandler[0]); HttpServletRequest req = mock(HttpServletRequest.class); HttpServletResponse res = mock(HttpServletResponse.class); when(req.getPathInfo()).thenReturn("/"); - boolean result = h1.handle(req, res); + ic.doFilter(req, res); - assertFalse(result); verify(this.servlet, never()).service(req, res); } @@ -187,9 +192,8 @@ public class SimpleServletHandlerTest ex when(this.context.handleSecurity(req, res)).thenReturn(true); when(req.getRequestURI()).thenReturn(null); - boolean result = h1.handle(req, res); + h1.handle(req, res); - assertTrue(result); verify(this.servlet).service(req, res); }