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 } |
