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