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