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 } |