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