Mercurial Hosting > luan
comparison src/org/eclipse/jetty/server/Dispatcher.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
801:6a21393191c1 | 802:3428c60d7cfc |
---|---|
1 // | |
2 // ======================================================================== | |
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. | |
4 // ------------------------------------------------------------------------ | |
5 // All rights reserved. This program and the accompanying materials | |
6 // are made available under the terms of the Eclipse Public License v1.0 | |
7 // and Apache License v2.0 which accompanies this distribution. | |
8 // | |
9 // The Eclipse Public License is available at | |
10 // http://www.eclipse.org/legal/epl-v10.html | |
11 // | |
12 // The Apache License v2.0 is available at | |
13 // http://www.opensource.org/licenses/apache2.0.php | |
14 // | |
15 // You may elect to redistribute this code under either of these licenses. | |
16 // ======================================================================== | |
17 // | |
18 | |
19 package org.eclipse.jetty.server; | |
20 | |
21 import java.io.IOException; | |
22 import java.util.Collections; | |
23 import java.util.Enumeration; | |
24 import java.util.HashSet; | |
25 import java.util.Iterator; | |
26 import java.util.Map; | |
27 | |
28 import javax.servlet.DispatcherType; | |
29 import javax.servlet.RequestDispatcher; | |
30 import javax.servlet.ServletException; | |
31 import javax.servlet.ServletRequest; | |
32 import javax.servlet.ServletResponse; | |
33 import javax.servlet.http.HttpServletRequest; | |
34 import javax.servlet.http.HttpServletResponse; | |
35 | |
36 import org.eclipse.jetty.server.handler.ContextHandler; | |
37 import org.eclipse.jetty.util.Attributes; | |
38 import org.eclipse.jetty.util.LazyList; | |
39 import org.eclipse.jetty.util.MultiMap; | |
40 import org.eclipse.jetty.util.UrlEncoded; | |
41 | |
42 /* ------------------------------------------------------------ */ | |
43 /** Servlet RequestDispatcher. | |
44 * | |
45 * | |
46 */ | |
47 public class Dispatcher implements RequestDispatcher | |
48 { | |
49 /** Dispatch include attribute names */ | |
50 public final static String __INCLUDE_PREFIX="javax.servlet.include."; | |
51 | |
52 /** Dispatch include attribute names */ | |
53 public final static String __FORWARD_PREFIX="javax.servlet.forward."; | |
54 | |
55 /** JSP attributes */ | |
56 public final static String __JSP_FILE="org.apache.catalina.jsp_file"; | |
57 | |
58 /* ------------------------------------------------------------ */ | |
59 private final ContextHandler _contextHandler; | |
60 private final String _uri; | |
61 private final String _path; | |
62 private final String _dQuery; | |
63 private final String _named; | |
64 | |
65 /* ------------------------------------------------------------ */ | |
66 /** | |
67 * @param contextHandler | |
68 * @param uri | |
69 * @param pathInContext | |
70 * @param query | |
71 */ | |
72 public Dispatcher(ContextHandler contextHandler, String uri, String pathInContext, String query) | |
73 { | |
74 _contextHandler=contextHandler; | |
75 _uri=uri; | |
76 _path=pathInContext; | |
77 _dQuery=query; | |
78 _named=null; | |
79 } | |
80 | |
81 | |
82 /* ------------------------------------------------------------ */ | |
83 /** Constructor. | |
84 * @param contextHandler | |
85 * @param name | |
86 */ | |
87 public Dispatcher(ContextHandler contextHandler,String name) | |
88 throws IllegalStateException | |
89 { | |
90 _contextHandler=contextHandler; | |
91 _named=name; | |
92 _uri=null; | |
93 _path=null; | |
94 _dQuery=null; | |
95 } | |
96 | |
97 /* ------------------------------------------------------------ */ | |
98 /* | |
99 * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) | |
100 */ | |
101 public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException | |
102 { | |
103 forward(request, response, DispatcherType.FORWARD); | |
104 } | |
105 | |
106 /* ------------------------------------------------------------ */ | |
107 /* | |
108 * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) | |
109 */ | |
110 public void error(ServletRequest request, ServletResponse response) throws ServletException, IOException | |
111 { | |
112 forward(request, response, DispatcherType.ERROR); | |
113 } | |
114 | |
115 /* ------------------------------------------------------------ */ | |
116 /* | |
117 * @see javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) | |
118 */ | |
119 public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException | |
120 { | |
121 Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest(); | |
122 | |
123 | |
124 if (!(request instanceof HttpServletRequest)) | |
125 request = new ServletRequestHttpWrapper(request); | |
126 if (!(response instanceof HttpServletResponse)) | |
127 response = new ServletResponseHttpWrapper(response); | |
128 | |
129 | |
130 // TODO - allow stream or writer???? | |
131 | |
132 final DispatcherType old_type = baseRequest.getDispatcherType(); | |
133 final Attributes old_attr=baseRequest.getAttributes(); | |
134 MultiMap old_params=baseRequest.getParameters(); | |
135 try | |
136 { | |
137 baseRequest.setDispatcherType(DispatcherType.INCLUDE); | |
138 baseRequest.getConnection().include(); | |
139 if (_named!=null) | |
140 _contextHandler.handle(_named,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); | |
141 else | |
142 { | |
143 String query=_dQuery; | |
144 | |
145 if (query!=null) | |
146 { | |
147 // force parameter extraction | |
148 if (old_params==null) | |
149 { | |
150 baseRequest.extractParameters(); | |
151 old_params=baseRequest.getParameters(); | |
152 } | |
153 | |
154 MultiMap parameters=new MultiMap(); | |
155 UrlEncoded.decodeTo(query,parameters,baseRequest.getCharacterEncoding()); | |
156 | |
157 if (old_params!=null && old_params.size()>0) | |
158 { | |
159 // Merge parameters. | |
160 Iterator iter = old_params.entrySet().iterator(); | |
161 while (iter.hasNext()) | |
162 { | |
163 Map.Entry entry = (Map.Entry)iter.next(); | |
164 String name=(String)entry.getKey(); | |
165 Object values=entry.getValue(); | |
166 for (int i=0;i<LazyList.size(values);i++) | |
167 parameters.add(name, LazyList.get(values, i)); | |
168 } | |
169 } | |
170 baseRequest.setParameters(parameters); | |
171 } | |
172 | |
173 IncludeAttributes attr = new IncludeAttributes(old_attr); | |
174 | |
175 attr._requestURI=_uri; | |
176 attr._contextPath=_contextHandler.getContextPath(); | |
177 attr._servletPath=null; // set by ServletHandler | |
178 attr._pathInfo=_path; | |
179 attr._query=query; | |
180 | |
181 baseRequest.setAttributes(attr); | |
182 | |
183 _contextHandler.handle(_path,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); | |
184 } | |
185 } | |
186 finally | |
187 { | |
188 baseRequest.setAttributes(old_attr); | |
189 baseRequest.getConnection().included(); | |
190 baseRequest.setParameters(old_params); | |
191 baseRequest.setDispatcherType(old_type); | |
192 } | |
193 } | |
194 | |
195 | |
196 /* ------------------------------------------------------------ */ | |
197 /* | |
198 * @see javax.servlet.RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) | |
199 */ | |
200 protected void forward(ServletRequest request, ServletResponse response, DispatcherType dispatch) throws ServletException, IOException | |
201 { | |
202 Request baseRequest=(request instanceof Request)?((Request)request):AbstractHttpConnection.getCurrentConnection().getRequest(); | |
203 Response base_response=baseRequest.getResponse(); | |
204 response.resetBuffer(); | |
205 base_response.fwdReset(); | |
206 | |
207 | |
208 if (!(request instanceof HttpServletRequest)) | |
209 request = new ServletRequestHttpWrapper(request); | |
210 if (!(response instanceof HttpServletResponse)) | |
211 response = new ServletResponseHttpWrapper(response); | |
212 | |
213 final boolean old_handled=baseRequest.isHandled(); | |
214 final String old_uri=baseRequest.getRequestURI(); | |
215 final String old_context_path=baseRequest.getContextPath(); | |
216 final String old_servlet_path=baseRequest.getServletPath(); | |
217 final String old_path_info=baseRequest.getPathInfo(); | |
218 final String old_query=baseRequest.getQueryString(); | |
219 final Attributes old_attr=baseRequest.getAttributes(); | |
220 final DispatcherType old_type=baseRequest.getDispatcherType(); | |
221 MultiMap<String> old_params=baseRequest.getParameters(); | |
222 | |
223 try | |
224 { | |
225 baseRequest.setHandled(false); | |
226 baseRequest.setDispatcherType(dispatch); | |
227 | |
228 if (_named!=null) | |
229 _contextHandler.handle(_named,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); | |
230 else | |
231 { | |
232 | |
233 // process any query string from the dispatch URL | |
234 String query=_dQuery; | |
235 if (query!=null) | |
236 { | |
237 // force parameter extraction | |
238 if (old_params==null) | |
239 { | |
240 baseRequest.extractParameters(); | |
241 old_params=baseRequest.getParameters(); | |
242 } | |
243 | |
244 baseRequest.mergeQueryString(query); | |
245 } | |
246 | |
247 ForwardAttributes attr = new ForwardAttributes(old_attr); | |
248 | |
249 //If we have already been forwarded previously, then keep using the established | |
250 //original value. Otherwise, this is the first forward and we need to establish the values. | |
251 //Note: the established value on the original request for pathInfo and | |
252 //for queryString is allowed to be null, but cannot be null for the other values. | |
253 if (old_attr.getAttribute(FORWARD_REQUEST_URI) != null) | |
254 { | |
255 attr._pathInfo=(String)old_attr.getAttribute(FORWARD_PATH_INFO); | |
256 attr._query=(String)old_attr.getAttribute(FORWARD_QUERY_STRING); | |
257 attr._requestURI=(String)old_attr.getAttribute(FORWARD_REQUEST_URI); | |
258 attr._contextPath=(String)old_attr.getAttribute(FORWARD_CONTEXT_PATH); | |
259 attr._servletPath=(String)old_attr.getAttribute(FORWARD_SERVLET_PATH); | |
260 } | |
261 else | |
262 { | |
263 attr._pathInfo=old_path_info; | |
264 attr._query=old_query; | |
265 attr._requestURI=old_uri; | |
266 attr._contextPath=old_context_path; | |
267 attr._servletPath=old_servlet_path; | |
268 } | |
269 | |
270 baseRequest.setRequestURI(_uri); | |
271 baseRequest.setContextPath(_contextHandler.getContextPath()); | |
272 baseRequest.setServletPath(null); | |
273 baseRequest.setPathInfo(_uri); | |
274 baseRequest.setAttributes(attr); | |
275 | |
276 _contextHandler.handle(_path,baseRequest, (HttpServletRequest)request, (HttpServletResponse)response); | |
277 | |
278 if (!baseRequest.getAsyncContinuation().isAsyncStarted()) | |
279 commitResponse(response,baseRequest); | |
280 } | |
281 } | |
282 finally | |
283 { | |
284 baseRequest.setHandled(old_handled); | |
285 baseRequest.setRequestURI(old_uri); | |
286 baseRequest.setContextPath(old_context_path); | |
287 baseRequest.setServletPath(old_servlet_path); | |
288 baseRequest.setPathInfo(old_path_info); | |
289 baseRequest.setAttributes(old_attr); | |
290 baseRequest.setParameters(old_params); | |
291 baseRequest.setQueryString(old_query); | |
292 baseRequest.setDispatcherType(old_type); | |
293 } | |
294 } | |
295 | |
296 | |
297 /* ------------------------------------------------------------ */ | |
298 private void commitResponse(ServletResponse response, Request baseRequest) throws IOException | |
299 { | |
300 if (baseRequest.getResponse().isWriting()) | |
301 { | |
302 try | |
303 { | |
304 response.getWriter().close(); | |
305 } | |
306 catch (IllegalStateException e) | |
307 { | |
308 response.getOutputStream().close(); | |
309 } | |
310 } | |
311 else | |
312 { | |
313 try | |
314 { | |
315 response.getOutputStream().close(); | |
316 } | |
317 catch (IllegalStateException e) | |
318 { | |
319 response.getWriter().close(); | |
320 } | |
321 } | |
322 } | |
323 | |
324 | |
325 /* ------------------------------------------------------------ */ | |
326 /* ------------------------------------------------------------ */ | |
327 /* ------------------------------------------------------------ */ | |
328 private class ForwardAttributes implements Attributes | |
329 { | |
330 final Attributes _attr; | |
331 | |
332 String _requestURI; | |
333 String _contextPath; | |
334 String _servletPath; | |
335 String _pathInfo; | |
336 String _query; | |
337 | |
338 ForwardAttributes(Attributes attributes) | |
339 { | |
340 _attr=attributes; | |
341 } | |
342 | |
343 /* ------------------------------------------------------------ */ | |
344 public Object getAttribute(String key) | |
345 { | |
346 if (Dispatcher.this._named==null) | |
347 { | |
348 if (key.equals(FORWARD_PATH_INFO)) | |
349 return _pathInfo; | |
350 if (key.equals(FORWARD_REQUEST_URI)) | |
351 return _requestURI; | |
352 if (key.equals(FORWARD_SERVLET_PATH)) | |
353 return _servletPath; | |
354 if (key.equals(FORWARD_CONTEXT_PATH)) | |
355 return _contextPath; | |
356 if (key.equals(FORWARD_QUERY_STRING)) | |
357 return _query; | |
358 } | |
359 | |
360 if (key.startsWith(__INCLUDE_PREFIX)) | |
361 return null; | |
362 | |
363 return _attr.getAttribute(key); | |
364 } | |
365 | |
366 /* ------------------------------------------------------------ */ | |
367 public Enumeration getAttributeNames() | |
368 { | |
369 HashSet set=new HashSet(); | |
370 Enumeration e=_attr.getAttributeNames(); | |
371 while(e.hasMoreElements()) | |
372 { | |
373 String name=(String)e.nextElement(); | |
374 if (!name.startsWith(__INCLUDE_PREFIX) && | |
375 !name.startsWith(__FORWARD_PREFIX)) | |
376 set.add(name); | |
377 } | |
378 | |
379 if (_named==null) | |
380 { | |
381 if (_pathInfo!=null) | |
382 set.add(FORWARD_PATH_INFO); | |
383 else | |
384 set.remove(FORWARD_PATH_INFO); | |
385 set.add(FORWARD_REQUEST_URI); | |
386 set.add(FORWARD_SERVLET_PATH); | |
387 set.add(FORWARD_CONTEXT_PATH); | |
388 if (_query!=null) | |
389 set.add(FORWARD_QUERY_STRING); | |
390 else | |
391 set.remove(FORWARD_QUERY_STRING); | |
392 } | |
393 | |
394 return Collections.enumeration(set); | |
395 } | |
396 | |
397 /* ------------------------------------------------------------ */ | |
398 public void setAttribute(String key, Object value) | |
399 { | |
400 if (_named==null && key.startsWith("javax.servlet.")) | |
401 { | |
402 if (key.equals(FORWARD_PATH_INFO)) | |
403 _pathInfo=(String)value; | |
404 else if (key.equals(FORWARD_REQUEST_URI)) | |
405 _requestURI=(String)value; | |
406 else if (key.equals(FORWARD_SERVLET_PATH)) | |
407 _servletPath=(String)value; | |
408 else if (key.equals(FORWARD_CONTEXT_PATH)) | |
409 _contextPath=(String)value; | |
410 else if (key.equals(FORWARD_QUERY_STRING)) | |
411 _query=(String)value; | |
412 | |
413 else if (value==null) | |
414 _attr.removeAttribute(key); | |
415 else | |
416 _attr.setAttribute(key,value); | |
417 } | |
418 else if (value==null) | |
419 _attr.removeAttribute(key); | |
420 else | |
421 _attr.setAttribute(key,value); | |
422 } | |
423 | |
424 /* ------------------------------------------------------------ */ | |
425 @Override | |
426 public String toString() | |
427 { | |
428 return "FORWARD+"+_attr.toString(); | |
429 } | |
430 | |
431 /* ------------------------------------------------------------ */ | |
432 public void clearAttributes() | |
433 { | |
434 throw new IllegalStateException(); | |
435 } | |
436 | |
437 /* ------------------------------------------------------------ */ | |
438 public void removeAttribute(String name) | |
439 { | |
440 setAttribute(name,null); | |
441 } | |
442 } | |
443 | |
444 /* ------------------------------------------------------------ */ | |
445 private class IncludeAttributes implements Attributes | |
446 { | |
447 final Attributes _attr; | |
448 | |
449 String _requestURI; | |
450 String _contextPath; | |
451 String _servletPath; | |
452 String _pathInfo; | |
453 String _query; | |
454 | |
455 IncludeAttributes(Attributes attributes) | |
456 { | |
457 _attr=attributes; | |
458 } | |
459 | |
460 /* ------------------------------------------------------------ */ | |
461 /* ------------------------------------------------------------ */ | |
462 /* ------------------------------------------------------------ */ | |
463 public Object getAttribute(String key) | |
464 { | |
465 if (Dispatcher.this._named==null) | |
466 { | |
467 if (key.equals(INCLUDE_PATH_INFO)) return _pathInfo; | |
468 if (key.equals(INCLUDE_SERVLET_PATH)) return _servletPath; | |
469 if (key.equals(INCLUDE_CONTEXT_PATH)) return _contextPath; | |
470 if (key.equals(INCLUDE_QUERY_STRING)) return _query; | |
471 if (key.equals(INCLUDE_REQUEST_URI)) return _requestURI; | |
472 } | |
473 else if (key.startsWith(__INCLUDE_PREFIX)) | |
474 return null; | |
475 | |
476 | |
477 return _attr.getAttribute(key); | |
478 } | |
479 | |
480 /* ------------------------------------------------------------ */ | |
481 public Enumeration getAttributeNames() | |
482 { | |
483 HashSet set=new HashSet(); | |
484 Enumeration e=_attr.getAttributeNames(); | |
485 while(e.hasMoreElements()) | |
486 { | |
487 String name=(String)e.nextElement(); | |
488 if (!name.startsWith(__INCLUDE_PREFIX)) | |
489 set.add(name); | |
490 } | |
491 | |
492 if (_named==null) | |
493 { | |
494 if (_pathInfo!=null) | |
495 set.add(INCLUDE_PATH_INFO); | |
496 else | |
497 set.remove(INCLUDE_PATH_INFO); | |
498 set.add(INCLUDE_REQUEST_URI); | |
499 set.add(INCLUDE_SERVLET_PATH); | |
500 set.add(INCLUDE_CONTEXT_PATH); | |
501 if (_query!=null) | |
502 set.add(INCLUDE_QUERY_STRING); | |
503 else | |
504 set.remove(INCLUDE_QUERY_STRING); | |
505 } | |
506 | |
507 return Collections.enumeration(set); | |
508 } | |
509 | |
510 /* ------------------------------------------------------------ */ | |
511 public void setAttribute(String key, Object value) | |
512 { | |
513 if (_named==null && key.startsWith("javax.servlet.")) | |
514 { | |
515 if (key.equals(INCLUDE_PATH_INFO)) _pathInfo=(String)value; | |
516 else if (key.equals(INCLUDE_REQUEST_URI)) _requestURI=(String)value; | |
517 else if (key.equals(INCLUDE_SERVLET_PATH)) _servletPath=(String)value; | |
518 else if (key.equals(INCLUDE_CONTEXT_PATH)) _contextPath=(String)value; | |
519 else if (key.equals(INCLUDE_QUERY_STRING)) _query=(String)value; | |
520 else if (value==null) | |
521 _attr.removeAttribute(key); | |
522 else | |
523 _attr.setAttribute(key,value); | |
524 } | |
525 else if (value==null) | |
526 _attr.removeAttribute(key); | |
527 else | |
528 _attr.setAttribute(key,value); | |
529 } | |
530 | |
531 /* ------------------------------------------------------------ */ | |
532 @Override | |
533 public String toString() | |
534 { | |
535 return "INCLUDE+"+_attr.toString(); | |
536 } | |
537 | |
538 /* ------------------------------------------------------------ */ | |
539 public void clearAttributes() | |
540 { | |
541 throw new IllegalStateException(); | |
542 } | |
543 | |
544 /* ------------------------------------------------------------ */ | |
545 public void removeAttribute(String name) | |
546 { | |
547 setAttribute(name,null); | |
548 } | |
549 } | |
550 } |