1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.Handler;
31 import org.eclipse.jetty.server.HandlerContainer;
32 import org.eclipse.jetty.server.HttpChannelState;
33 import org.eclipse.jetty.server.Request;
34 import org.eclipse.jetty.util.LazyList;
35 import org.eclipse.jetty.util.annotation.ManagedObject;
36 import org.eclipse.jetty.util.annotation.ManagedOperation;
37 import org.eclipse.jetty.util.log.Log;
38 import org.eclipse.jetty.util.log.Logger;
39
40
41
42
43
44
45
46
47
48
49
50
51 @ManagedObject("Context Handler Collection")
52 public class ContextHandlerCollection extends HandlerCollection
53 {
54 private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class);
55
56 private volatile PathMap<Object> _contextMap;
57 private Class<? extends ContextHandler> _contextClass = ContextHandler.class;
58
59
60 public ContextHandlerCollection()
61 {
62 super(true);
63 }
64
65
66
67
68
69
70 @ManagedOperation("update the mapping of context path to context")
71 public void mapContexts()
72 {
73 PathMap<Object> contextMap = new PathMap<Object>();
74 Handler[] branches = getHandlers();
75
76
77 for (int b=0;branches!=null && b<branches.length;b++)
78 {
79 Handler[] handlers=null;
80
81 if (branches[b] instanceof ContextHandler)
82 {
83 handlers = new Handler[]{ branches[b] };
84 }
85 else if (branches[b] instanceof HandlerContainer)
86 {
87 handlers = ((HandlerContainer)branches[b]).getChildHandlersByClass(ContextHandler.class);
88 }
89 else
90 continue;
91
92 for (int i=0;i<handlers.length;i++)
93 {
94 ContextHandler handler=(ContextHandler)handlers[i];
95
96 String contextPath=handler.getContextPath();
97
98 if (contextPath==null || contextPath.indexOf(',')>=0 || contextPath.startsWith("*"))
99 throw new IllegalArgumentException ("Illegal context spec:"+contextPath);
100
101 if(!contextPath.startsWith("/"))
102 contextPath='/'+contextPath;
103
104 if (contextPath.length()>1)
105 {
106 if (contextPath.endsWith("/"))
107 contextPath+="*";
108 else if (!contextPath.endsWith("/*"))
109 contextPath+="/*";
110 }
111
112 Object contexts=contextMap.get(contextPath);
113 String[] vhosts=handler.getVirtualHosts();
114
115
116 if (vhosts!=null && vhosts.length>0)
117 {
118 Map<String, Object> hosts;
119
120 if (contexts instanceof Map)
121 hosts=(Map<String, Object>)contexts;
122 else
123 {
124 hosts=new HashMap<String, Object>();
125 hosts.put("*",contexts);
126 contextMap.put(contextPath, hosts);
127 }
128
129 for (int j=0;j<vhosts.length;j++)
130 {
131 String vhost=vhosts[j];
132 contexts=hosts.get(vhost);
133 contexts=LazyList.add(contexts,branches[b]);
134 hosts.put(vhost,contexts);
135 }
136 }
137 else if (contexts instanceof Map)
138 {
139 Map<String, Object> hosts=(Map<String, Object>)contexts;
140 contexts=hosts.get("*");
141 contexts= LazyList.add(contexts, branches[b]);
142 hosts.put("*",contexts);
143 }
144 else
145 {
146 contexts= LazyList.add(contexts, branches[b]);
147 contextMap.put(contextPath, contexts);
148 }
149 }
150 }
151 _contextMap=contextMap;
152
153 }
154
155
156
157
158
159
160
161 @Override
162 public void setHandlers(Handler[] handlers)
163 {
164 _contextMap=null;
165 super.setHandlers(handlers);
166 if (isStarted())
167 mapContexts();
168 }
169
170
171 @Override
172 protected void doStart() throws Exception
173 {
174 mapContexts();
175 super.doStart();
176 }
177
178
179
180
181
182
183 @Override
184 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
185 {
186 Handler[] handlers = getHandlers();
187 if (handlers==null || handlers.length==0)
188 return;
189
190 HttpChannelState async = baseRequest.getHttpChannelState();
191 if (async.isAsync())
192 {
193 ContextHandler context=async.getContextHandler();
194 if (context!=null)
195 {
196 context.handle(target,baseRequest,request, response);
197 return;
198 }
199 }
200
201
202
203
204
205 PathMap<Object> map = _contextMap;
206 if (map!=null && target!=null && target.startsWith("/"))
207 {
208
209 Object contexts = map.getLazyMatches(target);
210
211 for (int i=0; i<LazyList.size(contexts); i++)
212 {
213
214 Map.Entry entry = (Map.Entry)LazyList.get(contexts, i);
215 Object list = entry.getValue();
216
217 if (list instanceof Map)
218 {
219 Map hosts = (Map)list;
220 String host = normalizeHostname(request.getServerName());
221
222
223 list=hosts.get(host);
224 for (int j=0; j<LazyList.size(list); j++)
225 {
226 Handler handler = (Handler)LazyList.get(list,j);
227 handler.handle(target,baseRequest, request, response);
228 if (baseRequest.isHandled())
229 return;
230 }
231
232
233 list=hosts.get("*."+host.substring(host.indexOf(".")+1));
234 for (int j=0; j<LazyList.size(list); j++)
235 {
236 Handler handler = (Handler)LazyList.get(list,j);
237 handler.handle(target,baseRequest, request, response);
238 if (baseRequest.isHandled())
239 return;
240 }
241
242
243
244 list=hosts.get("*");
245 for (int j=0; j<LazyList.size(list); j++)
246 {
247 Handler handler = (Handler)LazyList.get(list,j);
248 handler.handle(target,baseRequest, request, response);
249 if (baseRequest.isHandled())
250 return;
251 }
252 }
253 else
254 {
255 for (int j=0; j<LazyList.size(list); j++)
256 {
257 Handler handler = (Handler)LazyList.get(list,j);
258 handler.handle(target,baseRequest, request, response);
259 if (baseRequest.isHandled())
260 return;
261 }
262 }
263 }
264 }
265 else
266 {
267
268 for (int i=0;i<handlers.length;i++)
269 {
270 handlers[i].handle(target,baseRequest, request, response);
271 if ( baseRequest.isHandled())
272 return;
273 }
274 }
275 }
276
277
278
279
280
281
282
283 public ContextHandler addContext(String contextPath,String resourceBase)
284 {
285 try
286 {
287 ContextHandler context = _contextClass.newInstance();
288 context.setContextPath(contextPath);
289 context.setResourceBase(resourceBase);
290 addHandler(context);
291 return context;
292 }
293 catch (Exception e)
294 {
295 LOG.debug(e);
296 throw new Error(e);
297 }
298 }
299
300
301
302
303
304
305
306 public Class<?> getContextClass()
307 {
308 return _contextClass;
309 }
310
311
312
313
314
315
316 public void setContextClass(Class<? extends ContextHandler> contextClass)
317 {
318 if (contextClass ==null || !(ContextHandler.class.isAssignableFrom(contextClass)))
319 throw new IllegalArgumentException();
320 _contextClass = contextClass;
321 }
322
323
324 private String normalizeHostname( String host )
325 {
326 if ( host == null )
327 return null;
328
329 if ( host.endsWith( "." ) )
330 return host.substring( 0, host.length() -1);
331
332 return host;
333 }
334
335 }