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.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.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 boolean hasMetaData()
1792 {
1793 return _metadata!=null;
1794 }
1795
1796
1797 protected void recycle()
1798 {
1799 _metadata=null;
1800
1801 if (_context != null)
1802 throw new IllegalStateException("Request in context!");
1803
1804 if (_inputState == __READER)
1805 {
1806 try
1807 {
1808 int r = _reader.read();
1809 while (r != -1)
1810 r = _reader.read();
1811 }
1812 catch (Exception e)
1813 {
1814 LOG.ignore(e);
1815 _reader = null;
1816 }
1817 }
1818
1819 _dispatcherType=null;
1820 setAuthentication(Authentication.NOT_CHECKED);
1821 getHttpChannelState().recycle();
1822 if (_async!=null)
1823 _async.reset();
1824 _async=null;
1825 _asyncSupported = true;
1826 _handled = false;
1827 if (_attributes != null)
1828 _attributes.clearAttributes();
1829 _characterEncoding = null;
1830 _contextPath = null;
1831 if (_cookies != null)
1832 _cookies.reset();
1833 _cookiesExtracted = false;
1834 _context = null;
1835 _newContext=false;
1836 _pathInfo = null;
1837 _queryEncoding = null;
1838 _requestedSessionId = null;
1839 _requestedSessionIdFromCookie = false;
1840 _secure=false;
1841 _session = null;
1842 _sessionManager = null;
1843 _scope = null;
1844 _servletPath = null;
1845 _timeStamp = 0;
1846 _queryParameters = null;
1847 _contentParameters = null;
1848 _parameters = null;
1849 _paramsExtracted = false;
1850 _inputState = __NONE;
1851
1852 if (_savedNewSessions != null)
1853 _savedNewSessions.clear();
1854 _savedNewSessions=null;
1855 _multiPartInputStream = null;
1856 _remote=null;
1857 _input.recycle();
1858 }
1859
1860
1861
1862
1863
1864 @Override
1865 public void removeAttribute(String name)
1866 {
1867 Object old_value = _attributes == null?null:_attributes.getAttribute(name);
1868
1869 if (_attributes != null)
1870 _attributes.removeAttribute(name);
1871
1872 if (old_value != null && !_requestAttributeListeners.isEmpty())
1873 {
1874 final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value);
1875 for (ServletRequestAttributeListener listener : _requestAttributeListeners)
1876 listener.attributeRemoved(event);
1877 }
1878 }
1879
1880
1881 public void removeEventListener(final EventListener listener)
1882 {
1883 _requestAttributeListeners.remove(listener);
1884 }
1885
1886
1887 public void saveNewSession(Object key, HttpSession session)
1888 {
1889 if (_savedNewSessions == null)
1890 _savedNewSessions = new HashMap<>();
1891 _savedNewSessions.put(key,session);
1892 }
1893
1894
1895 public void setAsyncSupported(boolean supported)
1896 {
1897 _asyncSupported = supported;
1898 }
1899
1900
1901
1902
1903
1904
1905
1906
1907 @Override
1908 public void setAttribute(String name, Object value)
1909 {
1910 Object old_value = _attributes == null?null:_attributes.getAttribute(name);
1911
1912 if ("org.eclipse.jetty.server.Request.queryEncoding".equals(name))
1913 setQueryEncoding(value == null?null:value.toString());
1914 else if ("org.eclipse.jetty.server.sendContent".equals(name))
1915 LOG.warn("Deprecated: org.eclipse.jetty.server.sendContent");
1916
1917 if (_attributes == null)
1918 _attributes = new AttributesMap();
1919 _attributes.setAttribute(name,value);
1920
1921 if (!_requestAttributeListeners.isEmpty())
1922 {
1923 final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value == null?value:old_value);
1924 for (ServletRequestAttributeListener l : _requestAttributeListeners)
1925 {
1926 if (old_value == null)
1927 l.attributeAdded(event);
1928 else if (value == null)
1929 l.attributeRemoved(event);
1930 else
1931 l.attributeReplaced(event);
1932 }
1933 }
1934 }
1935
1936
1937
1938
1939 public void setAttributes(Attributes attributes)
1940 {
1941 _attributes = attributes;
1942 }
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953 public void setAuthentication(Authentication authentication)
1954 {
1955 _authentication = authentication;
1956 }
1957
1958
1959
1960
1961
1962 @Override
1963 public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException
1964 {
1965 if (_inputState != __NONE)
1966 return;
1967
1968 _characterEncoding = encoding;
1969
1970
1971 if (!StringUtil.isUTF8(encoding))
1972 {
1973 try
1974 {
1975 Charset.forName(encoding);
1976 }
1977 catch (UnsupportedCharsetException e)
1978 {
1979 throw new UnsupportedEncodingException(e.getMessage());
1980 }
1981 }
1982 }
1983
1984
1985
1986
1987
1988 public void setCharacterEncodingUnchecked(String encoding)
1989 {
1990 _characterEncoding = encoding;
1991 }
1992
1993
1994
1995
1996
1997 public void setContentType(String contentType)
1998 {
1999 _metadata.getFields().put(HttpHeader.CONTENT_TYPE,contentType);
2000 }
2001
2002
2003
2004
2005
2006
2007
2008
2009 public void setContext(Context context)
2010 {
2011 _newContext = _context != context;
2012 _context = context;
2013 }
2014
2015
2016
2017
2018
2019
2020 public boolean takeNewContext()
2021 {
2022 boolean nc = _newContext;
2023 _newContext = false;
2024 return nc;
2025 }
2026
2027
2028
2029
2030
2031
2032
2033 public void setContextPath(String contextPath)
2034 {
2035 _contextPath = contextPath;
2036 }
2037
2038
2039
2040
2041
2042
2043 public void setCookies(Cookie[] cookies)
2044 {
2045 if (_cookies == null)
2046 _cookies = new CookieCutter();
2047 _cookies.setCookies(cookies);
2048 }
2049
2050
2051 public void setDispatcherType(DispatcherType type)
2052 {
2053 _dispatcherType = type;
2054 }
2055
2056
2057 public void setHandled(boolean h)
2058 {
2059 _handled = h;
2060 }
2061
2062
2063
2064
2065
2066
2067 public void setMethod(String method)
2068 {
2069 _metadata.setMethod(method);
2070 }
2071
2072
2073 public boolean isHead()
2074 {
2075 return _metadata!=null && HttpMethod.HEAD.is(_metadata.getMethod());
2076 }
2077
2078
2079
2080
2081
2082
2083 public void setPathInfo(String pathInfo)
2084 {
2085 _pathInfo = pathInfo;
2086 }
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097 public void setQueryEncoding(String queryEncoding)
2098 {
2099 _queryEncoding = queryEncoding;
2100 }
2101
2102
2103
2104
2105
2106
2107 public void setQueryString(String queryString)
2108 {
2109 _metadata.getURI().setQuery(queryString);
2110 _queryEncoding = null;
2111 }
2112
2113
2114
2115
2116
2117
2118 public void setRemoteAddr(InetSocketAddress addr)
2119 {
2120 _remote = addr;
2121 }
2122
2123
2124
2125
2126
2127
2128 public void setRequestedSessionId(String requestedSessionId)
2129 {
2130 _requestedSessionId = requestedSessionId;
2131 }
2132
2133
2134
2135
2136
2137
2138 public void setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie)
2139 {
2140 _requestedSessionIdFromCookie = requestedSessionIdCookie;
2141 }
2142
2143
2144 public void setURIPathQuery(String requestURI)
2145 {
2146 _metadata.getURI().setPathQuery(requestURI);
2147 }
2148
2149
2150
2151
2152
2153
2154 public void setScheme(String scheme)
2155 {
2156 _metadata.getURI().setScheme(scheme);
2157 }
2158
2159
2160
2161
2162
2163
2164
2165
2166 public void setAuthority(String host,int port)
2167 {
2168 _metadata.getURI().setAuthority(host,port);;
2169 }
2170
2171
2172
2173
2174
2175
2176 public void setServletPath(String servletPath)
2177 {
2178 _servletPath = servletPath;
2179 }
2180
2181
2182
2183
2184
2185
2186 public void setSession(HttpSession session)
2187 {
2188 _session = session;
2189 }
2190
2191
2192
2193
2194
2195
2196 public void setSessionManager(SessionManager sessionManager)
2197 {
2198 _sessionManager = sessionManager;
2199 }
2200
2201
2202 public void setTimeStamp(long ts)
2203 {
2204 _timeStamp = ts;
2205 }
2206
2207
2208 public void setUserIdentityScope(UserIdentity.Scope scope)
2209 {
2210 _scope = scope;
2211 }
2212
2213
2214 @Override
2215 public AsyncContext startAsync() throws IllegalStateException
2216 {
2217 if (!_asyncSupported)
2218 throw new IllegalStateException("!asyncSupported");
2219 HttpChannelState state = getHttpChannelState();
2220 if (_async==null)
2221 _async=new AsyncContextState(state);
2222 AsyncContextEvent event = new AsyncContextEvent(_context,_async,state,this,this,getResponse());
2223 state.startAsync(event);
2224 return _async;
2225 }
2226
2227
2228 @Override
2229 public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException
2230 {
2231 if (!_asyncSupported)
2232 throw new IllegalStateException("!asyncSupported");
2233 HttpChannelState state = getHttpChannelState();
2234 if (_async==null)
2235 _async=new AsyncContextState(state);
2236 AsyncContextEvent event = new AsyncContextEvent(_context,_async,state,this,servletRequest,servletResponse);
2237 event.setDispatchContext(getServletContext());
2238 event.setDispatchPath(URIUtil.addPaths(getServletPath(),getPathInfo()));
2239 state.startAsync(event);
2240 return _async;
2241 }
2242
2243
2244 @Override
2245 public String toString()
2246 {
2247 return (_handled?"[":"(") + getMethod() + " " + _metadata.getURI() + (_handled?"]@":")@") + hashCode() + " " + super.toString();
2248 }
2249
2250
2251 @Override
2252 public boolean authenticate(HttpServletResponse response) throws IOException, ServletException
2253 {
2254 if (_authentication instanceof Authentication.Deferred)
2255 {
2256 setAuthentication(((Authentication.Deferred)_authentication).authenticate(this,response));
2257 return !(_authentication instanceof Authentication.ResponseSent);
2258 }
2259 response.sendError(HttpStatus.UNAUTHORIZED_401);
2260 return false;
2261 }
2262
2263
2264 @Override
2265 public Part getPart(String name) throws IOException, ServletException
2266 {
2267 getParts();
2268
2269 return _multiPartInputStream.getPart(name);
2270 }
2271
2272
2273 @Override
2274 public Collection<Part> getParts() throws IOException, ServletException
2275 {
2276 if (getContentType() == null || !getContentType().startsWith("multipart/form-data"))
2277 throw new ServletException("Content-Type != multipart/form-data");
2278 return getParts(null);
2279 }
2280
2281 private Collection<Part> getParts(MultiMap<String> params) throws IOException, ServletException
2282 {
2283 if (_multiPartInputStream == null)
2284 _multiPartInputStream = (MultiPartInputStreamParser)getAttribute(__MULTIPART_INPUT_STREAM);
2285
2286 if (_multiPartInputStream == null)
2287 {
2288 MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT);
2289
2290 if (config == null)
2291 throw new IllegalStateException("No multipart config for servlet");
2292
2293 _multiPartInputStream = new MultiPartInputStreamParser(getInputStream(),
2294 getContentType(), config,
2295 (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null));
2296
2297 setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream);
2298 setAttribute(__MULTIPART_CONTEXT, _context);
2299 Collection<Part> parts = _multiPartInputStream.getParts();
2300 ByteArrayOutputStream os = null;
2301 for (Part p:parts)
2302 {
2303 MultiPartInputStreamParser.MultiPart mp = (MultiPartInputStreamParser.MultiPart)p;
2304 if (mp.getContentDispositionFilename() == null)
2305 {
2306
2307 String charset = null;
2308 if (mp.getContentType() != null)
2309 charset = MimeTypes.getCharsetFromContentType(mp.getContentType());
2310
2311 try (InputStream is = mp.getInputStream())
2312 {
2313 if (os == null)
2314 os = new ByteArrayOutputStream();
2315 IO.copy(is, os);
2316 String content=new String(os.toByteArray(),charset==null?StandardCharsets.UTF_8:Charset.forName(charset));
2317 if (_contentParameters == null)
2318 _contentParameters = params == null ? new MultiMap<String>() : params;
2319 _contentParameters.add(mp.getName(), content);
2320 }
2321 os.reset();
2322 }
2323 }
2324 }
2325
2326 return _multiPartInputStream.getParts();
2327 }
2328
2329
2330 @Override
2331 public void login(String username, String password) throws ServletException
2332 {
2333 if (_authentication instanceof Authentication.Deferred)
2334 {
2335 _authentication=((Authentication.Deferred)_authentication).login(username,password,this);
2336 if (_authentication == null)
2337 throw new Authentication.Failed("Authentication failed for username '"+username+"'");
2338 }
2339 else
2340 {
2341 throw new Authentication.Failed("Authenticated failed for username '"+username+"'. Already authenticated as "+_authentication);
2342 }
2343 }
2344
2345
2346 @Override
2347 public void logout() throws ServletException
2348 {
2349 if (_authentication instanceof Authentication.User)
2350 ((Authentication.User)_authentication).logout();
2351 _authentication=Authentication.UNAUTHENTICATED;
2352 }
2353
2354
2355 public void mergeQueryParameters(String oldQuery,String newQuery, boolean updateQueryString)
2356 {
2357
2358
2359 MultiMap<String> newQueryParams = null;
2360
2361 if (newQuery!=null)
2362 {
2363 newQueryParams = new MultiMap<>();
2364 UrlEncoded.decodeTo(newQuery, newQueryParams, UrlEncoded.ENCODING);
2365 }
2366
2367 MultiMap<String> oldQueryParams = _queryParameters;
2368 if (oldQueryParams == null && oldQuery != null)
2369 {
2370 oldQueryParams = new MultiMap<>();
2371 UrlEncoded.decodeTo(oldQuery, oldQueryParams, getQueryEncoding());
2372 }
2373
2374 MultiMap<String> mergedQueryParams;
2375 if (newQueryParams==null || newQueryParams.size()==0)
2376 mergedQueryParams=oldQueryParams==null?NO_PARAMS:oldQueryParams;
2377 else if (oldQueryParams==null || oldQueryParams.size()==0)
2378 mergedQueryParams=newQueryParams==null?NO_PARAMS:newQueryParams;
2379 else
2380 {
2381
2382 mergedQueryParams=new MultiMap<>(newQueryParams);
2383 mergedQueryParams.addAllValues(oldQueryParams);
2384 }
2385
2386 setQueryParameters(mergedQueryParams);
2387 resetParameters();
2388
2389 if (updateQueryString)
2390 {
2391
2392
2393 StringBuilder mergedQuery = new StringBuilder();
2394 if (newQuery!=null)
2395 mergedQuery.append(newQuery);
2396 for (Map.Entry<String, List<String>> entry : mergedQueryParams.entrySet())
2397 {
2398 if (newQueryParams!=null && newQueryParams.containsKey(entry.getKey()))
2399 continue;
2400 for (String value : entry.getValue())
2401 {
2402 if (mergedQuery.length()>0)
2403 mergedQuery.append("&");
2404 mergedQuery.append(entry.getKey()).append("=").append(value);
2405 }
2406 }
2407
2408 setQueryString(mergedQuery.toString());
2409 }
2410 }
2411
2412
2413
2414
2415 @Override
2416 public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException
2417 {
2418 if (getContext() == null)
2419 throw new ServletException ("Unable to instantiate "+handlerClass);
2420
2421 try
2422 {
2423
2424 T h = getContext().createInstance(handlerClass);
2425
2426
2427
2428 return h;
2429 }
2430 catch (Exception e)
2431 {
2432 if (e instanceof ServletException)
2433 throw (ServletException)e;
2434 throw new ServletException(e);
2435 }
2436 }
2437
2438
2439 }