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