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.HttpConnection;
29 import org.eclipse.jetty.server.Request;
30 import org.eclipse.jetty.util.LazyList;
31 import org.eclipse.jetty.util.log.Log;
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class ContextHandlerCollection extends HandlerCollection
46 {
47 private volatile PathMap _contextMap;
48 private Class<? extends ContextHandler> _contextClass = ContextHandler.class;
49
50 public ContextHandlerCollection()
51 {
52 super(true);
53 }
54
55
56
57
58
59 public void mapContexts()
60 {
61 PathMap contextMap = new PathMap();
62 Handler[] branches = getHandlers();
63
64
65 for (int b=0;branches!=null && b<branches.length;b++)
66 {
67 Handler[] handlers=null;
68
69 if (branches[b] instanceof ContextHandler)
70 {
71 handlers = new Handler[]{ branches[b] };
72 }
73 else if (branches[b] instanceof HandlerContainer)
74 {
75 handlers = ((HandlerContainer)branches[b]).getChildHandlersByClass(ContextHandler.class);
76 }
77 else
78 continue;
79
80 for (int i=0;i<handlers.length;i++)
81 {
82 ContextHandler handler=(ContextHandler)handlers[i];
83
84 String contextPath=handler.getContextPath();
85
86 if (contextPath==null || contextPath.indexOf(',')>=0 || contextPath.startsWith("*"))
87 throw new IllegalArgumentException ("Illegal context spec:"+contextPath);
88
89 if(!contextPath.startsWith("/"))
90 contextPath='/'+contextPath;
91
92 if (contextPath.length()>1)
93 {
94 if (contextPath.endsWith("/"))
95 contextPath+="*";
96 else if (!contextPath.endsWith("/*"))
97 contextPath+="/*";
98 }
99
100 Object contexts=contextMap.get(contextPath);
101 String[] vhosts=handler.getVirtualHosts();
102
103
104 if (vhosts!=null && vhosts.length>0)
105 {
106 Map hosts;
107
108 if (contexts instanceof Map)
109 hosts=(Map)contexts;
110 else
111 {
112 hosts=new HashMap();
113 hosts.put("*",contexts);
114 contextMap.put(contextPath, hosts);
115 }
116
117 for (int j=0;j<vhosts.length;j++)
118 {
119 String vhost=vhosts[j];
120 contexts=hosts.get(vhost);
121 contexts=LazyList.add(contexts,branches[b]);
122 hosts.put(vhost,contexts);
123 }
124 }
125 else if (contexts instanceof Map)
126 {
127 Map hosts=(Map)contexts;
128 contexts=hosts.get("*");
129 contexts= LazyList.add(contexts, branches[b]);
130 hosts.put("*",contexts);
131 }
132 else
133 {
134 contexts= LazyList.add(contexts, branches[b]);
135 contextMap.put(contextPath, contexts);
136 }
137 }
138 }
139 _contextMap=contextMap;
140
141 }
142
143
144
145
146
147
148
149 public void setHandlers(Handler[] handlers)
150 {
151 _contextMap=null;
152 super.setHandlers(handlers);
153 if (isStarted())
154 mapContexts();
155 }
156
157
158 protected void doStart() throws Exception
159 {
160 mapContexts();
161 super.doStart();
162 }
163
164
165
166
167
168
169 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
170 {
171 Handler[] handlers = getHandlers();
172 if (handlers==null || handlers.length==0)
173 return;
174
175 AsyncContinuation async = baseRequest.getAsyncContinuation();
176 if (async.isAsync())
177 {
178 ContextHandler context=async.getContextHandler();
179 if (context!=null)
180 {
181 context.handle(target,baseRequest,request, response);
182 return;
183 }
184 }
185
186
187
188
189
190 PathMap map = _contextMap;
191 if (map!=null && target!=null && target.startsWith("/"))
192 {
193
194 Object contexts = map.getLazyMatches(target);
195
196 for (int i=0; i<LazyList.size(contexts); i++)
197 {
198
199 Map.Entry entry = (Map.Entry)LazyList.get(contexts, i);
200 Object list = entry.getValue();
201
202 if (list instanceof Map)
203 {
204 Map hosts = (Map)list;
205 String host = normalizeHostname(request.getServerName());
206
207
208 list=hosts.get(host);
209 for (int j=0; j<LazyList.size(list); j++)
210 {
211 Handler handler = (Handler)LazyList.get(list,j);
212 handler.handle(target,baseRequest, request, response);
213 if (baseRequest.isHandled())
214 return;
215 }
216
217
218 list=hosts.get("*."+host.substring(host.indexOf(".")+1));
219 for (int j=0; j<LazyList.size(list); j++)
220 {
221 Handler handler = (Handler)LazyList.get(list,j);
222 handler.handle(target,baseRequest, request, response);
223 if (baseRequest.isHandled())
224 return;
225 }
226
227
228
229 list=hosts.get("*");
230 for (int j=0; j<LazyList.size(list); j++)
231 {
232 Handler handler = (Handler)LazyList.get(list,j);
233 handler.handle(target,baseRequest, request, response);
234 if (baseRequest.isHandled())
235 return;
236 }
237 }
238 else
239 {
240 for (int j=0; j<LazyList.size(list); j++)
241 {
242 Handler handler = (Handler)LazyList.get(list,j);
243 handler.handle(target,baseRequest, request, response);
244 if (baseRequest.isHandled())
245 return;
246 }
247 }
248 }
249 }
250 else
251 {
252
253 for (int i=0;i<handlers.length;i++)
254 {
255 handlers[i].handle(target,baseRequest, request, response);
256 if ( baseRequest.isHandled())
257 return;
258 }
259 }
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.warn(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 }