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