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