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 }