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.BufferedReader; 22 import java.io.ByteArrayOutputStream; 23 import java.io.File; 24 import java.io.IOException; 25 import java.io.InputStream; 26 import java.io.InputStreamReader; 27 import java.io.UnsupportedEncodingException; 28 import java.net.InetAddress; 29 import java.nio.ByteBuffer; 30 import java.security.Principal; 31 import java.util.Collection; 32 import java.util.Collections; 33 import java.util.Enumeration; 34 import java.util.EventListener; 35 import java.util.HashMap; 36 import java.util.Iterator; 37 import java.util.List; 38 import java.util.Locale; 39 import java.util.Map; 40 import java.util.Map.Entry; 41 42 import javax.servlet.AsyncContext; 43 import javax.servlet.AsyncEvent; 44 import javax.servlet.AsyncListener; 45 import javax.servlet.DispatcherType; 46 import javax.servlet.MultipartConfigElement; 47 import javax.servlet.RequestDispatcher; 48 import javax.servlet.ServletContext; 49 import javax.servlet.ServletException; 50 import javax.servlet.ServletInputStream; 51 import javax.servlet.ServletRequest; 52 import javax.servlet.ServletRequestAttributeEvent; 53 import javax.servlet.ServletRequestAttributeListener; 54 import javax.servlet.ServletRequestEvent; 55 import javax.servlet.ServletRequestListener; 56 import javax.servlet.ServletResponse; 57 import javax.servlet.http.Cookie; 58 import javax.servlet.http.HttpServletRequest; 59 import javax.servlet.http.HttpServletResponse; 60 import javax.servlet.http.HttpSession; 61 import javax.servlet.http.Part; 62 63 import org.eclipse.jetty.continuation.Continuation; 64 import org.eclipse.jetty.continuation.ContinuationListener; 65 import org.eclipse.jetty.http.HttpCookie; 66 import org.eclipse.jetty.http.HttpFields; 67 import org.eclipse.jetty.http.HttpHeaders; 68 import org.eclipse.jetty.http.HttpMethods; 69 import org.eclipse.jetty.http.HttpParser; 70 import org.eclipse.jetty.http.HttpStatus; 71 import org.eclipse.jetty.http.HttpURI; 72 import org.eclipse.jetty.http.HttpVersions; 73 import org.eclipse.jetty.http.MimeTypes; 74 import org.eclipse.jetty.io.Buffer; 75 import org.eclipse.jetty.io.BufferUtil; 76 import org.eclipse.jetty.io.ByteArrayBuffer; 77 import org.eclipse.jetty.io.EndPoint; 78 import org.eclipse.jetty.io.nio.DirectNIOBuffer; 79 import org.eclipse.jetty.io.nio.IndirectNIOBuffer; 80 import org.eclipse.jetty.io.nio.NIOBuffer; 81 import org.eclipse.jetty.server.handler.ContextHandler; 82 import org.eclipse.jetty.server.handler.ContextHandler.Context; 83 import org.eclipse.jetty.util.Attributes; 84 import org.eclipse.jetty.util.AttributesMap; 85 import org.eclipse.jetty.util.IO; 86 import org.eclipse.jetty.util.LazyList; 87 import org.eclipse.jetty.util.MultiException; 88 import org.eclipse.jetty.util.MultiMap; 89 import org.eclipse.jetty.util.MultiPartInputStream; 90 import org.eclipse.jetty.util.StringUtil; 91 import org.eclipse.jetty.util.URIUtil; 92 import org.eclipse.jetty.util.UrlEncoded; 93 import org.eclipse.jetty.util.log.Log; 94 import org.eclipse.jetty.util.log.Logger; 95 96 /* ------------------------------------------------------------ */ 97 /** 98 * Jetty Request. 99 * <p> 100 * Implements {@link javax.servlet.http.HttpServletRequest} from the <code>javax.servlet.http</code> package. 101 * </p> 102 * <p> 103 * The standard interface of mostly getters, is extended with setters so that the request is mutable by the handlers that it is passed to. This allows the 104 * request object to be as lightweight as possible and not actually implement any significant behavior. For example 105 * <ul> 106 * 107 * <li>The {@link Request#getContextPath()} method will return null, until the request has been passed to a {@link ContextHandler} which matches the 108 * {@link Request#getPathInfo()} with a context path and calls {@link Request#setContextPath(String)} as a result.</li> 109 * 110 * <li>the HTTP session methods will all return null sessions until such time as a request has been passed to a 111 * {@link org.eclipse.jetty.server.session.SessionHandler} which checks for session cookies and enables the ability to create new sessions.</li> 112 * 113 * <li>The {@link Request#getServletPath()} method will return null until the request has been passed to a <code>org.eclipse.jetty.servlet.ServletHandler</code> 114 * and the pathInfo matched against the servlet URL patterns and {@link Request#setServletPath(String)} called as a result.</li> 115 * </ul> 116 * 117 * A request instance is created for each {@link AbstractHttpConnection} accepted by the server and recycled for each HTTP request received via that connection. 118 * An effort is made to avoid reparsing headers and cookies that are likely to be the same for requests from the same connection. 119 * 120 * <p> 121 * The form content that a request can process is limited to protect from Denial of Service attacks. The size in bytes is limited by 122 * {@link ContextHandler#getMaxFormContentSize()} or if there is no context then the "org.eclipse.jetty.server.Request.maxFormContentSize" {@link Server} 123 * attribute. The number of parameters keys is limited by {@link ContextHandler#getMaxFormKeys()} or if there is no context then the 124 * "org.eclipse.jetty.server.Request.maxFormKeys" {@link Server} attribute. 125 * 126 * 127 */ 128 public class Request implements HttpServletRequest 129 { 130 public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig"; 131 public static final String __MULTIPART_INPUT_STREAM = "org.eclipse.multiPartInputStream"; 132 public static final String __MULTIPART_CONTEXT = "org.eclipse.multiPartContext"; 133 private static final Logger LOG = Log.getLogger(Request.class); 134 135 private static final String __ASYNC_FWD = "org.eclipse.asyncfwd"; 136 private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault()); 137 private static final int __NONE = 0, _STREAM = 1, __READER = 2; 138 139 public static class MultiPartCleanerListener implements ServletRequestListener 140 { 141 142 @Override requestDestroyed(ServletRequestEvent sre)143 public void requestDestroyed(ServletRequestEvent sre) 144 { 145 //Clean up any tmp files created by MultiPartInputStream 146 MultiPartInputStream mpis = (MultiPartInputStream)sre.getServletRequest().getAttribute(__MULTIPART_INPUT_STREAM); 147 if (mpis != null) 148 { 149 ContextHandler.Context context = (ContextHandler.Context)sre.getServletRequest().getAttribute(__MULTIPART_CONTEXT); 150 151 //Only do the cleanup if we are exiting from the context in which a servlet parsed the multipart files 152 if (context == sre.getServletContext()) 153 { 154 try 155 { 156 mpis.deleteParts(); 157 } 158 catch (MultiException e) 159 { 160 sre.getServletContext().log("Errors deleting multipart tmp files", e); 161 } 162 } 163 } 164 } 165 166 @Override requestInitialized(ServletRequestEvent sre)167 public void requestInitialized(ServletRequestEvent sre) 168 { 169 //nothing to do, multipart config set up by ServletHolder.handle() 170 } 171 172 } 173 174 175 /* ------------------------------------------------------------ */ getRequest(HttpServletRequest request)176 public static Request getRequest(HttpServletRequest request) 177 { 178 if (request instanceof Request) 179 return (Request)request; 180 181 return AbstractHttpConnection.getCurrentConnection().getRequest(); 182 } 183 protected final AsyncContinuation _async = new AsyncContinuation(); 184 private boolean _asyncSupported = true; 185 private volatile Attributes _attributes; 186 private Authentication _authentication; 187 private MultiMap<String> _baseParameters; 188 private String _characterEncoding; 189 protected AbstractHttpConnection _connection; 190 private ContextHandler.Context _context; 191 private boolean _newContext; 192 private String _contextPath; 193 private CookieCutter _cookies; 194 private boolean _cookiesExtracted = false; 195 private DispatcherType _dispatcherType; 196 private boolean _dns = false; 197 private EndPoint _endp; 198 private boolean _handled = false; 199 private int _inputState = __NONE; 200 private String _method; 201 private MultiMap<String> _parameters; 202 private boolean _paramsExtracted; 203 private String _pathInfo; 204 private int _port; 205 private String _protocol = HttpVersions.HTTP_1_1; 206 private String _queryEncoding; 207 private String _queryString; 208 private BufferedReader _reader; 209 private String _readerEncoding; 210 private String _remoteAddr; 211 private String _remoteHost; 212 private Object _requestAttributeListeners; 213 private String _requestedSessionId; 214 private boolean _requestedSessionIdFromCookie = false; 215 private String _requestURI; 216 private Map<Object, HttpSession> _savedNewSessions; 217 private String _scheme = URIUtil.HTTP; 218 private UserIdentity.Scope _scope; 219 private String _serverName; 220 private String _servletPath; 221 private HttpSession _session; 222 private SessionManager _sessionManager; 223 private long _timeStamp; 224 private long _dispatchTime; 225 226 private Buffer _timeStampBuffer; 227 private HttpURI _uri; 228 229 private MultiPartInputStream _multiPartInputStream; //if the request is a multi-part mime 230 231 /* ------------------------------------------------------------ */ Request()232 public Request() 233 { 234 } 235 236 /* ------------------------------------------------------------ */ Request(AbstractHttpConnection connection)237 public Request(AbstractHttpConnection connection) 238 { 239 setConnection(connection); 240 } 241 242 /* ------------------------------------------------------------ */ addEventListener(final EventListener listener)243 public void addEventListener(final EventListener listener) 244 { 245 if (listener instanceof ServletRequestAttributeListener) 246 _requestAttributeListeners = LazyList.add(_requestAttributeListeners,listener); 247 if (listener instanceof ContinuationListener) 248 throw new IllegalArgumentException(listener.getClass().toString()); 249 if (listener instanceof AsyncListener) 250 throw new IllegalArgumentException(listener.getClass().toString()); 251 } 252 253 /* ------------------------------------------------------------ */ 254 /** 255 * Extract Parameters from query string and/or form _content. 256 */ extractParameters()257 public void extractParameters() 258 { 259 if (_baseParameters == null) 260 _baseParameters = new MultiMap(16); 261 262 if (_paramsExtracted) 263 { 264 if (_parameters == null) 265 _parameters = _baseParameters; 266 return; 267 } 268 269 _paramsExtracted = true; 270 271 try 272 { 273 // Handle query string 274 if (_uri != null && _uri.hasQuery()) 275 { 276 if (_queryEncoding == null) 277 _uri.decodeQueryTo(_baseParameters); 278 else 279 { 280 try 281 { 282 _uri.decodeQueryTo(_baseParameters,_queryEncoding); 283 } 284 catch (UnsupportedEncodingException e) 285 { 286 if (LOG.isDebugEnabled()) 287 LOG.warn(e); 288 else 289 LOG.warn(e.toString()); 290 } 291 } 292 } 293 294 // handle any _content. 295 String encoding = getCharacterEncoding(); 296 String content_type = getContentType(); 297 if (content_type != null && content_type.length() > 0) 298 { 299 content_type = HttpFields.valueParameters(content_type,null); 300 301 if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && _inputState == __NONE 302 && (HttpMethods.POST.equals(getMethod()) || HttpMethods.PUT.equals(getMethod()))) 303 { 304 int content_length = getContentLength(); 305 if (content_length != 0) 306 { 307 try 308 { 309 int maxFormContentSize = -1; 310 int maxFormKeys = -1; 311 312 if (_context != null) 313 { 314 maxFormContentSize = _context.getContextHandler().getMaxFormContentSize(); 315 maxFormKeys = _context.getContextHandler().getMaxFormKeys(); 316 } 317 318 if (maxFormContentSize < 0) 319 { 320 Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize"); 321 if (obj == null) 322 maxFormContentSize = 200000; 323 else if (obj instanceof Number) 324 { 325 Number size = (Number)obj; 326 maxFormContentSize = size.intValue(); 327 } 328 else if (obj instanceof String) 329 { 330 maxFormContentSize = Integer.valueOf((String)obj); 331 } 332 } 333 334 if (maxFormKeys < 0) 335 { 336 Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys"); 337 if (obj == null) 338 maxFormKeys = 1000; 339 else if (obj instanceof Number) 340 { 341 Number keys = (Number)obj; 342 maxFormKeys = keys.intValue(); 343 } 344 else if (obj instanceof String) 345 { 346 maxFormKeys = Integer.valueOf((String)obj); 347 } 348 } 349 350 if (content_length > maxFormContentSize && maxFormContentSize > 0) 351 { 352 throw new IllegalStateException("Form too large " + content_length + ">" + maxFormContentSize); 353 } 354 InputStream in = getInputStream(); 355 356 // Add form params to query params 357 UrlEncoded.decodeTo(in,_baseParameters,encoding,content_length < 0?maxFormContentSize:-1,maxFormKeys); 358 } 359 catch (IOException e) 360 { 361 if (LOG.isDebugEnabled()) 362 LOG.warn(e); 363 else 364 LOG.warn(e.toString()); 365 } 366 } 367 } 368 369 } 370 371 if (_parameters == null) 372 _parameters = _baseParameters; 373 else if (_parameters != _baseParameters) 374 { 375 // Merge parameters (needed if parameters extracted after a forward). 376 Iterator iter = _baseParameters.entrySet().iterator(); 377 while (iter.hasNext()) 378 { 379 Map.Entry entry = (Map.Entry)iter.next(); 380 String name = (String)entry.getKey(); 381 Object values = entry.getValue(); 382 for (int i = 0; i < LazyList.size(values); i++) 383 _parameters.add(name,LazyList.get(values,i)); 384 } 385 } 386 387 if (content_type != null && content_type.length()>0 && content_type.startsWith("multipart/form-data") && getAttribute(__MULTIPART_CONFIG_ELEMENT)!=null) 388 { 389 try 390 { 391 getParts(); 392 } 393 catch (IOException e) 394 { 395 if (LOG.isDebugEnabled()) 396 LOG.warn(e); 397 else 398 LOG.warn(e.toString()); 399 } 400 catch (ServletException e) 401 { 402 if (LOG.isDebugEnabled()) 403 LOG.warn(e); 404 else 405 LOG.warn(e.toString()); 406 } 407 } 408 } 409 finally 410 { 411 // ensure params always set (even if empty) after extraction 412 if (_parameters == null) 413 _parameters = _baseParameters; 414 } 415 } 416 417 /* ------------------------------------------------------------ */ getAsyncContext()418 public AsyncContext getAsyncContext() 419 { 420 if (_async.isInitial() && !_async.isAsyncStarted()) 421 throw new IllegalStateException(_async.getStatusString()); 422 return _async; 423 } 424 425 /* ------------------------------------------------------------ */ getAsyncContinuation()426 public AsyncContinuation getAsyncContinuation() 427 { 428 return _async; 429 } 430 431 /* ------------------------------------------------------------ */ 432 /* 433 * @see javax.servlet.ServletRequest#getAttribute(java.lang.String) 434 */ getAttribute(String name)435 public Object getAttribute(String name) 436 { 437 if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name)) 438 return new Long(getConnection().getEndPoint().getMaxIdleTime()); 439 440 Object attr = (_attributes == null)?null:_attributes.getAttribute(name); 441 if (attr == null && Continuation.ATTRIBUTE.equals(name)) 442 return _async; 443 return attr; 444 } 445 446 /* ------------------------------------------------------------ */ 447 /* 448 * @see javax.servlet.ServletRequest#getAttributeNames() 449 */ getAttributeNames()450 public Enumeration getAttributeNames() 451 { 452 if (_attributes == null) 453 return Collections.enumeration(Collections.EMPTY_LIST); 454 455 return AttributesMap.getAttributeNamesCopy(_attributes); 456 } 457 458 /* ------------------------------------------------------------ */ 459 /* 460 */ getAttributes()461 public Attributes getAttributes() 462 { 463 if (_attributes == null) 464 _attributes = new AttributesMap(); 465 return _attributes; 466 } 467 468 /* ------------------------------------------------------------ */ 469 /** 470 * Get the authentication. 471 * 472 * @return the authentication 473 */ getAuthentication()474 public Authentication getAuthentication() 475 { 476 return _authentication; 477 } 478 479 /* ------------------------------------------------------------ */ 480 /* 481 * @see javax.servlet.http.HttpServletRequest#getAuthType() 482 */ getAuthType()483 public String getAuthType() 484 { 485 if (_authentication instanceof Authentication.Deferred) 486 setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); 487 488 if (_authentication instanceof Authentication.User) 489 return ((Authentication.User)_authentication).getAuthMethod(); 490 return null; 491 } 492 493 /* ------------------------------------------------------------ */ 494 /* 495 * @see javax.servlet.ServletRequest#getCharacterEncoding() 496 */ getCharacterEncoding()497 public String getCharacterEncoding() 498 { 499 return _characterEncoding; 500 } 501 502 /* ------------------------------------------------------------ */ 503 /** 504 * @return Returns the connection. 505 */ getConnection()506 public AbstractHttpConnection getConnection() 507 { 508 return _connection; 509 } 510 511 /* ------------------------------------------------------------ */ 512 /* 513 * @see javax.servlet.ServletRequest#getContentLength() 514 */ getContentLength()515 public int getContentLength() 516 { 517 return (int)_connection.getRequestFields().getLongField(HttpHeaders.CONTENT_LENGTH_BUFFER); 518 } 519 getContentRead()520 public long getContentRead() 521 { 522 if (_connection == null || _connection.getParser() == null) 523 return -1; 524 525 return ((HttpParser)_connection.getParser()).getContentRead(); 526 } 527 528 /* ------------------------------------------------------------ */ 529 /* 530 * @see javax.servlet.ServletRequest#getContentType() 531 */ getContentType()532 public String getContentType() 533 { 534 return _connection.getRequestFields().getStringField(HttpHeaders.CONTENT_TYPE_BUFFER); 535 } 536 537 /* ------------------------------------------------------------ */ 538 /** 539 * @return The current {@link Context context} used for this request, or <code>null</code> if {@link #setContext} has not yet been called. 540 */ getContext()541 public Context getContext() 542 { 543 return _context; 544 } 545 546 /* ------------------------------------------------------------ */ 547 /* 548 * @see javax.servlet.http.HttpServletRequest#getContextPath() 549 */ getContextPath()550 public String getContextPath() 551 { 552 return _contextPath; 553 } 554 555 /* ------------------------------------------------------------ */ 556 /* 557 * @see javax.servlet.http.HttpServletRequest#getCookies() 558 */ getCookies()559 public Cookie[] getCookies() 560 { 561 if (_cookiesExtracted) 562 return _cookies == null?null:_cookies.getCookies(); 563 564 _cookiesExtracted = true; 565 566 Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.COOKIE_BUFFER); 567 568 // Handle no cookies 569 if (enm != null) 570 { 571 if (_cookies == null) 572 _cookies = new CookieCutter(); 573 574 while (enm.hasMoreElements()) 575 { 576 String c = (String)enm.nextElement(); 577 _cookies.addCookieField(c); 578 } 579 } 580 581 return _cookies == null?null:_cookies.getCookies(); 582 } 583 584 /* ------------------------------------------------------------ */ 585 /* 586 * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String) 587 */ getDateHeader(String name)588 public long getDateHeader(String name) 589 { 590 return _connection.getRequestFields().getDateField(name); 591 } 592 593 /* ------------------------------------------------------------ */ getDispatcherType()594 public DispatcherType getDispatcherType() 595 { 596 return _dispatcherType; 597 } 598 599 /* ------------------------------------------------------------ */ 600 /* 601 * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String) 602 */ getHeader(String name)603 public String getHeader(String name) 604 { 605 return _connection.getRequestFields().getStringField(name); 606 } 607 608 /* ------------------------------------------------------------ */ 609 /* 610 * @see javax.servlet.http.HttpServletRequest#getHeaderNames() 611 */ getHeaderNames()612 public Enumeration getHeaderNames() 613 { 614 return _connection.getRequestFields().getFieldNames(); 615 } 616 617 /* ------------------------------------------------------------ */ 618 /* 619 * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String) 620 */ getHeaders(String name)621 public Enumeration getHeaders(String name) 622 { 623 Enumeration e = _connection.getRequestFields().getValues(name); 624 if (e == null) 625 return Collections.enumeration(Collections.EMPTY_LIST); 626 return e; 627 } 628 629 /* ------------------------------------------------------------ */ 630 /** 631 * @return Returns the inputState. 632 */ getInputState()633 public int getInputState() 634 { 635 return _inputState; 636 } 637 638 /* ------------------------------------------------------------ */ 639 /* 640 * @see javax.servlet.ServletRequest#getInputStream() 641 */ getInputStream()642 public ServletInputStream getInputStream() throws IOException 643 { 644 if (_inputState != __NONE && _inputState != _STREAM) 645 throw new IllegalStateException("READER"); 646 _inputState = _STREAM; 647 return _connection.getInputStream(); 648 } 649 650 /* ------------------------------------------------------------ */ 651 /* 652 * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String) 653 */ getIntHeader(String name)654 public int getIntHeader(String name) 655 { 656 return (int)_connection.getRequestFields().getLongField(name); 657 } 658 659 /* ------------------------------------------------------------ */ 660 /* 661 * @see javax.servlet.ServletRequest#getLocalAddr() 662 */ getLocalAddr()663 public String getLocalAddr() 664 { 665 return _endp == null?null:_endp.getLocalAddr(); 666 } 667 668 /* ------------------------------------------------------------ */ 669 /* 670 * @see javax.servlet.ServletRequest#getLocale() 671 */ getLocale()672 public Locale getLocale() 673 { 674 Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators); 675 676 // handle no locale 677 if (enm == null || !enm.hasMoreElements()) 678 return Locale.getDefault(); 679 680 // sort the list in quality order 681 List acceptLanguage = HttpFields.qualityList(enm); 682 if (acceptLanguage.size() == 0) 683 return Locale.getDefault(); 684 685 int size = acceptLanguage.size(); 686 687 if (size > 0) 688 { 689 String language = (String)acceptLanguage.get(0); 690 language = HttpFields.valueParameters(language,null); 691 String country = ""; 692 int dash = language.indexOf('-'); 693 if (dash > -1) 694 { 695 country = language.substring(dash + 1).trim(); 696 language = language.substring(0,dash).trim(); 697 } 698 return new Locale(language,country); 699 } 700 701 return Locale.getDefault(); 702 } 703 704 /* ------------------------------------------------------------ */ 705 /* 706 * @see javax.servlet.ServletRequest#getLocales() 707 */ getLocales()708 public Enumeration getLocales() 709 { 710 711 Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators); 712 713 // handle no locale 714 if (enm == null || !enm.hasMoreElements()) 715 return Collections.enumeration(__defaultLocale); 716 717 // sort the list in quality order 718 List acceptLanguage = HttpFields.qualityList(enm); 719 720 if (acceptLanguage.size() == 0) 721 return Collections.enumeration(__defaultLocale); 722 723 Object langs = null; 724 int size = acceptLanguage.size(); 725 726 // convert to locals 727 for (int i = 0; i < size; i++) 728 { 729 String language = (String)acceptLanguage.get(i); 730 language = HttpFields.valueParameters(language,null); 731 String country = ""; 732 int dash = language.indexOf('-'); 733 if (dash > -1) 734 { 735 country = language.substring(dash + 1).trim(); 736 language = language.substring(0,dash).trim(); 737 } 738 langs = LazyList.ensureSize(langs,size); 739 langs = LazyList.add(langs,new Locale(language,country)); 740 } 741 742 if (LazyList.size(langs) == 0) 743 return Collections.enumeration(__defaultLocale); 744 745 return Collections.enumeration(LazyList.getList(langs)); 746 } 747 748 /* ------------------------------------------------------------ */ 749 /* 750 * @see javax.servlet.ServletRequest#getLocalName() 751 */ getLocalName()752 public String getLocalName() 753 { 754 if (_endp == null) 755 return null; 756 if (_dns) 757 return _endp.getLocalHost(); 758 759 String local = _endp.getLocalAddr(); 760 if (local != null && local.indexOf(':') >= 0) 761 local = "[" + local + "]"; 762 return local; 763 } 764 765 /* ------------------------------------------------------------ */ 766 /* 767 * @see javax.servlet.ServletRequest#getLocalPort() 768 */ getLocalPort()769 public int getLocalPort() 770 { 771 return _endp == null?0:_endp.getLocalPort(); 772 } 773 774 /* ------------------------------------------------------------ */ 775 /* 776 * @see javax.servlet.http.HttpServletRequest#getMethod() 777 */ getMethod()778 public String getMethod() 779 { 780 return _method; 781 } 782 783 /* ------------------------------------------------------------ */ 784 /* 785 * @see javax.servlet.ServletRequest#getParameter(java.lang.String) 786 */ getParameter(String name)787 public String getParameter(String name) 788 { 789 if (!_paramsExtracted) 790 extractParameters(); 791 return (String)_parameters.getValue(name,0); 792 } 793 794 /* ------------------------------------------------------------ */ 795 /* 796 * @see javax.servlet.ServletRequest#getParameterMap() 797 */ getParameterMap()798 public Map getParameterMap() 799 { 800 if (!_paramsExtracted) 801 extractParameters(); 802 803 return Collections.unmodifiableMap(_parameters.toStringArrayMap()); 804 } 805 806 /* ------------------------------------------------------------ */ 807 /* 808 * @see javax.servlet.ServletRequest#getParameterNames() 809 */ getParameterNames()810 public Enumeration getParameterNames() 811 { 812 if (!_paramsExtracted) 813 extractParameters(); 814 return Collections.enumeration(_parameters.keySet()); 815 } 816 817 /* ------------------------------------------------------------ */ 818 /** 819 * @return Returns the parameters. 820 */ getParameters()821 public MultiMap<String> getParameters() 822 { 823 return _parameters; 824 } 825 826 /* ------------------------------------------------------------ */ 827 /* 828 * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String) 829 */ getParameterValues(String name)830 public String[] getParameterValues(String name) 831 { 832 if (!_paramsExtracted) 833 extractParameters(); 834 List<Object> vals = _parameters.getValues(name); 835 if (vals == null) 836 return null; 837 return vals.toArray(new String[vals.size()]); 838 } 839 840 /* ------------------------------------------------------------ */ 841 /* 842 * @see javax.servlet.http.HttpServletRequest#getPathInfo() 843 */ getPathInfo()844 public String getPathInfo() 845 { 846 return _pathInfo; 847 } 848 849 /* ------------------------------------------------------------ */ 850 /* 851 * @see javax.servlet.http.HttpServletRequest#getPathTranslated() 852 */ getPathTranslated()853 public String getPathTranslated() 854 { 855 if (_pathInfo == null || _context == null) 856 return null; 857 return _context.getRealPath(_pathInfo); 858 } 859 860 /* ------------------------------------------------------------ */ 861 /* 862 * @see javax.servlet.ServletRequest#getProtocol() 863 */ getProtocol()864 public String getProtocol() 865 { 866 return _protocol; 867 } 868 869 /* ------------------------------------------------------------ */ getQueryEncoding()870 public String getQueryEncoding() 871 { 872 return _queryEncoding; 873 } 874 875 /* ------------------------------------------------------------ */ 876 /* 877 * @see javax.servlet.http.HttpServletRequest#getQueryString() 878 */ getQueryString()879 public String getQueryString() 880 { 881 if (_queryString == null && _uri != null) 882 { 883 if (_queryEncoding == null) 884 _queryString = _uri.getQuery(); 885 else 886 _queryString = _uri.getQuery(_queryEncoding); 887 } 888 return _queryString; 889 } 890 891 /* ------------------------------------------------------------ */ 892 /* 893 * @see javax.servlet.ServletRequest#getReader() 894 */ getReader()895 public BufferedReader getReader() throws IOException 896 { 897 if (_inputState != __NONE && _inputState != __READER) 898 throw new IllegalStateException("STREAMED"); 899 900 if (_inputState == __READER) 901 return _reader; 902 903 String encoding = getCharacterEncoding(); 904 if (encoding == null) 905 encoding = StringUtil.__ISO_8859_1; 906 907 if (_reader == null || !encoding.equalsIgnoreCase(_readerEncoding)) 908 { 909 final ServletInputStream in = getInputStream(); 910 _readerEncoding = encoding; 911 _reader = new BufferedReader(new InputStreamReader(in,encoding)) 912 { 913 @Override 914 public void close() throws IOException 915 { 916 in.close(); 917 } 918 }; 919 } 920 _inputState = __READER; 921 return _reader; 922 } 923 924 /* ------------------------------------------------------------ */ 925 /* 926 * @see javax.servlet.ServletRequest#getRealPath(java.lang.String) 927 */ getRealPath(String path)928 public String getRealPath(String path) 929 { 930 if (_context == null) 931 return null; 932 return _context.getRealPath(path); 933 } 934 935 /* ------------------------------------------------------------ */ 936 /* 937 * @see javax.servlet.ServletRequest#getRemoteAddr() 938 */ getRemoteAddr()939 public String getRemoteAddr() 940 { 941 if (_remoteAddr != null) 942 return _remoteAddr; 943 return _endp == null?null:_endp.getRemoteAddr(); 944 } 945 946 /* ------------------------------------------------------------ */ 947 /* 948 * @see javax.servlet.ServletRequest#getRemoteHost() 949 */ getRemoteHost()950 public String getRemoteHost() 951 { 952 if (_dns) 953 { 954 if (_remoteHost != null) 955 { 956 return _remoteHost; 957 } 958 return _endp == null?null:_endp.getRemoteHost(); 959 } 960 return getRemoteAddr(); 961 } 962 963 /* ------------------------------------------------------------ */ 964 /* 965 * @see javax.servlet.ServletRequest#getRemotePort() 966 */ getRemotePort()967 public int getRemotePort() 968 { 969 return _endp == null?0:_endp.getRemotePort(); 970 } 971 972 /* ------------------------------------------------------------ */ 973 /* 974 * @see javax.servlet.http.HttpServletRequest#getRemoteUser() 975 */ getRemoteUser()976 public String getRemoteUser() 977 { 978 Principal p = getUserPrincipal(); 979 if (p == null) 980 return null; 981 return p.getName(); 982 } 983 984 /* ------------------------------------------------------------ */ 985 /* 986 * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String) 987 */ getRequestDispatcher(String path)988 public RequestDispatcher getRequestDispatcher(String path) 989 { 990 if (path == null || _context == null) 991 return null; 992 993 // handle relative path 994 if (!path.startsWith("/")) 995 { 996 String relTo = URIUtil.addPaths(_servletPath,_pathInfo); 997 int slash = relTo.lastIndexOf("/"); 998 if (slash > 1) 999 relTo = relTo.substring(0,slash + 1); 1000 else 1001 relTo = "/"; 1002 path = URIUtil.addPaths(relTo,path); 1003 } 1004 1005 return _context.getRequestDispatcher(path); 1006 } 1007 1008 /* ------------------------------------------------------------ */ 1009 /* 1010 * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId() 1011 */ getRequestedSessionId()1012 public String getRequestedSessionId() 1013 { 1014 return _requestedSessionId; 1015 } 1016 1017 /* ------------------------------------------------------------ */ 1018 /* 1019 * @see javax.servlet.http.HttpServletRequest#getRequestURI() 1020 */ getRequestURI()1021 public String getRequestURI() 1022 { 1023 if (_requestURI == null && _uri != null) 1024 _requestURI = _uri.getPathAndParam(); 1025 return _requestURI; 1026 } 1027 1028 /* ------------------------------------------------------------ */ 1029 /* 1030 * @see javax.servlet.http.HttpServletRequest#getRequestURL() 1031 */ getRequestURL()1032 public StringBuffer getRequestURL() 1033 { 1034 final StringBuffer url = new StringBuffer(48); 1035 synchronized (url) 1036 { 1037 String scheme = getScheme(); 1038 int port = getServerPort(); 1039 1040 url.append(scheme); 1041 url.append("://"); 1042 url.append(getServerName()); 1043 if (_port > 0 && ((scheme.equalsIgnoreCase(URIUtil.HTTP) && port != 80) || (scheme.equalsIgnoreCase(URIUtil.HTTPS) && port != 443))) 1044 { 1045 url.append(':'); 1046 url.append(_port); 1047 } 1048 1049 url.append(getRequestURI()); 1050 return url; 1051 } 1052 } 1053 1054 /* ------------------------------------------------------------ */ getResponse()1055 public Response getResponse() 1056 { 1057 return _connection._response; 1058 } 1059 1060 /* ------------------------------------------------------------ */ 1061 /** 1062 * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and, but it does not include a 1063 * path. 1064 * <p> 1065 * Because this method returns a <code>StringBuffer</code>, not a string, you can modify the URL easily, for example, to append path and query parameters. 1066 * 1067 * This method is useful for creating redirect messages and for reporting errors. 1068 * 1069 * @return "scheme://host:port" 1070 */ getRootURL()1071 public StringBuilder getRootURL() 1072 { 1073 StringBuilder url = new StringBuilder(48); 1074 String scheme = getScheme(); 1075 int port = getServerPort(); 1076 1077 url.append(scheme); 1078 url.append("://"); 1079 url.append(getServerName()); 1080 1081 if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443))) 1082 { 1083 url.append(':'); 1084 url.append(port); 1085 } 1086 return url; 1087 } 1088 1089 /* ------------------------------------------------------------ */ 1090 /* 1091 * @see javax.servlet.ServletRequest#getScheme() 1092 */ getScheme()1093 public String getScheme() 1094 { 1095 return _scheme; 1096 } 1097 1098 /* ------------------------------------------------------------ */ 1099 /* 1100 * @see javax.servlet.ServletRequest#getServerName() 1101 */ getServerName()1102 public String getServerName() 1103 { 1104 // Return already determined host 1105 if (_serverName != null) 1106 return _serverName; 1107 1108 if (_uri == null) 1109 throw new IllegalStateException("No uri"); 1110 1111 // Return host from absolute URI 1112 _serverName = _uri.getHost(); 1113 _port = _uri.getPort(); 1114 if (_serverName != null) 1115 return _serverName; 1116 1117 // Return host from header field 1118 Buffer hostPort = _connection.getRequestFields().get(HttpHeaders.HOST_BUFFER); 1119 if (hostPort != null) 1120 { 1121 loop: for (int i = hostPort.putIndex(); i-- > hostPort.getIndex();) 1122 { 1123 char ch = (char)(0xff & hostPort.peek(i)); 1124 switch (ch) 1125 { 1126 case ']': 1127 break loop; 1128 1129 case ':': 1130 _serverName = BufferUtil.to8859_1_String(hostPort.peek(hostPort.getIndex(),i - hostPort.getIndex())); 1131 try 1132 { 1133 _port = BufferUtil.toInt(hostPort.peek(i + 1,hostPort.putIndex() - i - 1)); 1134 } 1135 catch (NumberFormatException e) 1136 { 1137 try 1138 { 1139 if (_connection != null) 1140 _connection._generator.sendError(HttpStatus.BAD_REQUEST_400,"Bad Host header",null,true); 1141 } 1142 catch (IOException e1) 1143 { 1144 throw new RuntimeException(e1); 1145 } 1146 } 1147 return _serverName; 1148 } 1149 } 1150 if (_serverName == null || _port < 0) 1151 { 1152 _serverName = BufferUtil.to8859_1_String(hostPort); 1153 _port = 0; 1154 } 1155 1156 return _serverName; 1157 } 1158 1159 // Return host from connection 1160 if (_connection != null) 1161 { 1162 _serverName = getLocalName(); 1163 _port = getLocalPort(); 1164 if (_serverName != null && !StringUtil.ALL_INTERFACES.equals(_serverName)) 1165 return _serverName; 1166 } 1167 1168 // Return the local host 1169 try 1170 { 1171 _serverName = InetAddress.getLocalHost().getHostAddress(); 1172 } 1173 catch (java.net.UnknownHostException e) 1174 { 1175 LOG.ignore(e); 1176 } 1177 return _serverName; 1178 } 1179 1180 /* ------------------------------------------------------------ */ 1181 /* 1182 * @see javax.servlet.ServletRequest#getServerPort() 1183 */ getServerPort()1184 public int getServerPort() 1185 { 1186 if (_port <= 0) 1187 { 1188 if (_serverName == null) 1189 getServerName(); 1190 1191 if (_port <= 0) 1192 { 1193 if (_serverName != null && _uri != null) 1194 _port = _uri.getPort(); 1195 else 1196 _port = _endp == null?0:_endp.getLocalPort(); 1197 } 1198 } 1199 1200 if (_port <= 0) 1201 { 1202 if (getScheme().equalsIgnoreCase(URIUtil.HTTPS)) 1203 return 443; 1204 return 80; 1205 } 1206 return _port; 1207 } 1208 1209 /* ------------------------------------------------------------ */ getServletContext()1210 public ServletContext getServletContext() 1211 { 1212 return _context; 1213 } 1214 1215 /* ------------------------------------------------------------ */ 1216 /* 1217 */ getServletName()1218 public String getServletName() 1219 { 1220 if (_scope != null) 1221 return _scope.getName(); 1222 return null; 1223 } 1224 1225 /* ------------------------------------------------------------ */ 1226 /* 1227 * @see javax.servlet.http.HttpServletRequest#getServletPath() 1228 */ getServletPath()1229 public String getServletPath() 1230 { 1231 if (_servletPath == null) 1232 _servletPath = ""; 1233 return _servletPath; 1234 } 1235 1236 /* ------------------------------------------------------------ */ getServletResponse()1237 public ServletResponse getServletResponse() 1238 { 1239 return _connection.getResponse(); 1240 } 1241 1242 /* ------------------------------------------------------------ */ 1243 /* 1244 * @see javax.servlet.http.HttpServletRequest#getSession() 1245 */ getSession()1246 public HttpSession getSession() 1247 { 1248 return getSession(true); 1249 } 1250 1251 /* ------------------------------------------------------------ */ 1252 /* 1253 * @see javax.servlet.http.HttpServletRequest#getSession(boolean) 1254 */ getSession(boolean create)1255 public HttpSession getSession(boolean create) 1256 { 1257 if (_session != null) 1258 { 1259 if (_sessionManager != null && !_sessionManager.isValid(_session)) 1260 _session = null; 1261 else 1262 return _session; 1263 } 1264 1265 if (!create) 1266 return null; 1267 1268 if (_sessionManager == null) 1269 throw new IllegalStateException("No SessionManager"); 1270 1271 _session = _sessionManager.newHttpSession(this); 1272 HttpCookie cookie = _sessionManager.getSessionCookie(_session,getContextPath(),isSecure()); 1273 if (cookie != null) 1274 _connection.getResponse().addCookie(cookie); 1275 1276 return _session; 1277 } 1278 1279 /* ------------------------------------------------------------ */ 1280 /** 1281 * @return Returns the sessionManager. 1282 */ getSessionManager()1283 public SessionManager getSessionManager() 1284 { 1285 return _sessionManager; 1286 } 1287 1288 /* ------------------------------------------------------------ */ 1289 /** 1290 * Get Request TimeStamp 1291 * 1292 * @return The time that the request was received. 1293 */ getTimeStamp()1294 public long getTimeStamp() 1295 { 1296 return _timeStamp; 1297 } 1298 1299 /* ------------------------------------------------------------ */ 1300 /** 1301 * Get Request TimeStamp 1302 * 1303 * @return The time that the request was received. 1304 */ getTimeStampBuffer()1305 public Buffer getTimeStampBuffer() 1306 { 1307 if (_timeStampBuffer == null && _timeStamp > 0) 1308 _timeStampBuffer = HttpFields.__dateCache.formatBuffer(_timeStamp); 1309 return _timeStampBuffer; 1310 } 1311 1312 /* ------------------------------------------------------------ */ 1313 /** 1314 * @return Returns the uri. 1315 */ getUri()1316 public HttpURI getUri() 1317 { 1318 return _uri; 1319 } 1320 1321 /* ------------------------------------------------------------ */ getUserIdentity()1322 public UserIdentity getUserIdentity() 1323 { 1324 if (_authentication instanceof Authentication.Deferred) 1325 setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); 1326 1327 if (_authentication instanceof Authentication.User) 1328 return ((Authentication.User)_authentication).getUserIdentity(); 1329 return null; 1330 } 1331 1332 /* ------------------------------------------------------------ */ 1333 /** 1334 * @return The resolved user Identity, which may be null if the {@link Authentication} is not {@link Authentication.User} (eg. 1335 * {@link Authentication.Deferred}). 1336 */ getResolvedUserIdentity()1337 public UserIdentity getResolvedUserIdentity() 1338 { 1339 if (_authentication instanceof Authentication.User) 1340 return ((Authentication.User)_authentication).getUserIdentity(); 1341 return null; 1342 } 1343 1344 /* ------------------------------------------------------------ */ getUserIdentityScope()1345 public UserIdentity.Scope getUserIdentityScope() 1346 { 1347 return _scope; 1348 } 1349 1350 /* ------------------------------------------------------------ */ 1351 /* 1352 * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() 1353 */ getUserPrincipal()1354 public Principal getUserPrincipal() 1355 { 1356 if (_authentication instanceof Authentication.Deferred) 1357 setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); 1358 1359 if (_authentication instanceof Authentication.User) 1360 { 1361 UserIdentity user = ((Authentication.User)_authentication).getUserIdentity(); 1362 return user.getUserPrincipal(); 1363 } 1364 1365 return null; 1366 } 1367 1368 /* ------------------------------------------------------------ */ 1369 /** 1370 * Get timestamp of the request dispatch 1371 * 1372 * @return timestamp 1373 */ getDispatchTime()1374 public long getDispatchTime() 1375 { 1376 return _dispatchTime; 1377 } 1378 1379 /* ------------------------------------------------------------ */ isHandled()1380 public boolean isHandled() 1381 { 1382 return _handled; 1383 } 1384 isAsyncStarted()1385 public boolean isAsyncStarted() 1386 { 1387 return _async.isAsyncStarted(); 1388 } 1389 1390 1391 /* ------------------------------------------------------------ */ isAsyncSupported()1392 public boolean isAsyncSupported() 1393 { 1394 return _asyncSupported; 1395 } 1396 1397 /* ------------------------------------------------------------ */ 1398 /* 1399 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie() 1400 */ isRequestedSessionIdFromCookie()1401 public boolean isRequestedSessionIdFromCookie() 1402 { 1403 return _requestedSessionId != null && _requestedSessionIdFromCookie; 1404 } 1405 1406 /* ------------------------------------------------------------ */ 1407 /* 1408 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl() 1409 */ isRequestedSessionIdFromUrl()1410 public boolean isRequestedSessionIdFromUrl() 1411 { 1412 return _requestedSessionId != null && !_requestedSessionIdFromCookie; 1413 } 1414 1415 /* ------------------------------------------------------------ */ 1416 /* 1417 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL() 1418 */ isRequestedSessionIdFromURL()1419 public boolean isRequestedSessionIdFromURL() 1420 { 1421 return _requestedSessionId != null && !_requestedSessionIdFromCookie; 1422 } 1423 1424 /* ------------------------------------------------------------ */ 1425 /* 1426 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid() 1427 */ isRequestedSessionIdValid()1428 public boolean isRequestedSessionIdValid() 1429 { 1430 if (_requestedSessionId == null) 1431 return false; 1432 1433 HttpSession session = getSession(false); 1434 return (session != null && _sessionManager.getSessionIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session))); 1435 } 1436 1437 /* ------------------------------------------------------------ */ 1438 /* 1439 * @see javax.servlet.ServletRequest#isSecure() 1440 */ isSecure()1441 public boolean isSecure() 1442 { 1443 return _connection.isConfidential(this); 1444 } 1445 1446 /* ------------------------------------------------------------ */ 1447 /* 1448 * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String) 1449 */ isUserInRole(String role)1450 public boolean isUserInRole(String role) 1451 { 1452 if (_authentication instanceof Authentication.Deferred) 1453 setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); 1454 1455 if (_authentication instanceof Authentication.User) 1456 return ((Authentication.User)_authentication).isUserInRole(_scope,role); 1457 return false; 1458 } 1459 1460 /* ------------------------------------------------------------ */ recoverNewSession(Object key)1461 public HttpSession recoverNewSession(Object key) 1462 { 1463 if (_savedNewSessions == null) 1464 return null; 1465 return _savedNewSessions.get(key); 1466 } 1467 1468 /* ------------------------------------------------------------ */ recycle()1469 protected void recycle() 1470 { 1471 if (_inputState == __READER) 1472 { 1473 try 1474 { 1475 int r = _reader.read(); 1476 while (r != -1) 1477 r = _reader.read(); 1478 } 1479 catch (Exception e) 1480 { 1481 LOG.ignore(e); 1482 _reader = null; 1483 } 1484 } 1485 1486 setAuthentication(Authentication.NOT_CHECKED); 1487 _async.recycle(); 1488 _asyncSupported = true; 1489 _handled = false; 1490 if (_context != null) 1491 throw new IllegalStateException("Request in context!"); 1492 if (_attributes != null) 1493 _attributes.clearAttributes(); 1494 _characterEncoding = null; 1495 _contextPath = null; 1496 if (_cookies != null) 1497 _cookies.reset(); 1498 _cookiesExtracted = false; 1499 _context = null; 1500 _serverName = null; 1501 _method = null; 1502 _pathInfo = null; 1503 _port = 0; 1504 _protocol = HttpVersions.HTTP_1_1; 1505 _queryEncoding = null; 1506 _queryString = null; 1507 _requestedSessionId = null; 1508 _requestedSessionIdFromCookie = false; 1509 _session = null; 1510 _sessionManager = null; 1511 _requestURI = null; 1512 _scope = null; 1513 _scheme = URIUtil.HTTP; 1514 _servletPath = null; 1515 _timeStamp = 0; 1516 _timeStampBuffer = null; 1517 _uri = null; 1518 if (_baseParameters != null) 1519 _baseParameters.clear(); 1520 _parameters = null; 1521 _paramsExtracted = false; 1522 _inputState = __NONE; 1523 1524 if (_savedNewSessions != null) 1525 _savedNewSessions.clear(); 1526 _savedNewSessions=null; 1527 _multiPartInputStream = null; 1528 } 1529 1530 /* ------------------------------------------------------------ */ 1531 /* 1532 * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String) 1533 */ removeAttribute(String name)1534 public void removeAttribute(String name) 1535 { 1536 Object old_value = _attributes == null?null:_attributes.getAttribute(name); 1537 1538 if (_attributes != null) 1539 _attributes.removeAttribute(name); 1540 1541 if (old_value != null) 1542 { 1543 if (_requestAttributeListeners != null) 1544 { 1545 final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value); 1546 final int size = LazyList.size(_requestAttributeListeners); 1547 for (int i = 0; i < size; i++) 1548 { 1549 final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i); 1550 if (listener instanceof ServletRequestAttributeListener) 1551 { 1552 final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener; 1553 l.attributeRemoved(event); 1554 } 1555 } 1556 } 1557 } 1558 } 1559 1560 /* ------------------------------------------------------------ */ removeEventListener(final EventListener listener)1561 public void removeEventListener(final EventListener listener) 1562 { 1563 _requestAttributeListeners = LazyList.remove(_requestAttributeListeners,listener); 1564 } 1565 1566 /* ------------------------------------------------------------ */ saveNewSession(Object key, HttpSession session)1567 public void saveNewSession(Object key, HttpSession session) 1568 { 1569 if (_savedNewSessions == null) 1570 _savedNewSessions = new HashMap<Object, HttpSession>(); 1571 _savedNewSessions.put(key,session); 1572 } 1573 1574 /* ------------------------------------------------------------ */ setAsyncSupported(boolean supported)1575 public void setAsyncSupported(boolean supported) 1576 { 1577 _asyncSupported = supported; 1578 } 1579 1580 /* ------------------------------------------------------------ */ 1581 /* 1582 * Set a request attribute. if the attribute name is "org.eclipse.jetty.server.server.Request.queryEncoding" then the value is also passed in a call to 1583 * {@link #setQueryEncoding}. <p> if the attribute name is "org.eclipse.jetty.server.server.ResponseBuffer", then the response buffer is flushed with @{link 1584 * #flushResponseBuffer} <p> if the attribute name is "org.eclipse.jetty.io.EndPoint.maxIdleTime", then the value is passed to the associated {@link 1585 * EndPoint#setMaxIdleTime}. 1586 * 1587 * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object) 1588 */ setAttribute(String name, Object value)1589 public void setAttribute(String name, Object value) 1590 { 1591 Object old_value = _attributes == null?null:_attributes.getAttribute(name); 1592 1593 if (name.startsWith("org.eclipse.jetty.")) 1594 { 1595 if ("org.eclipse.jetty.server.Request.queryEncoding".equals(name)) 1596 setQueryEncoding(value == null?null:value.toString()); 1597 else if ("org.eclipse.jetty.server.sendContent".equals(name)) 1598 { 1599 try 1600 { 1601 ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendContent(value); 1602 } 1603 catch (IOException e) 1604 { 1605 throw new RuntimeException(e); 1606 } 1607 } 1608 else if ("org.eclipse.jetty.server.ResponseBuffer".equals(name)) 1609 { 1610 try 1611 { 1612 final ByteBuffer byteBuffer = (ByteBuffer)value; 1613 synchronized (byteBuffer) 1614 { 1615 NIOBuffer buffer = byteBuffer.isDirect()?new DirectNIOBuffer(byteBuffer,true):new IndirectNIOBuffer(byteBuffer,true); 1616 ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer); 1617 } 1618 } 1619 catch (IOException e) 1620 { 1621 throw new RuntimeException(e); 1622 } 1623 } 1624 else if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name)) 1625 { 1626 try 1627 { 1628 getConnection().getEndPoint().setMaxIdleTime(Integer.valueOf(value.toString())); 1629 } 1630 catch (IOException e) 1631 { 1632 throw new RuntimeException(e); 1633 } 1634 } 1635 } 1636 1637 if (_attributes == null) 1638 _attributes = new AttributesMap(); 1639 _attributes.setAttribute(name,value); 1640 1641 if (_requestAttributeListeners != null) 1642 { 1643 final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value == null?value:old_value); 1644 final int size = LazyList.size(_requestAttributeListeners); 1645 for (int i = 0; i < size; i++) 1646 { 1647 final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i); 1648 if (listener instanceof ServletRequestAttributeListener) 1649 { 1650 final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener; 1651 1652 if (old_value == null) 1653 l.attributeAdded(event); 1654 else if (value == null) 1655 l.attributeRemoved(event); 1656 else 1657 l.attributeReplaced(event); 1658 } 1659 } 1660 } 1661 } 1662 1663 /* ------------------------------------------------------------ */ 1664 /* 1665 */ setAttributes(Attributes attributes)1666 public void setAttributes(Attributes attributes) 1667 { 1668 _attributes = attributes; 1669 } 1670 1671 /* ------------------------------------------------------------ */ 1672 1673 /* ------------------------------------------------------------ */ 1674 /** 1675 * Set the authentication. 1676 * 1677 * @param authentication 1678 * the authentication to set 1679 */ setAuthentication(Authentication authentication)1680 public void setAuthentication(Authentication authentication) 1681 { 1682 _authentication = authentication; 1683 } 1684 1685 /* ------------------------------------------------------------ */ 1686 /* 1687 * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) 1688 */ setCharacterEncoding(String encoding)1689 public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException 1690 { 1691 if (_inputState != __NONE) 1692 return; 1693 1694 _characterEncoding = encoding; 1695 1696 // check encoding is supported 1697 if (!StringUtil.isUTF8(encoding)) 1698 // noinspection ResultOfMethodCallIgnored 1699 "".getBytes(encoding); 1700 } 1701 1702 /* ------------------------------------------------------------ */ 1703 /* 1704 * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) 1705 */ setCharacterEncodingUnchecked(String encoding)1706 public void setCharacterEncodingUnchecked(String encoding) 1707 { 1708 _characterEncoding = encoding; 1709 } 1710 1711 /* ------------------------------------------------------------ */ 1712 // final so we can safely call this from constructor setConnection(AbstractHttpConnection connection)1713 protected final void setConnection(AbstractHttpConnection connection) 1714 { 1715 _connection = connection; 1716 _async.setConnection(connection); 1717 _endp = connection.getEndPoint(); 1718 _dns = connection.getResolveNames(); 1719 } 1720 1721 /* ------------------------------------------------------------ */ 1722 /* 1723 * @see javax.servlet.ServletRequest#getContentType() 1724 */ setContentType(String contentType)1725 public void setContentType(String contentType) 1726 { 1727 _connection.getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,contentType); 1728 1729 } 1730 1731 /* ------------------------------------------------------------ */ 1732 /** 1733 * Set request context 1734 * 1735 * @param context 1736 * context object 1737 */ setContext(Context context)1738 public void setContext(Context context) 1739 { 1740 _newContext = _context != context; 1741 _context = context; 1742 } 1743 1744 /* ------------------------------------------------------------ */ 1745 /** 1746 * @return True if this is the first call of {@link #takeNewContext()} since the last 1747 * {@link #setContext(org.eclipse.jetty.server.handler.ContextHandler.Context)} call. 1748 */ takeNewContext()1749 public boolean takeNewContext() 1750 { 1751 boolean nc = _newContext; 1752 _newContext = false; 1753 return nc; 1754 } 1755 1756 /* ------------------------------------------------------------ */ 1757 /** 1758 * Sets the "context path" for this request 1759 * 1760 * @see HttpServletRequest#getContextPath() 1761 */ setContextPath(String contextPath)1762 public void setContextPath(String contextPath) 1763 { 1764 _contextPath = contextPath; 1765 } 1766 1767 /* ------------------------------------------------------------ */ 1768 /** 1769 * @param cookies 1770 * The cookies to set. 1771 */ setCookies(Cookie[] cookies)1772 public void setCookies(Cookie[] cookies) 1773 { 1774 if (_cookies == null) 1775 _cookies = new CookieCutter(); 1776 _cookies.setCookies(cookies); 1777 } 1778 1779 /* ------------------------------------------------------------ */ setDispatcherType(DispatcherType type)1780 public void setDispatcherType(DispatcherType type) 1781 { 1782 _dispatcherType = type; 1783 } 1784 1785 /* ------------------------------------------------------------ */ setHandled(boolean h)1786 public void setHandled(boolean h) 1787 { 1788 _handled = h; 1789 } 1790 1791 /* ------------------------------------------------------------ */ 1792 /** 1793 * @param method 1794 * The method to set. 1795 */ setMethod(String method)1796 public void setMethod(String method) 1797 { 1798 _method = method; 1799 } 1800 1801 /* ------------------------------------------------------------ */ 1802 /** 1803 * @param parameters 1804 * The parameters to set. 1805 */ setParameters(MultiMap<String> parameters)1806 public void setParameters(MultiMap<String> parameters) 1807 { 1808 _parameters = (parameters == null)?_baseParameters:parameters; 1809 if (_paramsExtracted && _parameters == null) 1810 throw new IllegalStateException(); 1811 } 1812 1813 /* ------------------------------------------------------------ */ 1814 /** 1815 * @param pathInfo 1816 * The pathInfo to set. 1817 */ setPathInfo(String pathInfo)1818 public void setPathInfo(String pathInfo) 1819 { 1820 _pathInfo = pathInfo; 1821 } 1822 1823 /* ------------------------------------------------------------ */ 1824 /** 1825 * @param protocol 1826 * The protocol to set. 1827 */ setProtocol(String protocol)1828 public void setProtocol(String protocol) 1829 { 1830 _protocol = protocol; 1831 } 1832 1833 /* ------------------------------------------------------------ */ 1834 /** 1835 * Set the character encoding used for the query string. This call will effect the return of getQueryString and getParamaters. It must be called before any 1836 * geParameter methods. 1837 * 1838 * The request attribute "org.eclipse.jetty.server.server.Request.queryEncoding" may be set as an alternate method of calling setQueryEncoding. 1839 * 1840 * @param queryEncoding 1841 */ setQueryEncoding(String queryEncoding)1842 public void setQueryEncoding(String queryEncoding) 1843 { 1844 _queryEncoding = queryEncoding; 1845 _queryString = null; 1846 } 1847 1848 /* ------------------------------------------------------------ */ 1849 /** 1850 * @param queryString 1851 * The queryString to set. 1852 */ setQueryString(String queryString)1853 public void setQueryString(String queryString) 1854 { 1855 _queryString = queryString; 1856 _queryEncoding = null; //assume utf-8 1857 } 1858 1859 /* ------------------------------------------------------------ */ 1860 /** 1861 * @param addr 1862 * The address to set. 1863 */ setRemoteAddr(String addr)1864 public void setRemoteAddr(String addr) 1865 { 1866 _remoteAddr = addr; 1867 } 1868 1869 /* ------------------------------------------------------------ */ 1870 /** 1871 * @param host 1872 * The host to set. 1873 */ setRemoteHost(String host)1874 public void setRemoteHost(String host) 1875 { 1876 _remoteHost = host; 1877 } 1878 1879 /* ------------------------------------------------------------ */ 1880 /** 1881 * @param requestedSessionId 1882 * The requestedSessionId to set. 1883 */ setRequestedSessionId(String requestedSessionId)1884 public void setRequestedSessionId(String requestedSessionId) 1885 { 1886 _requestedSessionId = requestedSessionId; 1887 } 1888 1889 /* ------------------------------------------------------------ */ 1890 /** 1891 * @param requestedSessionIdCookie 1892 * The requestedSessionIdCookie to set. 1893 */ setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie)1894 public void setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie) 1895 { 1896 _requestedSessionIdFromCookie = requestedSessionIdCookie; 1897 } 1898 1899 /* ------------------------------------------------------------ */ 1900 /** 1901 * @param requestURI 1902 * The requestURI to set. 1903 */ setRequestURI(String requestURI)1904 public void setRequestURI(String requestURI) 1905 { 1906 _requestURI = requestURI; 1907 } 1908 1909 /* ------------------------------------------------------------ */ 1910 /** 1911 * @param scheme 1912 * The scheme to set. 1913 */ setScheme(String scheme)1914 public void setScheme(String scheme) 1915 { 1916 _scheme = scheme; 1917 } 1918 1919 /* ------------------------------------------------------------ */ 1920 /** 1921 * @param host 1922 * The host to set. 1923 */ setServerName(String host)1924 public void setServerName(String host) 1925 { 1926 _serverName = host; 1927 } 1928 1929 /* ------------------------------------------------------------ */ 1930 /** 1931 * @param port 1932 * The port to set. 1933 */ setServerPort(int port)1934 public void setServerPort(int port) 1935 { 1936 _port = port; 1937 } 1938 1939 /* ------------------------------------------------------------ */ 1940 /** 1941 * @param servletPath 1942 * The servletPath to set. 1943 */ setServletPath(String servletPath)1944 public void setServletPath(String servletPath) 1945 { 1946 _servletPath = servletPath; 1947 } 1948 1949 /* ------------------------------------------------------------ */ 1950 /** 1951 * @param session 1952 * The session to set. 1953 */ setSession(HttpSession session)1954 public void setSession(HttpSession session) 1955 { 1956 _session = session; 1957 } 1958 1959 /* ------------------------------------------------------------ */ 1960 /** 1961 * @param sessionManager 1962 * The sessionManager to set. 1963 */ setSessionManager(SessionManager sessionManager)1964 public void setSessionManager(SessionManager sessionManager) 1965 { 1966 _sessionManager = sessionManager; 1967 } 1968 1969 /* ------------------------------------------------------------ */ setTimeStamp(long ts)1970 public void setTimeStamp(long ts) 1971 { 1972 _timeStamp = ts; 1973 } 1974 1975 /* ------------------------------------------------------------ */ 1976 /** 1977 * @param uri 1978 * The uri to set. 1979 */ setUri(HttpURI uri)1980 public void setUri(HttpURI uri) 1981 { 1982 _uri = uri; 1983 } 1984 1985 /* ------------------------------------------------------------ */ setUserIdentityScope(UserIdentity.Scope scope)1986 public void setUserIdentityScope(UserIdentity.Scope scope) 1987 { 1988 _scope = scope; 1989 } 1990 1991 /* ------------------------------------------------------------ */ 1992 /** 1993 * Set timetstamp of request dispatch 1994 * 1995 * @param value 1996 * timestamp 1997 */ setDispatchTime(long value)1998 public void setDispatchTime(long value) 1999 { 2000 _dispatchTime = value; 2001 } 2002 2003 /* ------------------------------------------------------------ */ startAsync()2004 public AsyncContext startAsync() throws IllegalStateException 2005 { 2006 if (!_asyncSupported) 2007 throw new IllegalStateException("!asyncSupported"); 2008 _async.startAsync(); 2009 return _async; 2010 } 2011 2012 /* ------------------------------------------------------------ */ startAsync(ServletRequest servletRequest, ServletResponse servletResponse)2013 public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException 2014 { 2015 if (!_asyncSupported) 2016 throw new IllegalStateException("!asyncSupported"); 2017 _async.startAsync(_context,servletRequest,servletResponse); 2018 return _async; 2019 } 2020 2021 /* ------------------------------------------------------------ */ 2022 @Override toString()2023 public String toString() 2024 { 2025 return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString(); 2026 } 2027 2028 /* ------------------------------------------------------------ */ authenticate(HttpServletResponse response)2029 public boolean authenticate(HttpServletResponse response) throws IOException, ServletException 2030 { 2031 if (_authentication instanceof Authentication.Deferred) 2032 { 2033 setAuthentication(((Authentication.Deferred)_authentication).authenticate(this,response)); 2034 return !(_authentication instanceof Authentication.ResponseSent); 2035 } 2036 response.sendError(HttpStatus.UNAUTHORIZED_401); 2037 return false; 2038 } 2039 2040 /* ------------------------------------------------------------ */ getPart(String name)2041 public Part getPart(String name) throws IOException, ServletException 2042 { 2043 getParts(); 2044 return _multiPartInputStream.getPart(name); 2045 } 2046 2047 /* ------------------------------------------------------------ */ getParts()2048 public Collection<Part> getParts() throws IOException, ServletException 2049 { 2050 if (getContentType() == null || !getContentType().startsWith("multipart/form-data")) 2051 throw new ServletException("Content-Type != multipart/form-data"); 2052 2053 if (_multiPartInputStream == null) 2054 _multiPartInputStream = (MultiPartInputStream)getAttribute(__MULTIPART_INPUT_STREAM); 2055 2056 if (_multiPartInputStream == null) 2057 { 2058 MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT); 2059 2060 if (config == null) 2061 throw new IllegalStateException("No multipart config for servlet"); 2062 2063 _multiPartInputStream = new MultiPartInputStream(getInputStream(), 2064 getContentType(), config, 2065 (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null)); 2066 2067 setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream); 2068 setAttribute(__MULTIPART_CONTEXT, _context); 2069 Collection<Part> parts = _multiPartInputStream.getParts(); //causes parsing 2070 for (Part p:parts) 2071 { 2072 MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p; 2073 if (mp.getContentDispositionFilename() == null) 2074 { 2075 //Servlet Spec 3.0 pg 23, parts without filenames must be put into init params 2076 String charset = null; 2077 if (mp.getContentType() != null) 2078 charset = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(mp.getContentType())); 2079 2080 ByteArrayOutputStream os = null; 2081 InputStream is = mp.getInputStream(); //get the bytes regardless of being in memory or in temp file 2082 try 2083 { 2084 os = new ByteArrayOutputStream(); 2085 IO.copy(is, os); 2086 String content=new String(os.toByteArray(),charset==null?StringUtil.__UTF8:charset); 2087 getParameter(""); //cause params to be evaluated 2088 getParameters().add(mp.getName(), content); 2089 } 2090 finally 2091 { 2092 IO.close(os); 2093 IO.close(is); 2094 } 2095 } 2096 } 2097 } 2098 2099 return _multiPartInputStream.getParts(); 2100 } 2101 2102 /* ------------------------------------------------------------ */ login(String username, String password)2103 public void login(String username, String password) throws ServletException 2104 { 2105 if (_authentication instanceof Authentication.Deferred) 2106 { 2107 _authentication=((Authentication.Deferred)_authentication).login(username,password,this); 2108 if (_authentication == null) 2109 throw new ServletException(); 2110 } 2111 else 2112 { 2113 throw new ServletException("Authenticated as "+_authentication); 2114 } 2115 } 2116 2117 /* ------------------------------------------------------------ */ logout()2118 public void logout() throws ServletException 2119 { 2120 if (_authentication instanceof Authentication.User) 2121 ((Authentication.User)_authentication).logout(); 2122 _authentication=Authentication.UNAUTHENTICATED; 2123 } 2124 2125 /* ------------------------------------------------------------ */ 2126 /** 2127 * Merge in a new query string. The query string is merged with the existing parameters and {@link #setParameters(MultiMap)} and 2128 * {@link #setQueryString(String)} are called with the result. The merge is according to the rules of the servlet dispatch forward method. 2129 * 2130 * @param query 2131 * The query string to merge into the request. 2132 */ mergeQueryString(String query)2133 public void mergeQueryString(String query) 2134 { 2135 // extract parameters from dispatch query 2136 MultiMap<String> parameters = new MultiMap<String>(); 2137 UrlEncoded.decodeTo(query,parameters, StringUtil.__UTF8); //have to assume UTF-8 because we can't know otherwise 2138 2139 boolean merge_old_query = false; 2140 2141 // Have we evaluated parameters 2142 if (!_paramsExtracted) 2143 extractParameters(); 2144 2145 // Are there any existing parameters? 2146 if (_parameters != null && _parameters.size() > 0) 2147 { 2148 // Merge parameters; new parameters of the same name take precedence. 2149 Iterator<Entry<String, Object>> iter = _parameters.entrySet().iterator(); 2150 while (iter.hasNext()) 2151 { 2152 Map.Entry<String, Object> entry = iter.next(); 2153 String name = entry.getKey(); 2154 2155 // If the names match, we will need to remake the query string 2156 if (parameters.containsKey(name)) 2157 merge_old_query = true; 2158 2159 // Add the old values to the new parameter map 2160 Object values = entry.getValue(); 2161 for (int i = 0; i < LazyList.size(values); i++) 2162 parameters.add(name,LazyList.get(values,i)); 2163 } 2164 } 2165 2166 if (_queryString != null && _queryString.length() > 0) 2167 { 2168 if (merge_old_query) 2169 { 2170 StringBuilder overridden_query_string = new StringBuilder(); 2171 MultiMap<String> overridden_old_query = new MultiMap<String>(); 2172 UrlEncoded.decodeTo(_queryString,overridden_old_query,getQueryEncoding());//decode using any queryencoding set for the request 2173 2174 2175 MultiMap<String> overridden_new_query = new MultiMap<String>(); 2176 UrlEncoded.decodeTo(query,overridden_new_query,StringUtil.__UTF8); //have to assume utf8 as we cannot know otherwise 2177 2178 Iterator<Entry<String, Object>> iter = overridden_old_query.entrySet().iterator(); 2179 while (iter.hasNext()) 2180 { 2181 Map.Entry<String, Object> entry = iter.next(); 2182 String name = entry.getKey(); 2183 if (!overridden_new_query.containsKey(name)) 2184 { 2185 Object values = entry.getValue(); 2186 for (int i = 0; i < LazyList.size(values); i++) 2187 { 2188 overridden_query_string.append("&").append(name).append("=").append(LazyList.get(values,i)); 2189 } 2190 } 2191 } 2192 2193 query = query + overridden_query_string; 2194 } 2195 else 2196 { 2197 query = query + "&" + _queryString; 2198 } 2199 } 2200 2201 setParameters(parameters); 2202 setQueryString(query); 2203 } 2204 } 2205