X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Fserver%2Fhandler%2FContextHandlerCollection.java;h=b4f359b3da9299c124d4626e8a1863f31fe8b79e;hp=4ade3649030e3db9cd8c46c028f5eb983e58b2ae;hb=ba4f228fa9f72d50991a2218cfd83987ef5d385e;hpb=875b5e9651498a0cd8e0001c0742ba843e47cad0 diff --git a/lib/jetty/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/lib/jetty/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index 4ade3649..b4f359b3 100644 --- a/lib/jetty/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/lib/jetty/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2016 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 @@ -19,6 +19,15 @@ package org.eclipse.jetty.server.handler; import java.io.IOException; +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -52,7 +61,8 @@ public class ContextHandlerCollection extends HandlerCollection { private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class); - private volatile Trie _contexts; + private final ConcurrentMap _contextBranches = new ConcurrentHashMap<>(); + private volatile Trie> _pathBranches; private Class _contextClass = ContextHandler.class; /* ------------------------------------------------------------ */ @@ -69,71 +79,70 @@ public class ContextHandlerCollection extends HandlerCollection @ManagedOperation("update the mapping of context path to context") public void mapContexts() { - int capacity=512; + _contextBranches.clear(); + + if (getHandlers()==null) + { + _pathBranches=new ArrayTernaryTrie<>(false,16); + return; + } + + // Create map of contextPath to handler Branch + Map map = new HashMap<>(); + for (Handler handler:getHandlers()) + { + Branch branch=new Branch(handler); + for (String contextPath : branch.getContextPaths()) + { + Branch[] branches=map.get(contextPath); + map.put(contextPath, ArrayUtil.addToArray(branches, branch, Branch.class)); + } + + for (ContextHandler context : branch.getContextHandlers()) + _contextBranches.putIfAbsent(context, branch.getHandler()); + } + + // Sort the branches so those with virtual hosts are considered before those without + for (Map.Entry entry: map.entrySet()) + { + Branch[] branches=entry.getValue(); + Branch[] sorted=new Branch[branches.length]; + int i=0; + for (Branch branch:branches) + if (branch.hasVirtualHost()) + sorted[i++]=branch; + for (Branch branch:branches) + if (!branch.hasVirtualHost()) + sorted[i++]=branch; + entry.setValue(sorted); + } // Loop until we have a big enough trie to hold all the context paths - Trie trie; + int capacity=512; + Trie> trie; loop: while(true) { trie=new ArrayTernaryTrie<>(false,capacity); - - Handler[] branches = getHandlers(); - - // loop over each group of contexts - for (int b=0;branches!=null && b entry: map.entrySet()) { - Handler[] handlers=null; - - if (branches[b] instanceof ContextHandler) + if (!trie.put(entry.getKey().substring(1),entry)) { - handlers = new Handler[]{ branches[b] }; - } - else if (branches[b] instanceof HandlerContainer) - { - handlers = ((HandlerContainer)branches[b]).getChildHandlersByClass(ContextHandler.class); - } - else - continue; - - // for each context handler in a group - for (int i=0;handlers!=null && i0) - sorted[i++]=handler; - for (ContextHandler handler:contexts) - if (handler.getVirtualHosts()==null || handler.getVirtualHosts().length==0) - sorted[i++]=handler; - trie.put(ctx,sorted); + for (String ctx : trie.keySet()) + LOG.debug("{}->{}",ctx,Arrays.asList(trie.get(ctx).getValue())); } - - //for (String ctx : trie.keySet()) - // System.err.printf("'%s'->%s%n",ctx,Arrays.asList(trie.get(ctx))); - _contexts=trie; + _pathBranches=trie; } - /* ------------------------------------------------------------ */ /* * @see org.eclipse.jetty.server.server.handler.HandlerCollection#setHandlers(org.eclipse.jetty.server.server.Handler[]) @@ -164,60 +173,66 @@ public class ContextHandlerCollection extends HandlerCollection { Handler[] handlers = getHandlers(); if (handlers==null || handlers.length==0) - return; + return; - HttpChannelState async = baseRequest.getHttpChannelState(); - if (async.isAsync()) - { - ContextHandler context=async.getContextHandler(); - if (context!=null) - { - context.handle(target,baseRequest,request, response); - return; - } - } - - // data structure which maps a request to a context; first-best match wins - // { context path => [ context ] } - // } - if (target.startsWith("/")) - { - int limit = target.length()-1; - - while (limit>=0) - { - // Get best match - ContextHandler[] contexts = _contexts.getBest(target,1,limit); - if (contexts==null) - break; + HttpChannelState async = baseRequest.getHttpChannelState(); + if (async.isAsync()) + { + ContextHandler context=async.getContextHandler(); + if (context!=null) + { + Handler branch = _contextBranches.get(context); + + if (branch==null) + context.handle(target,baseRequest,request, response); + else + branch.handle(target, baseRequest, request, response); + return; + } + } + + // data structure which maps a request to a context; first-best match wins + // { context path => [ context ] } + // } + if (target.startsWith("/")) + { + int limit = target.length()-1; - int l=contexts[0].getContextPath().length(); - if (l==1 || target.length()==l || target.charAt(l)=='/') - { - for (ContextHandler handler : contexts) - { - handler.handle(target,baseRequest, request, response); - if (baseRequest.isHandled()) - return; - } - } - - limit=l-2; - } - } - else - { + while (limit>=0) + { + // Get best match + Map.Entry branches = _pathBranches.getBest(target,1,limit); + + + if (branches==null) + break; + + int l=branches.getKey().length(); + if (l==1 || target.length()==l || target.charAt(l)=='/') + { + for (Branch branch : branches.getValue()) + { + branch.getHandler().handle(target,baseRequest, request, response); + if (baseRequest.isHandled()) + return; + } + } + + limit=l-2; + } + } + else + { // This may not work in all circumstances... but then I think it should never be called - for (int i=0;i getContextPaths() + { + Set set = new HashSet(); + for (ContextHandler context:_contexts) + set.add(context.getContextPath()); + return set; + } + + boolean hasVirtualHost() + { + for (ContextHandler context:_contexts) + if (context.getVirtualHosts()!=null && context.getVirtualHosts().length>0) + return true; + return false; + } + + ContextHandler[] getContextHandlers() + { + return _contexts; + } + + Handler getHandler() + { + return _handler; + } + + @Override + public String toString() + { + return String.format("{%s,%s}",_handler,Arrays.asList(_contexts)); + } + } + }