Mercurial Hosting > luan
comparison src/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @ 802:3428c60d7cfc
replace jetty jars with source
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Wed, 07 Sep 2016 21:15:48 -0600 |
| parents | |
| children | 8e9db0bbf4f9 |
comparison
equal
deleted
inserted
replaced
| 801:6a21393191c1 | 802:3428c60d7cfc |
|---|---|
| 1 // | |
| 2 // ======================================================================== | |
| 3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. | |
| 4 // ------------------------------------------------------------------------ | |
| 5 // All rights reserved. This program and the accompanying materials | |
| 6 // are made available under the terms of the Eclipse Public License v1.0 | |
| 7 // and Apache License v2.0 which accompanies this distribution. | |
| 8 // | |
| 9 // The Eclipse Public License is available at | |
| 10 // http://www.eclipse.org/legal/epl-v10.html | |
| 11 // | |
| 12 // The Apache License v2.0 is available at | |
| 13 // http://www.opensource.org/licenses/apache2.0.php | |
| 14 // | |
| 15 // You may elect to redistribute this code under either of these licenses. | |
| 16 // ======================================================================== | |
| 17 // | |
| 18 | |
| 19 package org.eclipse.jetty.server.handler; | |
| 20 | |
| 21 import java.io.IOException; | |
| 22 import java.util.HashMap; | |
| 23 import java.util.Map; | |
| 24 | |
| 25 import javax.servlet.ServletException; | |
| 26 import javax.servlet.http.HttpServletRequest; | |
| 27 import javax.servlet.http.HttpServletResponse; | |
| 28 | |
| 29 import org.eclipse.jetty.http.PathMap; | |
| 30 import org.eclipse.jetty.server.AsyncContinuation; | |
| 31 import org.eclipse.jetty.server.Handler; | |
| 32 import org.eclipse.jetty.server.HandlerContainer; | |
| 33 import org.eclipse.jetty.server.Request; | |
| 34 import org.eclipse.jetty.util.LazyList; | |
| 35 import org.eclipse.jetty.util.log.Log; | |
| 36 import org.eclipse.jetty.util.log.Logger; | |
| 37 | |
| 38 /* ------------------------------------------------------------ */ | |
| 39 /** ContextHandlerCollection. | |
| 40 * | |
| 41 * This {@link org.eclipse.jetty.server.handler.HandlerCollection} is creates a | |
| 42 * {@link org.eclipse.jetty.http.PathMap} to it's contained handlers based | |
| 43 * on the context path and virtual hosts of any contained {@link org.eclipse.jetty.server.handler.ContextHandler}s. | |
| 44 * The contexts do not need to be directly contained, only children of the contained handlers. | |
| 45 * Multiple contexts may have the same context path and they are called in order until one | |
| 46 * handles the request. | |
| 47 * | |
| 48 * @org.apache.xbean.XBean element="contexts" | |
| 49 */ | |
| 50 public class ContextHandlerCollection extends HandlerCollection | |
| 51 { | |
| 52 private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class); | |
| 53 | |
| 54 private volatile PathMap _contextMap; | |
| 55 private Class<? extends ContextHandler> _contextClass = ContextHandler.class; | |
| 56 | |
| 57 /* ------------------------------------------------------------ */ | |
| 58 public ContextHandlerCollection() | |
| 59 { | |
| 60 super(true); | |
| 61 } | |
| 62 | |
| 63 | |
| 64 /* ------------------------------------------------------------ */ | |
| 65 /** | |
| 66 * Remap the context paths. | |
| 67 */ | |
| 68 public void mapContexts() | |
| 69 { | |
| 70 PathMap contextMap = new PathMap(); | |
| 71 Handler[] branches = getHandlers(); | |
| 72 | |
| 73 | |
| 74 for (int b=0;branches!=null && b<branches.length;b++) | |
| 75 { | |
| 76 Handler[] handlers=null; | |
| 77 | |
| 78 if (branches[b] instanceof ContextHandler) | |
| 79 { | |
| 80 handlers = new Handler[]{ branches[b] }; | |
| 81 } | |
| 82 else if (branches[b] instanceof HandlerContainer) | |
| 83 { | |
| 84 handlers = ((HandlerContainer)branches[b]).getChildHandlersByClass(ContextHandler.class); | |
| 85 } | |
| 86 else | |
| 87 continue; | |
| 88 | |
| 89 for (int i=0;i<handlers.length;i++) | |
| 90 { | |
| 91 ContextHandler handler=(ContextHandler)handlers[i]; | |
| 92 | |
| 93 String contextPath=handler.getContextPath(); | |
| 94 | |
| 95 if (contextPath==null || contextPath.indexOf(',')>=0 || contextPath.startsWith("*")) | |
| 96 throw new IllegalArgumentException ("Illegal context spec:"+contextPath); | |
| 97 | |
| 98 if(!contextPath.startsWith("/")) | |
| 99 contextPath='/'+contextPath; | |
| 100 | |
| 101 if (contextPath.length()>1) | |
| 102 { | |
| 103 if (contextPath.endsWith("/")) | |
| 104 contextPath+="*"; | |
| 105 else if (!contextPath.endsWith("/*")) | |
| 106 contextPath+="/*"; | |
| 107 } | |
| 108 | |
| 109 Object contexts=contextMap.get(contextPath); | |
| 110 String[] vhosts=handler.getVirtualHosts(); | |
| 111 | |
| 112 | |
| 113 if (vhosts!=null && vhosts.length>0) | |
| 114 { | |
| 115 Map hosts; | |
| 116 | |
| 117 if (contexts instanceof Map) | |
| 118 hosts=(Map)contexts; | |
| 119 else | |
| 120 { | |
| 121 hosts=new HashMap(); | |
| 122 hosts.put("*",contexts); | |
| 123 contextMap.put(contextPath, hosts); | |
| 124 } | |
| 125 | |
| 126 for (int j=0;j<vhosts.length;j++) | |
| 127 { | |
| 128 String vhost=vhosts[j]; | |
| 129 contexts=hosts.get(vhost); | |
| 130 contexts=LazyList.add(contexts,branches[b]); | |
| 131 hosts.put(vhost,contexts); | |
| 132 } | |
| 133 } | |
| 134 else if (contexts instanceof Map) | |
| 135 { | |
| 136 Map hosts=(Map)contexts; | |
| 137 contexts=hosts.get("*"); | |
| 138 contexts= LazyList.add(contexts, branches[b]); | |
| 139 hosts.put("*",contexts); | |
| 140 } | |
| 141 else | |
| 142 { | |
| 143 contexts= LazyList.add(contexts, branches[b]); | |
| 144 contextMap.put(contextPath, contexts); | |
| 145 } | |
| 146 } | |
| 147 } | |
| 148 _contextMap=contextMap; | |
| 149 | |
| 150 } | |
| 151 | |
| 152 | |
| 153 | |
| 154 /* ------------------------------------------------------------ */ | |
| 155 /* | |
| 156 * @see org.eclipse.jetty.server.server.handler.HandlerCollection#setHandlers(org.eclipse.jetty.server.server.Handler[]) | |
| 157 */ | |
| 158 @Override | |
| 159 public void setHandlers(Handler[] handlers) | |
| 160 { | |
| 161 _contextMap=null; | |
| 162 super.setHandlers(handlers); | |
| 163 if (isStarted()) | |
| 164 mapContexts(); | |
| 165 } | |
| 166 | |
| 167 /* ------------------------------------------------------------ */ | |
| 168 @Override | |
| 169 protected void doStart() throws Exception | |
| 170 { | |
| 171 mapContexts(); | |
| 172 super.doStart(); | |
| 173 } | |
| 174 | |
| 175 | |
| 176 /* ------------------------------------------------------------ */ | |
| 177 /* | |
| 178 * @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) | |
| 179 */ | |
| 180 @Override | |
| 181 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException | |
| 182 { | |
| 183 Handler[] handlers = getHandlers(); | |
| 184 if (handlers==null || handlers.length==0) | |
| 185 return; | |
| 186 | |
| 187 AsyncContinuation async = baseRequest.getAsyncContinuation(); | |
| 188 if (async.isAsync()) | |
| 189 { | |
| 190 ContextHandler context=async.getContextHandler(); | |
| 191 if (context!=null) | |
| 192 { | |
| 193 context.handle(target,baseRequest,request, response); | |
| 194 return; | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 // data structure which maps a request to a context; first-best match wins | |
| 199 // { context path => | |
| 200 // { virtual host => context } | |
| 201 // } | |
| 202 PathMap map = _contextMap; | |
| 203 if (map!=null && target!=null && target.startsWith("/")) | |
| 204 { | |
| 205 // first, get all contexts matched by context path | |
| 206 Object contexts = map.getLazyMatches(target); | |
| 207 | |
| 208 for (int i=0; i<LazyList.size(contexts); i++) | |
| 209 { | |
| 210 // then, match against the virtualhost of each context | |
| 211 Map.Entry entry = (Map.Entry)LazyList.get(contexts, i); | |
| 212 Object list = entry.getValue(); | |
| 213 | |
| 214 if (list instanceof Map) | |
| 215 { | |
| 216 Map hosts = (Map)list; | |
| 217 String host = normalizeHostname(request.getServerName()); | |
| 218 | |
| 219 // explicitly-defined virtual hosts, most specific | |
| 220 list=hosts.get(host); | |
| 221 for (int j=0; j<LazyList.size(list); j++) | |
| 222 { | |
| 223 Handler handler = (Handler)LazyList.get(list,j); | |
| 224 handler.handle(target,baseRequest, request, response); | |
| 225 if (baseRequest.isHandled()) | |
| 226 return; | |
| 227 } | |
| 228 | |
| 229 // wildcard for one level of names | |
| 230 list=hosts.get("*."+host.substring(host.indexOf(".")+1)); | |
| 231 for (int j=0; j<LazyList.size(list); j++) | |
| 232 { | |
| 233 Handler handler = (Handler)LazyList.get(list,j); | |
| 234 handler.handle(target,baseRequest, request, response); | |
| 235 if (baseRequest.isHandled()) | |
| 236 return; | |
| 237 } | |
| 238 | |
| 239 // no virtualhosts defined for the context, least specific | |
| 240 // will handle any request that does not match to a specific virtual host above | |
| 241 list=hosts.get("*"); | |
| 242 for (int j=0; j<LazyList.size(list); j++) | |
| 243 { | |
| 244 Handler handler = (Handler)LazyList.get(list,j); | |
| 245 handler.handle(target,baseRequest, request, response); | |
| 246 if (baseRequest.isHandled()) | |
| 247 return; | |
| 248 } | |
| 249 } | |
| 250 else | |
| 251 { | |
| 252 for (int j=0; j<LazyList.size(list); j++) | |
| 253 { | |
| 254 Handler handler = (Handler)LazyList.get(list,j); | |
| 255 handler.handle(target,baseRequest, request, response); | |
| 256 if (baseRequest.isHandled()) | |
| 257 return; | |
| 258 } | |
| 259 } | |
| 260 } | |
| 261 } | |
| 262 else | |
| 263 { | |
| 264 // This may not work in all circumstances... but then I think it should never be called | |
| 265 for (int i=0;i<handlers.length;i++) | |
| 266 { | |
| 267 handlers[i].handle(target,baseRequest, request, response); | |
| 268 if ( baseRequest.isHandled()) | |
| 269 return; | |
| 270 } | |
| 271 } | |
| 272 } | |
| 273 | |
| 274 | |
| 275 /* ------------------------------------------------------------ */ | |
| 276 /** Add a context handler. | |
| 277 * @param contextPath The context path to add | |
| 278 * @return the ContextHandler just added | |
| 279 */ | |
| 280 public ContextHandler addContext(String contextPath,String resourceBase) | |
| 281 { | |
| 282 try | |
| 283 { | |
| 284 ContextHandler context = _contextClass.newInstance(); | |
| 285 context.setContextPath(contextPath); | |
| 286 context.setResourceBase(resourceBase); | |
| 287 addHandler(context); | |
| 288 return context; | |
| 289 } | |
| 290 catch (Exception e) | |
| 291 { | |
| 292 LOG.debug(e); | |
| 293 throw new Error(e); | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 | |
| 298 | |
| 299 /* ------------------------------------------------------------ */ | |
| 300 /** | |
| 301 * @return The class to use to add new Contexts | |
| 302 */ | |
| 303 public Class getContextClass() | |
| 304 { | |
| 305 return _contextClass; | |
| 306 } | |
| 307 | |
| 308 | |
| 309 /* ------------------------------------------------------------ */ | |
| 310 /** | |
| 311 * @param contextClass The class to use to add new Contexts | |
| 312 */ | |
| 313 public void setContextClass(Class contextClass) | |
| 314 { | |
| 315 if (contextClass ==null || !(ContextHandler.class.isAssignableFrom(contextClass))) | |
| 316 throw new IllegalArgumentException(); | |
| 317 _contextClass = contextClass; | |
| 318 } | |
| 319 | |
| 320 /* ------------------------------------------------------------ */ | |
| 321 private String normalizeHostname( String host ) | |
| 322 { | |
| 323 if ( host == null ) | |
| 324 return null; | |
| 325 | |
| 326 if ( host.endsWith( "." ) ) | |
| 327 return host.substring( 0, host.length() -1); | |
| 328 | |
| 329 return host; | |
| 330 } | |
| 331 | |
| 332 } |
