comparison src/org/eclipse/jetty/server/Request.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 09d518d313b7
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.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
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
167 public void requestInitialized(ServletRequestEvent sre)
168 {
169 //nothing to do, multipart config set up by ServletHolder.handle()
170 }
171
172 }
173
174
175 /* ------------------------------------------------------------ */
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 /* ------------------------------------------------------------ */
232 public Request()
233 {
234 }
235
236 /* ------------------------------------------------------------ */
237 public Request(AbstractHttpConnection connection)
238 {
239 setConnection(connection);
240 }
241
242 /* ------------------------------------------------------------ */
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 */
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 /* ------------------------------------------------------------ */
418 public AsyncContext getAsyncContext()
419 {
420 if (_async.isInitial() && !_async.isAsyncStarted())
421 throw new IllegalStateException(_async.getStatusString());
422 return _async;
423 }
424
425 /* ------------------------------------------------------------ */
426 public AsyncContinuation getAsyncContinuation()
427 {
428 return _async;
429 }
430
431 /* ------------------------------------------------------------ */
432 /*
433 * @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
434 */
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 */
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 */
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 */
474 public Authentication getAuthentication()
475 {
476 return _authentication;
477 }
478
479 /* ------------------------------------------------------------ */
480 /*
481 * @see javax.servlet.http.HttpServletRequest#getAuthType()
482 */
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 */
497 public String getCharacterEncoding()
498 {
499 return _characterEncoding;
500 }
501
502 /* ------------------------------------------------------------ */
503 /**
504 * @return Returns the connection.
505 */
506 public AbstractHttpConnection getConnection()
507 {
508 return _connection;
509 }
510
511 /* ------------------------------------------------------------ */
512 /*
513 * @see javax.servlet.ServletRequest#getContentLength()
514 */
515 public int getContentLength()
516 {
517 return (int)_connection.getRequestFields().getLongField(HttpHeaders.CONTENT_LENGTH_BUFFER);
518 }
519
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 */
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 */
541 public Context getContext()
542 {
543 return _context;
544 }
545
546 /* ------------------------------------------------------------ */
547 /*
548 * @see javax.servlet.http.HttpServletRequest#getContextPath()
549 */
550 public String getContextPath()
551 {
552 return _contextPath;
553 }
554
555 /* ------------------------------------------------------------ */
556 /*
557 * @see javax.servlet.http.HttpServletRequest#getCookies()
558 */
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 */
588 public long getDateHeader(String name)
589 {
590 return _connection.getRequestFields().getDateField(name);
591 }
592
593 /* ------------------------------------------------------------ */
594 public DispatcherType getDispatcherType()
595 {
596 return _dispatcherType;
597 }
598
599 /* ------------------------------------------------------------ */
600 /*
601 * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String)
602 */
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 */
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 */
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 */
633 public int getInputState()
634 {
635 return _inputState;
636 }
637
638 /* ------------------------------------------------------------ */
639 /*
640 * @see javax.servlet.ServletRequest#getInputStream()
641 */
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 */
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 */
663 public String getLocalAddr()
664 {
665 return _endp == null?null:_endp.getLocalAddr();
666 }
667
668 /* ------------------------------------------------------------ */
669 /*
670 * @see javax.servlet.ServletRequest#getLocale()
671 */
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 */
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 */
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 */
769 public int getLocalPort()
770 {
771 return _endp == null?0:_endp.getLocalPort();
772 }
773
774 /* ------------------------------------------------------------ */
775 /*
776 * @see javax.servlet.http.HttpServletRequest#getMethod()
777 */
778 public String getMethod()
779 {
780 return _method;
781 }
782
783 /* ------------------------------------------------------------ */
784 /*
785 * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
786 */
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 */
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 */
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 */
821 public MultiMap<String> getParameters()
822 {
823 return _parameters;
824 }
825
826 /* ------------------------------------------------------------ */
827 /*
828 * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
829 */
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 */
844 public String getPathInfo()
845 {
846 return _pathInfo;
847 }
848
849 /* ------------------------------------------------------------ */
850 /*
851 * @see javax.servlet.http.HttpServletRequest#getPathTranslated()
852 */
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 */
864 public String getProtocol()
865 {
866 return _protocol;
867 }
868
869 /* ------------------------------------------------------------ */
870 public String getQueryEncoding()
871 {
872 return _queryEncoding;
873 }
874
875 /* ------------------------------------------------------------ */
876 /*
877 * @see javax.servlet.http.HttpServletRequest#getQueryString()
878 */
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 */
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 */
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 */
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 */
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 */
967 public int getRemotePort()
968 {
969 return _endp == null?0:_endp.getRemotePort();
970 }
971
972 /* ------------------------------------------------------------ */
973 /*
974 * @see javax.servlet.http.HttpServletRequest#getRemoteUser()
975 */
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 */
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 */
1012 public String getRequestedSessionId()
1013 {
1014 return _requestedSessionId;
1015 }
1016
1017 /* ------------------------------------------------------------ */
1018 /*
1019 * @see javax.servlet.http.HttpServletRequest#getRequestURI()
1020 */
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 */
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 /* ------------------------------------------------------------ */
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 */
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 */
1093 public String getScheme()
1094 {
1095 return _scheme;
1096 }
1097
1098 /* ------------------------------------------------------------ */
1099 /*
1100 * @see javax.servlet.ServletRequest#getServerName()
1101 */
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 */
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 /* ------------------------------------------------------------ */
1210 public ServletContext getServletContext()
1211 {
1212 return _context;
1213 }
1214
1215 /* ------------------------------------------------------------ */
1216 /*
1217 */
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 */
1229 public String getServletPath()
1230 {
1231 if (_servletPath == null)
1232 _servletPath = "";
1233 return _servletPath;
1234 }
1235
1236 /* ------------------------------------------------------------ */
1237 public ServletResponse getServletResponse()
1238 {
1239 return _connection.getResponse();
1240 }
1241
1242 /* ------------------------------------------------------------ */
1243 /*
1244 * @see javax.servlet.http.HttpServletRequest#getSession()
1245 */
1246 public HttpSession getSession()
1247 {
1248 return getSession(true);
1249 }
1250
1251 /* ------------------------------------------------------------ */
1252 /*
1253 * @see javax.servlet.http.HttpServletRequest#getSession(boolean)
1254 */
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 */
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 */
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 */
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 */
1316 public HttpURI getUri()
1317 {
1318 return _uri;
1319 }
1320
1321 /* ------------------------------------------------------------ */
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 */
1337 public UserIdentity getResolvedUserIdentity()
1338 {
1339 if (_authentication instanceof Authentication.User)
1340 return ((Authentication.User)_authentication).getUserIdentity();
1341 return null;
1342 }
1343
1344 /* ------------------------------------------------------------ */
1345 public UserIdentity.Scope getUserIdentityScope()
1346 {
1347 return _scope;
1348 }
1349
1350 /* ------------------------------------------------------------ */
1351 /*
1352 * @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
1353 */
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 */
1374 public long getDispatchTime()
1375 {
1376 return _dispatchTime;
1377 }
1378
1379 /* ------------------------------------------------------------ */
1380 public boolean isHandled()
1381 {
1382 return _handled;
1383 }
1384
1385 public boolean isAsyncStarted()
1386 {
1387 return _async.isAsyncStarted();
1388 }
1389
1390
1391 /* ------------------------------------------------------------ */
1392 public boolean isAsyncSupported()
1393 {
1394 return _asyncSupported;
1395 }
1396
1397 /* ------------------------------------------------------------ */
1398 /*
1399 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie()
1400 */
1401 public boolean isRequestedSessionIdFromCookie()
1402 {
1403 return _requestedSessionId != null && _requestedSessionIdFromCookie;
1404 }
1405
1406 /* ------------------------------------------------------------ */
1407 /*
1408 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl()
1409 */
1410 public boolean isRequestedSessionIdFromUrl()
1411 {
1412 return _requestedSessionId != null && !_requestedSessionIdFromCookie;
1413 }
1414
1415 /* ------------------------------------------------------------ */
1416 /*
1417 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL()
1418 */
1419 public boolean isRequestedSessionIdFromURL()
1420 {
1421 return _requestedSessionId != null && !_requestedSessionIdFromCookie;
1422 }
1423
1424 /* ------------------------------------------------------------ */
1425 /*
1426 * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
1427 */
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 */
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 */
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 /* ------------------------------------------------------------ */
1461 public HttpSession recoverNewSession(Object key)
1462 {
1463 if (_savedNewSessions == null)
1464 return null;
1465 return _savedNewSessions.get(key);
1466 }
1467
1468 /* ------------------------------------------------------------ */
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 */
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 /* ------------------------------------------------------------ */
1561 public void removeEventListener(final EventListener listener)
1562 {
1563 _requestAttributeListeners = LazyList.remove(_requestAttributeListeners,listener);
1564 }
1565
1566 /* ------------------------------------------------------------ */
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 /* ------------------------------------------------------------ */
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 */
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 */
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 */
1680 public void setAuthentication(Authentication authentication)
1681 {
1682 _authentication = authentication;
1683 }
1684
1685 /* ------------------------------------------------------------ */
1686 /*
1687 * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String)
1688 */
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 */
1706 public void setCharacterEncodingUnchecked(String encoding)
1707 {
1708 _characterEncoding = encoding;
1709 }
1710
1711 /* ------------------------------------------------------------ */
1712 // final so we can safely call this from constructor
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 */
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 */
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 */
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 */
1762 public void setContextPath(String contextPath)
1763 {
1764 _contextPath = contextPath;
1765 }
1766
1767 /* ------------------------------------------------------------ */
1768 /**
1769 * @param cookies
1770 * The cookies to set.
1771 */
1772 public void setCookies(Cookie[] cookies)
1773 {
1774 if (_cookies == null)
1775 _cookies = new CookieCutter();
1776 _cookies.setCookies(cookies);
1777 }
1778
1779 /* ------------------------------------------------------------ */
1780 public void setDispatcherType(DispatcherType type)
1781 {
1782 _dispatcherType = type;
1783 }
1784
1785 /* ------------------------------------------------------------ */
1786 public void setHandled(boolean h)
1787 {
1788 _handled = h;
1789 }
1790
1791 /* ------------------------------------------------------------ */
1792 /**
1793 * @param method
1794 * The method to set.
1795 */
1796 public void setMethod(String method)
1797 {
1798 _method = method;
1799 }
1800
1801 /* ------------------------------------------------------------ */
1802 /**
1803 * @param parameters
1804 * The parameters to set.
1805 */
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 */
1818 public void setPathInfo(String pathInfo)
1819 {
1820 _pathInfo = pathInfo;
1821 }
1822
1823 /* ------------------------------------------------------------ */
1824 /**
1825 * @param protocol
1826 * The protocol to set.
1827 */
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 */
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 */
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 */
1864 public void setRemoteAddr(String addr)
1865 {
1866 _remoteAddr = addr;
1867 }
1868
1869 /* ------------------------------------------------------------ */
1870 /**
1871 * @param host
1872 * The host to set.
1873 */
1874 public void setRemoteHost(String host)
1875 {
1876 _remoteHost = host;
1877 }
1878
1879 /* ------------------------------------------------------------ */
1880 /**
1881 * @param requestedSessionId
1882 * The requestedSessionId to set.
1883 */
1884 public void setRequestedSessionId(String requestedSessionId)
1885 {
1886 _requestedSessionId = requestedSessionId;
1887 }
1888
1889 /* ------------------------------------------------------------ */
1890 /**
1891 * @param requestedSessionIdCookie
1892 * The requestedSessionIdCookie to set.
1893 */
1894 public void setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie)
1895 {
1896 _requestedSessionIdFromCookie = requestedSessionIdCookie;
1897 }
1898
1899 /* ------------------------------------------------------------ */
1900 /**
1901 * @param requestURI
1902 * The requestURI to set.
1903 */
1904 public void setRequestURI(String requestURI)
1905 {
1906 _requestURI = requestURI;
1907 }
1908
1909 /* ------------------------------------------------------------ */
1910 /**
1911 * @param scheme
1912 * The scheme to set.
1913 */
1914 public void setScheme(String scheme)
1915 {
1916 _scheme = scheme;
1917 }
1918
1919 /* ------------------------------------------------------------ */
1920 /**
1921 * @param host
1922 * The host to set.
1923 */
1924 public void setServerName(String host)
1925 {
1926 _serverName = host;
1927 }
1928
1929 /* ------------------------------------------------------------ */
1930 /**
1931 * @param port
1932 * The port to set.
1933 */
1934 public void setServerPort(int port)
1935 {
1936 _port = port;
1937 }
1938
1939 /* ------------------------------------------------------------ */
1940 /**
1941 * @param servletPath
1942 * The servletPath to set.
1943 */
1944 public void setServletPath(String servletPath)
1945 {
1946 _servletPath = servletPath;
1947 }
1948
1949 /* ------------------------------------------------------------ */
1950 /**
1951 * @param session
1952 * The session to set.
1953 */
1954 public void setSession(HttpSession session)
1955 {
1956 _session = session;
1957 }
1958
1959 /* ------------------------------------------------------------ */
1960 /**
1961 * @param sessionManager
1962 * The sessionManager to set.
1963 */
1964 public void setSessionManager(SessionManager sessionManager)
1965 {
1966 _sessionManager = sessionManager;
1967 }
1968
1969 /* ------------------------------------------------------------ */
1970 public void setTimeStamp(long ts)
1971 {
1972 _timeStamp = ts;
1973 }
1974
1975 /* ------------------------------------------------------------ */
1976 /**
1977 * @param uri
1978 * The uri to set.
1979 */
1980 public void setUri(HttpURI uri)
1981 {
1982 _uri = uri;
1983 }
1984
1985 /* ------------------------------------------------------------ */
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 */
1998 public void setDispatchTime(long value)
1999 {
2000 _dispatchTime = value;
2001 }
2002
2003 /* ------------------------------------------------------------ */
2004 public AsyncContext startAsync() throws IllegalStateException
2005 {
2006 if (!_asyncSupported)
2007 throw new IllegalStateException("!asyncSupported");
2008 _async.startAsync();
2009 return _async;
2010 }
2011
2012 /* ------------------------------------------------------------ */
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
2023 public String toString()
2024 {
2025 return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString();
2026 }
2027
2028 /* ------------------------------------------------------------ */
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 /* ------------------------------------------------------------ */
2041 public Part getPart(String name) throws IOException, ServletException
2042 {
2043 getParts();
2044 return _multiPartInputStream.getPart(name);
2045 }
2046
2047 /* ------------------------------------------------------------ */
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 /* ------------------------------------------------------------ */
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 /* ------------------------------------------------------------ */
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 */
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((Object)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 }